#include "arc/graphics/config.h" #include #include #include "renderer.h" #include "arc/graphics/sprite.h" #include "arc/graphics/spritesheet.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" #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; } } void ARC_ConfigType_SpritesheetDestroyFn(ARC_Config *config, void *type){ ARC_Spritesheet_Destroy((ARC_Spritesheet *)type); } void ARC_ConfigType_SpriteCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ //go into the 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 "); *type = NULL; return; } // -> OPEN_CURLY_BRACE 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); // -> COMMA | if(ARC_Vector_GetSize(valueArgsTagToken->tagTokens) == 1){ //TODO: error here } ARC_ParserTagToken *valueTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(valueArgsTagToken->tagTokens, 0); /* ~ spritesheet ~ */ //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); } //cleanup ARC_String_Destroy(valueString); valueString = NULL; /* ~ bounds aka frames ~ */ //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); *type = sprite; } 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); } //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); //}