mirror of https://github.com/libsdl-org/SDL
				
				
				
			
			You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			139 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C
		
	
			
		
		
	
	
			139 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C
		
	
| /*
 | |
|   Copyright (C) 1997-2025 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)
 | |
| {
 | |
|     const char *base = SDL_GetBasePath();
 | |
|     char *path;
 | |
| 
 | |
|     if (base) {
 | |
|         SDL_IOStream *rw;
 | |
| 
 | |
|         if (SDL_asprintf(&path, "%s%s", base, file) < 0) {
 | |
|             return NULL;
 | |
|         }
 | |
| 
 | |
|         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, 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 (SDL_GetSurfacePalette(temp)) {
 | |
|                 const Uint8 bpp = SDL_BITSPERPIXEL(temp->format);
 | |
|                 const Uint8 mask = (1 << bpp) - 1;
 | |
|                 if (SDL_PIXELORDER(temp->format) == SDL_BITMAPORDER_4321)
 | |
|                     SDL_SetSurfaceColorKey(temp, true, (*(Uint8 *)temp->pixels) & mask);
 | |
|                 else
 | |
|                     SDL_SetSurfaceColorKey(temp, true, ((*(Uint8 *)temp->pixels) >> (8 - bpp)) & mask);
 | |
|             } else {
 | |
|                 switch (SDL_BITSPERPIXEL(temp->format)) {
 | |
|                 case 15:
 | |
|                     SDL_SetSurfaceColorKey(temp, true,
 | |
|                                     (*(Uint16 *)temp->pixels) & 0x00007FFF);
 | |
|                     break;
 | |
|                 case 16:
 | |
|                     SDL_SetSurfaceColorKey(temp, true, *(Uint16 *)temp->pixels);
 | |
|                     break;
 | |
|                 case 24:
 | |
|                     SDL_SetSurfaceColorKey(temp, true,
 | |
|                                     (*(Uint32 *)temp->pixels) & 0x00FFFFFF);
 | |
|                     break;
 | |
|                 case 32:
 | |
|                     SDL_SetSurfaceColorKey(temp, 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", SDL_GetError());
 | |
|         }
 | |
|     }
 | |
|     SDL_DestroySurface(temp);
 | |
|     if (path) {
 | |
|         SDL_free(path);
 | |
|     }
 | |
|     return texture;
 | |
| }
 |