Files
SDL/test/testutils.c
Ryan C. Gordon 525919b315 rwops: Reworked RWops for SDL3.
- SDL_RWops is now an opaque struct.
- SDL_AllocRW is gone. If an app is creating a custom RWops, they pass the
  function pointers to SDL_CreateRW(), which are stored internally.
- SDL_RWclose is gone, there is only SDL_DestroyRW(), which calls the
  implementation's `->close` method before freeing other things.
- There is only one path to create and use RWops now, so we don't have to
  worry about whether `->close` will call SDL_DestroyRW, or if this will
  risk any Properties not being released, etc.
- SDL_RWFrom* still works as expected, for getting a RWops without having
  to supply your own implementation. Objects from these functions are also
  destroyed with SDL_DestroyRW.
- Lots of other cleanup and SDL3ization of the library code.
2024-03-14 19:36:08 -04:00

152 lines
4.4 KiB
C

/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
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.
*/
#include "testutils.h"
/**
* 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();
if (base) {
SDL_RWops *rw;
size_t len = SDL_strlen(base) + SDL_strlen(file) + 1;
path = SDL_malloc(len);
if (!path) {
SDL_free(base);
return NULL;
}
(void)SDL_snprintf(path, len, "%s%s", base, file);
SDL_free(base);
rw = SDL_RWFromFile(path, "rb");
if (rw) {
SDL_DestroyRW(rw);
return path;
}
/* Couldn't find the file in the base path */
SDL_free(path);
}
return SDL_strdup(file);
}
/**
* 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)
{
if (user_specified) {
return SDL_strdup(user_specified);
}
return GetNearbyFilename(def);
}
/**
* 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);
if (path) {
file = path;
}
temp = SDL_LoadBMP(file);
if (!temp) {
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) {
const Uint8 bpp = temp->format->bits_per_pixel;
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);
} else {
switch (temp->format->bits_per_pixel) {
case 15:
SDL_SetSurfaceColorKey(temp, SDL_TRUE,
(*(Uint16 *)temp->pixels) & 0x00007FFF);
break;
case 16:
SDL_SetSurfaceColorKey(temp, SDL_TRUE, *(Uint16 *)temp->pixels);
break;
case 24:
SDL_SetSurfaceColorKey(temp, SDL_TRUE,
(*(Uint32 *)temp->pixels) & 0x00FFFFFF);
break;
case 32:
SDL_SetSurfaceColorKey(temp, SDL_TRUE, *(Uint32 *)temp->pixels);
break;
}
}
}
if (width_out) {
*width_out = temp->w;
}
if (height_out) {
*height_out = temp->h;
}
texture = SDL_CreateTextureFromSurface(renderer, temp);
if (!texture) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError());
}
}
SDL_DestroySurface(temp);
if (path) {
SDL_free(path);
}
return texture;
}