From 83b87c6d639d40ef332c5fe21a2043660028ad89 Mon Sep 17 00:00:00 2001 From: herbglitch Date: Wed, 19 Mar 2025 05:13:11 -0600 Subject: [PATCH] wrote documentation for spritesheet, and worked on adding spritesheet to graphics config --- cmake/archeus_sdl2.cmake | 1 + include/arc/graphics/config.h | 2 +- include/arc/graphics/spritesheet.h | 52 +++++++++++- include/arc/std/config.h | 9 ++ packages/graphics/sdl/config.c | 127 ++++------------------------ packages/graphics/sdl/spritesheet.c | 56 +++++++++--- packages/graphics/sdl/spritesheet.h | 2 +- src/graphics/spritesheet.c | 2 +- src/std/config.c | 11 +++ 9 files changed, 136 insertions(+), 126 deletions(-) diff --git a/cmake/archeus_sdl2.cmake b/cmake/archeus_sdl2.cmake index 1e8e380..8b22655 100644 --- a/cmake/archeus_sdl2.cmake +++ b/cmake/archeus_sdl2.cmake @@ -1,4 +1,5 @@ set(ARCHEUS_SDL2_WINDOW_SOURCES + packages/graphics/sdl/config.c packages/graphics/sdl/window.c packages/graphics/sdl/renderer.c ) diff --git a/include/arc/graphics/config.h b/include/arc/graphics/config.h index 4e8a57e..a195743 100644 --- a/include/arc/graphics/config.h +++ b/include/arc/graphics/config.h @@ -11,7 +11,7 @@ extern "C" { /** * @brief */ -void ARC_GraphicsConfig_Init(ARC_Config *config, ARC_Renderer *renderer); +void ARC_Config_InitGraphics(ARC_Config *config, ARC_Renderer *renderer); /** * @brief diff --git a/include/arc/graphics/spritesheet.h b/include/arc/graphics/spritesheet.h index 1d03ce5..3310fe0 100644 --- a/include/arc/graphics/spritesheet.h +++ b/include/arc/graphics/spritesheet.h @@ -11,16 +11,64 @@ extern "C" { #include "arc/graphics/renderer.h" #include "arc/std/string.h" +/** + * @brief the spritesheet type, it will be defined within the backend (most likely in the backend's spritesheet header) +*/ typedef struct ARC_Spritesheet ARC_Spritesheet; +/** + * @brief creates a spritesheet from a given filepath and renderer + * + * @note this function only reads in pngs currently, will be updated later to support more file extensions + * + * @param[out] spritesheet ARC_Spritesheet to create + * @param[in] renderer the renderer used to create the spritesheet + * @param[in] path the path of the spritesheet to read in +*/ void ARC_Spritesheet_CreateFromFile(ARC_Spritesheet **spritesheet, ARC_Renderer *renderer, ARC_String *path); +/** + * @brief destroys a given spritehseet + * + * @param[in] spritesheet ARC_Spritesheet to free +*/ void ARC_Spritesheet_Destroy(ARC_Spritesheet *spritesheet); -void ARC_Spritesheet_RenderArea(ARC_Spritesheet *spritesheet, ARC_Rect *sheetBounds, ARC_Renderer *renderer, ARC_Rect *renderBounds); +/** + * @brief renders a section of a spritesheet + * + * @param[in] spritesheet ARC_Spritesheet to render part of + * @param[in] sheetBounds the area of the spritesheet to render + * @param[in] renderer the renderer to draw to + * @param[in] renderBounds the area of the renderer to copy the spritesheet area to +*/ +void ARC_Spritesheet_RenderArea(ARC_Spritesheet *spritesheet, ARC_Rect sheetBounds, ARC_Renderer *renderer, ARC_Rect renderBounds); +/** + * @brief renders a tile of a spritesheet + * + * @note if the tile size is zero this function will error + * + * @param[in] spritesheet ARC_Spritesheet to render tile from + * @param[in] tilePosition the coordinate of a tile to render (will be multiplied by tile size) + * @param[in] renderer the renderer to draw to + * @param[in] renderBounds the area of the renderer to copy the tile to +*/ +void ARC_Spritesheet_RenderTile(ARC_Spritesheet *spritesheet, ARC_Point tilePosition, ARC_Renderer *renderer, ARC_Rect renderBounds); + +/** + * @brief gets the x and y size of a given spritesheet in pixels + * + * @param[in] spritesheet ARC_Spritesheet to get the size of +*/ ARC_Point ARC_Spritesheet_GetSize(ARC_Spritesheet *spritesheet); -uint32_t *ARC_Spritesheet_GetTileSize(ARC_Spritesheet *spritesheet); + +/** + * @brief gets the length of a tile (square) in pixels of a spritesheet + * + * @param[in] spritesheet gets the tilesize of a spritesheet +*/ +uint32_t ARC_Spritesheet_GetTileSize(ARC_Spritesheet *spritesheet); #ifdef __cplusplus } diff --git a/include/arc/std/config.h b/include/arc/std/config.h index 969b6d8..9bce5be 100644 --- a/include/arc/std/config.h +++ b/include/arc/std/config.h @@ -35,11 +35,15 @@ typedef struct ARC_ConfigType { /** * @brief creates the arc config type (a type that loads in config files and can have types added to it) + * + * @param[out] ARC_Config to create */ void ARC_Config_Create(ARC_Config **config); /** * @brief destroys an ARC_Config type + * + * @param[in] config ARC_Config to destroy */ void ARC_Config_Destroy(ARC_Config *config); @@ -119,6 +123,11 @@ void ARC_Config_LoadFromString(ARC_Config *config, ARC_String **string); */ void ARC_Config_LoadFromFile(ARC_Config *config, ARC_String *path); +/** + * @brief TODO: write this +*/ +void ARC_Config_LoadFromFileWithCStr(ARC_Config *config, const char *path); + /** * @brief TODO: write this */ diff --git a/packages/graphics/sdl/config.c b/packages/graphics/sdl/config.c index f4d900d..07ced82 100644 --- a/packages/graphics/sdl/config.c +++ b/packages/graphics/sdl/config.c @@ -5,8 +5,8 @@ #include "renderer.h" #include "sprite.h" #include "spritesheet.h" -#include "arc/std/array.h" #include "arc/std/string.h" +#include "arc/std/parser/helpers.h" #include "arc/std/errno.h" #include "arc/graphics/sprite.h" #include "arc/graphics/spritesheet.h" @@ -14,146 +14,51 @@ #include "arc/math/point.h" #include "arc/math/rectangle.h" - void ARC_Config_InitGraphics(ARC_Config *config, ARC_Renderer *renderer){ - //ARC_Config_AddKeyCString(config, (char *)"SDL_Texture" , 11, ARC_SDL_Texture_Read, ARC_SDL_Texture_Delete); ARC_Config_RegisterTypeWithCStr(config, "ARC_Spritesheet", (ARC_ConfigType){ ARC_ConfigType_SpritesheetCopyFn, ARC_ConfigType_SpritesheetDestroyFn, renderer}); ARC_Config_RegisterTypeWithCStr(config, "ARC_Sprite" , (ARC_ConfigType){ ARC_ConfigType_SpriteCopyFn , ARC_ConfigType_SpriteDestroyFn , renderer}); } -int32_t ARC_SDL_Texture_Load(SDL_Texture **texture, ARC_Renderer *renderer, const char *path){ - 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_ - } +void ARC_ConfigType_SpritesheetString(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ + ARC_Renderer *renderer = (ARC_Renderer *)userdata; - SDL_BlendMode tempMode; - SDL_GetSurfaceBlendMode(surface, &tempMode); - *texture = SDL_CreateTextureFromSurface((SDL_Renderer *)renderer, surface); - SDL_GetTextureBlendMode(*texture, &tempMode); + //get the path + ARC_String *path; + ARC_String_Create(&path, NULL, 0); + ARC_ParserData_HelperRecurseStringAdd(&path, parsedData); - SDL_FreeSurface(surface); - IMG_Quit(); + //read in and set the texture + ARC_Spritesheet_CreateFromFile((ARC_Spritesheet **)type, renderer, path); - return 0; + //cleanup + ARC_String_Destroy(path); } -//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; -//} - void ARC_ConfigType_SpritesheetCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ ARC_ParserTagToken *valueTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(parsedData->tagTokens, 0); switch(valueTagToken->id){ case ARC_CONFIG_STRING: + ARC_ConfigType_SpritesheetString(type, valueTagToken, config, userdata); break; case ARC_CONFIG_NESTED_VALUE: - break; + return; default: + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_SpritesheetCopyFn(type, parsedData, config, userdata), cannot use a value that is not a string or nested value. Look at documention for this function for more info"); break; } -// 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; } -/** - * @brief -*/ void ARC_ConfigType_SpritesheetDestroyFn(void *type){ + ARC_Spritesheet_Destroy((ARC_Spritesheet *)type); } -/** - * @brief -*/ void ARC_ConfigType_SpriteCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ } -/** - * @brief -*/ void ARC_ConfigType_SpriteDestroyFn(void *type){ } diff --git a/packages/graphics/sdl/spritesheet.c b/packages/graphics/sdl/spritesheet.c index ad06e10..a2e8a20 100644 --- a/packages/graphics/sdl/spritesheet.c +++ b/packages/graphics/sdl/spritesheet.c @@ -3,29 +3,45 @@ #include "spritesheet.h" #include "renderer.h" #include "arc/math/point.h" +#include "arc/std/errno.h" #include #include #include -//TODO: Temp function void ARC_Spritesheet_CreateFromFile(ARC_Spritesheet **spritesheet, ARC_Renderer *renderer, ARC_String *path){ - *spritesheet = (ARC_Spritesheet *)malloc(sizeof(ARC_Spritesheet)); - + //TODO: allow other types of images + //init image as a png IMG_Init(IMG_INIT_PNG); + + //get and check the SDL surface SDL_Surface *surface = IMG_Load(path->data); if(!surface){ - printf("Error: reading png '%s'\nSDL_Image Error: %s", path->data, IMG_GetError()); + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_Spritesheet_CreateFromFile(spritesheet, renderer, path), could not read path \"%s\", SDL2_Image Error: %s", path->data, IMG_GetError()); + + //cleanup + IMG_Quit(); + + //set the spritesheet to null and throw an error + *spritesheet = NULL; + return; } + //create the place to store the spritesheet + *spritesheet = (ARC_Spritesheet *)malloc(sizeof(ARC_Spritesheet)); + + //set the texture SDL_BlendMode tempMode; SDL_GetSurfaceBlendMode(surface, &tempMode); (*spritesheet)->texture = SDL_CreateTextureFromSurface((SDL_Renderer *)renderer, surface); - SDL_GetTextureBlendMode((*spritesheet)->texture, &tempMode); + SDL_SetTextureBlendMode((*spritesheet)->texture, tempMode); + //set the tile size to empty + (*spritesheet)->size = 0; + + //cleanup SDL_FreeSurface(surface); IMG_Quit(); - - ARC_Spritesheet_GetSize(*spritesheet); } void ARC_Spritesheet_Destroy(ARC_Spritesheet *spritesheet){ @@ -33,8 +49,28 @@ void ARC_Spritesheet_Destroy(ARC_Spritesheet *spritesheet){ free(spritesheet); } -void ARC_Spritesheet_RenderArea(ARC_Spritesheet *spritesheet, ARC_Rect *sheetBounds, ARC_Renderer *renderer, ARC_Rect *renderBounds){ - SDL_RenderCopy((SDL_Renderer *)renderer, spritesheet->texture, (SDL_Rect *)sheetBounds, (SDL_Rect *)renderBounds); +void ARC_Spritesheet_RenderArea(ARC_Spritesheet *spritesheet, ARC_Rect sheetBounds, ARC_Renderer *renderer, ARC_Rect renderBounds){ + SDL_RenderCopy((SDL_Renderer *)renderer, spritesheet->texture, (SDL_Rect *)&sheetBounds, (SDL_Rect *)&renderBounds); +} + +void ARC_Spritesheet_RenderTile(ARC_Spritesheet *spritesheet, ARC_Point tilePosition, ARC_Renderer *renderer, ARC_Rect renderBounds){ + //error when size is 0 + if(spritesheet->size == 0){ + arc_errno = ARC_ERRNO_NULL; + ARC_DEBUG_LOG_ERROR("ARC_Spritesheet_RenderTile(spritesheet, tilePosition, renderer, renderBounds), could not render a tile of size 0"); + return; + } + + //get bounds based on the sheet size + ARC_Rect sheetBounds = { + spritesheet->size * tilePosition.x, + spritesheet->size * tilePosition.y, + spritesheet->size, + spritesheet->size + }; + + //render the bounds + SDL_RenderCopy((SDL_Renderer *)renderer, spritesheet->texture, (SDL_Rect *)&sheetBounds, (SDL_Rect *)&renderBounds); } ARC_Point ARC_Spritesheet_GetSize(ARC_Spritesheet *spritesheet){ @@ -43,6 +79,6 @@ ARC_Point ARC_Spritesheet_GetSize(ARC_Spritesheet *spritesheet){ return size; } -uint32_t *ARC_Spritesheet_GetTileSize(ARC_Spritesheet *spritesheet){ +uint32_t ARC_Spritesheet_GetTileSize(ARC_Spritesheet *spritesheet){ return spritesheet->size; } diff --git a/packages/graphics/sdl/spritesheet.h b/packages/graphics/sdl/spritesheet.h index 51094a1..b0f5972 100644 --- a/packages/graphics/sdl/spritesheet.h +++ b/packages/graphics/sdl/spritesheet.h @@ -6,7 +6,7 @@ struct ARC_Spritesheet { SDL_Texture *texture; - uint32_t *size; + uint32_t size; }; #endif // !ARC_SDL_SPRITESHEET_H_ diff --git a/src/graphics/spritesheet.c b/src/graphics/spritesheet.c index a08d5ce..12056d5 100644 --- a/src/graphics/spritesheet.c +++ b/src/graphics/spritesheet.c @@ -18,4 +18,4 @@ uint32_t *ARC_Spritesheet_GetTileSize(ARC_Spritesheet *spritesheet){ return NULL; } -#endif // !ARC_NONE_GRAPHICS \ No newline at end of file +#endif // !ARC_NONE_GRAPHICS diff --git a/src/std/config.c b/src/std/config.c index fa246cf..c04b1b8 100644 --- a/src/std/config.c +++ b/src/std/config.c @@ -739,6 +739,17 @@ void ARC_Config_LoadFromFile(ARC_Config *config, ARC_String *path){ ARC_Parser_ParseFile(config->parser, path); } +void ARC_Config_LoadFromFileWithCStr(ARC_Config *config, const char *path){ + config->load = ARC_True; + + ARC_String *pathString; + ARC_String_CreateWithStrlen(&pathString, (char *)path); + + ARC_Parser_ParseFile(config->parser, pathString); + + ARC_String_Destroy(pathString); +} + void ARC_Config_UnloadFromString(ARC_Config *config, ARC_String **string){ config->load = ARC_False; ARC_Parser_Parse(config->parser, string);