#include #include #include #include "loader.h" #include "printsdlerror.h" #include "util.h" /* Copyright (c) 2013-2021 Devine Lu Linvega 2018 web port by rezmason 2021 C89 port by rezmason Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE. */ static SDL_Renderer *_renderer = NULL; static char *basePath = NULL; static SDL_Surface *missingSurface = NULL; Sound * createEmptySound() { Sound *sound = (Sound *)malloc(sizeof(Sound)); sound->path = NULL; sound->chunk = NULL; sound->volume = 1; return sound; } void drawSurfaceToImage(Image *image, SDL_Surface *surface) { SDL_Texture *texture = SDL_CreateTextureFromSurface(_renderer, surface); if(texture == NULL) { printSDLError("SDL could not create texture."); } else { SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); image->w = surface->w; image->h = surface->h; image->texture = texture; } } int loadImage(Image *image) { char *fullPath = concat(basePath, image->filePath); SDL_Surface *loadedSurface = IMG_Load(fullPath); if(loadedSurface == NULL) { printSDLError("SDL could not load image %s.", fullPath); drawSurfaceToImage(image, missingSurface); } else { drawSurfaceToImage(image, loadedSurface); SDL_FreeSurface(loadedSurface); } free(fullPath); return image->texture != NULL; } int loadSound(Sound *sound) { char *fullPath = concat(basePath, sound->path); SDL_RWops *file = SDL_RWFromFile(fullPath, "rb"); Mix_Chunk *chunk = Mix_LoadWAV_RW(file, 1); if(chunk == NULL) { printSDLError("SDL could not load chunk %s.", fullPath); } else { int volume = MIX_MAX_VOLUME * sound->volume; sound->chunk = chunk; if(volume < 0) { volume = 0; } Mix_VolumeChunk(chunk, volume); } free(fullPath); return sound->chunk != NULL; } void Loader_Init(SDL_Renderer *renderer) { _renderer = renderer; basePath = SDL_GetBasePath(); missingSurface = SDL_CreateRGBSurface(0, 1, 1, 32, 0, 0, 0, 0); #ifdef DEBUG /* In debug builds, missing images appear magenta. */ SDL_FillRect(missingSurface, NULL, SDL_MapRGB(missingSurface->format, 0xFF, 0, 0xFF)); #endif } void Loader_Quit() { _renderer = NULL; free(basePath); basePath = NULL; SDL_FreeSurface(missingSurface); missingSurface = NULL; } Image * Loader_CreateImage(Image **ptr, LoadType loadType, char *filePath) { Image *image = (Image *)malloc(sizeof(Image)); image->texture = NULL; image->loadType = loadType; image->filePath = filePath; *ptr = image; return image; } int Loader_LoadImage(Image *image) { if(image == NULL) { return 1; } Loader_UnloadImage(image); return loadImage(image); } void Loader_UnloadImage(Image *image) { if(image == NULL) { return; } if(image->texture != NULL) { SDL_DestroyTexture(image->texture); image->texture = NULL; } } void Loader_DestroyImage(Image *image) { if(image == NULL) { return; } Loader_UnloadImage(image); free(image); } Sound * Loader_CreateSound(Sound **ptr, char *path, float volume) { Sound *sound = createEmptySound(); sound->path = path; sound->volume = volume; *ptr = sound; return sound; } int Loader_LoadSound(Sound *sound) { if(sound == NULL) { return 1; } Loader_UnloadSound(sound); return loadSound(sound); } void Loader_UnloadSound(Sound *sound) { if(sound == NULL) { return; } if(sound->chunk != NULL) { Mix_FreeChunk(sound->chunk); sound->chunk = NULL; } } void Loader_DestroySound(Sound *sound) { if(sound == NULL) { return; } Loader_UnloadSound(sound); free(sound); } int Loader_LoadText(char **ptr, char *path) { char *text = NULL; char *fullPath = concat(basePath, path); SDL_RWops *file = SDL_RWFromFile(fullPath, "r"); if(file == NULL) { printSDLError("SDL could not open text %s.", fullPath); } else { long fileSize = file->size(file); text = calloc(fileSize + 1, 1); if(SDL_RWread(file, text, fileSize, 1) == 0) { printSDLError("SDL could not read text %s.", fullPath); free(text); text = NULL; } SDL_RWclose(file); } free(fullPath); *ptr = text; return text != NULL; } int Loader_LoadCursor(SDL_Cursor **ptr, char *path) { SDL_Cursor *cursor = NULL; char *fullPath = concat(basePath, path); SDL_Surface *loadedSurface = IMG_Load(fullPath); if(loadedSurface == NULL) { printSDLError("SDL could not load image %s.", fullPath); } else { cursor = SDL_CreateColorCursor(loadedSurface, loadedSurface->w / 2, loadedSurface->h / 2); if(cursor == NULL) { printSDLError("SDL could not create a cursor from %s.", fullPath); } SDL_FreeSurface(loadedSurface); } free(fullPath); *ptr = cursor; return cursor != NULL; }