#include "arc/graphics/config.h" #include #include #include "renderer.h" #include "sprite.h" #include "spritesheet.h" #include "arc/std/array.h" #include "arc/std/string.h" #include "arc/std/errno.h" #include "arc/graphics/sprite.h" #include "arc/graphics/spritesheet.h" #include "arc/math/config.h" #include "arc/math/point.h" #include "arc/math/rectangle.h" // #define ARC_DEFAULT_CONFIG #include "arc/std/defaults/config.h" SDL_Renderer *global_renderer; uint8_t ARC_SDL_Texture_Read(ARC_Config *config, ARC_String *string, void **value); uint8_t ARC_Spritesheet_Read(ARC_Config *config, ARC_String *string, void **value); uint8_t ARC_Sprite_Read (ARC_Config *config, ARC_String *string, void **value); void ARC_SDL_Texture_Delete(ARC_Config *config, ARC_String *string, void *value); void ARC_Spritesheet_Delete(ARC_Config *config, ARC_String *string, void *value); void ARC_Sprite_Delete (ARC_Config *config, ARC_String *string, void *value); void ARC_GraphicsConfig_Init(ARC_Config *config, ARC_Renderer *renderer){ global_renderer = (SDL_Renderer *)renderer; ARC_Config_AddKeyCString(config, (char *)"SDL_Texture" , 11, ARC_SDL_Texture_Read, ARC_SDL_Texture_Delete); ARC_Config_AddKeyCString(config, (char *)"ARC_Spritesheet", 15, ARC_Spritesheet_Read, ARC_Spritesheet_Delete); ARC_Config_AddKeyCString(config, (char *)"ARC_Sprite" , 10, ARC_Sprite_Read , ARC_Sprite_Delete ); } uint64_t ARC_GraphicsConfig_GetIndexAndErrorCheck(ARC_String *string, char *search, uint64_t searchLength){ uint64_t separator = ARC_String_FindCString(string, ",", 1); if(separator == ~(uint64_t)0){ arc_errno = ARC_ERRNO_DATA; } return separator; } int32_t ARC_SDL_Texture_Load(const char *path, SDL_Texture **texture){ IMG_Init(IMG_INIT_PNG); SDL_Surface *surface = IMG_Load(path); if(!surface){ printf("Error: reading png '%s'\nSDL_Image Error: %s", path, IMG_GetError()); return 1; // GE_SDL_ERRNO_ } SDL_BlendMode tempMode; SDL_GetSurfaceBlendMode(surface, &tempMode); *texture = SDL_CreateTextureFromSurface(global_renderer, surface); SDL_GetTextureBlendMode(*texture, &tempMode); SDL_FreeSurface(surface); IMG_Quit(); return 0; } uint8_t ARC_SDL_Texture_Read(ARC_Config* config, ARC_String *string, void **value){ ARC_Config_Get(config, string, value); if(*value){ return 1; } ARC_String *tempStr, *textureStr; ARC_String_StripEndsWhitespace(&tempStr, string); ARC_String_CopySubstring(&textureStr, tempStr, 1, tempStr->length - 2); ARC_String_Destroy(tempStr); ARC_SDL_Texture_Load(textureStr->data, (SDL_Texture **)value); ARC_String_Destroy(textureStr); return 0; } void ARC_Spritesheet_ReadTexture(ARC_Config *config, ARC_String *string, uint32_t *size, void **value){ SDL_Texture *texture; ARC_String *tempStr, *textureStr; ARC_String_StripEndsWhitespace(&tempStr, string); //check for reference ARC_Config_Get(config, tempStr, (void **)&texture); if(!texture && (tempStr->data[0] != '"' || tempStr->data[string->length - 1] != '"')){ arc_errno = ARC_ERRNO_DATA; } ARC_String_CopySubstring(&textureStr, tempStr, 1, tempStr->length - 2); ARC_String_Destroy(tempStr); //try reading in the texture if(!texture){ ARC_SDL_Texture_Read(config, string, (void **)&texture); if(arc_errno){ *value = NULL; } } ARC_String_Destroy(textureStr); *value = malloc(sizeof(ARC_Spritesheet)); ((ARC_Spritesheet *) *value)->texture = texture; ((ARC_Spritesheet *) *value)->size = size; } uint8_t ARC_Spritesheet_Read(ARC_Config* config, ARC_String *string, void **value){ if(string->data[0] != '{' || string->data[string->length - 1] != '}'){ ARC_Spritesheet_ReadTexture(config, string, NULL, value); return 0; } uint64_t split = ARC_GraphicsConfig_GetIndexAndErrorCheck(string, ",", 1); if(arc_errno){ return 0; } ARC_String *temp, *textureStr, *sizeStr; ARC_String_CopySubstring(&temp, string, 1, split - 2); ARC_String_StripEndsWhitespace(&textureStr, temp); ARC_String_Destroy(temp); ARC_String_CopySubstring(&temp, string, split + 1, string->length - (split + 2)); ARC_String_StripEndsWhitespace(&sizeStr, temp); ARC_String_Destroy(temp); uint32_t *size; ARC_Config_Get(config, string, (void **)&size); if(!size){ ARC_ConfigKey_Read_Uint32_t(config, sizeStr, (void **)&size); if(arc_errno){ ARC_String_Destroy(sizeStr); ARC_String_Destroy(textureStr); return ARC_ERRNO_DATA; } } ARC_Spritesheet_ReadTexture(config, textureStr, size, value); ARC_String_Destroy(sizeStr); ARC_String_Destroy(textureStr); return 0; } uint8_t ARC_Sprite_Read(ARC_Config* config, ARC_String *string, void **value){ ARC_Config_Get(config, string, value); if(*value){ return 1; } if(string->data[0] != '{' || string->data[string->length - 1] != '}'){ ARC_Spritesheet_ReadTexture(config, string, NULL, value); return 0; } uint64_t split = ARC_GraphicsConfig_GetIndexAndErrorCheck(string, ",", 1); if(arc_errno){ return 0; } ARC_String *temp, *spritesheetStr, *framesStr; ARC_String_CopySubstring(&temp, string, 1, split - 2); ARC_String_StripEndsWhitespace(&spritesheetStr, temp); ARC_String_Destroy(temp); ARC_String_CopySubstring(&temp, string, split + 1, string->length - (split + 2)); ARC_String_StripEndsWhitespace(&framesStr, temp); ARC_String_Destroy(temp); //spritesheet ARC_Spritesheet *spritesheet; ARC_Config_Get(config, spritesheetStr, (void **)&spritesheet); if(!spritesheet){ ARC_Spritesheet_Read(config, spritesheetStr, (void **)&spritesheet); if(arc_errno){ ARC_String_Destroy(spritesheetStr); ARC_String_Destroy(framesStr ); return 0; } } //bounds ARC_Array *frames; ARC_Config_Get(config, framesStr, (void **)&frames); if(!frames){ ARC_RectArray_Read(config, framesStr, (void **)&frames); if(arc_errno){ ARC_String_Destroy(spritesheetStr); ARC_String_Destroy(framesStr ); return 0; } } ARC_String_Destroy(spritesheetStr); ARC_String_Destroy(framesStr ); // Scale frames to match spritesheet size // TODO: possible bug for sheets that use same frames if(spritesheet->size){ for(uint32_t i = 0; i < frames->size; i++){ ((ARC_Rect *)frames->data)[i].x *= *spritesheet->size; ((ARC_Rect *)frames->data)[i].y *= *spritesheet->size; ((ARC_Rect *)frames->data)[i].w *= *spritesheet->size; ((ARC_Rect *)frames->data)[i].h *= *spritesheet->size; } } //sprite ARC_Sprite_Create((ARC_Sprite **)value, spritesheet, frames); return 0; } void ARC_SDL_Texture_Delete(ARC_Config* config, ARC_String *string, void *value){ SDL_DestroyTexture((SDL_Texture *) value); } void ARC_Spritesheet_Delete(ARC_Config* config, ARC_String *string, void *value){ ARC_Spritesheet *sheetValue = (ARC_Spritesheet *)value; //check if read in as a Textrue reference void *temp; ARC_Config_Get(config, string, &temp); if(temp){ //TODO: test to see if this breaks references free(sheetValue); return; } uint64_t split = ARC_GraphicsConfig_GetIndexAndErrorCheck(string, ",", 1); if(arc_errno){ //TODO: test to make sure no edge cases // free(sheetValue); ARC_SDL_Texture_Delete(config, string, value); arc_errno = 0; return; } if(split == ~0){ } //check if texture and size are references ARC_String *tempStr, *textureStr, *sizeStr; ARC_String_CopySubstring(&tempStr, string, 1, split - 1); ARC_String_StripEndsWhitespace(&textureStr, tempStr); ARC_String_Destroy(tempStr); ARC_String_CopySubstring(&tempStr, string, split + 1, string->length - (split + 1)); ARC_String_StripEndsWhitespace(&sizeStr, tempStr); ARC_String_Destroy(tempStr); ARC_Config_Get(config, sizeStr, (void **)&temp); ARC_String_Destroy(sizeStr); if(temp){ free(sheetValue->size); } ARC_Config_Get(config, textureStr, (void **)&temp); ARC_String_Destroy(textureStr); if(temp){ free(sheetValue->size); } free(sheetValue); } void ARC_Sprite_Delete(ARC_Config* config, ARC_String *string, void *value){ ARC_Sprite *spriteValue = (ARC_Sprite *)value; //check if read in as a Textrue reference void *temp; uint64_t split = ARC_GraphicsConfig_GetIndexAndErrorCheck(string, ",", 1); if(arc_errno){ free(spriteValue); return; } //check if texture and size are references ARC_String *tempStr, *spritesheetStr, *framesStr; ARC_String_CopySubstring(&tempStr, string, 1, split - 1); ARC_String_StripEndsWhitespace(&spritesheetStr, tempStr); ARC_String_Destroy(tempStr); ARC_String_CopySubstring(&tempStr, string, split + 1, string->length - (split + 1)); ARC_String_StripEndsWhitespace(&framesStr, tempStr); ARC_String_Destroy(tempStr); ARC_Config_Get(config, spritesheetStr, (void **)&temp); ARC_String_Destroy(spritesheetStr); if(temp){ free(spriteValue->spritesheet); } ARC_Config_Get(config, framesStr, (void **)&temp); ARC_String_Destroy(framesStr); if(temp){ free(spriteValue->frames); } free(spriteValue); }