spritesheet being read in, needs testing and possible memory leak fix

This commit is contained in:
herbglitch 2025-03-26 04:27:02 -06:00
parent 15ee2819b1
commit 2e97d908d8
7 changed files with 120 additions and 202 deletions

View file

@ -1,22 +1,22 @@
#include "arc/graphics/config.h"
#include <SDL3_image/SDL_image.h>
#include <stdio.h>
#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 "spritesheet.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"
#include "arc/std/errno.h"
#include "arc/std/string.h"
#include "arc/std/parser/helpers.h"
#include "arc/std/vector/inline.h"
#include <stdio.h>
#include <stdlib.h>
#include <SDL3_image/SDL_image.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});
ARC_Config_RegisterTypeWithCStr(config, "ARC_Spritesheet", (ARC_ConfigType){ sizeof(ARC_Spritesheet), ARC_ConfigType_SpritesheetCopyFn, ARC_ConfigType_SpritesheetDestroyFn, renderer});
ARC_Config_RegisterTypeWithCStr(config, "ARC_Sprite" , (ARC_ConfigType){ sizeof(ARC_Sprite) , ARC_ConfigType_SpriteCopyFn , ARC_ConfigType_SpriteDestroyFn , renderer});
}
void ARC_ConfigType_SpritesheetString(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){
@ -71,6 +71,9 @@ void ARC_ConfigType_SpriteCopyFn(void **type, ARC_ParserTagToken *parsedData, AR
//<nestedValue> -> OPEN_CURLY_BRACE <whitespace> <valueArgs> <whitespace> CLOSE_CURLY_BRACE
ARC_ParserTagToken *valueArgsTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(childTagToken->tagTokens, 2);
if(ARC_Vector_GetSize(valueArgsTagToken->tagTokens) == 1){
//TODO: error here
}
ARC_Sprite *sprite;
ARC_Sprite_Create(&sprite, NULL, (ARC_Array){ 0, NULL });
@ -79,14 +82,11 @@ void ARC_ConfigType_SpriteCopyFn(void **type, ARC_ParserTagToken *parsedData, AR
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);
/* ~ spritesheet ~ */
//<valueArgs> -> <value> <whitespace> COMMA <whitespace> <valueArgs> | <value>
ARC_ParserTagToken *valueTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(valueArgsTagToken->tagTokens, 0);
//check if spritesheet exist
ARC_String *valueString;
ARC_String_Create(&valueString, NULL, 0);
@ -110,23 +110,86 @@ void ARC_ConfigType_SpriteCopyFn(void **type, ARC_ParserTagToken *parsedData, AR
ARC_String_Destroy(spritesheetName);
}
//set the spritesheet to the sprite
sprite->spritesheet = spritesheet;
//cleanup
ARC_String_Destroy(valueString);
valueString = NULL;
/* ~ bounds aka frames ~ */
//<valueArgs> -> <value> <whitespace> COMMA <whitespace> <valueArgs> | <value>
valueArgsTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(valueArgsTagToken->tagTokens, 4);
if(ARC_Vector_GetSize(valueArgsTagToken->tagTokens) == 1){
//TODO: error here
}
//<valueArgs> -> <value> <whitespace> COMMA <whitespace> <valueArgs> | <value>
valueTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(valueArgsTagToken->tagTokens, 0);
//check if bounds exist
ARC_String_Create(&valueString, NULL, 0);
ARC_ParserData_HelperRecurseStringAdd(&valueString, valueTagToken);
void *bounds = ARC_Config_Get(config, valueString);
ARC_Array *bounds = (ARC_Array *)ARC_Config_Get(config, valueString);
if(bounds == NULL){
//ARC_Config_AddWithCStr(config, "ARC_FRect[]", const char *name, void *value)
//create a temporary vector to read in the array
ARC_VectorInline *typeVector;
ARC_VectorInline_Create(&typeVector, sizeof(ARC_FRect), NULL, NULL);
//<value> -> <variable> | <float> | <numberSign> | <string> | <nestedValue>
valueArgsTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(valueTagToken->tagTokens, 0);
//<valueArgs> -> <value> <whitespace> COMMA <whitespace> <valueArgs> | <value>
while(valueArgsTagToken->id == ARC_CONFIG_VALUE_ARGS){
valueTagToken = ARC_Vector_Get(valueArgsTagToken->tagTokens, 0);
//copy the type and store it in the vector
void *typeData = NULL;
ARC_ConfigType_FRectCopyFn(&typeData, valueTagToken, config, userdata);
ARC_VectorInline_Add(typeVector, typeData);
//if this value args was the last one break
if(ARC_Vector_GetSize(valueArgsTagToken->tagTokens) == 1){
break;
}
//get the next valueArgs
valueArgsTagToken = ARC_Vector_Get(valueArgsTagToken->tagTokens, 4);
}
//copy the data in an ARC_Array
ARC_Array typeVectorArray = ARC_VectorInline_GetData(typeVector);
bounds = (ARC_Array *)malloc(sizeof(ARC_Array));
bounds->size = typeVectorArray.size;
bounds->data = NULL;
if(typeVectorArray.size != 0){
//copy the vector into the array's data
bounds->data = (void *)malloc(sizeof(ARC_FRect) * typeVectorArray.size);
memcpy(bounds->data, typeVectorArray.data, typeVectorArray.size);
}
//create a name based on the type and the sprite pointer to have a unique name for cleanup on remove
ARC_String *boundsName;
ARC_String_CreateWithStrlen(&boundsName, pointerCString);
ARC_String_AppendCStringWithStrlen(&boundsName, "ARC_FRect");
//add the new ARC_FRect as ARC_Array type to the config
ARC_Config_AddWithCStr(config, "ARC_FRect", boundsName->data, (void *)bounds);
//cleanup
ARC_String_Destroy(boundsName);
}
//set the bounds to the frames
sprite->frames = *bounds;
//cleanup
ARC_String_Destroy(valueString);
//set the type
*type = sprite;
}
@ -137,177 +200,26 @@ void ARC_ConfigType_SpriteDestroyFn(ARC_Config *config, void *type){
char pointerCString[64];
sprintf(pointerCString, "%p", sprite);
/* ~ spritesheet ~ */
//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);
ARC_Config_RemoveWithCStr(config, spritesheetName->data, ARC_False);
/* ~ ARC_FRect Array ~ */
//create a name based on the type and the sprite pointer to have a unique name for cleanup on remove
ARC_String *boundsName;
ARC_String_CreateWithStrlen(&boundsName, pointerCString);
ARC_String_AppendCStringWithStrlen(&boundsName, "ARC_FRect");
//remove the ARC_FRect from the config (it won't error if it doesn't exist)
ARC_Config_RemoveWithCStr(config, boundsName->data, ARC_False);
//cleanup
ARC_String_Destroy(boundsName);
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);
//}

View file

@ -42,7 +42,7 @@ void ARC_Sprite_Render(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_FRect ren
}
void ARC_Sprite_RenderAt(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_FPoint point, double scale){
ARC_FRect sourceRect = *(ARC_FRect *)(sprite->frames.data + sprite->frameIndex);
ARC_FRect sourceRect = ((ARC_FRect *)(sprite->frames.data))[sprite->frameIndex];
//TODO: check that this works
ARC_FRect destinationRect = {
(point.x - sprite->origin.x) * scale,

View file

@ -30,6 +30,7 @@ void ARC_Spritesheet_CreateFromFile(ARC_Spritesheet **spritesheet, ARC_Renderer
SDL_GetSurfaceBlendMode(surface, &tempMode);
(*spritesheet)->texture = SDL_CreateTextureFromSurface((SDL_Renderer *)renderer, surface);
SDL_SetTextureBlendMode((*spritesheet)->texture, tempMode);
SDL_SetTextureScaleMode((*spritesheet)->texture, SDL_SCALEMODE_NEAREST);
//set the tile size to empty
(*spritesheet)->size = 0;