diff --git a/include/arc/engine/engine.h b/include/arc/engine/engine.h index 0da5f25..e7f9f85 100644 --- a/include/arc/engine/engine.h +++ b/include/arc/engine/engine.h @@ -7,19 +7,27 @@ extern "C" { #include "arc/graphics/window.h" #include "arc/graphics/renderer.h" +#include "arc/input/mouse.h" +#include "arc/input/keyboard.h" #include "arc/std/handler.h" +#include "arc/math/point.h" typedef struct ARC_EngineData { ARC_Window *window; ARC_Renderer *renderer; ARC_Handler *state; + ARC_Mouse *mouse; + ARC_Keyboard *keyboard; double dt; + uint32_t running; + ARC_Point windowSize; } ARC_EngineData; //NOTE: most work below is temp, and will change once I figure out a better way to write this header -void ARC_EngineData_Create(ARC_EngineData **data); +void ARC_EngineData_Create(ARC_EngineData **data, ARC_Handler_CleanDataFn cleanfn); + void ARC_EngineData_Destroy(ARC_EngineData *data); /** diff --git a/include/arc/engine/state.h b/include/arc/engine/state.h index 8efb2f8..ae43005 100644 --- a/include/arc/engine/state.h +++ b/include/arc/engine/state.h @@ -5,9 +5,12 @@ extern "C" { #endif +typedef void (* ARC_State_UpdateFn)(void *data); +typedef void (* ARC_State_RenderFn)(void *data); typedef struct ARC_State { - void (* updateFn)(); - void (* renderFn)(); + ARC_State_UpdateFn updateFn; + ARC_State_RenderFn renderFn; + void *data; } ARC_State; void ARC_State_Update(void *data); diff --git a/include/arc/graphics/config.h b/include/arc/graphics/config.h index 9b9e021..b173267 100644 --- a/include/arc/graphics/config.h +++ b/include/arc/graphics/config.h @@ -4,7 +4,7 @@ #ifdef __cplusplus extern "C" { #endif - + #include "arc/std/config.h" #include "arc/graphics/renderer.h" @@ -14,4 +14,4 @@ void ARC_GraphicsConfig_Init(ARC_Config *config, ARC_Renderer *renderer); } #endif -#endif // !ARC_GRAPHICS_CONFIG_H_ +#endif // !ARC_GRAPHICS_CONFIG_H_ \ No newline at end of file diff --git a/include/arc/graphics/renderer.h b/include/arc/graphics/renderer.h index 619d03e..692b771 100644 --- a/include/arc/graphics/renderer.h +++ b/include/arc/graphics/renderer.h @@ -18,7 +18,7 @@ typedef struct ARC_RenderInfo ARC_RenderInfo; * @param renderer ARC_Renderer to initialize * @param info Info on how to create ARC_Window */ -void ARC_Renderer_Create(ARC_Renderer **renderer, ARC_RenderInfo *data); +void ARC_Renderer_Create(ARC_Renderer **renderer, ARC_RenderInfo *info); /** * @brief destroys ARC_Renderer type diff --git a/include/arc/graphics/sdl/sprite.h b/include/arc/graphics/sdl/sprite.h index 4287860..6576219 100644 --- a/include/arc/graphics/sdl/sprite.h +++ b/include/arc/graphics/sdl/sprite.h @@ -4,11 +4,13 @@ #ifdef ARC_SDL #include -#include "arc/graphics/spritesheet.h" +#include "arc/graphics/sprite.h" struct ARC_Sprite { ARC_Spritesheet *spritesheet; - SDL_Rect *bounds; + ARC_Rect *frames; + uint32_t *frameSize; + uint32_t *frameIndex; }; #endif // ARC_SDL diff --git a/include/arc/graphics/sprite.h b/include/arc/graphics/sprite.h index f5ddc32..ff04dfa 100644 --- a/include/arc/graphics/sprite.h +++ b/include/arc/graphics/sprite.h @@ -5,8 +5,22 @@ extern "C" { #endif +#include "arc/graphics/renderer.h" +#include "arc/graphics/spritesheet.h" +#include "arc/math/rectangle.h" + typedef struct ARC_Sprite ARC_Sprite; +void ARC_Sprite_Create(ARC_Sprite **sprite, ARC_Spritesheet *spritesheet, ARC_Rect *bounds); + +void ARC_Sprite_Destroy(ARC_Sprite *sprite); + +void ARC_Sprite_Render(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *renderBounds); + +void ARC_Sprite_IterateFrame(ARC_Sprite *sprite); + +ARC_Rect *ARC_Sprite_GetBounds(ARC_Sprite *sprite); + #ifdef __cplusplus } #endif diff --git a/include/arc/input/keyboard.h b/include/arc/input/keyboard.h new file mode 100644 index 0000000..7d562a4 --- /dev/null +++ b/include/arc/input/keyboard.h @@ -0,0 +1,32 @@ +#ifndef ARC_GRAPHICS_KEYBOARD_H_ +#define ARC_GRAPHICS_KEYBOARD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +typedef struct ARC_Keyboard ARC_Keyboard; + +typedef struct ARC_KeyboardInfo ARC_KeyboardInfo; + +typedef enum ARC_KeyboardState { + ARC_KEY_NONE, + ARC_KEY_PRESSED, + ARC_KEY_RELEASED +} ARC_KeyboardState; + +#define ARC_KEYBOARD_BUTTON_NUM 239 + +void ARC_Keyboard_Create(ARC_Keyboard **keyboard, ARC_KeyboardInfo *info); +void ARC_Keyboard_Destroy(ARC_Keyboard *keyboard); +void ARC_Keyboard_Update(ARC_Keyboard *keyboard); + +ARC_KeyboardState ARC_Keyboard_GetState(ARC_Keyboard *keyboard, uint8_t keys); + +#ifdef __cplusplus +} +#endif + +#endif // !ARC_GRAPHICS_KEYBOARD_H_ \ No newline at end of file diff --git a/include/arc/input/mouse.h b/include/arc/input/mouse.h new file mode 100644 index 0000000..e857cbf --- /dev/null +++ b/include/arc/input/mouse.h @@ -0,0 +1,40 @@ +#ifndef ARC_GRAPHICS_MOUSE_H_ +#define ARC_GRAPHICS_MOUSE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "arc/math/point.h" + +typedef struct ARC_Mouse ARC_Mouse; + +typedef struct ARC_MouseInfo ARC_MouseInfo; + +typedef enum ARC_MouseState { + ARC_MOUSE_NONE, + ARC_MOUSE_PRESSED, + ARC_MOUSE_RELEASED +} ARC_MouseState; + +typedef enum ARC_MouseButton { + ARC_MOUSE_LEFT = 0, + ARC_MOUSE_MIDDLE = 1, + ARC_MOUSE_RIGHT = 2, + ARC_MOUSE_X1 = 3, + ARC_MOUSE_X2 = 4 +} ARC_MouseButton; + +#define ARC_MOUSE_BUTTON_NUM 5 + +void ARC_Mouse_Create(ARC_Mouse **mouse, ARC_MouseInfo *info); +void ARC_Mouse_Destroy(ARC_Mouse *mouse); +void ARC_Mouse_Update(ARC_Mouse *mouse); +ARC_Point *ARC_Mouse_GetCoords(ARC_Mouse *mouse); +ARC_MouseState ARC_Mouse_GetState(ARC_Mouse *mouse, ARC_MouseButton button); + +#ifdef __cplusplus +} +#endif + +#endif // !ARC_GRAPHICS_MOUSE_H_ \ No newline at end of file diff --git a/include/arc/input/sdl/keyboard.h b/include/arc/input/sdl/keyboard.h new file mode 100644 index 0000000..c1b04bc --- /dev/null +++ b/include/arc/input/sdl/keyboard.h @@ -0,0 +1,21 @@ +#ifndef ARC_SDL_KEYBOARD_H_ +#define ARC_SDL_KEYBOARD_H_ + +#ifdef ARC_SDL +#include +#include "arc/input/keyboard.h" + +struct ARC_Keyboard { + SDL_Event *event; + + ARC_KeyboardState *keys; + ARC_KeyboardState *released; +}; + +struct ARC_KeyboardInfo { + SDL_Event *event; +}; + +#endif // ARC_SDL + +#endif // !ARC_SDL_KEYBOARD_H_ \ No newline at end of file diff --git a/include/arc/input/sdl/mouse.h b/include/arc/input/sdl/mouse.h new file mode 100644 index 0000000..1acea38 --- /dev/null +++ b/include/arc/input/sdl/mouse.h @@ -0,0 +1,24 @@ +#ifndef ARC_SDL_MOUSE_H_ +#define ARC_SDL_MOUSE_H_ + +#ifdef ARC_SDL +#include +#include "arc/input/mouse.h" +#include "arc/math/point.h" + +struct ARC_Mouse { + SDL_Event *event; + ARC_Point *coords; + int32_t *scroll; + + ARC_MouseState *buttons; + uint8_t *buttonsReleased; +}; + +struct ARC_MouseInfo { + SDL_Event *event; +}; + +#endif // ARC_SDL + +#endif // !ARC_SDL_MOUSE_H_ \ No newline at end of file diff --git a/include/arc/math/point.h b/include/arc/math/point.h new file mode 100644 index 0000000..bfdad69 --- /dev/null +++ b/include/arc/math/point.h @@ -0,0 +1,14 @@ +#ifndef ARC_MATH_POINT_H_ +#define ARC_MATH_POINT_H_ + +#include + +typedef struct ARC_Point { + int32_t x, y; +} ARC_Point; + +typedef struct ARC_UPoint { + uint32_t x, y; +} ARC_UPoint; + +#endif // ARC_MATH_POINT_H_ diff --git a/include/arc/math/rectangle.h b/include/arc/math/rectangle.h index e69de29..c35f2d7 100644 --- a/include/arc/math/rectangle.h +++ b/include/arc/math/rectangle.h @@ -0,0 +1,20 @@ +#ifndef ARC_MATH_RECT_H_ +#define ARC_MATH_RECT_H_ + +#include + +typedef struct ARC_Rect { + int32_t x; + int32_t y; + int32_t w; + int32_t h; +} ARC_Rect; + +typedef struct ARC_URect { + uint32_t x; + uint32_t y; + uint32_t w; + uint32_t h; +} ARC_URect; + +#endif // ARC_MATH_POINT_H_ diff --git a/include/arc/math/vector2.h b/include/arc/math/vector2.h index 61fd6da..c68c085 100644 --- a/include/arc/math/vector2.h +++ b/include/arc/math/vector2.h @@ -1,30 +1,12 @@ #ifndef ARC_MATH_VECTOR2_H_ #define ARC_MATH_VECTOR2_H_ -#include - typedef struct ARC_Vector2 { - int32_t x, y; -} ARC_Vector2; - -typedef struct ARC_UVector2 { - uint32_t x, y; -} ARC_UVector2; - -typedef struct ARC_FVector2 { float x, y; -} ARC_FVector2; +} ARC_Vector2; typedef struct ARC_DVector2 { double x, y; } ARC_DVector2; -typedef struct ARC_LVector2 { - int64_t x, y; -} ARC_LVector2; - -typedef struct ARC_ULVector2 { - uint64_t x, y; -} ARC_ULVector2; - #endif // ARC_MATH_VECTOR2_H_ diff --git a/include/arc/std/errno.h b/include/arc/std/errno.h index 813cbdd..47bbf0c 100644 --- a/include/arc/std/errno.h +++ b/include/arc/std/errno.h @@ -8,12 +8,12 @@ #define ARC_ERRNO_COPY -0x03 #define ARC_ERRNO_EXISTS -0x04 #define ARC_ERRNO_OVERFLOW -0x05 - +#define ARC_ERRNO_INIT -0x06 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-variable" static int32_t arc_errno = 0; -// #pragma GCC diagnostic pop +#pragma GCC diagnostic pop #ifdef __cplusplus diff --git a/include/arc/std/handler.h b/include/arc/std/handler.h index 9e2fbe2..4a5abe3 100644 --- a/include/arc/std/handler.h +++ b/include/arc/std/handler.h @@ -12,6 +12,18 @@ extern "C" { */ typedef struct ARC_Handler ARC_Handler; +/** + * @brief data comparison function ptr + * + * @note this is used for comparison within vectors + * + * @param a first data struct + * @param b second data struct + * + * @return 0 when a == b + */ +typedef uint32_t (* ARC_Handler_CompareDataFn)(void *a, void *b); + /** * @brief a function that will take iterated data * @@ -30,14 +42,17 @@ typedef void (* ARC_Handler_CleanDataFn)(void *data); * @brief creates ARC_Handler type * * @param config ARC_Handler to initialize - * @param dataSize size of type the handler will use + * @param cleanfn function to clean data in handler + * can be null */ -void ARC_Handler_Create(ARC_Handler **handler, uint32_t dataSize); +void ARC_Handler_Create(ARC_Handler **handler, ARC_Handler_CleanDataFn cleanfn); /** * @brief destroyes ARC_Handler type + * + * @param handler ARC_Handler to destory */ -void ARC_Handler_Destroy(ARC_Handler *handler, ARC_Handler_CleanDataFn cleanfn); +void ARC_Handler_Destroy(ARC_Handler *handler); /** * @brief adds data to handler @@ -57,7 +72,7 @@ void ARC_Handler_Add(ARC_Handler *handler, void *data); * @param handler ARC_Handler to remove from * @param data data that is being removed */ -void ARC_Handler_Remove(ARC_Handler *handler, void *data); +void ARC_Handler_Remove(ARC_Handler *handler, void *data, ARC_Handler_CompareDataFn compare); /** * @brief remove from handler @@ -92,10 +107,8 @@ void ARC_Handler_Clear(ARC_Handler *handler); * @note cleanfn's main purpose is to help manage memory * * @param handler ARC_Handler to remove trash from - * @param cleanfn user provided function to run on trash before clearing from trash vector - * can be null */ -void ARC_Handler_Clean(ARC_Handler *handler, ARC_Handler_CleanDataFn cleanfn); +void ARC_Handler_Clean(ARC_Handler *handler); /** * @brief gets size of vector diff --git a/include/arc/std/vector.h b/include/arc/std/vector.h index 22ec4ec..dcf4ff2 100644 --- a/include/arc/std/vector.h +++ b/include/arc/std/vector.h @@ -20,15 +20,14 @@ typedef struct ARC_Vector ARC_Vector; * * @return 0 when a == b */ -typedef int8_t (* ARC_Vector_CompareDataFn)(void *a, void *b); +typedef int32_t (* ARC_Vector_CompareDataFn)(void *a, void *b); /** * @brief creates ARC_Vector type * - * @param vector ARC_Vector to initialize - * @param dataSize size of type the vector will store + * @param vector ARC_Vector to initialize */ -void ARC_Vector_Create(ARC_Vector **vector, uint32_t dataSize); +void ARC_Vector_Create(ARC_Vector **vector); /** * @brief destroyes ARC_Vector type @@ -80,4 +79,4 @@ void *ARC_Vector_Get(ARC_Vector *vector, uint32_t *index); } #endif -#endif //ARC_STD_VECTOR_H_ \ No newline at end of file +#endif //ARC_STD_VECTOR_H_ diff --git a/src/engine/engine.c b/src/engine/engine.c index 35180c9..cf5523a 100644 --- a/src/engine/engine.c +++ b/src/engine/engine.c @@ -4,76 +4,109 @@ #include "arc/engine/state.h" #include "arc/graphics/window.h" #include "arc/graphics/renderer.h" +#include "arc/input/mouse.h" +#include "arc/input/keyboard.h" +#include "arc/std/errno.h" #include "arc/std/handler.h" -//NOTE: this is very temp, mostly to get smthn running so I can test out different ideas +//NOTE: some of this file is temporary, mostly to get smthn running so I can test out different ideas #ifdef ARC_SDL #include #include "arc/graphics/sdl/window.h" #include "arc/graphics/sdl/renderer.h" +#include "arc/input/sdl/mouse.h" +#include "arc/input/sdl/keyboard.h" #endif // ARC_SDL -void ARC_EngineData_Create(ARC_EngineData **data){ +void ARC_EngineData_Create(ARC_EngineData **data, ARC_Handler_CleanDataFn cleanfn){ *data = (ARC_EngineData *)malloc(sizeof(ARC_EngineData)); (*data)->window = NULL; (*data)->renderer = NULL; - ARC_Handler_Create(&((*data)->state), sizeof(ARC_State)); + (*data)->mouse = NULL; - ARC_WindowInfo windowInfo; - ARC_RenderInfo renderInfo; + ARC_Handler_Create(&((*data)->state), cleanfn); + + ARC_WindowInfo windowInfo; + ARC_RenderInfo renderInfo; + ARC_MouseInfo mouseInfo; + ARC_KeyboardInfo keyboardInfo; + + (*data)->windowSize = (ARC_Point){ 2560, 1440 }; #ifdef ARC_SDL - if(SDL_Init(SDL_INIT_VIDEO) < 0){ - printf("Error: initializing SDL\nSDL Error: %s\n", SDL_GetError()); - free(*data); - return; - } - - windowInfo = (ARC_WindowInfo){ "title", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 720, 480, 0 }; + windowInfo = (ARC_WindowInfo){ "title", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, (*data)->windowSize.x, (*data)->windowSize.y, 0 }; #endif // ARC_SDL ARC_Window_Create(&((*data)->window), &windowInfo); - //TODO: handle arc_errno errors here + if(arc_errno){ + free(data); + return; + } #ifdef ARC_SDL renderInfo = (ARC_RenderInfo){ (SDL_Window *)(*data)->window->window, -1, SDL_RENDERER_ACCELERATED }; #endif // ARC_SDL ARC_Renderer_Create(&((*data)->renderer), &renderInfo); - //TODO: handle arc_errno errors here + if(arc_errno){ + ARC_Window_Destroy((*data)->window); + free(data); + } + +#ifdef ARC_SDL + SDL_Event *event = (SDL_Event *)malloc(sizeof(SDL_Event)); + mouseInfo = (ARC_MouseInfo ){ event }; + keyboardInfo = (ARC_KeyboardInfo){ event }; +#endif // ARC_SDL + + ARC_Mouse_Create(&((*data)->mouse), &mouseInfo); + + ARC_Keyboard_Create(&((*data)->keyboard), &keyboardInfo); } void ARC_EngineData_Destroy(ARC_EngineData *data){ #ifdef ARC_SDL - ARC_Handler_Destroy(data->state, NULL); //TODO: replace null with cleanup function + free(data->mouse->event); +#endif // ARC_SDL + + ARC_Mouse_Destroy(data->mouse); + ARC_Keyboard_Destroy(data->keyboard); ARC_Renderer_Destroy(data->renderer); ARC_Window_Destroy(data->window); -#endif // ARC_SDL + ARC_Handler_Destroy(data->state); } void ARC_Engine_Run(ARC_EngineData *data){ - double lastTime = 0, currentTime; + if(arc_errno){ + return; + } #ifdef ARC_SDL - SDL_Event event; + SDL_Event *event = data->mouse->event; #endif // ARC_SDL - while(1){ + double lastTime = 0, currentTime; + + data->dt = 0; + data->running = 0; + + while(!data->running){ #ifdef ARC_SDL currentTime = SDL_GetTicks(); data->dt = currentTime - lastTime; lastTime = currentTime; - while(SDL_PollEvent(&event)){ - if(event.type == SDL_QUIT){ return; } - if(event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_ESCAPE){ return; } - } + SDL_PollEvent(data->mouse->event); + if(event->type == SDL_QUIT){ return; } + if(event->type == SDL_KEYDOWN && event->key.keysym.sym == SDLK_ESCAPE){ return; } #endif // ARC_SDL - // data->mouse.update(data->event); - // data->keyboard.update(data->event); + ARC_Mouse_Update(data->mouse); + + ARC_Keyboard_Update(data->keyboard); + + ARC_Handler_Clean(data->state); - // data->state.update(); ARC_Handler_Iterate(data->state, ARC_State_Update); ARC_Renderer_Clear(data->renderer); diff --git a/src/engine/state.c b/src/engine/state.c index bca0a34..7f84745 100644 --- a/src/engine/state.c +++ b/src/engine/state.c @@ -1,11 +1,11 @@ #include "arc/engine/state.h" +#include void ARC_State_Update(void *data){ - ARC_State *temp = (ARC_State *) data; - ((ARC_State *)data)->updateFn(); + ARC_State *temp = (ARC_State *)data; + ((ARC_State *)data)->updateFn(((ARC_State *)data)->data); } void ARC_State_Render(void *data){ - ARC_State *temp = (ARC_State *) data; - ((ARC_State *)data)->renderFn(); + ((ARC_State *)data)->renderFn(((ARC_State *)data)->data); } \ No newline at end of file diff --git a/src/graphics/sdl/config.c b/src/graphics/sdl/config.c index a90142e..db872f8 100644 --- a/src/graphics/sdl/config.c +++ b/src/graphics/sdl/config.c @@ -10,25 +10,38 @@ #include "arc/graphics/sdl/sprite.h" #include "arc/graphics/spritesheet.h" #include "arc/graphics/sdl/spritesheet.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; -int32_t ARC_SDL_Rect_Read (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); +typedef struct ARC_Array { + uint32_t *size; + void *data; +} ARC_Array; + +int32_t ARC_Point_Read (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); +int32_t ARC_Rect_Read (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); +int32_t ARC_RectArray_Read (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); int32_t ARC_SDL_Texture_Read(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); int32_t ARC_Spritesheet_Read(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); int32_t ARC_Sprite_Read (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); -int32_t ARC_SDL_Rect_Delete (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); +int32_t ARC_Point_Delete (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); +int32_t ARC_Rect_Delete (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); +int32_t ARC_RectArray_Delete (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); int32_t ARC_SDL_Texture_Delete(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); int32_t ARC_Spritesheet_Delete(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); int32_t ARC_Sprite_Delete (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); void ARC_GraphicsConfig_Init(ARC_Config *config, ARC_Renderer *renderer){ global_renderer = renderer->renderer; - ARC_ConfigKey_Add(config, (char *)"SDL_Rect" , (ARC_ConfigKeyRead) ARC_SDL_Rect_Read , (ARC_ConfigKeyDelete) ARC_SDL_Rect_Delete ); + ARC_ConfigKey_Add(config, (char *)"ARC_Point" , (ARC_ConfigKeyRead) ARC_Point_Read , (ARC_ConfigKeyDelete) ARC_Point_Delete ); + ARC_ConfigKey_Add(config, (char *)"ARC_Rect" , (ARC_ConfigKeyRead) ARC_Rect_Read , (ARC_ConfigKeyDelete) ARC_Rect_Delete ); + ARC_ConfigKey_Add(config, (char *)"ARC_RectArray" , (ARC_ConfigKeyRead) ARC_RectArray_Read , (ARC_ConfigKeyDelete) ARC_RectArray_Delete ); ARC_ConfigKey_Add(config, (char *)"SDL_Texture" , (ARC_ConfigKeyRead) ARC_SDL_Texture_Read, (ARC_ConfigKeyDelete) ARC_SDL_Texture_Delete); ARC_ConfigKey_Add(config, (char *)"ARC_Spritesheet", (ARC_ConfigKeyRead) ARC_Spritesheet_Read, (ARC_ConfigKeyDelete) ARC_Spritesheet_Delete); ARC_ConfigKey_Add(config, (char *)"ARC_Sprite" , (ARC_ConfigKeyRead) ARC_Sprite_Read , (ARC_ConfigKeyDelete) ARC_Sprite_Delete ); @@ -50,21 +63,45 @@ int32_t ARC_SDL_Texture_Load(const char *path, SDL_Texture **texture){ return 0; } -int32_t ARC_SDL_Rect_Read(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){ +int32_t ARC_Point_Read(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){ ARC_StringSubstr_StripWhitespaceEnds((char *)data, subdata); if(data[subdata->index] != '{' || data[subdata->index + subdata->length - 1] != '}'){ return ARC_ERRNO_DATA; } subdata->index++; subdata->length -= 2; uint64_t split; - *value = malloc(sizeof(SDL_Rect)); + *value = malloc(sizeof(ARC_Rect)); //x int32_t err = ARC_String_Find(((char *)data) + subdata->index, (char *)",", &split); if(err){ return err; } if(split == ~((uint64_t)0) || split > subdata->length){ return ARC_ERRNO_DATA; } ARC_StringSubstr temp = { subdata->index, split }; - ((SDL_Rect *) *value)->x = (int)ARC_String_ToUint64_t(data, &temp); + ((SDL_Point *) *value)->x = (int)ARC_String_ToUint64_t(data, &temp); + + //y + temp = (ARC_StringSubstr){ temp.index + split + 1, subdata->length - split - 1 }; + ((SDL_Point *) *value)->y = (int)ARC_String_ToUint64_t(data, &temp); + + return 0; +} + +int32_t ARC_Rect_Read(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){ + ARC_StringSubstr_StripWhitespaceEnds((char *)data, subdata); + if(data[subdata->index] != '{' || data[subdata->index + subdata->length - 1] != '}'){ return ARC_ERRNO_DATA; } + subdata->index++; + subdata->length -= 2; + + uint64_t split; + *value = malloc(sizeof(ARC_Rect)); + + //x + int32_t err = ARC_String_Find(((char *)data) + subdata->index, (char *)",", &split); + if(err){ return err; } + if(split == ~((uint64_t)0) || split > subdata->length){ return ARC_ERRNO_DATA; } + ARC_StringSubstr temp = { subdata->index, split }; + ((ARC_Rect *) *value)->x = (int)ARC_String_ToUint64_t(data, &temp); + int32_t ttt = ((ARC_Rect *) *value)->x; //y temp.index = subdata->index + split + 1; @@ -73,6 +110,7 @@ int32_t ARC_SDL_Rect_Read(ARC_Config* config, const char *data, ARC_StringSubstr if(split == ~((uint64_t)0) || split > subdata->length){ return ARC_ERRNO_DATA; } temp.length = split; ((SDL_Rect *) *value)->y = (int)ARC_String_ToUint64_t(data, &temp); + ttt = ((ARC_Rect *) *value)->y; //w temp.index = temp.index + split + 1; @@ -81,12 +119,108 @@ int32_t ARC_SDL_Rect_Read(ARC_Config* config, const char *data, ARC_StringSubstr if(split == ~((uint64_t)0) || split > subdata->length){ return ARC_ERRNO_DATA; } temp.length = split; ((SDL_Rect *) *value)->w = (int)ARC_String_ToUint64_t(data, &temp); + ttt = ((ARC_Rect *) *value)->w; - //hhttps://w2g.tv/8r0knvefgpciytccsw + //h temp = (ARC_StringSubstr){ temp.index + split + 1, subdata->length - split - 1 }; ((SDL_Rect *) *value)->h = (int)ARC_String_ToUint64_t(data, &temp); + ttt = ((ARC_Rect *) *value)->h; - SDL_Rect *ntemp = ((SDL_Rect *) *value); + return 0; +} + +int32_t ARC_RectArray_Read(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){ + ARC_StringSubstr_StripWhitespaceEnds((char *)data, subdata); + if(data[subdata->index] != '{' || data[subdata->index + subdata->length - 1] != '}'){ return ARC_ERRNO_DATA; } + subdata->index++; + subdata->length -= 2; + + uint32_t arraySize = 1; + int32_t encapsulated = 0; + for(uint32_t i = subdata->index; i < subdata->index + subdata->length; i++){ + if(data[i] == '{'){ + encapsulated++; + continue; + } + + if(data[i] == '}'){ + encapsulated--; + continue; + } + + if(!encapsulated && data[i] == ','){ + arraySize++; + } + } + + if(encapsulated){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG(arc_errno, "in ARC_RectArray_Read(config, data, subdata, value); after looping encapsulated was %d", encapsulated); + return arc_errno; + } + + *value = malloc(sizeof(ARC_Array)); + ((ARC_Array *) *value)->data = malloc(sizeof(ARC_Rect) * arraySize); + ((ARC_Array *) *value)->size = malloc(sizeof(uint32_t)); + *((ARC_Array *) *value)->size = arraySize; + + ARC_StringSubstr temp = { subdata->index, 0 }; + arraySize = 0; + encapsulated = 0; + for(uint64_t i = subdata->index; i < subdata->index + subdata->length; i++){ + if(data[i] == '{'){ + encapsulated++; + continue; + } + + if(data[i] == '}'){ + encapsulated--; + continue; + } + + if(!encapsulated && data[i] == ','){ + temp.length = i - temp.index; + + ARC_Rect *tempRect = (ARC_Rect *)ARC_Config_GetReference(config, (char *)data, &temp); + if(!tempRect){ + ARC_Rect_Read(config, data, &temp, (void **) &tempRect); + if(arc_errno){ + return arc_errno; + } + } + + ((ARC_Rect *)((ARC_Array *) *value)->data)[arraySize] = *tempRect; + + ARC_Rect_Delete(config, data, &temp, (void *)tempRect); + if(arc_errno){ + return arc_errno; + } + + arraySize++; + temp = (ARC_StringSubstr){ i + 1, 0 }; + + if(arraySize == *((ARC_Array *) *value)->size){ + break; + } + } + } + + temp.length = (subdata->index + subdata->length) - temp.index; + ARC_Rect *tempRect = (ARC_Rect *)ARC_Config_GetReference(config, (char *)data, &temp); + if(!tempRect){ + int32_t ttt = ARC_Rect_Read(config, data, &temp, (void **) &tempRect); + if(arc_errno){ + return arc_errno; + } + } + + ((ARC_Rect *)((ARC_Array *) *value)->data)[arraySize] = *tempRect; + ARC_Rect ttt = ((ARC_Rect *)((ARC_Array *) *value)->data)[arraySize]; + + ARC_Rect_Delete(config, data, &temp, (void *)tempRect); + if(arc_errno){ + return arc_errno; + } return 0; } @@ -176,24 +310,58 @@ int32_t ARC_Sprite_Read(ARC_Config* config, const char *data, ARC_StringSubstr * } //bounds + uint8_t isRectArray = 0; temp = (ARC_StringSubstr){ subdata->index + split + 1, subdata->length - split - 1 }; ARC_StringSubstr_StripWhitespaceEnds((char *)data, &temp); - SDL_Rect *bounds = (SDL_Rect *)ARC_Config_GetReference(config, (char *)data, &temp); + ARC_Array *bounds = (ARC_Array *)ARC_Config_GetReference(config, (char *)data, &temp); if(!bounds){ - ARC_ConfigKey_Read_Uint64_t(config, data, &temp, (void **)&bounds); + err = ARC_RectArray_Read(config, data, &temp, (void **)&bounds); if(err){ return ARC_ERRNO_DATA; } + isRectArray = 1; + } + + //scale bounds on spritesheet size + // TODO: possible bug for sheets that use the same bounds + if(spritesheet->size){ + for(uint32_t i = 0; i < *bounds->size; i++){ + ((ARC_Rect *)bounds->data)[i].x *= *spritesheet->size; + ((ARC_Rect *)bounds->data)[i].y *= *spritesheet->size; + ((ARC_Rect *)bounds->data)[i].w *= *spritesheet->size; + ((ARC_Rect *)bounds->data)[i].h *= *spritesheet->size; + } } *value = malloc(sizeof(ARC_Sprite)); - ((ARC_Sprite *) *value)->spritesheet = spritesheet; - ((ARC_Sprite *) *value)->bounds = bounds; + ((ARC_Sprite *) *value)->frameIndex = malloc(sizeof(uint32_t)); + + ((ARC_Sprite *) *value)->spritesheet = spritesheet; + ((ARC_Sprite *) *value)->frames = bounds->data; + ((ARC_Sprite *) *value)->frameSize = bounds->size; + *((ARC_Sprite *) *value)->frameIndex = 0; + + ARC_Rect *ttt = (ARC_Rect *)bounds->data; + ARC_Rect ttf = ttt[0]; + + if(isRectArray){ + free(bounds); + } return 0; } -int32_t ARC_SDL_Rect_Delete(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ - if((SDL_Rect *)value){ free((SDL_Rect *)value); } +int32_t ARC_Point_Delete(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ + if((ARC_Point *)value){ free((ARC_Point *)value); } + return 0; +} + +int32_t ARC_Rect_Delete(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ + if((ARC_Rect *)value){ free((ARC_Rect *)value); } + return 0; +} + +int32_t ARC_RectArray_Delete(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ + if((ARC_Array *)value){ free((ARC_Array *)value); } return 0; } @@ -212,9 +380,14 @@ int32_t ARC_Spritesheet_Delete(ARC_Config* config, const char* data, ARC_StringS ARC_StringSubstr_StripWhitespaceEnds((char *)data, subdata); if(data[subdata->index] != '{'){ SDL_Texture *texture = (SDL_Texture *)ARC_Config_GetReference(config, (char *)data, subdata); - if(!texture){ ARC_SDL_Texture_Delete(config, data, subdata, (void *)spritesheet->texture); } + if(!texture){ + ARC_SDL_Texture_Delete(config, data, subdata, (void *)spritesheet->texture); + } + + // if(spritesheet){ + // free(spritesheet); + // } - free(spritesheet); return 0; } @@ -265,8 +438,12 @@ int32_t ARC_Sprite_Delete(ARC_Config* config, const char* data, ARC_StringSubstr ARC_StringSubstr_StripWhitespaceEnds((char *)data, &temp); SDL_Rect *bounds = (SDL_Rect *)ARC_Config_GetReference(config, (char *)data, &temp); - if(!bounds){ ARC_SDL_Rect_Delete(config, data, &temp, (void *)sprite->bounds); } + if(!bounds){ + free(sprite->frames); + free(sprite->frameSize); + } + free(sprite->frameIndex); free(sprite); return 0; } diff --git a/src/graphics/sdl/renderer.c b/src/graphics/sdl/renderer.c index e8878a0..ac6ea8a 100644 --- a/src/graphics/sdl/renderer.c +++ b/src/graphics/sdl/renderer.c @@ -17,9 +17,10 @@ void ARC_Renderer_Create(ARC_Renderer **renderer, ARC_RenderInfo *info){ *renderer = (ARC_Renderer *)malloc(sizeof(ARC_Renderer)); (*renderer)->renderer = SDL_CreateRenderer((SDL_Window *)info->window, info->index, info->flags); - if(!renderer){ + if(!(*renderer)->renderer){ arc_errno = ARC_ERRNO_NULL; ARC_DEBUG_LOG(arc_errno, "SDL_CreateRenderer(%p, %d, %u);", info->window, info->index, info->flags); + free(renderer); } } diff --git a/src/graphics/sdl/sprite.c b/src/graphics/sdl/sprite.c new file mode 100644 index 0000000..1928da5 --- /dev/null +++ b/src/graphics/sdl/sprite.c @@ -0,0 +1,38 @@ +#include "arc/graphics/sprite.h" +#ifdef ARC_SDL +#include "arc/graphics/sdl/sprite.h" +#include "arc/graphics/sdl/spritesheet.h" +#include "arc/graphics/sdl/renderer.h" +#include "arc/math/rectangle.h" +#include + +void ARC_Sprite_Create(ARC_Sprite **sprite, ARC_Spritesheet *spritesheet, ARC_Rect *frames){ + *sprite = (ARC_Sprite *)malloc(sizeof(ARC_Sprite)); + (*sprite)->spritesheet = spritesheet; + (*sprite)->frames = frames; + (*sprite)->frameIndex = (uint32_t *)malloc(sizeof(uint32_t)); + *(*sprite)->frameIndex = 0; +} + +void ARC_Sprite_Destroy(ARC_Sprite *sprite){ + free(sprite); +} + +void ARC_Sprite_Render(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *renderBounds){ + ARC_Rect *temp = &sprite->frames[*sprite->frameIndex]; + SDL_RenderCopy(renderer->renderer, sprite->spritesheet->texture, (SDL_Rect *)&sprite->frames[*sprite->frameIndex], (SDL_Rect *)renderBounds); +} + +void ARC_Sprite_IterateFrame(ARC_Sprite *sprite){ + ++*sprite->frameIndex; + + if(*sprite->frameIndex == *sprite->frameSize){ + *sprite->frameIndex = 0; + } +} + +ARC_Rect *ARC_Sprite_GetBounds(ARC_Sprite *sprite){ + return sprite->frames + *sprite->frameIndex; +} + +#endif // ARC_SDL \ No newline at end of file diff --git a/src/graphics/sdl/window.c b/src/graphics/sdl/window.c index 752ddfe..c9ed8b8 100644 --- a/src/graphics/sdl/window.c +++ b/src/graphics/sdl/window.c @@ -12,13 +12,19 @@ void ARC_Window_Create(ARC_Window **window, ARC_WindowInfo *info){ return; } - // (*window)->window = SDL_CreateWindow((const char *)info->title, info->x, info->y, info->w, info->h, info->flags); + if(SDL_Init(SDL_INIT_VIDEO) < 0){ + arc_errno = ARC_ERRNO_INIT; + printf("Error: initializing SDL\nSDL Error: %s\n", SDL_GetError()); + return; + } + *window = (ARC_Window *)malloc(sizeof(ARC_Window)); (*window)->window = SDL_CreateWindow((const char *)info->title, info->x, info->y, info->w, info->h, info->flags); if(!(*window)->window){ arc_errno = ARC_ERRNO_NULL; ARC_DEBUG_LOG(arc_errno, "SDL_CreateWindow(%s, %d, %d, %d, %d, %x);", info->title, info->x, info->y, info->w, info->h, info->flags); + free(window); } } diff --git a/src/input/sdl/keyboard.c b/src/input/sdl/keyboard.c new file mode 100644 index 0000000..ef273a4 --- /dev/null +++ b/src/input/sdl/keyboard.c @@ -0,0 +1,56 @@ +#ifdef ARC_SDL +#include "arc/input/sdl/keyboard.h" +#include "arc/input/keyboard.h" +#include "arc/math/point.h" +#include "arc/std/errno.h" +#include +#include +#include +#include + +void ARC_Keyboard_Create(ARC_Keyboard **keyboard, ARC_KeyboardInfo *info){ + *keyboard = (ARC_Keyboard *)malloc(sizeof(ARC_Keyboard)); + (*keyboard)->event = info->event; + (*keyboard)->keys = (ARC_KeyboardState *)malloc(sizeof(ARC_KeyboardState) * ARC_KEYBOARD_BUTTON_NUM); + + (*keyboard)->released = NULL; + + for(uint8_t i = 0; i < ARC_KEYBOARD_BUTTON_NUM; i++){ + (*keyboard)->keys[i] = ARC_KEY_NONE; + } +} + +void ARC_Keyboard_Destroy(ARC_Keyboard *keyboard){ + free(keyboard->keys); + + free(keyboard); +} + +void ARC_Keyboard_Update(ARC_Keyboard *keyboard){ + if(keyboard->released){ + *keyboard->released = ARC_KEY_NONE; + keyboard->released = NULL; + } + + if(keyboard->event->type != SDL_KEYDOWN && keyboard->event->type != SDL_KEYUP){ + return; + } + + if(keyboard->event->key.keysym.sym >= 239 || keyboard->event->key.keysym.sym < 0){ + return; + } + + if(keyboard->event->type == SDL_KEYDOWN){ + keyboard->keys[keyboard->event->key.keysym.sym] = ARC_KEY_PRESSED; + return; + } + + keyboard->keys[keyboard->event->key.keysym.sym] = ARC_KEY_RELEASED; + keyboard->released = (keyboard->keys + keyboard->event->key.keysym.sym); +} + +ARC_KeyboardState ARC_Keyboard_GetState(ARC_Keyboard *keyboard, uint8_t key){ + return keyboard->keys[key]; +} + +#endif // ARC_SDL \ No newline at end of file diff --git a/src/input/sdl/mouse.c b/src/input/sdl/mouse.c new file mode 100644 index 0000000..0a132b7 --- /dev/null +++ b/src/input/sdl/mouse.c @@ -0,0 +1,102 @@ +#ifdef ARC_SDL +#include "arc/input/sdl/mouse.h" +#include "arc/input/mouse.h" +#include "arc/math/point.h" +#include "arc/std/errno.h" +#include +#include +#include +#include + +void ARC_Mouse_Create(ARC_Mouse **mouse, ARC_MouseInfo *info){ + *mouse = (ARC_Mouse *)malloc(sizeof(ARC_Mouse)); + (*mouse)->event = info->event; + (*mouse)->coords = (ARC_Point *)malloc(sizeof(ARC_Point)); + (*mouse)->scroll = (int32_t *)malloc(sizeof(int32_t )); + (*mouse)->buttons = (ARC_MouseState *)malloc(sizeof(ARC_MouseState) * ARC_MOUSE_BUTTON_NUM); + + (*mouse)->buttonsReleased = (uint8_t *)malloc(sizeof(uint8_t)); + + *(*mouse)->coords = (ARC_Point){0, 0}; + *(*mouse)->scroll = 0; + + for(uint8_t i = 0; i < ARC_MOUSE_BUTTON_NUM; i++){ + (*mouse)->buttons[i] = ARC_MOUSE_NONE; + } + + *(*mouse)->buttonsReleased = 0; +} + +void ARC_Mouse_Destroy(ARC_Mouse *mouse){ + free(mouse->buttonsReleased); + + free(mouse->buttons); + free(mouse->scroll ); + free(mouse->coords ); + + free(mouse); +} + +void ARC_Mouse_UpdateButton(ARC_Mouse *mouse, uint8_t button, uint32_t *buttons, uint32_t mask){ + if(*buttons & mask){ + mouse->buttons[button] = ARC_MOUSE_PRESSED; + return; + } + + if(mouse->buttons[button] == ARC_MOUSE_NONE){ + return; + } + + if(mouse->buttons[button] == ARC_MOUSE_RELEASED){ + mouse->buttons[button] = ARC_MOUSE_NONE; + --*mouse->buttonsReleased; + return; + } + + mouse->buttons[button] = ARC_MOUSE_RELEASED; + ++*mouse->buttonsReleased; +} + +void ARC_Mouse_Update(ARC_Mouse *mouse){ + *mouse->scroll = 0; + if(mouse->event->type == SDL_MOUSEWHEEL){ + *mouse->scroll = mouse->event->wheel.y; + } + + uint32_t buttons = SDL_GetMouseState(&(mouse->coords->x), &(mouse->coords->y)); + + if(mouse->event->type != SDL_MOUSEBUTTONDOWN && mouse->event->type != SDL_MOUSEBUTTONUP){ + if(!*mouse->buttonsReleased){ + return; + } + + for(uint8_t i = *mouse->buttonsReleased; i > 0; i--){ + if(mouse->buttons[i - 1] == ARC_MOUSE_RELEASED){ + mouse->buttons[i - 1] = ARC_MOUSE_NONE; + --*mouse->buttonsReleased; + } + } + + // if(*mouse->buttonsReleased){ + // arc_errno = ARC_ERRNO_DATA; + // ARC_DEBUG_LOG(arc_errno, "in ARC_Mouse_Update mouse->buttonsReleased == %u, it needs to be 0\n", *(mouse->buttonsReleased)); + // } + return; + } + + ARC_Mouse_UpdateButton(mouse, ARC_MOUSE_LEFT , &buttons, SDL_BUTTON_LMASK ); + ARC_Mouse_UpdateButton(mouse, ARC_MOUSE_MIDDLE, &buttons, SDL_BUTTON_MMASK ); + ARC_Mouse_UpdateButton(mouse, ARC_MOUSE_RIGHT , &buttons, SDL_BUTTON_RMASK ); + ARC_Mouse_UpdateButton(mouse, ARC_MOUSE_X1 , &buttons, SDL_BUTTON_X1MASK); + ARC_Mouse_UpdateButton(mouse, ARC_MOUSE_X2 , &buttons, SDL_BUTTON_X2MASK); +} + +ARC_Point *ARC_Mouse_GetCoords(ARC_Mouse *mouse){ + return mouse->coords; +} + +ARC_MouseState ARC_Mouse_GetState(ARC_Mouse *mouse, ARC_MouseButton button){ + return mouse->buttons[button]; +} + +#endif // ARC_SDL \ No newline at end of file diff --git a/src/std/config.c b/src/std/config.c index 678c81e..10ad1db 100644 --- a/src/std/config.c +++ b/src/std/config.c @@ -149,7 +149,6 @@ int32_t ARC_Config_Get(ARC_Config *config, char *keyname, void **value){ int32_t ARC_Config_Remove(ARC_Config *config, const char *keyname, const char* data, ARC_StringSubstr *subdata){ ARC_DeleteUserData deldata = { .config = config, .data = data, .subdata = subdata }; - printf("data: %s\n\n", data); return ARC_Hashtable_Remove(config->currgroup, (void *)keyname, strlen(keyname), ARC_ConfigGroupNode_Destroy, (void *)&deldata); } diff --git a/src/std/handler.c b/src/std/handler.c index 2ece4b5..f482a94 100644 --- a/src/std/handler.c +++ b/src/std/handler.c @@ -7,17 +7,20 @@ struct ARC_Handler { ARC_Vector *data; ARC_Vector *trash; + + ARC_Handler_CleanDataFn cleanfn; }; -void ARC_Handler_Create(ARC_Handler **handler, uint32_t dataSize){ +void ARC_Handler_Create(ARC_Handler **handler, ARC_Handler_CleanDataFn cleanfn){ *handler = (ARC_Handler *) malloc(sizeof(ARC_Handler)); - ARC_Vector_Create(&((*handler)->data), dataSize); - ARC_Vector_Create(&((*handler)->trash), dataSize); + ARC_Vector_Create(&((*handler)->data)); + ARC_Vector_Create(&((*handler)->trash)); + (*handler)->cleanfn = cleanfn; } -void ARC_Handler_Destroy(ARC_Handler *handler, ARC_Handler_CleanDataFn cleanfn){ +void ARC_Handler_Destroy(ARC_Handler *handler){ ARC_Handler_Clear(handler); - ARC_Handler_Clean(handler, cleanfn); + ARC_Handler_Clean(handler); ARC_Vector_Destroy(handler->data); ARC_Vector_Destroy(handler->trash); @@ -29,17 +32,19 @@ void ARC_Handler_Add(ARC_Handler *handler, void *data){ ARC_Vector_Add(handler->data, data); } -int8_t ARC_Handler_RemoveCompareFn(void *a, void *b){ return a == b; } - -void ARC_Handler_Remove(ARC_Handler *handler, void *data){ - // ARC_Vector_Add(handler->trash, data); - ARC_Vector_Remove(handler->data, data, ARC_Handler_RemoveCompareFn); +void ARC_Handler_Remove(ARC_Handler *handler, void *data, ARC_Handler_CompareDataFn compare){ + ARC_Vector_Add(handler->trash, data); + ARC_Vector_Remove(handler->data, data, (ARC_Vector_CompareDataFn) compare); } void ARC_Handler_RemoveIndex(ARC_Handler *handler, uint32_t *index){ + if(!*ARC_Vector_Size(handler->data)){ + return; + } + void *data = ARC_Vector_Get(handler->data, index); - ARC_Vector_RemoveIndex(handler->data, index); ARC_Vector_Add(handler->trash, data); + ARC_Vector_RemoveIndex(handler->data, index); } void ARC_Handler_Iterate(ARC_Handler *handler, ARC_Handler_DataFn datafn){ @@ -49,16 +54,21 @@ void ARC_Handler_Iterate(ARC_Handler *handler, ARC_Handler_DataFn datafn){ } void ARC_Handler_Clear(ARC_Handler *handler){ + uint32_t zeroIndex = 0; while(*ARC_Vector_Size(handler->data)){ - ARC_Handler_Remove(handler, 0); + ARC_Handler_RemoveIndex(handler, &zeroIndex); } } -void ARC_Handler_Clean(ARC_Handler *handler, ARC_Handler_CleanDataFn cleanfn){ +void ARC_Handler_Clean(ARC_Handler *handler){ uint32_t i = 0; while(*ARC_Vector_Size(handler->trash)){ void *data = ARC_Vector_Get(handler->trash, &i); - cleanfn(data); + + if(handler->cleanfn){ + handler->cleanfn(data); + } + ARC_Vector_RemoveIndex(handler->trash, &i); } } diff --git a/src/std/vector.c b/src/std/vector.c index b02d03f..483fd4b 100644 --- a/src/std/vector.c +++ b/src/std/vector.c @@ -7,103 +7,97 @@ struct ARC_Vector { uint32_t *currentSize, *capacity; - uint32_t *dataSize; - void *data; + void **data; }; -void ARC_Vector_Create(ARC_Vector **vector, uint32_t dataSize){ +void ARC_Vector_Create(ARC_Vector **vector){ *vector = (ARC_Vector *) malloc(sizeof(ARC_Vector)); - (*vector)->currentSize = (uint32_t *) malloc(sizeof(uint32_t)); - (*vector)->capacity = (uint32_t *) malloc(sizeof(uint32_t)); - (*vector)->dataSize = (uint32_t *) malloc(sizeof(uint32_t)); - (*vector)->data = (void *) malloc(dataSize); + (*vector)->currentSize = (uint32_t *)malloc(sizeof(uint32_t)); + (*vector)->capacity = (uint32_t *)malloc(sizeof(uint32_t)); + (*vector)->data = (void *)malloc(sizeof(void *)); - *((*vector)->currentSize) = 0; - *((*vector)->capacity) = 1; - *((*vector)->dataSize) = dataSize; + *(*vector)->currentSize = 0; + *(*vector)->capacity = 1; } void ARC_Vector_Destroy(ARC_Vector *vector){ free(vector->currentSize); free(vector->capacity); free(vector->data); - free(vector->dataSize); free(vector); } void ARC_Vector_Add(ARC_Vector *vector, void *data){ - if(*(vector->currentSize) == ~((uint32_t)0)){ + if(*vector->currentSize == ~((uint32_t)0)){ arc_errno = ARC_ERRNO_OVERFLOW; return; } - if(*(vector->currentSize) == *(vector->capacity)){ - *(vector->capacity) <<= 1; + if(*vector->currentSize == *vector->capacity){ + if(!*vector->capacity){ + ++*vector->capacity; + } + *vector->capacity <<= 1; - vector->data = (void *) realloc(vector->data, *(vector->dataSize) * *(vector->capacity)); + vector->data = (void *)realloc(vector->data, sizeof(void *) * *vector->capacity); } - memcpy(vector->data + (*(vector->currentSize) * *(vector->dataSize)), data, *(vector->dataSize)); + vector->data[*vector->currentSize] = data; ++*(vector->currentSize); } +//this function removes the redundant checking currentSize and index that would happen if ARC_Vector_Remove called ARC_Vector_RemoveIndex +void ARC_Vector_RemoveIndexNoCheck(ARC_Vector *vector, uint32_t *index); + void ARC_Vector_Remove(ARC_Vector *vector, void *data, ARC_Vector_CompareDataFn compare){ - if(!*(vector->currentSize)){ + if(!*vector->currentSize){ arc_errno = ARC_ERRNO_DATA; return; } - --*(vector->currentSize); - - if(*(vector->currentSize) != *(vector->capacity) >> 1){ - for(uint32_t i = 0; i <= *(vector->currentSize); i++){ - if(!compare(data, vector->data + (i * *(vector->dataSize)))){ - memcpy(vector->data + (i * *(vector->dataSize)), vector->data + ((i + 1) * *(vector->dataSize)), *(vector->currentSize - i) * *(vector->dataSize)); - return; - } - } - - arc_errno = ARC_ERRNO_DATA; - return; - } - - *(vector->capacity) >>= 1; - void *temp = (void *) malloc(*(vector->dataSize) * *(vector->capacity)); - - for(uint32_t i = 0; i <= *(vector->currentSize); i++){ - if(compare(data, vector->data + (i * *(vector->dataSize)))){ - memcpy(temp, vector->data, i * *(vector->dataSize)); - memcpy(temp + (i * *(vector->dataSize)), vector->data + ((i + 1) * *(vector->dataSize)), *(vector->currentSize - i) * *(vector->dataSize)); - free(vector->data); - vector->data = temp; + for(uint32_t i = 0; i < *vector->currentSize; i++){ + if(!compare(data, vector->data[i])){ + ARC_Vector_RemoveIndexNoCheck(vector, &i); return; } } + //no matching data found in compare function arc_errno = ARC_ERRNO_DATA; } void ARC_Vector_RemoveIndex(ARC_Vector *vector, uint32_t *index){ - if(!*(vector->currentSize) || *index >= *(vector->currentSize)){ + if(!*vector->currentSize || *index >= *vector->currentSize){ arc_errno = ARC_ERRNO_DATA; return; } - --*(vector->currentSize); - if(*(vector->currentSize) != *(vector->capacity) >> 1){ - memcpy(vector->data + (*index * *(vector->dataSize)), vector->data + ((*index + 1) * *(vector->dataSize)), *(vector->currentSize - *index) * *(vector->dataSize)); + ARC_Vector_RemoveIndexNoCheck(vector, index); +} + +void ARC_Vector_RemoveIndexNoCheck(ARC_Vector *vector, uint32_t *index){ + for(uint32_t i = *index; i <= *vector->currentSize; i++){ + vector->data[i] = vector->data[i + 1]; + } + + --*vector->currentSize; + + if(*vector->currentSize != *vector->capacity >> 1){ return; } - *(vector->capacity) >>= 1; - void **temp = (void **) malloc(sizeof(void *) * (*(vector->capacity))); - memcpy(temp, vector->data, *index * *(vector->dataSize)); - memcpy(temp + (*index * *(vector->dataSize)), vector->data + ((*index + 1) * *(vector->dataSize)), *(vector->currentSize - *index) * *(vector->dataSize)); - - free(vector->data); - vector->data = temp; + *vector->capacity >>= 1; + vector->data = (void *)realloc(vector->data, sizeof(void *) * *vector->capacity); } -uint32_t *ARC_Vector_Size(ARC_Vector *vector){ return vector->currentSize; } +uint32_t *ARC_Vector_Size(ARC_Vector *vector){ + return vector->currentSize; +} -void *ARC_Vector_Get(ARC_Vector *vector, uint32_t *index){ return (void *)(uint8_t (*)[*(vector->dataSize)]) vector->data + (*index * *(vector->dataSize)); } +void *ARC_Vector_Get(ARC_Vector *vector, uint32_t *index){ + if(*index >= *vector->currentSize){ + return NULL; + } + + return vector->data[*index]; +}