diff --git a/CMakeLists.txt b/CMakeLists.txt index efa890c..6c9b71b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,7 @@ option(ARCHEUS_STD_OPENGL "Build with OpenGL" OFF) set(ARCHEUS_STD_FLAGS "") if(ARCHEUS_STD_DEBUG) - string(APPEND ARCHEUS_STD_FLAGS "-Wall -Werror -g -ggdb ") + string(APPEND ARCHEUS_STD_FLAGS "-Wall -Werror -g -ggdb -DARC_DEBUG ") endif() if(ARCHEUS_STD_DEFAULT_CONFIG) @@ -34,6 +34,7 @@ if(ARCHEUS_STD_SDL) find_package(SDL2 REQUIRED) find_package(SDL2_image REQUIRED) + find_package(SDL2_ttf REQUIRED) string(APPEND ARCHEUS_STD_FLAGS "-DARC_SDL ") endif() @@ -61,6 +62,9 @@ set(ARCHEUS_STD_SOURCES src/std/vector.c src/std/defaults/config.c + src/math/circle.c + src/math/config.c + src/math/obround.c src/math/rectangle.c src/math/vector2.c @@ -74,12 +78,15 @@ set(ARCHEUS_STD_SDL_SOURCES src/input/sdl/keyboard.c src/input/sdl/mouse.c + src/graphics/sdl/circle.c src/graphics/sdl/config.c src/graphics/sdl/line.c + src/graphics/sdl/obround.c src/graphics/sdl/rectangle.c src/graphics/sdl/renderer.c src/graphics/sdl/sprite.c src/graphics/sdl/spritesheet.c + src/graphics/sdl/text.c src/graphics/sdl/window.c ) @@ -123,7 +130,7 @@ if(ARCHEUS_STD_SDL) PRIVATE ${SDL2IMAGE_INCLUDE_DIRS} ) - target_link_libraries(archeus_std PUBLIC ${SDL2_LIBRARIES} SDL2_image::SDL2_image) + target_link_libraries(archeus_std PUBLIC ${SDL2_LIBRARIES} SDL2_image::SDL2_image SDL2_ttf::SDL2_ttf) endif() if(ARCHEUS_STD_OPENGL) diff --git a/include/arc/graphics/circle.h b/include/arc/graphics/circle.h new file mode 100644 index 0000000..fd35323 --- /dev/null +++ b/include/arc/graphics/circle.h @@ -0,0 +1,21 @@ +#ifndef ARC_GRAPHICS_CIRCLE_H_ +#define ARC_GRAPHICS_CIRCLE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "arc/graphics/color.h" +#include "arc/graphics/renderer.h" +#include "arc/math/circle.h" +#include + +void ARC_Circle_Render(ARC_Circle *circle, ARC_Renderer *renderer, ARC_Color *color); + +// void ARC_Rect_RenderFill(ARC_Rect *rect, ARC_Renderer *renderer, ARC_Color *color); + +#ifdef __cplusplus +} +#endif + +#endif // !ARC_GRAPHICS_RECT_H_ diff --git a/include/arc/graphics/obround.h b/include/arc/graphics/obround.h new file mode 100644 index 0000000..6ab1239 --- /dev/null +++ b/include/arc/graphics/obround.h @@ -0,0 +1,23 @@ +#ifndef ARC_GRAPHICS_OBROUND_H_ +#define ARC_GRAPHICS_OBROUND_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "arc/graphics/color.h" +#include "arc/graphics/renderer.h" +#include "arc/math/obround.h" +#include + +void ARC_Obround_Render(ARC_Obround *obround, ARC_Renderer *renderer, ARC_Color *color); + +void ARC_FObround_Render(ARC_FObround *obround, ARC_Renderer *renderer, ARC_Color *color); + +// void ARC_Rect_RenderFill(ARC_Rect *rect, ARC_Renderer *renderer, ARC_Color *color); + +#ifdef __cplusplus +} +#endif + +#endif // !ARC_GRAPHICS_OBROUND_H_ \ No newline at end of file diff --git a/include/arc/graphics/rectangle.h b/include/arc/graphics/rectangle.h index 1dea87d..d1bc881 100644 --- a/include/arc/graphics/rectangle.h +++ b/include/arc/graphics/rectangle.h @@ -14,6 +14,10 @@ void ARC_Rect_Render(ARC_Rect *rect, ARC_Renderer *renderer, ARC_Color *color); void ARC_Rect_RenderFill(ARC_Rect *rect, ARC_Renderer *renderer, ARC_Color *color); +void ARC_FRect_Render(ARC_FRect *rect, ARC_Renderer *renderer, ARC_Color *color); + +void ARC_FRect_RenderFill(ARC_FRect *rect, ARC_Renderer *renderer, ARC_Color *color); + #ifdef __cplusplus } #endif diff --git a/include/arc/graphics/sdl/text.h b/include/arc/graphics/sdl/text.h new file mode 100644 index 0000000..6137f5e --- /dev/null +++ b/include/arc/graphics/sdl/text.h @@ -0,0 +1,23 @@ +#ifndef ARC_SDL_TEXT_H_ +#define ARC_SDL_TEXT_H_ + +#include "arc/std/string.h" +#include "arc/graphics/color.h" +#include "arc/math/rectangle.h" + +#ifdef ARC_SDL +#include + +typedef struct ARC_Text { + ARC_String *name; + int32_t size; + + ARC_Color color; + + SDL_Texture *texture; + ARC_Rect bounds; +} ARC_Text; + +#endif // !ARC_SDL + +#endif // !ARC_SDL_TEXT_H_ diff --git a/include/arc/graphics/sprite.h b/include/arc/graphics/sprite.h index 96fe23b..e339886 100644 --- a/include/arc/graphics/sprite.h +++ b/include/arc/graphics/sprite.h @@ -23,9 +23,9 @@ typedef struct ARC_Sprite ARC_Sprite; * * @param sprite ARC_Sprite that is being created * @param spritesheet ARC_Spritesheet that ARC_Sprite will be pulled from - * @param bounds ARC_Array of bounds of sprite on spritesheet + * @param frames ARC_Array of bounds of sprite on spritesheet */ -void ARC_Sprite_Create(ARC_Sprite **sprite, ARC_Spritesheet *spritesheet, ARC_Array *bounds); +void ARC_Sprite_Create(ARC_Sprite **sprite, ARC_Spritesheet *spritesheet, ARC_Array *frames); /** * @brief destroys ARC_Sprite type @@ -51,6 +51,23 @@ void ARC_Sprite_Copy(ARC_Sprite **newSprite, ARC_Sprite *oldSprite); */ void ARC_Sprite_Render(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *renderBounds); +//TODO: move this to a better location +typedef enum ARC_Sprite_Axis { + ARC_SPRITE_AXIS_NONE = 0x00, + ARC_SPRITE_AXIS_Y = 0x01, + ARC_SPRITE_AXIS_X = 0x02, +} ARC_Sprite_Axix; + +/** + * @brief renders ARC_Sprite type with flip + * + * @param sprite ARC_Sprite that will be rendered + * @param renderer ARC_Renderer that is handling rendering + * @param renderBounds area of renderer that ARC_Sprite will be rendered to + * @param axis axis to flip sprite + */ +void ARC_Sprite_RenderFlip(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *renderBounds, enum ARC_Sprite_Axis axis); + /** * @brief renders ARC_Sprite type with rotation * @@ -62,6 +79,14 @@ void ARC_Sprite_Render(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *ren */ void ARC_Sprite_RenderRotated(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *renderBounds, ARC_Point *center, double angle); +/** + * @brief switches ARC_Sprite's frame to specified index + * + * @param sprite ARC_Sprite that is having its frame set + * @param index uint32_t to set ARC_Sprite's frame index to + */ +void ARC_Sprite_SetFrameIndex(ARC_Sprite *sprite, uint32_t index); + /** * @brief switches ARC_Sprite's frames to next for animation * @@ -76,6 +101,13 @@ void ARC_Sprite_IterateFrame(ARC_Sprite *sprite); */ ARC_Rect *ARC_Sprite_GetBounds(ARC_Sprite *sprite); +/** + * @brief returns the array of bounds that a sprite has + * + * @param sprite ARC_Sprite to get all the bounds from +*/ +ARC_Array *ARC_Sprite_GetAllBounds(ARC_Sprite *sprite); + #ifdef __cplusplus } #endif diff --git a/include/arc/graphics/text.h b/include/arc/graphics/text.h new file mode 100644 index 0000000..3838fd7 --- /dev/null +++ b/include/arc/graphics/text.h @@ -0,0 +1,30 @@ +#ifndef ARC_STD_TEXT_H_ +#define ARC_STD_TEXT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "arc/graphics/color.h" +#include "arc/graphics/renderer.h" +#include "arc/math/point.h" +#include "arc/std/string.h" + +typedef struct ARC_Text ARC_Text; + +void ARC_Text_Create(ARC_Text **text, ARC_String *path, int32_t size, ARC_Color color); + +void ARC_Text_Destroy(ARC_Text *font); + +void ARC_Text_SetString(ARC_Text *text, ARC_Renderer *renderer, ARC_String *string); + +void ARC_Text_Render(ARC_Text *text, ARC_Renderer *renderer); + +void ARC_Text_SetPos(ARC_Text *text, ARC_Point pos); + +#ifdef __cplusplus +} +#endif + +#endif //ARC_STD_STRING_H_ \ No newline at end of file diff --git a/include/arc/input/keyboard.h b/include/arc/input/keyboard.h index 6b35d75..849558c 100644 --- a/include/arc/input/keyboard.h +++ b/include/arc/input/keyboard.h @@ -51,6 +51,18 @@ typedef enum ARC_KeyboardKey { ARC_KEY_Y, ARC_KEY_Z, + ARC_KEY_0, + ARC_KEY_1, + ARC_KEY_2, + ARC_KEY_3, + ARC_KEY_4, + ARC_KEY_5, + ARC_KEY_6, + ARC_KEY_7, + ARC_KEY_8, + ARC_KEY_9, + + ARC_KEY_SPACE, ARC_KEY_ESC, } ARC_Keyboard_Key; diff --git a/include/arc/math/circle.h b/include/arc/math/circle.h new file mode 100644 index 0000000..da3e63b --- /dev/null +++ b/include/arc/math/circle.h @@ -0,0 +1,20 @@ +#ifndef ARC_MATH_CIRCLE_H_ +#define ARC_MATH_CIRCLE_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ARC_Circle { + int32_t x; + int32_t y; + int32_t r; +} ARC_Circle; + +#ifdef __cplusplus +} +#endif + +#endif // ARC_MATH_CIRCLE_H_ diff --git a/include/arc/math/config.h b/include/arc/math/config.h new file mode 100644 index 0000000..c44eaad --- /dev/null +++ b/include/arc/math/config.h @@ -0,0 +1,26 @@ +#ifndef ARC_MATH_CONFIG_H_ +#define ARC_MATH_CONFIG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "arc/std/string.h" + +typedef struct ARC_Config ARC_Config; +void ARC_MathConfig_Init(ARC_Config *config); + +uint8_t ARC_Point_Read (ARC_Config *config, ARC_String *string, void **value); +uint8_t ARC_Rect_Read (ARC_Config *config, ARC_String *string, void **value); +uint8_t ARC_RectArray_Read(ARC_Config *config, ARC_String *string, void **value); + +void ARC_Point_Delete (ARC_Config *config, ARC_String *string, void *value); +void ARC_Rect_Delete (ARC_Config *config, ARC_String *string, void *value); +void ARC_RectArray_Delete(ARC_Config *config, ARC_String *string, void *value); + +#ifdef __cplusplus +} +#endif + +#endif //ARC_MATH_CONFIG_H_ \ No newline at end of file diff --git a/include/arc/math/obround.h b/include/arc/math/obround.h new file mode 100644 index 0000000..f0f5f90 --- /dev/null +++ b/include/arc/math/obround.h @@ -0,0 +1,47 @@ +#ifndef ARC_MATH_OBROUND_H_ +#define ARC_MATH_OBROUND_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ARC_Obround { + int32_t x; + int32_t y; + int32_t r; + int32_t h; +} ARC_Obround; + +typedef struct ARC_FObround { + float x; + float y; + float r; + float h; +} ARC_FObround; + +/** + * @brief casts Obround to FObround + * + * @param obround ARC_Obround to be casted + * + * @return ARC_FObround + */ +ARC_FObround ARC_Obround_CastToFObround(ARC_Obround *obround); + +/** + * @brief casts FObround to Obround + * + * @param obround ARC_FObround to be casted + * + * @return ARC_Obround + */ +ARC_Obround ARC_FObround_CastToObround(ARC_FObround *obround); + +#ifdef __cplusplus +} +#endif + +#endif // ARC_MATH_OBROUND_H_ + diff --git a/include/arc/math/rectangle.h b/include/arc/math/rectangle.h index d2d1bcb..7427579 100644 --- a/include/arc/math/rectangle.h +++ b/include/arc/math/rectangle.h @@ -2,6 +2,8 @@ #define ARC_MATH_RECT_H_ #include +#include "point.h" +#include "vector2.h" #ifdef __cplusplus extern "C" { @@ -21,10 +23,117 @@ typedef struct ARC_URect { uint32_t h; } ARC_URect; +typedef struct ARC_FRect { + float x; + float y; + float w; + float h; +} ARC_FRect; + +/** + * @brief centers rect on given bounds + * + * @param rect ARC_Rect to be centered + * @param bounds ARC_Rect area to center rect on + */ +void ARC_Rect_CenterOn(ARC_Rect *rect, ARC_Rect *bounds); + +/** + * @brief centers rect on given bounds + * + * @param rect ARC_FRect to be centered + * @param bounds ARC_FRect area to center rect on + */ +void ARC_FRect_CenterOn(ARC_FRect *rect, ARC_FRect *bounds); + +/** + * @brief casts Rect to FRect + * + * @param rect ARC_Rect to be casted + * + * @return ARC_FRect + */ +ARC_FRect ARC_Rect_CastToFRect(ARC_Rect *rect); + +/** + * @brief casts FRect to Rect + * + * @param rect ARC_FRect to be casted + * + * @return ARC_Rect + */ +ARC_Rect ARC_FRect_CastToRect(ARC_FRect *rect); + +/** + * @brief checks if two ARC_Rects intersect + * + * @param rect1 ARC_Rect that will be checked against rect2 + * @param rect2 ARC_Rect that will be checked against rect1 + * + * @return 1 if they intersect, 0 if they don't intersect + */ int32_t ARC_Rect_Intersects(ARC_Rect *rect1, ARC_Rect *rect2); +/** + * @brief checks if two ARC_FRects intersect + * + * @param rect1 ARC_FRect that will be checked against rect2 + * @param rect2 ARC_FRect that will be checked against rect1 + * + * @return 1 if they intersect, 0 if they don't intersect + */ +int32_t ARC_FRect_Intersects(ARC_FRect *rect1, ARC_FRect *rect2); + +/** + * @brief checks if ARC_Rect intersects with point + * + * @param rect ARC_Rect that will be checked against point + * @param point ARC_Point that will be checked against rect + * + * @return 1 if they intersect, 0 if they don't intersect + */ +int32_t ARC_Rect_IntersectsPoint(ARC_Rect *rect, ARC_Point *point); + +/** + * @brief checks if ARC_FRect intersects with point + * + * @param rect ARC_FRect that will be checked against point + * @param point ARC_Point that will be checked against rect + * + * @return 1 if they intersect, 0 if they don't intersect + */ +int32_t ARC_FRect_IntersectsPoint(ARC_FRect *rect, ARC_Point *point); + +/** + * @brief checks if ARC_Rect intersects a line + * + * @note need to update this documenation to word it better + * + * @param rect ARC_Rect that will be checked against line + * @param x1 first point's x value + * @param y1 first point's y value + * @param y2 second point's x value + * @param y2 second point's y value + * + * @return 1 if they intersect, 0 if they don't intersect + */ int32_t ARC_Rect_LineIntersects(ARC_Rect *rect, int32_t *x1, int32_t *y1, int32_t *x2, int32_t *y2); +/** + * @brief checks for a ARC_Rect on ARC_Rect collision and slides on collision + * + * @note need to update this documenation to word it better + * + * @param rect ARC_Rect that might collide with the wall + * @param velocity the ammount ARC_Rect will move + * @param wall ARC_Rect that might have collision with rect + * + * @note velocity is updated based on colliding, + * rect's values are not changed, + * velocity should be applied after + */ +void ARC_FRect_CollideAndSlide(ARC_FRect *rect, ARC_Vector2 *velocity, ARC_FRect *wall); + #ifdef __cplusplus } #endif diff --git a/include/arc/std/array.h b/include/arc/std/array.h index dc802aa..aee55e0 100644 --- a/include/arc/std/array.h +++ b/include/arc/std/array.h @@ -11,7 +11,7 @@ extern "C" { * @brief a type that holds an array of data and its size */ typedef struct ARC_Array { - uint32_t *size; + uint32_t size; void *data; } ARC_Array; diff --git a/include/arc/std/defaults/config.h b/include/arc/std/defaults/config.h index 5e8b0e7..99daa6a 100644 --- a/include/arc/std/defaults/config.h +++ b/include/arc/std/defaults/config.h @@ -1,5 +1,3 @@ -#ifdef ARC_DEFAULT_CONFIG - #ifndef ARC_DEFAULTS_CONFIG_H_ #define ARC_DEFAULTS_CONFIG_H_ @@ -27,7 +25,7 @@ uint8_t ARC_ConfigKey_Read_Long (ARC_Config *config, ARC_String *string, v uint8_t ARC_ConfigKey_Read_Float (ARC_Config *config, ARC_String *string, void **value); uint8_t ARC_ConfigKey_Read_Double (ARC_Config *config, ARC_String *string, void **value); uint8_t ARC_ConfigKey_Read_String (ARC_Config *config, ARC_String *string, void **value); -// uint8_t ARC_ConfigKey_Read_StringArray(ARC_Config *config, ARC_String *string, void **value); +uint8_t ARC_ConfigKey_Read_StringArray(ARC_Config *config, ARC_String *string, void **value); void ARC_ConfigKey_Delete_Uint8_t (ARC_Config *config, ARC_String *string, void *value); void ARC_ConfigKey_Delete_Int8_t (ARC_Config *config, ARC_String *string, void *value); @@ -43,12 +41,10 @@ void ARC_ConfigKey_Delete_Long (ARC_Config *config, ARC_String *string, vo void ARC_ConfigKey_Delete_Float (ARC_Config *config, ARC_String *string, void *value); void ARC_ConfigKey_Delete_Double (ARC_Config *config, ARC_String *string, void *value); void ARC_ConfigKey_Delete_String (ARC_Config *config, ARC_String *string, void *value); -// void ARC_ConfigKey_Delete_StringArray(ARC_Config *config, ARC_String *string, void *value); +void ARC_ConfigKey_Delete_StringArray(ARC_Config *config, ARC_String *string, void *value); #ifdef __cplusplus } #endif -#endif //ARC_DEFAULTS_CONFIG_H_ - -#endif //ARC_DEFAULT_CONFIG +#endif //ARC_DEFAULTS_CONFIG_H_ \ No newline at end of file diff --git a/include/arc/std/string.h b/include/arc/std/string.h index f17ad3b..1a604c9 100644 --- a/include/arc/std/string.h +++ b/include/arc/std/string.h @@ -82,6 +82,8 @@ uint8_t ARC_String_Equals(ARC_String *first, ARC_String *second); * @param string ARC_string to check * @param cstring cstring to check * @param length length of cstring + * + * @return 1 if match, 0 if they don't match */ uint8_t ARC_String_EqualsCString(ARC_String *string, const char *cstring, uint64_t length); diff --git a/src/engine/engine.c b/src/engine/engine.c index 228ba5e..3b0fa67 100644 --- a/src/engine/engine.c +++ b/src/engine/engine.c @@ -16,6 +16,7 @@ #include "arc/input/sdl/keyboard.h" #include #include +#include #elif ARC_OPENGL #include "arc/graphics/opengl/window.h" #include "arc/graphics/opengl/renderer.h" @@ -39,6 +40,10 @@ void ARC_EngineData_Create(ARC_EngineData **data, ARC_Handler_CleanDataFn cleanf ARC_KeyboardInfo keyboardInfo; (*data)->windowSize = windowSize; +//TEMP +#ifdef ARC_SDL + TTF_Init(); +#endif #ifdef ARC_SDL windowInfo = (ARC_WindowInfo){ "title", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, (*data)->windowSize.x, (*data)->windowSize.y, 0 }; diff --git a/src/files/config.c b/src/files/config.c index 1eb151b..ec8df39 100644 --- a/src/files/config.c +++ b/src/files/config.c @@ -36,9 +36,8 @@ uint8_t ARC_CSV_Read(ARC_Config *config, ARC_String *string, void **value){ } *value = malloc(sizeof(ARC_Array)); - ((ARC_Array *)*value)->data = malloc(sizeof(ARC_Array *) * height); - ((ARC_Array *)*value)->size = malloc(sizeof(uint32_t) ); - *((ARC_Array *)*value)->size = height; + ((ARC_Array *)*value)->data = malloc(sizeof(ARC_Array *) * height); + ((ARC_Array *)*value)->size = height; uint32_t index = 0; for(uint32_t y = 0; y < height; y++){ @@ -65,8 +64,7 @@ uint8_t ARC_CSV_Read(ARC_Config *config, ARC_String *string, void **value){ ((ARC_Array **)((ARC_Array *)*value)->data)[y] = (ARC_Array *) malloc(sizeof(ARC_Array)); ((ARC_Array **)((ARC_Array *)*value)->data)[y]->data = malloc(sizeof(int32_t ) * width); - ((ARC_Array **)((ARC_Array *)*value)->data)[y]->size = malloc(sizeof(uint32_t) ); - *((ARC_Array **)((ARC_Array *)*value)->data)[y]->size = width; + ((ARC_Array **)((ARC_Array *)*value)->data)[y]->size = width; for(uint32_t i = index; i < fileData->length; i++){ if(fileData->data[i] != ',' && fileData->data[i] != '\n'){ @@ -92,13 +90,11 @@ uint8_t ARC_CSV_Read(ARC_Config *config, ARC_String *string, void **value){ void ARC_CSV_Delete(ARC_Config *config, ARC_String *string, void *value){ ARC_Array *valueArray = value; - for(uint32_t i = 0; i < *valueArray->size; i++){ + for(uint32_t i = 0; i < valueArray->size; i++){ free((int32_t *)((ARC_Array **)valueArray->data)[i]->data); - free((uint32_t *)((ARC_Array **)valueArray->data)[i]->size); free((ARC_Array *)((ARC_Array **)valueArray->data)[i]); } free((ARC_Array **)valueArray->data); - free((uint32_t *)valueArray->size); free(valueArray); } \ No newline at end of file diff --git a/src/graphics/sdl/circle.c b/src/graphics/sdl/circle.c new file mode 100644 index 0000000..cf53a70 --- /dev/null +++ b/src/graphics/sdl/circle.c @@ -0,0 +1,43 @@ +#ifdef ARC_SDL +#include "arc/graphics/circle.h" +#include "arc/graphics/sdl/renderer.h" +#include + +//Modified from https://stackoverflow.com/questions/38334081/how-to-draw-circles-arcs-and-vector-graphics-in-sdl +void ARC_Circle_Render(ARC_Circle *circle, ARC_Renderer *renderer, ARC_Color *color){ + SDL_SetRenderDrawColor((SDL_Renderer *)renderer, color->r, color->g, color->b, color->a); + + int32_t diameter = (circle->r * 2); + + int32_t x = (circle->r - 1); + int32_t y = 0; + int32_t tx = 1; + int32_t ty = 1; + int32_t error = (tx - diameter); + + while(x >= y){ + // Each of the following renders an octant of the circle + SDL_RenderDrawPoint((SDL_Renderer *)renderer, circle->x + x, circle->y - y); + SDL_RenderDrawPoint((SDL_Renderer *)renderer, circle->x + x, circle->y + y); + SDL_RenderDrawPoint((SDL_Renderer *)renderer, circle->x - x, circle->y - y); + SDL_RenderDrawPoint((SDL_Renderer *)renderer, circle->x - x, circle->y + y); + SDL_RenderDrawPoint((SDL_Renderer *)renderer, circle->x + y, circle->y - x); + SDL_RenderDrawPoint((SDL_Renderer *)renderer, circle->x + y, circle->y + x); + SDL_RenderDrawPoint((SDL_Renderer *)renderer, circle->x - y, circle->y - x); + SDL_RenderDrawPoint((SDL_Renderer *)renderer, circle->x - y, circle->y + x); + + if(error <= 0){ + ++y; + error += ty; + ty += 2; + } + + if(error > 0){ + --x; + tx += 2; + error += (tx - diameter); + } + } +} + +#endif // ARC_SDL \ No newline at end of file diff --git a/src/graphics/sdl/config.c b/src/graphics/sdl/config.c index e03b21b..22c8f0f 100644 --- a/src/graphics/sdl/config.c +++ b/src/graphics/sdl/config.c @@ -11,6 +11,7 @@ #include "arc/graphics/sdl/sprite.h" #include "arc/graphics/spritesheet.h" #include "arc/graphics/sdl/spritesheet.h" +#include "arc/math/config.h" #include "arc/math/point.h" #include "arc/math/rectangle.h" @@ -19,30 +20,31 @@ SDL_Renderer *global_renderer; -uint8_t ARC_Point_Read (ARC_Config *config, ARC_String *string, void **value); -uint8_t ARC_Rect_Read (ARC_Config *config, ARC_String *string, void **value); -uint8_t ARC_RectArray_Read (ARC_Config *config, ARC_String *string, void **value); uint8_t ARC_SDL_Texture_Read(ARC_Config *config, ARC_String *string, void **value); uint8_t ARC_Spritesheet_Read(ARC_Config *config, ARC_String *string, void **value); uint8_t ARC_Sprite_Read (ARC_Config *config, ARC_String *string, void **value); -void ARC_Point_Delete (ARC_Config *config, ARC_String *string, void *value); -void ARC_Rect_Delete (ARC_Config *config, ARC_String *string, void *value); -void ARC_RectArray_Delete (ARC_Config *config, ARC_String *string, void *value); void ARC_SDL_Texture_Delete(ARC_Config *config, ARC_String *string, void *value); void ARC_Spritesheet_Delete(ARC_Config *config, ARC_String *string, void *value); void ARC_Sprite_Delete (ARC_Config *config, ARC_String *string, void *value); void ARC_GraphicsConfig_Init(ARC_Config *config, ARC_Renderer *renderer){ global_renderer = (SDL_Renderer *)renderer; - ARC_Config_AddKeyCString(config, (char *)"ARC_Point" , 9, ARC_Point_Read , ARC_Point_Delete ); - ARC_Config_AddKeyCString(config, (char *)"ARC_Rect" , 8, ARC_Rect_Read , ARC_Rect_Delete ); - ARC_Config_AddKeyCString(config, (char *)"ARC_Rect[]" , 10, ARC_RectArray_Read , ARC_RectArray_Delete ); ARC_Config_AddKeyCString(config, (char *)"SDL_Texture" , 11, ARC_SDL_Texture_Read, ARC_SDL_Texture_Delete); ARC_Config_AddKeyCString(config, (char *)"ARC_Spritesheet", 15, ARC_Spritesheet_Read, ARC_Spritesheet_Delete); ARC_Config_AddKeyCString(config, (char *)"ARC_Sprite" , 10, ARC_Sprite_Read , ARC_Sprite_Delete ); } +uint64_t ARC_GraphicsConfig_GetIndexAndErrorCheck(ARC_String *string, char *search, uint64_t searchLength){ + uint64_t separator = ARC_String_FindCString(string, ",", 1); + + if(separator == ~(uint64_t)0){ + arc_errno = ARC_ERRNO_DATA; + } + + return separator; +} + int32_t ARC_SDL_Texture_Load(const char *path, SDL_Texture **texture){ IMG_Init(IMG_INIT_PNG); SDL_Surface *surface = IMG_Load(path); @@ -59,252 +61,6 @@ int32_t ARC_SDL_Texture_Load(const char *path, SDL_Texture **texture){ return 0; } -uint64_t getIndexAndErrorCheck(ARC_String *string, char *search, uint64_t searchLength){ - uint64_t separator = ARC_String_FindCString(string, ",", 1); - - if(separator == ~(uint64_t)0){ - arc_errno = ARC_ERRNO_DATA; - } - - return separator; -} - -uint8_t ARC_Point_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_DEBUG_LOG(arc_errno, "in ARC_Point_Read(config, string, value); no matching curly braces: %s", string->data); - arc_errno = ARC_ERRNO_DATA; - return 0; - } - - uint64_t separator = getIndexAndErrorCheck(string, ",", 1); - if(arc_errno){ - return 0; - } - - ARC_String *xString, *yString; - ARC_String_CopySubstring(&xString, string, 1 , separator - 1 ); - ARC_String_CopySubstring(&yString, string, separator + 1, string->length - (separator + 2)); - - SDL_Point *point = (SDL_Point *)malloc(sizeof(SDL_Point)); - point->x = (int32_t)ARC_String_ToInt64_t(xString); - point->y = (int32_t)ARC_String_ToInt64_t(yString); - - ARC_String_Destroy(xString); - ARC_String_Destroy(yString); - - *value = point; - return 0; -} - -uint8_t ARC_Rect_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_errno = ARC_ERRNO_DATA; - ARC_DEBUG_LOG(arc_errno, "in ARC_Rect_Read(config, string, value); no matching curly braces: %s", string->data); - return 0; - } - - ARC_String *current; - ARC_String_CopySubstring(¤t, string, 1, string->length - 2); - - ARC_String *temp, *tempStripped; - int32_t x, y, w, h; - int64_t separator; - - //x - separator = getIndexAndErrorCheck(current, ",", 1); - if(arc_errno){ - return 0; - } - - ARC_String_CopySubstring(&temp, current, 0, separator - 1); - ARC_String_StripEndsWhitespace(temp, &tempStripped); - x = ARC_String_ToInt64_t(tempStripped); - ARC_String_Destroy(temp); - ARC_String_Destroy(tempStripped); - - temp = current; - ARC_String_CopySubstring(¤t, temp, separator + 1, temp->length - (separator + 1)); - ARC_String_Destroy(temp); - - //y - separator = getIndexAndErrorCheck(current, ",", 1); - if(arc_errno){ - return 0; - } - - ARC_String_CopySubstring(&temp, current, 0, separator - 1); - ARC_String_StripEndsWhitespace(temp, &tempStripped); - y = ARC_String_ToInt64_t(tempStripped); - ARC_String_Destroy(temp); - ARC_String_Destroy(tempStripped); - - temp = current; - ARC_String_CopySubstring(¤t, temp, separator + 1, temp->length - (separator + 1)); - ARC_String_Destroy(temp); - - //w - separator = getIndexAndErrorCheck(current, ",", 1); - if(arc_errno){ - return 0; - } - - ARC_String_CopySubstring(&temp, current, 0, separator - 1); - ARC_String_StripEndsWhitespace(temp, &tempStripped); - w = ARC_String_ToInt64_t(tempStripped); - ARC_String_Destroy(temp); - ARC_String_Destroy(tempStripped); - - temp = current; - ARC_String_CopySubstring(¤t, temp, separator + 1, temp->length - (separator + 1)); - ARC_String_Destroy(temp); - - //h - separator = current->length; - if(arc_errno){ - return 0; - } - - ARC_String_CopySubstring(&temp, current, 0, separator); - ARC_String_StripEndsWhitespace(temp, &tempStripped); - h = ARC_String_ToInt64_t(tempStripped); - ARC_String_Destroy(temp); - ARC_String_Destroy(tempStripped); - ARC_String_Destroy(current); - - *value = malloc(sizeof(ARC_Rect)); - ((ARC_Rect *) *value)->x = x; - ((ARC_Rect *) *value)->y = y; - ((ARC_Rect *) *value)->w = w; - ((ARC_Rect *) *value)->h = h; - return 0; -} - -void ARC_RectArray_ReadRect(ARC_Config* config, ARC_String *stripped, uint64_t index, uint64_t length, uint64_t *arrayIndex, void **value){ - ARC_String *substr, *temp; - ARC_String_CopySubstring(&temp, stripped, index, length); - ARC_String_StripEndsWhitespace(temp, &substr); - ARC_String_Destroy(temp); - - // reading in reference - ARC_Rect *tempRect; - ARC_Config_Get(config, substr, (void **) &tempRect); - if(tempRect){ - ARC_String_Destroy(substr); - - ((ARC_Rect *)((ARC_Array *) *value)->data)[*arrayIndex] = *tempRect; - ++*arrayIndex; - - return; - } - - //reading in value - ARC_Rect_Read(config, substr, (void **) &tempRect); - if(arc_errno){ - ARC_DEBUG_LOG(arc_errno, "in ARC_RectArray_ReadRect(config, string, index, length, arrayIndex, value); failed to read rect: %s", substr->data); - ARC_String_Destroy(substr); - return; - } - - ((ARC_Rect *)((ARC_Array *) *value)->data)[*arrayIndex] = *tempRect; - ++*arrayIndex; - - ARC_Rect_Delete(config, substr, (void *)tempRect); - ARC_String_Destroy(substr); -} - -uint8_t ARC_RectArray_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_errno = ARC_ERRNO_DATA; - ARC_DEBUG_LOG(arc_errno, "in ARC_RectArray_Read(config, string, value); no matching curly braces: %s", string->data); - return 0; - } - - ARC_String *temp, *stripped; - ARC_String_CopySubstring(&temp, string, 1, string->length - 2); - ARC_String_StripEndsWhitespace(temp, &stripped); - ARC_String_Destroy(temp); - - uint64_t arraySize = 1; - int64_t encapsulated = 0; - for(uint64_t i = 0; i < stripped->length; i++){ - if(stripped->data[i] == '{'){ - encapsulated++; - continue; - } - - if(stripped->data[i] == '}'){ - encapsulated--; - continue; - } - - if(!encapsulated && stripped->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 %ld", encapsulated); - ARC_String_Destroy(stripped); - return 0; - } - - *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; - - uint64_t index = 0; - arraySize = 0; - encapsulated = 0; - for(uint64_t i = 0; i < stripped->length; i++){ - if(stripped->data[i] == '{'){ - encapsulated++; - continue; - } - - if(stripped->data[i] == '}'){ - encapsulated--; - continue; - } - - if(!encapsulated && stripped->data[i] == ','){ - ARC_RectArray_ReadRect(config, stripped, index, i - index, &arraySize, value); - if(arc_errno){ - return 0; - } - - index = i + 1; - - if(arraySize == *((ARC_Array *) *value)->size){ - break; - } - } - } - - if(arraySize != *((ARC_Array *) *value)->size){ - ARC_RectArray_ReadRect(config, stripped, index, stripped->length - index, &arraySize, value); - } - ARC_String_Destroy(stripped); - return 0; -} - - uint8_t ARC_SDL_Texture_Read(ARC_Config* config, ARC_String *string, void **value){ ARC_Config_Get(config, string, value); if(*value){ @@ -359,7 +115,7 @@ uint8_t ARC_Spritesheet_Read(ARC_Config* config, ARC_String *string, void **valu return 0; } - uint64_t split = getIndexAndErrorCheck(string, ",", 1); + uint64_t split = ARC_GraphicsConfig_GetIndexAndErrorCheck(string, ",", 1); if(arc_errno){ return 0; } @@ -403,7 +159,7 @@ uint8_t ARC_Sprite_Read(ARC_Config* config, ARC_String *string, void **value){ return 0; } - uint64_t split = getIndexAndErrorCheck(string, ",", 1); + uint64_t split = ARC_GraphicsConfig_GetIndexAndErrorCheck(string, ",", 1); if(arc_errno){ return 0; } @@ -449,7 +205,7 @@ uint8_t ARC_Sprite_Read(ARC_Config* config, ARC_String *string, void **value){ // 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++){ + 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; @@ -467,23 +223,10 @@ uint8_t ARC_Sprite_Read(ARC_Config* config, ARC_String *string, void **value){ return 0; } -void ARC_Point_Delete(ARC_Config* config, ARC_String *string, void *value){ - free((ARC_Point *)value); -} - -void ARC_Rect_Delete(ARC_Config* config, ARC_String *string, void *value){ - free((ARC_Rect *)value); -} - -void ARC_RectArray_Delete(ARC_Config* config, ARC_String *string, void *value){ - free((ARC_Array *)value); -} - 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; @@ -491,16 +234,24 @@ void ARC_Spritesheet_Delete(ARC_Config* config, ARC_String *string, void *value) void *temp; ARC_Config_Get(config, string, &temp); if(temp){ + //TODO: test to see if this breaks references free(sheetValue); return; } - uint64_t split = getIndexAndErrorCheck(string, ",", 1); + uint64_t split = ARC_GraphicsConfig_GetIndexAndErrorCheck(string, ",", 1); if(arc_errno){ - free(sheetValue); + //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); @@ -531,7 +282,7 @@ void ARC_Sprite_Delete(ARC_Config* config, ARC_String *string, void *value){ //check if read in as a Textrue reference void *temp; - uint64_t split = getIndexAndErrorCheck(string, ",", 1); + uint64_t split = ARC_GraphicsConfig_GetIndexAndErrorCheck(string, ",", 1); if(arc_errno){ free(spriteValue); return; diff --git a/src/graphics/sdl/obround.c b/src/graphics/sdl/obround.c new file mode 100644 index 0000000..403c573 --- /dev/null +++ b/src/graphics/sdl/obround.c @@ -0,0 +1,51 @@ +#ifdef ARC_SDL +#include "arc/graphics/obround.h" +#include "arc/graphics/sdl/renderer.h" +#include + +//Modified from https://stackoverflow.com/questions/38334081/how-to-draw-circles-arcs-and-vector-graphics-in-sdl +void ARC_Obround_Render(ARC_Obround *obround, ARC_Renderer *renderer, ARC_Color *color){ + SDL_SetRenderDrawColor((SDL_Renderer *)renderer, color->r, color->g, color->b, color->a); + + int32_t diameter = (obround->r * 2); + + int32_t x = (obround->r - 1); + int32_t y = 0; + int32_t tx = 1; + int32_t ty = 1; + int32_t error = (tx - diameter); + + SDL_RenderDrawLine((SDL_Renderer *)renderer, obround->x - obround->r, obround->y - (obround->h / 2), obround->x - obround->r, obround->y + (obround->h / 2)); + SDL_RenderDrawLine((SDL_Renderer *)renderer, obround->x + obround->r, obround->y - (obround->h / 2), obround->x + obround->r, obround->y + (obround->h / 2)); + + while(x >= y){ + // Each of the following renders an octant of the circle + SDL_RenderDrawPoint((SDL_Renderer *)renderer, obround->x + x, obround->y - y - (obround->h / 2)); + SDL_RenderDrawPoint((SDL_Renderer *)renderer, obround->x + x, obround->y + y + (obround->h / 2)); + SDL_RenderDrawPoint((SDL_Renderer *)renderer, obround->x - x, obround->y - y - (obround->h / 2)); + SDL_RenderDrawPoint((SDL_Renderer *)renderer, obround->x - x, obround->y + y + (obround->h / 2)); + SDL_RenderDrawPoint((SDL_Renderer *)renderer, obround->x + y, obround->y - x - (obround->h / 2)); + SDL_RenderDrawPoint((SDL_Renderer *)renderer, obround->x + y, obround->y + x + (obround->h / 2)); + SDL_RenderDrawPoint((SDL_Renderer *)renderer, obround->x - y, obround->y - x - (obround->h / 2)); + SDL_RenderDrawPoint((SDL_Renderer *)renderer, obround->x - y, obround->y + x + (obround->h / 2)); + + if(error <= 0){ + ++y; + error += ty; + ty += 2; + } + + if(error > 0){ + --x; + tx += 2; + error += (tx - diameter); + } + } +} + +void ARC_FObround_Render(ARC_FObround *obround, ARC_Renderer *renderer, ARC_Color *color){ + ARC_Obround casted = ARC_FObround_CastToObround(obround); + ARC_Obround_Render(&casted, renderer, color); +} + +#endif // ARC_SDL \ No newline at end of file diff --git a/src/graphics/sdl/rectangle.c b/src/graphics/sdl/rectangle.c index 79d5f32..636f4d9 100644 --- a/src/graphics/sdl/rectangle.c +++ b/src/graphics/sdl/rectangle.c @@ -13,4 +13,14 @@ void ARC_Rect_RenderFill(ARC_Rect *rect, ARC_Renderer *renderer, ARC_Color *colo SDL_RenderFillRect((SDL_Renderer *)renderer, (SDL_Rect *) rect); } +void ARC_FRect_Render(ARC_FRect *rect, ARC_Renderer *renderer, ARC_Color *color){ + ARC_Rect casted = ARC_FRect_CastToRect(rect); + ARC_Rect_Render(&casted, renderer, color); +} + +void ARC_FRect_RenderFill(ARC_FRect *rect, ARC_Renderer *renderer, ARC_Color *color){ + ARC_Rect casted = ARC_FRect_CastToRect(rect); + ARC_Rect_RenderFill(&casted, renderer, color); +} + #endif // ARC_SDL \ No newline at end of file diff --git a/src/graphics/sdl/sprite.c b/src/graphics/sdl/sprite.c index 82e802e..8fa6d4f 100644 --- a/src/graphics/sdl/sprite.c +++ b/src/graphics/sdl/sprite.c @@ -5,6 +5,7 @@ #include "arc/graphics/sdl/renderer.h" #include "arc/math/point.h" #include "arc/math/rectangle.h" +#include "arc/std/errno.h" #include void ARC_Sprite_Create(ARC_Sprite **sprite, ARC_Spritesheet *spritesheet, ARC_Array *frames){ @@ -31,14 +32,36 @@ void ARC_Sprite_Render(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *ren SDL_RenderCopy((SDL_Renderer *)renderer, sprite->spritesheet->texture, (SDL_Rect *)sprite->frames->data + *sprite->frameIndex, (SDL_Rect *)renderBounds); } +void ARC_Sprite_RenderFlip(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *renderBounds, enum ARC_Sprite_Axis axis){ + SDL_RendererFlip flip = SDL_FLIP_NONE; + if(axis & ARC_SPRITE_AXIS_X){ + flip |= SDL_FLIP_HORIZONTAL; + } + + if(axis & ARC_SPRITE_AXIS_Y){ + flip |= SDL_FLIP_VERTICAL; + } + + SDL_RenderCopyEx((SDL_Renderer *)renderer, sprite->spritesheet->texture, (SDL_Rect *)sprite->frames->data + *sprite->frameIndex, (SDL_Rect *)renderBounds, 0.0, NULL, flip); +} + void ARC_Sprite_RenderRotated(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *renderBounds, ARC_Point *center, double angle){ SDL_RenderCopyEx((SDL_Renderer *)renderer, sprite->spritesheet->texture, (SDL_Rect *)sprite->frames->data + *sprite->frameIndex, (SDL_Rect *)renderBounds, angle, (SDL_Point *)center, SDL_FLIP_NONE); } +void ARC_Sprite_SetFrameIndex(ARC_Sprite *sprite, uint32_t index){ + if(sprite->frames->size <= index){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG(arc_errno, "in ARC_Sprite_SetFrameIndex(sprite, %d); index out of bounds", index); + return; + } + *sprite->frameIndex = index; +} + void ARC_Sprite_IterateFrame(ARC_Sprite *sprite){ ++*sprite->frameIndex; - if(*sprite->frameIndex == *sprite->frames->size){ + if(*sprite->frameIndex == sprite->frames->size){ *sprite->frameIndex = 0; } } @@ -47,4 +70,8 @@ ARC_Rect *ARC_Sprite_GetBounds(ARC_Sprite *sprite){ return (ARC_Rect *)sprite->frames->data + *sprite->frameIndex; } +ARC_Array *ARC_Sprite_GetAllBounds(ARC_Sprite *sprite){ + return sprite->frames; +} + #endif // ARC_SDL \ No newline at end of file diff --git a/src/graphics/sdl/text.c b/src/graphics/sdl/text.c new file mode 100644 index 0000000..9d65ed9 --- /dev/null +++ b/src/graphics/sdl/text.c @@ -0,0 +1,56 @@ +#include "arc/graphics/text.h" +#include "arc/graphics/sdl/text.h" +#include "arc/graphics/color.h" +#include "arc/math/point.h" +#include "arc/math/rectangle.h" +#include "arc/std/string.h" + +#include + +void ARC_Text_Create(ARC_Text **text, ARC_String *path, int32_t size, ARC_Color color){ + *text = (ARC_Text *)malloc(sizeof(ARC_Text)); + ARC_String_Copy(&(*text)->name, path); + (*text)->size = size; + (*text)->color = color; + (*text)->texture = NULL; + (*text)->bounds = (ARC_Rect){ 0, 0, 0, 0 }; +} + +void ARC_Text_Destroy(ARC_Text *font){ + if(font->texture != NULL){ + SDL_DestroyTexture(font->texture); + } + ARC_String_Destroy(font->name); + free(font); +} + +void ARC_Text_SetString(ARC_Text *text, ARC_Renderer *renderer, ARC_String *string){ + TTF_Font *ttfont = TTF_OpenFont(text->name->data, text->size); + SDL_Color textColor = (SDL_Color){ text->color.r, text->color.g, text->color.b, text->color.a }; + SDL_Surface *surface = TTF_RenderText_Blended_Wrapped(ttfont, string->data, textColor, 0); + + text->bounds.w = surface->w; + text->bounds.h = surface->h; + + if(text->texture){ + SDL_DestroyTexture(text->texture); + } + text->texture = SDL_CreateTextureFromSurface((SDL_Renderer *)renderer, surface); + + SDL_FreeSurface(surface); + TTF_CloseFont(ttfont); +} + +void ARC_Text_Render(ARC_Text *text, ARC_Renderer *renderer){ + if(text->texture == NULL){ + return; + } + + SDL_Rect bounds = (SDL_Rect){ text->bounds.x, text->bounds.y, text->bounds.w, text->bounds.h }; + SDL_RenderCopy((SDL_Renderer *)renderer, text->texture, NULL, &bounds); +} + +void ARC_Text_SetPos(ARC_Text *text, ARC_Point pos){ + text->bounds.x = pos.x; + text->bounds.y = pos.y; +} \ No newline at end of file diff --git a/src/input/sdl/keyboard.c b/src/input/sdl/keyboard.c index 2a536fa..c120335 100644 --- a/src/input/sdl/keyboard.c +++ b/src/input/sdl/keyboard.c @@ -79,7 +79,19 @@ ARC_KeyboardState ARC_Keyboard_GetState(ARC_Keyboard *keyboard, enum ARC_Keyboar case ARC_KEY_Y: return keyboard->keys[SDLK_y]; case ARC_KEY_Z: return keyboard->keys[SDLK_z]; - case ARC_KEY_ESC: return keyboard->keys[SDLK_ESCAPE]; + case ARC_KEY_0: return keyboard->keys[SDLK_0]; + case ARC_KEY_1: return keyboard->keys[SDLK_1]; + case ARC_KEY_2: return keyboard->keys[SDLK_2]; + case ARC_KEY_3: return keyboard->keys[SDLK_3]; + case ARC_KEY_4: return keyboard->keys[SDLK_4]; + case ARC_KEY_5: return keyboard->keys[SDLK_5]; + case ARC_KEY_6: return keyboard->keys[SDLK_6]; + case ARC_KEY_7: return keyboard->keys[SDLK_7]; + case ARC_KEY_8: return keyboard->keys[SDLK_8]; + case ARC_KEY_9: return keyboard->keys[SDLK_9]; + + case ARC_KEY_SPACE: return keyboard->keys[SDLK_SPACE ]; + case ARC_KEY_ESC: return keyboard->keys[SDLK_ESCAPE]; default: return ARC_KEY_NONE; } diff --git a/src/math/circle.c b/src/math/circle.c new file mode 100644 index 0000000..e69de29 diff --git a/src/math/config.c b/src/math/config.c new file mode 100644 index 0000000..11c0214 --- /dev/null +++ b/src/math/config.c @@ -0,0 +1,276 @@ +#include "arc/math/config.h" +#include +#include +#include "arc/std/array.h" +#include "arc/std/string.h" +#include "arc/std/errno.h" +#include "arc/std/config.h" +#include "arc/math/point.h" +#include "arc/math/rectangle.h" + +// #define ARC_DEFAULT_CONFIG +#include "arc/std/defaults/config.h" + +void ARC_MathConfig_Init(ARC_Config *config){ + ARC_Config_AddKeyCString(config, (char *)"ARC_Point" , 9, ARC_Point_Read , ARC_Point_Delete ); + ARC_Config_AddKeyCString(config, (char *)"ARC_Rect" , 8, ARC_Rect_Read , ARC_Rect_Delete ); + ARC_Config_AddKeyCString(config, (char *)"ARC_Rect[]", 10, ARC_RectArray_Read, ARC_RectArray_Delete); +} + +uint64_t ARC_MathConfig_GetIndexAndErrorCheck(ARC_String *string, char *search, uint64_t searchLength){ + uint64_t separator = ARC_String_FindCString(string, ",", 1); + + if(separator == ~(uint64_t)0){ + arc_errno = ARC_ERRNO_DATA; + } + + return separator; +} + +uint8_t ARC_Point_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_DEBUG_LOG(arc_errno, "in ARC_Point_Read(config, string, value); no matching curly braces: %s", string->data); + arc_errno = ARC_ERRNO_DATA; + return 0; + } + + uint64_t separator = ARC_MathConfig_GetIndexAndErrorCheck(string, ",", 1); + if(arc_errno){ + return 0; + } + + ARC_String *xString, *yString; + ARC_String_CopySubstring(&xString, string, 1 , separator - 1 ); + ARC_String_CopySubstring(&yString, string, separator + 1, string->length - (separator + 2)); + + ARC_Point *point = (ARC_Point *)malloc(sizeof(ARC_Point)); + point->x = (int32_t)ARC_String_ToInt64_t(xString); + point->y = (int32_t)ARC_String_ToInt64_t(yString); + + ARC_String_Destroy(xString); + ARC_String_Destroy(yString); + + *value = point; + return 0; +} + +uint8_t ARC_Rect_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_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG(arc_errno, "in ARC_Rect_Read(config, string, value); no matching curly braces: %s", string->data); + return 0; + } + + ARC_String *current; + ARC_String_CopySubstring(¤t, string, 1, string->length - 2); + + ARC_String *temp, *tempStripped; + int32_t x, y, w, h; + int64_t separator; + + //x + separator = ARC_MathConfig_GetIndexAndErrorCheck(current, ",", 1); + if(arc_errno){ + return 0; + } + + ARC_String_CopySubstring(&temp, current, 0, separator - 1); + ARC_String_StripEndsWhitespace(temp, &tempStripped); + x = ARC_String_ToInt64_t(tempStripped); + ARC_String_Destroy(temp); + ARC_String_Destroy(tempStripped); + + temp = current; + ARC_String_CopySubstring(¤t, temp, separator + 1, temp->length - (separator + 1)); + ARC_String_Destroy(temp); + + //y + separator = ARC_MathConfig_GetIndexAndErrorCheck(current, ",", 1); + if(arc_errno){ + return 0; + } + + ARC_String_CopySubstring(&temp, current, 0, separator - 1); + ARC_String_StripEndsWhitespace(temp, &tempStripped); + y = ARC_String_ToInt64_t(tempStripped); + ARC_String_Destroy(temp); + ARC_String_Destroy(tempStripped); + + temp = current; + ARC_String_CopySubstring(¤t, temp, separator + 1, temp->length - (separator + 1)); + ARC_String_Destroy(temp); + + //w + separator = ARC_MathConfig_GetIndexAndErrorCheck(current, ",", 1); + if(arc_errno){ + return 0; + } + + ARC_String_CopySubstring(&temp, current, 0, separator - 1); + ARC_String_StripEndsWhitespace(temp, &tempStripped); + w = ARC_String_ToInt64_t(tempStripped); + ARC_String_Destroy(temp); + ARC_String_Destroy(tempStripped); + + temp = current; + ARC_String_CopySubstring(¤t, temp, separator + 1, temp->length - (separator + 1)); + ARC_String_Destroy(temp); + + //h + separator = current->length; + if(arc_errno){ + return 0; + } + + ARC_String_CopySubstring(&temp, current, 0, separator); + ARC_String_StripEndsWhitespace(temp, &tempStripped); + h = ARC_String_ToInt64_t(tempStripped); + ARC_String_Destroy(temp); + ARC_String_Destroy(tempStripped); + ARC_String_Destroy(current); + + *value = malloc(sizeof(ARC_Rect)); + ((ARC_Rect *) *value)->x = x; + ((ARC_Rect *) *value)->y = y; + ((ARC_Rect *) *value)->w = w; + ((ARC_Rect *) *value)->h = h; + return 0; +} + +void ARC_RectArray_ReadRect(ARC_Config* config, ARC_String *stripped, uint64_t index, uint64_t length, uint64_t *arrayIndex, void **value){ + ARC_String *substr, *temp; + ARC_String_CopySubstring(&temp, stripped, index, length); + ARC_String_StripEndsWhitespace(temp, &substr); + ARC_String_Destroy(temp); + + // reading in reference + ARC_Rect *tempRect; + ARC_Config_Get(config, substr, (void **) &tempRect); + if(tempRect){ + ARC_String_Destroy(substr); + + ((ARC_Rect *)((ARC_Array *) *value)->data)[*arrayIndex] = *tempRect; + ++*arrayIndex; + + return; + } + + //reading in value + ARC_Rect_Read(config, substr, (void **) &tempRect); + if(arc_errno){ + ARC_DEBUG_LOG(arc_errno, "in ARC_RectArray_ReadRect(config, string, index, length, arrayIndex, value); failed to read rect: %s", substr->data); + ARC_String_Destroy(substr); + return; + } + + ((ARC_Rect *)((ARC_Array *) *value)->data)[*arrayIndex] = *tempRect; + ++*arrayIndex; + + ARC_Rect_Delete(config, substr, (void *)tempRect); + ARC_String_Destroy(substr); +} + +uint8_t ARC_RectArray_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_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG(arc_errno, "in ARC_RectArray_Read(config, string, value); no matching curly braces: %s", string->data); + return 0; + } + + ARC_String *temp, *stripped; + ARC_String_CopySubstring(&temp, string, 1, string->length - 2); + ARC_String_StripEndsWhitespace(temp, &stripped); + ARC_String_Destroy(temp); + + uint64_t arraySize = 1; + int64_t encapsulated = 0; + for(uint64_t i = 0; i < stripped->length; i++){ + if(stripped->data[i] == '{'){ + encapsulated++; + continue; + } + + if(stripped->data[i] == '}'){ + encapsulated--; + continue; + } + + if(!encapsulated && stripped->data[i] == ','){ + arraySize++; + } + } + + if(encapsulated){ + arc_errno = ARC_ERRNO_DATA; + //TODO: Fix this for windows SMFH + // ARC_DEBUG_LOG(arc_errno, "in ARC_RectArray_Read(config, data, subdata, value); after looping encapsulated was %ld", encapsulated); + ARC_String_Destroy(stripped); + return 0; + } + + *value = malloc(sizeof(ARC_Array)); + ((ARC_Array *) *value)->data = malloc(sizeof(ARC_Rect) * arraySize); + ((ARC_Array *) *value)->size = arraySize; + + uint64_t index = 0; + arraySize = 0; + encapsulated = 0; + for(uint64_t i = 0; i < stripped->length; i++){ + if(stripped->data[i] == '{'){ + encapsulated++; + continue; + } + + if(stripped->data[i] == '}'){ + encapsulated--; + continue; + } + + if(!encapsulated && stripped->data[i] == ','){ + ARC_RectArray_ReadRect(config, stripped, index, i - index, &arraySize, value); + if(arc_errno){ + return 0; + } + + index = i + 1; + + if(arraySize == ((ARC_Array *) *value)->size){ + break; + } + } + } + + if(arraySize != ((ARC_Array *) *value)->size){ + ARC_RectArray_ReadRect(config, stripped, index, stripped->length - index, &arraySize, value); + } + ARC_String_Destroy(stripped); + return 0; +} + +void ARC_Point_Delete(ARC_Config* config, ARC_String *string, void *value){ + free((ARC_Point *)value); +} + +void ARC_Rect_Delete(ARC_Config* config, ARC_String *string, void *value){ + free((ARC_Rect *)value); +} + +void ARC_RectArray_Delete(ARC_Config* config, ARC_String *string, void *value){ + //TODO free value->data + free((ARC_Array *)value); +} \ No newline at end of file diff --git a/src/math/obround.c b/src/math/obround.c new file mode 100644 index 0000000..b8ef45c --- /dev/null +++ b/src/math/obround.c @@ -0,0 +1,19 @@ +#include "arc/math/obround.h" + +ARC_FObround ARC_Obround_CastToFObround(ARC_Obround *obround){ + return (ARC_FObround){ + .x = (float)obround->x, + .y = (float)obround->y, + .r = (float)obround->r, + .h = (float)obround->h + }; +} + +ARC_Obround ARC_FObround_CastToObround(ARC_FObround *obround){ + return (ARC_Obround){ + .x = (int32_t)obround->x, + .y = (int32_t)obround->y, + .r = (int32_t)obround->r, + .h = (int32_t)obround->h + }; +} \ No newline at end of file diff --git a/src/math/rectangle.c b/src/math/rectangle.c index 71c5897..ce1a3d4 100644 --- a/src/math/rectangle.c +++ b/src/math/rectangle.c @@ -3,6 +3,34 @@ //VERY TEMP // #include +void ARC_Rect_CenterOn(ARC_Rect *rect, ARC_Rect *bounds){ + rect->x = (bounds->x + (bounds->w / 2)) - (rect->w / 2); + rect->y = (bounds->y + (bounds->h / 2)) - (rect->h / 2); +} + +void ARC_FRect_CenterOn(ARC_FRect *rect, ARC_FRect *bounds){ + rect->x = (bounds->x + (bounds->w / 2.0f)) - (rect->w / 2.0f); + rect->y = (bounds->y + (bounds->h / 2.0f)) - (rect->h / 2.0f); +} + +ARC_FRect ARC_Rect_CastToFRect(ARC_Rect *rect){ + return (ARC_FRect){ + .x = (float)rect->x, + .y = (float)rect->y, + .w = (float)rect->w, + .h = (float)rect->h, + }; +} + +ARC_Rect ARC_FRect_CastToRect(ARC_FRect *rect){ + return (ARC_Rect){ + .x = (int32_t)rect->x, + .y = (int32_t)rect->y, + .w = (int32_t)rect->w, + .h = (int32_t)rect->h, + }; +} + int32_t ARC_Rect_Intersects(ARC_Rect *rect1, ARC_Rect *rect2){ if(rect1->x <= rect2->x + rect2->w && rect1->x + rect1->w >= rect2->x && rect1->y <= rect2->y + rect2->h && rect1->y + rect1->h >= rect2->y){ @@ -11,9 +39,60 @@ int32_t ARC_Rect_Intersects(ARC_Rect *rect1, ARC_Rect *rect2){ return 0; } +int32_t ARC_FRect_Intersects(ARC_FRect *rect1, ARC_FRect *rect2){ + if(rect1->x <= rect2->x + rect2->w && rect1->x + rect1->w >= rect2->x && + rect1->y <= rect2->y + rect2->h && rect1->y + rect1->h >= rect2->y){ + return 1; + } + return 0; +} + +int32_t ARC_Rect_IntersectsPoint(ARC_Rect *rect, ARC_Point *point){ + if(rect->x <= point->x && rect->x + rect->w >= point->x && + rect->y <= point->y && rect->y + rect->h >= point->y){ + return 1; + } + return 0; +} + +int32_t ARC_FRect_IntersectsPoint(ARC_FRect *rect, ARC_Point *point){ + if(rect->x <= point->x && rect->x + rect->w >= point->x && + rect->y <= point->y && rect->y + rect->h >= point->y){ + return 1; + } + return 0; +} + int32_t ARC_Rect_LineIntersects(ARC_Rect *rect, int32_t *x1, int32_t *y1, int32_t *x2, int32_t *y2){ //TODO: Replace soon // return SDL_IntersectRectAndLine((SDL_Rect *) rect, x1, y1, x2, y2); return 1; } +//TODO: position 1px away from colliding, so if velocity is greater than 2px it doesn't have weird gap spacing +// might need to check diagnals as well, this is a rudamentry implementation +void ARC_FRect_CollideAndSlide(ARC_FRect *rect, ARC_Vector2 *velocity, ARC_FRect *wall){ + ARC_FRect nextRectPosition = { + .x = rect->x + velocity->x, + .y = rect->y + velocity->y, + .w = rect->w, + .h = rect->h + }; + + //there is no collision, return + if(!ARC_FRect_Intersects(&nextRectPosition, wall)){ + return; + } + + nextRectPosition.x = rect->x + velocity->x; + nextRectPosition.y = rect->y; + if(ARC_FRect_Intersects(&nextRectPosition, wall)){ + velocity->x = 0; + } + + nextRectPosition.x = rect->x; + nextRectPosition.y = rect->y + velocity->y; + if(ARC_FRect_Intersects(&nextRectPosition, wall)){ + velocity->y = 0; + } +} \ No newline at end of file diff --git a/src/math/vector2.c b/src/math/vector2.c index c0fdabe..a825903 100644 --- a/src/math/vector2.c +++ b/src/math/vector2.c @@ -3,6 +3,10 @@ void ARC_Vector2_Normalize(ARC_Vector2 *vector){ float length = sqrtf((vector->x * vector->x) + (vector->y * vector->y)); + if(length == 0){ + return; + } + vector->x /= length; vector->y /= length; } diff --git a/src/std/config.c b/src/std/config.c index ade3198..b8c91c7 100644 --- a/src/std/config.c +++ b/src/std/config.c @@ -211,6 +211,7 @@ void ARC_Config_LoadFromKey(ARC_Config *config, ARC_String *keyType, ARC_String ARC_Hashtable_Get(config->keys, keyType->data, keyType->length, (void **)&key); if(key == NULL){ arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG(arc_errno, "in ARC_Config_LoadFromKey(config, string, value); no matching key: %s", keyType->data); } if(arc_errno){ diff --git a/src/std/defaults/config.c b/src/std/defaults/config.c index 11838d3..844f988 100644 --- a/src/std/defaults/config.c +++ b/src/std/defaults/config.c @@ -11,21 +11,21 @@ #include void ARC_Defaults_ConfigKey_Create(ARC_Config *config){ - ARC_Config_AddKeyCString(config, "uint8_t" , 7, ARC_ConfigKey_Read_Uint8_t , ARC_ConfigKey_Delete_Uint8_t ); - ARC_Config_AddKeyCString(config, "int8_t" , 6, ARC_ConfigKey_Read_Int8_t , ARC_ConfigKey_Delete_Int8_t ); - ARC_Config_AddKeyCString(config, "uint16_t", 8, ARC_ConfigKey_Read_Uint16_t , ARC_ConfigKey_Delete_Uint16_t ); - ARC_Config_AddKeyCString(config, "int16_t" , 7, ARC_ConfigKey_Read_Int16_t , ARC_ConfigKey_Delete_Int16_t ); - ARC_Config_AddKeyCString(config, "uint32_t", 8, ARC_ConfigKey_Read_Uint32_t , ARC_ConfigKey_Delete_Uint32_t ); - ARC_Config_AddKeyCString(config, "int32_t" , 7, ARC_ConfigKey_Read_Int32_t , ARC_ConfigKey_Delete_Int32_t ); - ARC_Config_AddKeyCString(config, "uint64_t", 8, ARC_ConfigKey_Read_Uint64_t , ARC_ConfigKey_Delete_Uint64_t ); - ARC_Config_AddKeyCString(config, "int64_t" , 7, ARC_ConfigKey_Read_Int64_t , ARC_ConfigKey_Delete_Int64_t ); - // ARC_Config_AddKeyCString(config, "char" , 4, ARC_ConfigKey_Read_Char , ARC_ConfigKey_Delete_Char ); - ARC_Config_AddKeyCString(config, "int" , 3, ARC_ConfigKey_Read_Int , ARC_ConfigKey_Delete_Int ); - ARC_Config_AddKeyCString(config, "long" , 4, ARC_ConfigKey_Read_Long , ARC_ConfigKey_Delete_Long ); - ARC_Config_AddKeyCString(config, "float" , 5, ARC_ConfigKey_Read_Float , ARC_ConfigKey_Delete_Float ); - ARC_Config_AddKeyCString(config, "double" , 6, ARC_ConfigKey_Read_Double , ARC_ConfigKey_Delete_Double ); - ARC_Config_AddKeyCString(config, "string" , 6, ARC_ConfigKey_Read_String , ARC_ConfigKey_Delete_String ); - // ARC_Config_AddKeyCString(config, "string[]", ARC_ConfigKey_Read_StringArray, ARC_ConfigKey_Delete_StringArray); + ARC_Config_AddKeyCString(config, "uint8_t" , 7, ARC_ConfigKey_Read_Uint8_t , ARC_ConfigKey_Delete_Uint8_t ); + ARC_Config_AddKeyCString(config, "int8_t" , 6, ARC_ConfigKey_Read_Int8_t , ARC_ConfigKey_Delete_Int8_t ); + ARC_Config_AddKeyCString(config, "uint16_t" , 8, ARC_ConfigKey_Read_Uint16_t , ARC_ConfigKey_Delete_Uint16_t ); + ARC_Config_AddKeyCString(config, "int16_t" , 7, ARC_ConfigKey_Read_Int16_t , ARC_ConfigKey_Delete_Int16_t ); + ARC_Config_AddKeyCString(config, "uint32_t" , 8, ARC_ConfigKey_Read_Uint32_t , ARC_ConfigKey_Delete_Uint32_t ); + ARC_Config_AddKeyCString(config, "int32_t" , 7, ARC_ConfigKey_Read_Int32_t , ARC_ConfigKey_Delete_Int32_t ); + ARC_Config_AddKeyCString(config, "uint64_t" , 8, ARC_ConfigKey_Read_Uint64_t , ARC_ConfigKey_Delete_Uint64_t ); + ARC_Config_AddKeyCString(config, "int64_t" , 7, ARC_ConfigKey_Read_Int64_t , ARC_ConfigKey_Delete_Int64_t ); + // ARC_Config_AddKeyCString(config, "char" , 4, ARC_ConfigKey_Read_Char , ARC_ConfigKey_Delete_Char ); + ARC_Config_AddKeyCString(config, "int" , 3, ARC_ConfigKey_Read_Int , ARC_ConfigKey_Delete_Int ); + ARC_Config_AddKeyCString(config, "long" , 4, ARC_ConfigKey_Read_Long , ARC_ConfigKey_Delete_Long ); + ARC_Config_AddKeyCString(config, "float" , 5, ARC_ConfigKey_Read_Float , ARC_ConfigKey_Delete_Float ); + ARC_Config_AddKeyCString(config, "double" , 6, ARC_ConfigKey_Read_Double , ARC_ConfigKey_Delete_Double ); + ARC_Config_AddKeyCString(config, "ARC_String", 10, ARC_ConfigKey_Read_String , ARC_ConfigKey_Delete_String ); + ARC_Config_AddKeyCString(config, "string[]" , 8, ARC_ConfigKey_Read_StringArray, ARC_ConfigKey_Delete_StringArray); } uint8_t ARC_ConfigKey_Read_Uint8_t(ARC_Config* config, ARC_String *string, void **value){ @@ -183,79 +183,101 @@ uint8_t ARC_ConfigKey_Read_String(ARC_Config* config, ARC_String *string, void * return 1; } - ARC_String_Copy((ARC_String **)value, string); + if(string->data[0] != '"' || string->data[string->length - 1] != '"'){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG(arc_errno, "in ARC_ConfigKey_Read_String(config, string, value); no matching quotes: %s", string->data); + return 0; + } + + ARC_String_CopySubstring((ARC_String **)value, string, 1, string->length - 2); return 0; } -/* -void ARC_ConfigKey_Read_StringArray(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; - for(uint32_t i = subdata->index; i < subdata->index + subdata->length; i++){ - if(data[i] == ','){ +void ARC_ConfigKey_StringArray_ReadString(ARC_Config* config, ARC_String *stripped, uint64_t index, uint64_t length, uint64_t *arrayIndex, void **value){ + ARC_String *substr, *temp; + ARC_String_CopySubstring(&temp, stripped, index, length); + ARC_String_StripEndsWhitespace(temp, &substr); + ARC_String_Destroy(temp); + + // reading in reference + ARC_String *tempString; + // ARC_Config_Get(config, substr, (void **) &tempString); + // if(tempString){ + // ARC_String_Destroy(substr); + + // ((ARC_String *)((ARC_Array *) *value)->data)[*arrayIndex] = *tempString; + // ++*arrayIndex; + + // return; + // } + + //reading in value + ARC_ConfigKey_Read_String(config, substr, (void **) &tempString); + if(arc_errno){ + ARC_DEBUG_LOG(arc_errno, "in ARC_RectArray_ReadRect(config, string, index, length, arrayIndex, value); failed to read string: %s", substr->data); + ARC_String_Destroy(substr); + return; + } + + ((ARC_String **)((ARC_Array *) *value)->data)[*arrayIndex] = tempString; + ++*arrayIndex; + + ARC_String_Destroy(substr); +} + +uint8_t ARC_ConfigKey_Read_StringArray(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_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG(arc_errno, "in ARC_ConfigKey_Read_StringArray(config, string, value); no matching curly braces: %s", string->data); + return 0; + } + + ARC_String *temp, *stripped; + ARC_String_CopySubstring(&temp, string, 1, string->length - 2); + ARC_String_StripEndsWhitespace(temp, &stripped); + ARC_String_Destroy(temp); + + uint64_t arraySize = 1; + for(uint64_t i = 0; i < stripped->length; i++){ + if(stripped->data[i] == ','){ arraySize++; } } + + *value = malloc(sizeof(ARC_Array)); + ((ARC_Array *) *value)->data = malloc(sizeof(ARC_String *) * arraySize); + ((ARC_Array *) *value)->size = arraySize; - *value = malloc(sizeof(char *)); - ((ARC_Array *) *value)->data = malloc(sizeof(char *) * arraySize); - ((ARC_Array *) *value)->size = malloc(sizeof(uint32_t)); - *((ARC_Array *) *value)->size = arraySize; - - ARC_StringSubstr temp = { subdata->index, 0 }; + uint64_t index = 0; arraySize = 0; - for(uint64_t i = subdata->index; i < subdata->index + subdata->length; i++){ - if(data[i] != ','){ - continue; - } - - temp.length = i - temp.index; - - char *tempStr = (char *)ARC_Config_GetReference(config, (char *)data, &temp); - if(!tempStr){ - ARC_ConfigKey_Read_String(config, data, &temp, (void **) &tempStr); + for(uint64_t i = 0; i < stripped->length; i++){ + if(stripped->data[i] == ','){ + ARC_ConfigKey_StringArray_ReadString(config, stripped, index, i - index, &arraySize, value); if(arc_errno){ - return arc_errno; + return 0; + } + + index = i + 1; + + if(arraySize == ((ARC_Array *) *value)->size){ + break; } } - - ((char **)((ARC_Array *) *value)->data)[arraySize] = tempStr; - - // ARC_ConfigKey_Delete_String(config, data, &temp, (void *)tempStr); - // 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; - char *tempStr = (char *)ARC_Config_GetReference(config, (char *)data, &temp); - if(!tempStr){ - ARC_ConfigKey_Read_String(config, data, &temp, (void **) &tempStr); - if(arc_errno){ - return arc_errno; - } + if(arraySize != ((ARC_Array *) *value)->size){ + ARC_ConfigKey_StringArray_ReadString(config, stripped, index, stripped->length - index, &arraySize, value); } - - ((char **)((ARC_Array *) *value)->data)[arraySize] = tempStr; - - // ARC_ConfigKey_Delete_String(config, data, &temp, (void *)tempStr); - // if(arc_errno){ - // return arc_errno; - // } - + ARC_String_Destroy(stripped); return 0; } -*/ + + void ARC_ConfigKey_Delete_Uint8_t(ARC_Config *config, ARC_String *string, void *value){ free((uint8_t *)value); @@ -313,4 +335,11 @@ void ARC_ConfigKey_Delete_String(ARC_Config *config, ARC_String *string, void *v ARC_String_Destroy((ARC_String *)value); } +void ARC_ConfigKey_Delete_StringArray(ARC_Config *config, ARC_String *string, void *value){ + for(uint32_t i = 0; i < ((ARC_Array *)value)->size; i++){ + free(((ARC_String **)((ARC_Array *)value)->data)[i]); + } + free((ARC_Array *)value); +} + #endif //ARC_DEFAULT_CONFIG diff --git a/src/std/string.c b/src/std/string.c index 3854af2..fe29aa5 100644 --- a/src/std/string.c +++ b/src/std/string.c @@ -303,7 +303,6 @@ void ARC_String_StripWhitespace(ARC_String *original, ARC_String **stripped){ ARC_String_Create(stripped, data, length); } - void ARC_String_StripEndsWhitespace(ARC_String *original, ARC_String **stripped){ uint64_t index; for(uint64_t i = 0; i < original->length; i++){ @@ -328,7 +327,7 @@ void ARC_String_StripEndsWhitespace(ARC_String *original, ARC_String **stripped) } uint64_t endIndex; - for(uint64_t i = original->length; i > 0; i--){ + for(uint64_t i = original->length;; i--){ if(original->data[i - 1] == ' '){ continue; } diff --git a/src/std/vector.c b/src/std/vector.c index 483fd4b..7e9158b 100644 --- a/src/std/vector.c +++ b/src/std/vector.c @@ -14,7 +14,7 @@ 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)->data = (void *)malloc(sizeof(void *)); + (*vector)->data = (void **)malloc(sizeof(void *)); *(*vector)->currentSize = 0; *(*vector)->capacity = 1; @@ -77,6 +77,9 @@ void ARC_Vector_RemoveIndex(ARC_Vector *vector, uint32_t *index){ void ARC_Vector_RemoveIndexNoCheck(ARC_Vector *vector, uint32_t *index){ for(uint32_t i = *index; i <= *vector->currentSize; i++){ + if(i + 1 >= *vector->currentSize - 1){ + break; + } vector->data[i] = vector->data[i + 1]; } @@ -87,6 +90,10 @@ void ARC_Vector_RemoveIndexNoCheck(ARC_Vector *vector, uint32_t *index){ } *vector->capacity >>= 1; + if(*vector->capacity <= 0){ + *vector->capacity = 1; + } + vector->data = (void *)realloc(vector->data, sizeof(void *) * *vector->capacity); }