#include #define STB_NO_STDIO #define STB_IMAGE_IMPLEMENTATION #define STB_ASSERT(x) #define STB_ONLY_PNG #include "stb_image.h" #include "util.h" #include "sprites.h" #include "assets.h" typedef struct { unsigned char *im_data; SDL_Surface *surface; } sprite_set_t; static sprite_set_t sprite_set_init( const asset_id_t asset_id ) { sprite_set_t set; // get asset const asset_t * const asset = asset_get(asset_id); // load image int im_w, im_h; set.im_data = stbi_load_from_memory(asset->buf, asset->len, &im_w, &im_h, NULL, 4); if (!set.im_data) { die("stbi_load(): %s", stbi_failure_reason()); } // create surface set.surface = SDL_CreateRGBSurfaceWithFormatFrom(set.im_data, im_w, im_h, 32, 4 * im_w, SDL_PIXELFORMAT_RGBA32); if (!set.surface) { die("SDLCreateRGBSurfaceFrom(): %s", SDL_GetError()); } // return sprite set return set; } static void sprite_set_fini( const sprite_set_t * const set ) { // free main surface SDL_FreeSurface(set->surface); // free image data stbi_image_free(set->im_data); } static SDL_Surface * sprite_set_get_sprite_surface( const sprite_set_t * const set, const sprite_t icon_sprite ) { // create surface SDL_Surface *r = SDL_CreateRGBSurfaceWithFormat(0, 32, 32, 32, SDL_PIXELFORMAT_RGBA32); if (!r) { die("SDL_CreateRGBSurfaceWithFormat(): %s", SDL_GetError()); } // copy from main surface const SDL_Rect src_rect = { icon_sprite * 32, 0, 32, 32 }; if (SDL_BlitScaled(set->surface, &src_rect, r, NULL)) { die("SDL_BlitScaled(): %s", SDL_GetError()); } // return surface return r; } void sprites_init( SDL_Renderer * const renderer, SDL_Texture **sprites ) { // init sprite set from asset sprite_set_t set = sprite_set_init(ASSET_SPRITES_PNG); // create sprite textures for (size_t i = 0; i < SPRITE_LAST; i++) { // create surface SDL_Surface *s = sprite_set_get_sprite_surface(&set, i); // create texture sprites[i] = SDL_CreateTextureFromSurface(renderer, s); if (!sprites[i]) { die("SDLCreateTextureFromSurface(): %s", SDL_GetError()); } // free surface SDL_FreeSurface(s); } // fini sprite set sprite_set_fini(&set); } SDL_Rect sprites_get_rect( const sprite_t sprite ) { const int x = ((sprite < SPRITE_LAST) ? sprite : SPRITE_NONE) * 32; return (SDL_Rect) { .x = x, .y = 0, .w = 32, .h = 32 }; } void sprites_set_window_icon( SDL_Window * const win, const sprite_t sprite_id ) { // init sprite set from asset sprite_set_t set = sprite_set_init(ASSET_SPRITES_PNG); // create icon surface SDL_Surface *surface = sprite_set_get_sprite_surface(&set, sprite_id); // set window icon SDL_SetWindowIcon(win, surface); // free icon surface SDL_FreeSurface(surface); // fini sprite set sprite_set_fini(&set); }