2025-03-22 23:25:21 -06:00
# include "arc/graphics/config.h"
# include <SDL3_image/SDL_image.h>
# include <stdio.h>
# include "renderer.h"
2025-03-23 00:45:39 -06:00
# include "arc/graphics/sprite.h"
# include "arc/graphics/spritesheet.h"
2025-03-22 23:25:21 -06:00
# 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"
# include "arc/math/config.h"
# include "arc/math/point.h"
# include "arc/math/rectangle.h"
void ARC_Config_InitGraphics ( ARC_Config * config , ARC_Renderer * renderer ) {
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 } ) ;
}
void ARC_ConfigType_SpritesheetString ( void * * type , ARC_ParserTagToken * parsedData , ARC_Config * config , void * userdata ) {
ARC_Renderer * renderer = ( ARC_Renderer * ) userdata ;
//get the string chars between the quotes
ARC_ParserTagToken * stringCharsTagToken = ( ARC_ParserTagToken * ) ARC_Vector_Get ( parsedData - > tagTokens , 1 ) ;
//get the path
ARC_String * path ;
ARC_String_Create ( & path , NULL , 0 ) ;
ARC_ParserData_HelperRecurseStringAdd ( & path , stringCharsTagToken ) ;
//read in and set the texture
ARC_Spritesheet_CreateFromFile ( ( ARC_Spritesheet * * ) type , renderer , path ) ;
//cleanup
ARC_String_Destroy ( path ) ;
}
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 :
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 ;
}
}
2025-03-25 04:54:13 -06:00
void ARC_ConfigType_SpritesheetDestroyFn ( ARC_Config * config , void * type ) {
2025-03-22 23:25:21 -06:00
ARC_Spritesheet_Destroy ( ( ARC_Spritesheet * ) type ) ;
}
void ARC_ConfigType_SpriteCopyFn ( void * * type , ARC_ParserTagToken * parsedData , ARC_Config * config , void * userdata ) {
2025-03-25 04:54:13 -06:00
//go into the <nestedValue> tag
ARC_ParserTagToken * childTagToken = ( ARC_ParserTagToken * ) ARC_Vector_Get ( parsedData - > tagTokens , 0 ) ;
if ( childTagToken - > id ! = ARC_CONFIG_NESTED_VALUE ) {
arc_errno = ARC_ERRNO_DATA ;
ARC_DEBUG_LOG_ERROR ( " ARC_ConfigType_SpriteCopyFn(type, parsedData, config, userdata), parsed data was not a <nestedValue> " ) ;
* type = NULL ;
return ;
}
//<nestedValue> -> OPEN_CURLY_BRACE <whitespace> <valueArgs> <whitespace> CLOSE_CURLY_BRACE
ARC_ParserTagToken * valueArgsTagToken = ( ARC_ParserTagToken * ) ARC_Vector_Get ( childTagToken - > tagTokens , 2 ) ;
ARC_Sprite * sprite ;
ARC_Sprite_Create ( & sprite , NULL , ( ARC_Array ) { 0 , NULL } ) ;
//really large number in case a system has 64 digit pointer addresses
char pointerCString [ 64 ] ;
sprintf ( pointerCString , " %p " , sprite ) ;
//<valueArgs> -> <value> <whitespace> COMMA <whitespace> <valueArgs> | <value>
if ( ARC_Vector_GetSize ( valueArgsTagToken - > tagTokens ) = = 1 ) {
//TODO: error here
}
ARC_ParserTagToken * valueTagToken = ( ARC_ParserTagToken * ) ARC_Vector_Get ( valueArgsTagToken - > tagTokens , 0 ) ;
2025-03-25 19:19:47 -06:00
/* ~ spritesheet ~ */
2025-03-25 04:54:13 -06:00
//check if spritesheet exist
ARC_String * valueString ;
ARC_String_Create ( & valueString , NULL , 0 ) ;
ARC_ParserData_HelperRecurseStringAdd ( & valueString , valueTagToken ) ;
ARC_Spritesheet * spritesheet = ( ARC_Spritesheet * ) ARC_Config_Get ( config , valueString ) ;
if ( spritesheet = = NULL ) {
//create a name based on the type and the sprite pointer to have a unique name for cleanup on remove
ARC_String * spritesheetName ;
ARC_String_CreateWithStrlen ( & spritesheetName , pointerCString ) ;
ARC_String_AppendCStringWithStrlen ( & spritesheetName , " ARC_Spritesheet " ) ;
//copy the spritesheet
ARC_Spritesheet * sheet ;
ARC_ConfigType_SpritesheetCopyFn ( ( void * ) & sheet , valueTagToken , config , userdata ) ;
//add the new spritesheet type to the config
ARC_Config_AddWithCStr ( config , " ARC_Spritesheet " , spritesheetName - > data , ( void * ) sheet ) ;
//cleanup
ARC_String_Destroy ( spritesheetName ) ;
}
2025-03-25 19:19:47 -06:00
//cleanup
2025-03-25 04:54:13 -06:00
ARC_String_Destroy ( valueString ) ;
valueString = NULL ;
2025-03-25 19:19:47 -06:00
/* ~ bounds aka frames ~ */
2025-03-25 04:54:13 -06:00
//check if bounds exist
ARC_String_Create ( & valueString , NULL , 0 ) ;
ARC_ParserData_HelperRecurseStringAdd ( & valueString , valueTagToken ) ;
void * bounds = ARC_Config_Get ( config , valueString ) ;
if ( bounds = = NULL ) {
//ARC_Config_AddWithCStr(config, "ARC_FRect[]", const char *name, void *value)
}
ARC_String_Destroy ( valueString ) ;
2025-03-25 19:19:47 -06:00
* type = sprite ;
2025-03-22 23:25:21 -06:00
}
2025-03-25 04:54:13 -06:00
void ARC_ConfigType_SpriteDestroyFn ( ARC_Config * config , void * type ) {
ARC_Sprite * sprite = ( ARC_Sprite * ) type ;
//really large number in case a system has 64 digit pointer addresses
char pointerCString [ 64 ] ;
sprintf ( pointerCString , " %p " , sprite ) ;
//create a name based on the type and the sprite pointer to have a unique name for cleanup on remove
ARC_String * spritesheetName ;
ARC_String_CreateWithStrlen ( & spritesheetName , pointerCString ) ;
ARC_String_AppendCStringWithStrlen ( & spritesheetName , " ARC_Spritesheet " ) ;
//remove the spritesheet from the config (it won't error if it doesn't exist)
//ARC_Config_RemoveWithCStr(config, spritesheetName->data, ARC_False);
//cleanup
ARC_String_Destroy ( spritesheetName ) ;
2025-03-22 23:25:21 -06:00
}
//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);
//}