mirror of
				https://github.com/libsdl-org/SDL.git
				synced 2025-11-04 09:44:35 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			152 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			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_IOStream *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_IOFromFile(path, "rb");
 | 
						|
        if (rw) {
 | 
						|
            SDL_CloseIO(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;
 | 
						|
}
 |