2022-04-12 06:07:18 -06:00
|
|
|
/*
|
2024-01-01 14:15:26 -07:00
|
|
|
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
2023-07-12 10:53:52 -06:00
|
|
|
Copyright 2022 Collabora Ltd.
|
|
|
|
|
|
|
|
This software is provided 'as-is', without any express or implied
|
|
|
|
warranty. In no event will the authors be held liable for any damages
|
|
|
|
arising from the use of this software.
|
|
|
|
|
|
|
|
Permission is granted to anyone to use this software for any purpose,
|
|
|
|
including commercial applications, and to alter it and redistribute it
|
|
|
|
freely.
|
2022-04-12 06:07:18 -06:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "testutils.h"
|
|
|
|
|
2023-02-01 16:21:53 -07:00
|
|
|
/**
|
2022-04-12 06:07:18 -06:00
|
|
|
* Return the absolute path to def in the SDL_GetBasePath() if possible, or
|
|
|
|
* the relative path to def on platforms that don't have a working
|
|
|
|
* SDL_GetBasePath(). Free the result with SDL_free.
|
|
|
|
*
|
|
|
|
* Fails and returns NULL if out of memory.
|
|
|
|
*/
|
|
|
|
char *
|
|
|
|
GetNearbyFilename(const char *file)
|
|
|
|
{
|
|
|
|
char *base;
|
|
|
|
char *path;
|
|
|
|
|
|
|
|
base = SDL_GetBasePath();
|
|
|
|
|
2023-11-09 14:29:15 -07:00
|
|
|
if (base) {
|
2022-05-18 10:59:12 -06:00
|
|
|
SDL_RWops *rw;
|
2022-05-19 15:54:23 -06:00
|
|
|
size_t len = SDL_strlen(base) + SDL_strlen(file) + 1;
|
2022-04-12 06:07:18 -06:00
|
|
|
|
|
|
|
path = SDL_malloc(len);
|
|
|
|
|
2023-11-09 14:29:15 -07:00
|
|
|
if (!path) {
|
2022-05-18 09:23:26 -06:00
|
|
|
SDL_free(base);
|
2022-04-12 06:07:18 -06:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2022-12-01 14:07:03 -07:00
|
|
|
(void)SDL_snprintf(path, len, "%s%s", base, file);
|
2022-04-12 06:07:18 -06:00
|
|
|
SDL_free(base);
|
2022-05-18 10:59:12 -06:00
|
|
|
|
|
|
|
rw = SDL_RWFromFile(path, "rb");
|
|
|
|
if (rw) {
|
2024-03-12 07:01:37 -06:00
|
|
|
SDL_CloseRW(rw);
|
2022-05-18 10:59:12 -06:00
|
|
|
return path;
|
2022-05-18 09:23:26 -06:00
|
|
|
}
|
2022-05-18 10:59:12 -06:00
|
|
|
|
|
|
|
/* Couldn't find the file in the base path */
|
|
|
|
SDL_free(path);
|
2022-04-12 06:07:18 -06:00
|
|
|
}
|
|
|
|
|
error: SDL's allocators now call SDL_OutOfMemory on error.
This means the allocator's caller doesn't need to use SDL_OutOfMemory directly
if the allocation fails.
This applies to the usual allocators: SDL_malloc, SDL_calloc, SDL_realloc
(all of these regardless of if the app supplied a custom allocator or we're
using system malloc() or an internal copy of dlmalloc under the hood),
SDL_aligned_alloc, SDL_small_alloc, SDL_strdup, SDL_asprintf, SDL_wcsdup...
probably others. If it returns something you can pass to SDL_free, it should
work.
The caller might still need to use SDL_OutOfMemory if something that wasn't
SDL allocated the memory: operator new in C++ code, Objective-C's alloc
message, win32 GlobalAlloc, etc.
Fixes #8642.
2023-11-29 22:14:27 -07:00
|
|
|
return SDL_strdup(file);
|
2022-04-12 06:07:18 -06:00
|
|
|
}
|
|
|
|
|
2023-02-01 16:21:53 -07:00
|
|
|
/**
|
2022-04-12 06:07:18 -06:00
|
|
|
* If user_specified is non-NULL, return a copy of it. Free with SDL_free.
|
|
|
|
*
|
|
|
|
* Otherwise, return the absolute path to def in the SDL_GetBasePath() if
|
|
|
|
* possible, or the relative path to def on platforms that don't have a
|
|
|
|
* working SDL_GetBasePath(). Free the result with SDL_free.
|
|
|
|
*
|
|
|
|
* Fails and returns NULL if out of memory.
|
|
|
|
*/
|
|
|
|
char *
|
|
|
|
GetResourceFilename(const char *user_specified, const char *def)
|
|
|
|
{
|
2023-11-09 14:29:15 -07:00
|
|
|
if (user_specified) {
|
error: SDL's allocators now call SDL_OutOfMemory on error.
This means the allocator's caller doesn't need to use SDL_OutOfMemory directly
if the allocation fails.
This applies to the usual allocators: SDL_malloc, SDL_calloc, SDL_realloc
(all of these regardless of if the app supplied a custom allocator or we're
using system malloc() or an internal copy of dlmalloc under the hood),
SDL_aligned_alloc, SDL_small_alloc, SDL_strdup, SDL_asprintf, SDL_wcsdup...
probably others. If it returns something you can pass to SDL_free, it should
work.
The caller might still need to use SDL_OutOfMemory if something that wasn't
SDL allocated the memory: operator new in C++ code, Objective-C's alloc
message, win32 GlobalAlloc, etc.
Fixes #8642.
2023-11-29 22:14:27 -07:00
|
|
|
return SDL_strdup(user_specified);
|
2022-04-12 06:07:18 -06:00
|
|
|
}
|
error: SDL's allocators now call SDL_OutOfMemory on error.
This means the allocator's caller doesn't need to use SDL_OutOfMemory directly
if the allocation fails.
This applies to the usual allocators: SDL_malloc, SDL_calloc, SDL_realloc
(all of these regardless of if the app supplied a custom allocator or we're
using system malloc() or an internal copy of dlmalloc under the hood),
SDL_aligned_alloc, SDL_small_alloc, SDL_strdup, SDL_asprintf, SDL_wcsdup...
probably others. If it returns something you can pass to SDL_free, it should
work.
The caller might still need to use SDL_OutOfMemory if something that wasn't
SDL allocated the memory: operator new in C++ code, Objective-C's alloc
message, win32 GlobalAlloc, etc.
Fixes #8642.
2023-11-29 22:14:27 -07:00
|
|
|
return GetNearbyFilename(def);
|
2022-04-12 06:07:18 -06:00
|
|
|
}
|
|
|
|
|
2023-02-01 16:21:53 -07:00
|
|
|
/**
|
2022-04-12 06:07:18 -06:00
|
|
|
* Load the .bmp file whose name is file, from the SDL_GetBasePath() if
|
|
|
|
* possible or the current working directory if not.
|
|
|
|
*
|
|
|
|
* If transparent is true, set the transparent colour from the top left pixel.
|
|
|
|
*
|
|
|
|
* If width_out is non-NULL, set it to the texture width.
|
|
|
|
*
|
|
|
|
* If height_out is non-NULL, set it to the texture height.
|
|
|
|
*/
|
|
|
|
SDL_Texture *
|
|
|
|
LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent,
|
|
|
|
int *width_out, int *height_out)
|
|
|
|
{
|
|
|
|
SDL_Surface *temp = NULL;
|
|
|
|
SDL_Texture *texture = NULL;
|
|
|
|
char *path;
|
|
|
|
|
|
|
|
path = GetNearbyFilename(file);
|
|
|
|
|
2023-11-09 14:29:15 -07:00
|
|
|
if (path) {
|
2022-04-12 06:07:18 -06:00
|
|
|
file = path;
|
|
|
|
}
|
|
|
|
|
|
|
|
temp = SDL_LoadBMP(file);
|
2023-11-09 14:29:15 -07:00
|
|
|
if (!temp) {
|
2022-04-12 06:07:18 -06:00
|
|
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError());
|
|
|
|
} else {
|
|
|
|
/* Set transparent pixel as the pixel at (0,0) */
|
|
|
|
if (transparent) {
|
|
|
|
if (temp->format->palette) {
|
2024-02-11 09:03:26 -07:00
|
|
|
const Uint8 bpp = temp->format->bits_per_pixel;
|
2023-11-17 07:10:32 -07:00
|
|
|
const Uint8 mask = (1 << bpp) - 1;
|
|
|
|
if (SDL_PIXELORDER(temp->format->format) == SDL_BITMAPORDER_4321)
|
|
|
|
SDL_SetSurfaceColorKey(temp, SDL_TRUE, (*(Uint8 *)temp->pixels) & mask);
|
|
|
|
else
|
|
|
|
SDL_SetSurfaceColorKey(temp, SDL_TRUE, ((*(Uint8 *)temp->pixels) >> (8 - bpp)) & mask);
|
2022-04-12 06:07:18 -06:00
|
|
|
} else {
|
2024-02-11 09:03:26 -07:00
|
|
|
switch (temp->format->bits_per_pixel) {
|
2022-04-12 06:07:18 -06:00
|
|
|
case 15:
|
2022-12-27 07:36:39 -07:00
|
|
|
SDL_SetSurfaceColorKey(temp, SDL_TRUE,
|
2022-11-30 13:51:59 -07:00
|
|
|
(*(Uint16 *)temp->pixels) & 0x00007FFF);
|
2022-04-12 06:07:18 -06:00
|
|
|
break;
|
|
|
|
case 16:
|
2022-12-27 07:36:39 -07:00
|
|
|
SDL_SetSurfaceColorKey(temp, SDL_TRUE, *(Uint16 *)temp->pixels);
|
2022-04-12 06:07:18 -06:00
|
|
|
break;
|
|
|
|
case 24:
|
2022-12-27 07:36:39 -07:00
|
|
|
SDL_SetSurfaceColorKey(temp, SDL_TRUE,
|
2022-11-30 13:51:59 -07:00
|
|
|
(*(Uint32 *)temp->pixels) & 0x00FFFFFF);
|
2022-04-12 06:07:18 -06:00
|
|
|
break;
|
|
|
|
case 32:
|
2022-12-27 07:36:39 -07:00
|
|
|
SDL_SetSurfaceColorKey(temp, SDL_TRUE, *(Uint32 *)temp->pixels);
|
2022-04-12 06:07:18 -06:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-09 14:29:15 -07:00
|
|
|
if (width_out) {
|
2022-04-12 06:07:18 -06:00
|
|
|
*width_out = temp->w;
|
|
|
|
}
|
|
|
|
|
2023-11-09 14:29:15 -07:00
|
|
|
if (height_out) {
|
2022-04-12 06:07:18 -06:00
|
|
|
*height_out = temp->h;
|
|
|
|
}
|
|
|
|
|
|
|
|
texture = SDL_CreateTextureFromSurface(renderer, temp);
|
2023-11-09 14:29:15 -07:00
|
|
|
if (!texture) {
|
2022-04-12 06:07:18 -06:00
|
|
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError());
|
|
|
|
}
|
|
|
|
}
|
2022-12-27 07:36:39 -07:00
|
|
|
SDL_DestroySurface(temp);
|
2022-04-12 06:07:18 -06:00
|
|
|
if (path) {
|
|
|
|
SDL_free(path);
|
|
|
|
}
|
|
|
|
return texture;
|
|
|
|
}
|