From 1b2e2cb7f147cf67db0ba61e8e8af009da58f546 Mon Sep 17 00:00:00 2001 From: herbglitch Date: Sat, 22 Mar 2025 23:25:21 -0600 Subject: [PATCH] sdl3 migrate now compiling, need to go through all the files and clean them up --- cmake/archeus_sdl3.cmake | 89 +++++++++++ packages/audio/sdl3/audio.c | 7 + packages/audio/sdl3/audio.h | 10 ++ packages/audio/sdl3/config.c | 43 +++++ packages/graphics/sdl3/circle.c | 12 ++ packages/graphics/sdl3/config.c | 228 +++++++++++++++++++++++++++ packages/graphics/sdl3/line.c | 7 + packages/graphics/sdl3/obround.c | 13 ++ packages/graphics/sdl3/rectangle.c | 23 +++ packages/graphics/sdl3/renderer.c | 39 +++++ packages/graphics/sdl3/renderer.h | 10 ++ packages/graphics/sdl3/sprite.c | 96 +++++++++++ packages/graphics/sdl3/sprite.h | 14 ++ packages/graphics/sdl3/spritesheet.c | 86 ++++++++++ packages/graphics/sdl3/spritesheet.h | 12 ++ packages/graphics/sdl3/text.c | 66 ++++++++ packages/graphics/sdl3/text.h | 20 +++ packages/graphics/sdl3/view.c | 35 ++++ packages/graphics/sdl3/window.c | 26 +++ packages/graphics/sdl3/window.h | 9 ++ packages/input/sdl3/input.c | 45 ++++++ packages/input/sdl3/input.h | 15 ++ packages/input/sdl3/keyboard.c | 98 ++++++++++++ packages/input/sdl3/keyboard.h | 14 ++ packages/input/sdl3/mouse.c | 105 ++++++++++++ packages/input/sdl3/mouse.h | 17 ++ 26 files changed, 1139 insertions(+) create mode 100644 cmake/archeus_sdl3.cmake create mode 100644 packages/audio/sdl3/audio.c create mode 100644 packages/audio/sdl3/audio.h create mode 100644 packages/audio/sdl3/config.c create mode 100644 packages/graphics/sdl3/circle.c create mode 100644 packages/graphics/sdl3/config.c create mode 100644 packages/graphics/sdl3/line.c create mode 100644 packages/graphics/sdl3/obround.c create mode 100644 packages/graphics/sdl3/rectangle.c create mode 100644 packages/graphics/sdl3/renderer.c create mode 100644 packages/graphics/sdl3/renderer.h create mode 100644 packages/graphics/sdl3/sprite.c create mode 100644 packages/graphics/sdl3/sprite.h create mode 100644 packages/graphics/sdl3/spritesheet.c create mode 100644 packages/graphics/sdl3/spritesheet.h create mode 100644 packages/graphics/sdl3/text.c create mode 100644 packages/graphics/sdl3/text.h create mode 100644 packages/graphics/sdl3/view.c create mode 100644 packages/graphics/sdl3/window.c create mode 100644 packages/graphics/sdl3/window.h create mode 100644 packages/input/sdl3/input.c create mode 100644 packages/input/sdl3/input.h create mode 100644 packages/input/sdl3/keyboard.c create mode 100644 packages/input/sdl3/keyboard.h create mode 100644 packages/input/sdl3/mouse.c create mode 100644 packages/input/sdl3/mouse.h diff --git a/cmake/archeus_sdl3.cmake b/cmake/archeus_sdl3.cmake new file mode 100644 index 0000000..4a1cbc3 --- /dev/null +++ b/cmake/archeus_sdl3.cmake @@ -0,0 +1,89 @@ +set(ARCHEUS_SDL3_WINDOW_SOURCES + packages/graphics/sdl3/config.c + packages/graphics/sdl3/window.c + packages/graphics/sdl3/renderer.c +) + +set(ARCHEUS_SDL3_INPUT_SOURCES + packages/input/sdl3/input.c + packages/input/sdl3/keyboard.c + packages/input/sdl3/mouse.c + + #TODO: remove this + packages/audio/sdl3/config.c +) + +set(ARCHEUS_SDL3_GRAPHICS_SOURCES + packages/graphics/sdl3/circle.c + packages/graphics/sdl3/config.c + packages/graphics/sdl3/line.c + packages/graphics/sdl3/obround.c + packages/graphics/sdl3/rectangle.c + packages/graphics/sdl3/sprite.c + packages/graphics/sdl3/spritesheet.c + packages/graphics/sdl3/text.c +) + +function(sdl3_check_and_init_needed _ARCHEUS_SOURCES _ARCHEUS_INCLUDE_DIRECTORIES _ARCHEUS_LINK_LIBRARIES ARCHEUS_WINDOW_BACKEND ARCHEUS_INPUT_BACKEND ARCHEUS_GRAPHICS_BACKEND) + #if no backend uses sdl return + if(NOT ${ARCHEUS_WINDOW_BACKEND} STREQUAL "SDL3" AND NOT ${ARCHEUS_INPUT_BACKEND} STREQUAL "SDL3" AND NOT ${ARCHEUS_GRAPHICS_BACKEND} STREQUAL "SDL3") + return() + endif() + + #get needed libraries for backends + find_package(SDL3 REQUIRED) + + #add to include directories + list(APPEND ${_ARCHEUS_INCLUDE_DIRECTORIES} + PRIVATE ${SDL3_INCLUDE_DIRS} + ) + + #add to link libraries + list(APPEND ${_ARCHEUS_LINK_LIBRARIES} + PUBLIC ${SDL3_LIBRARIES} + ) + + #add matching files for the selected backends + if(${ARCHEUS_WINDOW_BACKEND} STREQUAL "SDL3") + list(APPEND ${_ARCHEUS_SOURCES} ${ARCHEUS_SDL3_WINDOW_SOURCES}) + endif() + + if(${ARCHEUS_INPUT_BACKEND} STREQUAL "SDL3") + #TODO: remove this + find_package(SDL3_mixer REQUIRED) + + list(APPEND ${_ARCHEUS_SOURCES} ${ARCHEUS_SDL3_INPUT_SOURCES}) + + #TODO: remove this + list(APPEND ${_ARCHEUS_LINK_LIBRARIES} + PUBLIC SDL3_mixer::SDL3_mixer + ) + endif() + + if(${ARCHEUS_GRAPHICS_BACKEND} STREQUAL "SDL3") + find_package(SDL3_image REQUIRED) + find_package(SDL3_ttf REQUIRED) + + #find_package(PkgConfig REQUIRED) + #pkg_check_modules(SDL3_GFX REQUIRED SDL3_gfx) + + list(APPEND ${_ARCHEUS_SOURCES} ${ARCHEUS_SDL3_GRAPHICS_SOURCES}) + + #add to include directories + list(APPEND ${_ARCHEUS_INCLUDE_DIRECTORIES} + PRIVATE ${SDL3IMAGE_INCLUDE_DIRS} + #PRIVATE ${SDL3_GFX_INCLUDE_DIRS} + ) + + #add to link libraries + list(APPEND ${_ARCHEUS_LINK_LIBRARIES} + PUBLIC SDL3_image::SDL3_image + PUBLIC SDL3_ttf::SDL3_ttf + #PUBLIC ${SDL3_GFX_LIBRARIES} + ) + endif() + + set(${_ARCHEUS_SOURCES} ${${_ARCHEUS_SOURCES}} PARENT_SCOPE) + set(${_ARCHEUS_INCLUDE_DIRECTORIES} ${${_ARCHEUS_INCLUDE_DIRECTORIES}} PARENT_SCOPE) + set(${_ARCHEUS_LINK_LIBRARIES} ${${_ARCHEUS_LINK_LIBRARIES}} PARENT_SCOPE) +endfunction() diff --git a/packages/audio/sdl3/audio.c b/packages/audio/sdl3/audio.c new file mode 100644 index 0000000..3b1ad27 --- /dev/null +++ b/packages/audio/sdl3/audio.c @@ -0,0 +1,7 @@ +#include "arc/audio/audio.h" +#include "audio.h" +#include + +void ARC_Audio_Play(ARC_Audio *audio){ + Mix_PlayChannel(-1, audio->chunk, 0); +} \ No newline at end of file diff --git a/packages/audio/sdl3/audio.h b/packages/audio/sdl3/audio.h new file mode 100644 index 0000000..3aa6d08 --- /dev/null +++ b/packages/audio/sdl3/audio.h @@ -0,0 +1,10 @@ +#ifndef ARC_SDL_AUDIO_H_ +#define ARC_SDL_AUDIO_H_ + +#include + +typedef struct ARC_Audio { + Mix_Chunk *chunk; +} ARC_Audio; + +#endif // !ARC_SDL_AUDIO_H_ diff --git a/packages/audio/sdl3/config.c b/packages/audio/sdl3/config.c new file mode 100644 index 0000000..0b068b8 --- /dev/null +++ b/packages/audio/sdl3/config.c @@ -0,0 +1,43 @@ +#include "arc/audio/config.h" + +#include "audio.h" +#include +#include "arc/std/config.h" +#include "arc/std/errno.h" +#include "arc/audio/audio.h" + +// #define ARC_DEFAULT_CONFIG +//#include "arc/std/defaults/config.h" +// +//void ARC_AudioConfig_Init(ARC_Config *config){ +// ARC_Config_AddKeyCString(config, (char *)"ARC_Audio", 9, ARC_Audio_Read, ARC_Audio_Delete); +//} +// +//uint8_t ARC_Audio_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_ERROR_WITH_VARIABLES("in ARC_Point_Read(config, string, value); no matching quotes: %s", string->data); +// arc_errno = ARC_ERRNO_DATA; +// return 0; +// } +// +// ARC_Audio *audio = (ARC_Audio *)malloc(sizeof(ARC_Audio)); +// +// ARC_String *path; +// ARC_String_CopySubstring(&path, string, 1, string->length - 2); +// audio->chunk = Mix_LoadWAV(path->data); +// +// //TODO: get error message if not loaded +// +// *value = (void *)audio; +// return 0; +//} +// +//void ARC_Audio_Delete(ARC_Config* config, ARC_String *string, void *value){ +// Mix_FreeChunk(((ARC_Audio *)value)->chunk); +// free((ARC_Audio *)value); +//} diff --git a/packages/graphics/sdl3/circle.c b/packages/graphics/sdl3/circle.c new file mode 100644 index 0000000..b68a9e2 --- /dev/null +++ b/packages/graphics/sdl3/circle.c @@ -0,0 +1,12 @@ +#include "arc/graphics/circle.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){ +// circleRGBA((SDL_Renderer *)renderer, (Sint16)circle.x, (Sint16)circle.y, (Sint16)circle.r, (Uint8)color.r, (Uint8)color.g, (Uint8)color.b, (Uint8)color.a); +} + +//TODO: very temp +void ARC_Circle_RenderFill(ARC_Circle circle, ARC_Renderer *renderer, ARC_Color color){ +// filledCircleRGBA((SDL_Renderer *)renderer, (Sint16)circle.x, (Sint16)circle.y, (Sint16)circle.r, (Uint8)color.r, (Uint8)color.g, (Uint8)color.b, (Uint8)color.a); +} diff --git a/packages/graphics/sdl3/config.c b/packages/graphics/sdl3/config.c new file mode 100644 index 0000000..0ddd255 --- /dev/null +++ b/packages/graphics/sdl3/config.c @@ -0,0 +1,228 @@ +#include "arc/graphics/config.h" + +#include +#include +#include "renderer.h" +#include "sprite.h" +#include "spritesheet.h" +#include "arc/std/string.h" +#include "arc/std/parser/helpers.h" +#include "arc/std/errno.h" +#include "arc/graphics/sprite.h" +#include "arc/graphics/spritesheet.h" +#include "arc/math/config.h" +#include "arc/math/point.h" +#include "arc/math/rectangle.h" + +void ARC_Config_InitGraphics(ARC_Config *config, ARC_Renderer *renderer){ + ARC_Config_RegisterTypeWithCStr(config, "ARC_Spritesheet", (ARC_ConfigType){ ARC_ConfigType_SpritesheetCopyFn, ARC_ConfigType_SpritesheetDestroyFn, renderer}); + ARC_Config_RegisterTypeWithCStr(config, "ARC_Sprite" , (ARC_ConfigType){ ARC_ConfigType_SpriteCopyFn , ARC_ConfigType_SpriteDestroyFn , renderer}); +} + +void ARC_ConfigType_SpritesheetString(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ + ARC_Renderer *renderer = (ARC_Renderer *)userdata; + + //get the string chars between the quotes + ARC_ParserTagToken *stringCharsTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(parsedData->tagTokens, 1); + + //get the path + ARC_String *path; + ARC_String_Create(&path, NULL, 0); + ARC_ParserData_HelperRecurseStringAdd(&path, stringCharsTagToken); + + //read in and set the texture + ARC_Spritesheet_CreateFromFile((ARC_Spritesheet **)type, renderer, path); + + //cleanup + ARC_String_Destroy(path); +} + +void ARC_ConfigType_SpritesheetCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ + ARC_ParserTagToken *valueTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(parsedData->tagTokens, 0); + + switch(valueTagToken->id){ + case ARC_CONFIG_STRING: + ARC_ConfigType_SpritesheetString(type, valueTagToken, config, userdata); + break; + + case ARC_CONFIG_NESTED_VALUE: + return; + + default: + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_SpritesheetCopyFn(type, parsedData, config, userdata), cannot use a value that is not a string or nested value. Look at documention for this function for more info"); + break; + } +} + +void ARC_ConfigType_SpritesheetDestroyFn(void *type){ + ARC_Spritesheet_Destroy((ARC_Spritesheet *)type); +} + +void ARC_ConfigType_SpriteCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ +} + +void ARC_ConfigType_SpriteDestroyFn(void *type){ +} + + + +//uint8_t ARC_Sprite_Read(ARC_Config* config, ARC_String *string, void **value){ +// ARC_Config_Get(config, string, value); +// if(*value){ +// return 1; +// } +// +// if(string->data[0] != '{' || string->data[string->length - 1] != '}'){ +// ARC_Spritesheet_ReadTexture(config, string, NULL, value); +// return 0; +// } +// +// uint64_t split = ARC_GraphicsConfig_GetIndexAndErrorCheck(string, ",", 1); +// if(arc_errno){ +// return 0; +// } +// +// ARC_String *temp, *spritesheetStr, *framesStr; +// ARC_String_CopySubstring(&temp, string, 1, split - 2); +// ARC_String_StripEndsWhitespace(&spritesheetStr, temp); +// ARC_String_Destroy(temp); +// +// ARC_String_CopySubstring(&temp, string, split + 1, string->length - (split + 2)); +// ARC_String_StripEndsWhitespace(&framesStr, temp); +// ARC_String_Destroy(temp); +// +// //spritesheet +// ARC_Spritesheet *spritesheet; +// ARC_Config_Get(config, spritesheetStr, (void **)&spritesheet); +// +// if(!spritesheet){ +// ARC_Spritesheet_Read(config, spritesheetStr, (void **)&spritesheet); +// if(arc_errno){ +// ARC_String_Destroy(spritesheetStr); +// ARC_String_Destroy(framesStr ); +// return 0; +// } +// } +// +// //bounds +// ARC_Array *frames; +// ARC_Config_Get(config, framesStr, (void **)&frames); +// +// if(!frames){ +// ARC_RectArray_Read(config, framesStr, (void **)&frames); +// if(arc_errno){ +// ARC_String_Destroy(spritesheetStr); +// ARC_String_Destroy(framesStr ); +// return 0; +// } +// } +// +// ARC_String_Destroy(spritesheetStr); +// ARC_String_Destroy(framesStr ); +// +// // Scale frames to match spritesheet size +// // TODO: possible bug for sheets that use same frames +// if(spritesheet->size){ +// for(uint32_t i = 0; i < frames->size; i++){ +// ((ARC_Rect *)frames->data)[i].x *= *spritesheet->size; +// ((ARC_Rect *)frames->data)[i].y *= *spritesheet->size; +// ((ARC_Rect *)frames->data)[i].w *= *spritesheet->size; +// ((ARC_Rect *)frames->data)[i].h *= *spritesheet->size; +// } +// } +// //sprite +// ARC_Sprite_Create((ARC_Sprite **)value, spritesheet, frames); +// +// return 0; +//} +// +//void ARC_SDL_Texture_Delete(ARC_Config* config, ARC_String *string, void *value){ +// SDL_DestroyTexture((SDL_Texture *) value); +//} +// +//void ARC_Spritesheet_Delete(ARC_Config* config, ARC_String *string, void *value){ +// ARC_Spritesheet *sheetValue = (ARC_Spritesheet *)value; +// +// //check if read in as a Textrue reference +// void *temp; +// ARC_Config_Get(config, string, &temp); +// if(temp){ +// //TODO: test to see if this breaks references +// free(sheetValue); +// return; +// } +// +// uint64_t split = ARC_GraphicsConfig_GetIndexAndErrorCheck(string, ",", 1); +// if(arc_errno){ +// //TODO: test to make sure no edge cases +// // free(sheetValue); +// ARC_SDL_Texture_Delete(config, string, value); +// arc_errno = 0; +// return; +// } +// +// if(split == ~0){ +// +// } +// +// //check if texture and size are references +// ARC_String *tempStr, *textureStr, *sizeStr; +// ARC_String_CopySubstring(&tempStr, string, 1, split - 1); +// ARC_String_StripEndsWhitespace(&textureStr, tempStr); +// ARC_String_Destroy(tempStr); +// +// ARC_String_CopySubstring(&tempStr, string, split + 1, string->length - (split + 1)); +// ARC_String_StripEndsWhitespace(&sizeStr, tempStr); +// ARC_String_Destroy(tempStr); +// +// ARC_Config_Get(config, sizeStr, (void **)&temp); +// ARC_String_Destroy(sizeStr); +// if(temp){ +// free(sheetValue->size); +// } +// +// ARC_Config_Get(config, textureStr, (void **)&temp); +// ARC_String_Destroy(textureStr); +// if(temp){ +// free(sheetValue->size); +// } +// +// free(sheetValue); +//} +// +//void ARC_Sprite_Delete(ARC_Config* config, ARC_String *string, void *value){ +// ARC_Sprite *spriteValue = (ARC_Sprite *)value; +// +// //check if read in as a Textrue reference +// void *temp; +// uint64_t split = ARC_GraphicsConfig_GetIndexAndErrorCheck(string, ",", 1); +// if(arc_errno){ +// free(spriteValue); +// return; +// } +// +// //check if texture and size are references +// ARC_String *tempStr, *spritesheetStr, *framesStr; +// ARC_String_CopySubstring(&tempStr, string, 1, split - 1); +// ARC_String_StripEndsWhitespace(&spritesheetStr, tempStr); +// ARC_String_Destroy(tempStr); +// +// ARC_String_CopySubstring(&tempStr, string, split + 1, string->length - (split + 1)); +// ARC_String_StripEndsWhitespace(&framesStr, tempStr); +// ARC_String_Destroy(tempStr); +// +// ARC_Config_Get(config, spritesheetStr, (void **)&temp); +// ARC_String_Destroy(spritesheetStr); +// if(temp){ +// free(spriteValue->spritesheet); +// } +// +// ARC_Config_Get(config, framesStr, (void **)&temp); +// ARC_String_Destroy(framesStr); +// if(temp){ +// free(spriteValue->frames); +// } +// +// free(spriteValue); +//} diff --git a/packages/graphics/sdl3/line.c b/packages/graphics/sdl3/line.c new file mode 100644 index 0000000..6035a4c --- /dev/null +++ b/packages/graphics/sdl3/line.c @@ -0,0 +1,7 @@ +#include "arc/graphics/line.h" +#include "renderer.h" + +void ARC_Line_Render(ARC_Point point1, ARC_Point point2, ARC_Renderer *renderer, ARC_Color color){ + SDL_SetRenderDrawColor((SDL_Renderer *)renderer, color.r, color.g, color.b, color.a); + SDL_RenderLine((SDL_Renderer *)renderer, point1.x, point1.y, point2.x, point2.y); +} diff --git a/packages/graphics/sdl3/obround.c b/packages/graphics/sdl3/obround.c new file mode 100644 index 0000000..bf1f669 --- /dev/null +++ b/packages/graphics/sdl3/obround.c @@ -0,0 +1,13 @@ +#include "arc/graphics/obround.h" +#include "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){ + //TODO: write this +} + +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); +} diff --git a/packages/graphics/sdl3/rectangle.c b/packages/graphics/sdl3/rectangle.c new file mode 100644 index 0000000..cc51480 --- /dev/null +++ b/packages/graphics/sdl3/rectangle.c @@ -0,0 +1,23 @@ +#include "arc/graphics/rectangle.h" +#include "renderer.h" +#include + +void ARC_Rect_Render(ARC_Rect rect, ARC_Renderer *renderer, ARC_Color color){ + ARC_FRect casted = ARC_Rect_CastToFRect(rect); + ARC_FRect_Render(casted, renderer, color); +} + +void ARC_Rect_RenderFill(ARC_Rect rect, ARC_Renderer *renderer, ARC_Color color){ + ARC_FRect casted = ARC_Rect_CastToFRect(rect); + ARC_FRect_RenderFill(casted, renderer, color); +} + +void ARC_FRect_Render(ARC_FRect rect, ARC_Renderer *renderer, ARC_Color color){ + SDL_SetRenderDrawColor((SDL_Renderer *)renderer, color.r, color.g, color.b, color.a); + SDL_RenderRect((SDL_Renderer *)renderer, (SDL_FRect *)&rect); +} + +void ARC_FRect_RenderFill(ARC_FRect rect, ARC_Renderer *renderer, ARC_Color color){ + SDL_SetRenderDrawColor((SDL_Renderer *)renderer, color.r, color.g, color.b, color.a); + SDL_RenderFillRect((SDL_Renderer *)renderer, (SDL_FRect *)&rect); +} diff --git a/packages/graphics/sdl3/renderer.c b/packages/graphics/sdl3/renderer.c new file mode 100644 index 0000000..a4d6e2c --- /dev/null +++ b/packages/graphics/sdl3/renderer.c @@ -0,0 +1,39 @@ +#include "arc/graphics/renderer.h" +#include "renderer.h" + +#include +#include +#include "arc/engine/engine.h" +#include "arc/graphics/window.h" +#include "arc/std/errno.h" + +void ARC_Renderer_CreateWithEngineData(ARC_Renderer **renderer, ARC_EngineData *data){ + if(!data){ + arc_errno = ARC_ERRNO_NULL; + ARC_DEBUG_LOG_ERROR("ARC_Renderer_CreateWithEngineData(**renderer, NULL)"); + return; + } + + *renderer = (ARC_Renderer *)SDL_CreateRenderer((SDL_Window *)(data->window), NULL); + + if(!*renderer){ + arc_errno = ARC_ERRNO_NULL; + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("SDL_CreateRenderer(%p, NULL);", data->window); + free(renderer); + } + + SDL_SetRenderDrawBlendMode((SDL_Renderer *)*renderer, SDL_BLENDMODE_BLEND); +} + +void ARC_Renderer_Destroy(ARC_Renderer *renderer){ + SDL_DestroyRenderer((SDL_Renderer *) renderer); +} + +void ARC_Renderer_Clear(ARC_Renderer *renderer){ + SDL_SetRenderDrawColor((SDL_Renderer *)renderer, 0x1c, 0x2c, 0x3c, 0xff); + SDL_RenderClear((SDL_Renderer *)renderer); +} + +void ARC_Renderer_Render(ARC_Renderer *renderer){ + SDL_RenderPresent((SDL_Renderer *)renderer); +} diff --git a/packages/graphics/sdl3/renderer.h b/packages/graphics/sdl3/renderer.h new file mode 100644 index 0000000..2609e6b --- /dev/null +++ b/packages/graphics/sdl3/renderer.h @@ -0,0 +1,10 @@ +#ifndef ARC_SDL_RENDERER_H_ +#define ARC_SDL_RENDERER_H_ + +#include "arc/graphics/renderer.h" +#include "arc/graphics/window.h" +#include + +typedef SDL_Renderer ARC_RendererType; + +#endif // !ARC_SDL_RENDERER_H_ diff --git a/packages/graphics/sdl3/sprite.c b/packages/graphics/sdl3/sprite.c new file mode 100644 index 0000000..b97fe88 --- /dev/null +++ b/packages/graphics/sdl3/sprite.c @@ -0,0 +1,96 @@ +#include "arc/graphics/sprite.h" + +#include "sprite.h" +#include "spritesheet.h" +#include "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){ + *sprite = (ARC_Sprite *)malloc(sizeof(ARC_Sprite)); + (*sprite)->spritesheet = spritesheet; + (*sprite)->frames = frames; + (*sprite)->frameIndex = (uint32_t *)malloc(sizeof(uint32_t)); + *(*sprite)->frameIndex = 0; + (*sprite)->opacity = 255; +} + +void ARC_Sprite_Destroy(ARC_Sprite *sprite){ + free(sprite); +} + +void ARC_Sprite_Copy(ARC_Sprite **newSprite, ARC_Sprite *oldSprite){ + *newSprite = (ARC_Sprite *)malloc(sizeof(ARC_Sprite)); + (*newSprite)->spritesheet = oldSprite->spritesheet; + (*newSprite)->frames = oldSprite->frames; + (*newSprite)->frameIndex = (uint32_t *)malloc(sizeof(uint32_t)); + *(*newSprite)->frameIndex = *oldSprite->frameIndex; +} + +void ARC_Sprite_SetOpacity(ARC_Sprite *sprite, uint8_t opacity){ + sprite->opacity = opacity; +} + +void ARC_Sprite_Render(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *renderBounds){ + //TODO: note, this is set here so not all entities in the sheet get opacity set + SDL_SetTextureAlphaMod((SDL_Texture *)sprite->spritesheet->texture, sprite->opacity); + ARC_FRect sourceRect = ARC_Rect_CastToFRect(*(ARC_Rect *)(sprite->frames->data + *sprite->frameIndex)); + ARC_FRect destinationRect = ARC_Rect_CastToFRect(*renderBounds); + SDL_RenderTexture((SDL_Renderer *)renderer, sprite->spritesheet->texture, (SDL_FRect *)&sourceRect, (SDL_FRect *)&destinationRect); +} + +void ARC_Sprite_RenderFlip(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *renderBounds, enum ARC_Sprite_Axis axis){ + SDL_FlipMode flip = SDL_FLIP_NONE; + if(axis & ARC_SPRITE_AXIS_X){ + flip |= SDL_FLIP_HORIZONTAL; + } + + if(axis & ARC_SPRITE_AXIS_Y){ + flip |= SDL_FLIP_VERTICAL; + } + + //TODO: note, this is set here so not all entities in the sheet get opacity set + SDL_SetTextureAlphaMod((SDL_Texture *)sprite->spritesheet->texture, sprite->opacity); + ARC_FRect sourceRect = ARC_Rect_CastToFRect(*(ARC_Rect *)(sprite->frames->data + *sprite->frameIndex)); + ARC_FRect destinationRect = ARC_Rect_CastToFRect(*renderBounds); + SDL_RenderTextureRotated((SDL_Renderer *)renderer, sprite->spritesheet->texture, (SDL_FRect *)&sourceRect, (SDL_FRect *)&destinationRect, 0.0, NULL, flip); +} + +void ARC_Sprite_RenderRotated(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *renderBounds, ARC_Point *center, double angle){ + //TODO: note, this is set here so not all entities in the sheet get opacity set + SDL_SetTextureAlphaMod((SDL_Texture *)sprite->spritesheet->texture, sprite->opacity); + ARC_FRect sourceRect = ARC_Rect_CastToFRect(*(ARC_Rect *)(sprite->frames->data + *sprite->frameIndex)); + ARC_FRect destinationRect = ARC_Rect_CastToFRect(*renderBounds); + SDL_RenderTextureRotated((SDL_Renderer *)renderer, sprite->spritesheet->texture, (SDL_FRect *)&sourceRect, (SDL_FRect *)&destinationRect, angle, NULL, 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_ERROR_WITH_VARIABLES("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){ + *sprite->frameIndex = 0; + } +} + +uint32_t ARC_Sprite_GetFrameIndex(ARC_Sprite *sprite){ + return *sprite->frameIndex; +} + +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; +} diff --git a/packages/graphics/sdl3/sprite.h b/packages/graphics/sdl3/sprite.h new file mode 100644 index 0000000..ced571a --- /dev/null +++ b/packages/graphics/sdl3/sprite.h @@ -0,0 +1,14 @@ +#ifndef ARC_SDL_SPRITE_H_ +#define ARC_SDL_SPRITE_H_ + +#include "arc/graphics/sprite.h" + +struct ARC_Sprite { + ARC_Spritesheet *spritesheet; + ARC_Array *frames; + uint32_t *frameIndex; + //TODO: temp + uint8_t opacity; +}; + +#endif // !ARC_SDL_SPRITE_H_ diff --git a/packages/graphics/sdl3/spritesheet.c b/packages/graphics/sdl3/spritesheet.c new file mode 100644 index 0000000..041dd6c --- /dev/null +++ b/packages/graphics/sdl3/spritesheet.c @@ -0,0 +1,86 @@ +#include "arc/graphics/spritesheet.h" + +#include "spritesheet.h" +#include "renderer.h" +#include "arc/math/point.h" +#include "arc/std/errno.h" +#include +#include +#include + +void ARC_Spritesheet_CreateFromFile(ARC_Spritesheet **spritesheet, ARC_Renderer *renderer, ARC_String *path){ + //TODO: allow other types of images + + //get and check the SDL surface + SDL_Surface *surface = IMG_Load(path->data); + if(!surface){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_Spritesheet_CreateFromFile(spritesheet, renderer, path), could not read path \"%s\"", path->data); + + //set the spritesheet to null and throw an error + *spritesheet = NULL; + return; + } + + //create the place to store the spritesheet + *spritesheet = (ARC_Spritesheet *)malloc(sizeof(ARC_Spritesheet)); + + //set the texture + SDL_BlendMode tempMode; + SDL_GetSurfaceBlendMode(surface, &tempMode); + (*spritesheet)->texture = SDL_CreateTextureFromSurface((SDL_Renderer *)renderer, surface); + SDL_SetTextureBlendMode((*spritesheet)->texture, tempMode); + + //set the tile size to empty + (*spritesheet)->size = 0; + + //cleanup + SDL_DestroySurface(surface); +} + +void ARC_Spritesheet_Destroy(ARC_Spritesheet *spritesheet){ + SDL_DestroyTexture(spritesheet->texture); + free(spritesheet); +} + +void ARC_Spritesheet_Render(ARC_Spritesheet *spritesheet, ARC_Renderer *renderer, ARC_FRect renderBounds){ + SDL_RenderTexture((SDL_Renderer *)renderer, spritesheet->texture, NULL, (SDL_FRect *)&renderBounds); +} + +void ARC_Spritesheet_RenderArea(ARC_Spritesheet *spritesheet, ARC_Rect sheetBounds, ARC_Renderer *renderer, ARC_FRect renderBounds){ + ARC_FRect bounds = ARC_Rect_CastToFRect(sheetBounds); + SDL_RenderTexture((SDL_Renderer *)renderer, spritesheet->texture, (SDL_FRect *)&bounds, (SDL_FRect *)&renderBounds); +} + +void ARC_Spritesheet_RenderTile(ARC_Spritesheet *spritesheet, ARC_Point tilePosition, ARC_Renderer *renderer, ARC_FRect renderBounds){ + //error when size is 0 + if(spritesheet->size == 0){ + arc_errno = ARC_ERRNO_NULL; + ARC_DEBUG_LOG_ERROR("ARC_Spritesheet_RenderTile(spritesheet, tilePosition, renderer, renderBounds), could not render a tile of size 0"); + return; + } + + //get bounds based on the sheet size + ARC_FRect sheetBounds = { + spritesheet->size * tilePosition.x, + spritesheet->size * tilePosition.y, + spritesheet->size, + spritesheet->size + }; + + //render the bounds + SDL_RenderTexture((SDL_Renderer *)renderer, spritesheet->texture, (SDL_FRect *)&sheetBounds, (SDL_FRect *)&renderBounds); +} + +ARC_Point ARC_Spritesheet_GetSize(ARC_Spritesheet *spritesheet){ + float x = 0.0; + float y = 0.0; + + SDL_GetTextureSize(spritesheet->texture, &x, &y); + + return (ARC_Point){ x, y }; +} + +uint32_t ARC_Spritesheet_GetTileSize(ARC_Spritesheet *spritesheet){ + return spritesheet->size; +} diff --git a/packages/graphics/sdl3/spritesheet.h b/packages/graphics/sdl3/spritesheet.h new file mode 100644 index 0000000..c7927d7 --- /dev/null +++ b/packages/graphics/sdl3/spritesheet.h @@ -0,0 +1,12 @@ +#ifndef ARC_SDL_SPRITESHEET_H_ +#define ARC_SDL_SPRITESHEET_H_ + +#include "arc/graphics/spritesheet.h" +#include + +struct ARC_Spritesheet { + SDL_Texture *texture; + uint32_t size; +}; + +#endif // !ARC_SDL_SPRITESHEET_H_ diff --git a/packages/graphics/sdl3/text.c b/packages/graphics/sdl3/text.c new file mode 100644 index 0000000..d87ed08 --- /dev/null +++ b/packages/graphics/sdl3/text.c @@ -0,0 +1,66 @@ +#include "arc/graphics/text.h" + +#include "text.h" +#include "arc/graphics/color.h" +#include "arc/math/point.h" +#include "arc/math/rectangle.h" +#include "arc/std/string.h" +#include +#include + +#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 }; + + //TODO: fix this + if(TTF_Init() == false) { + printf("TTF_Init: %s\n", SDL_GetError()); + exit(2); + } +} + +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(ttfont, string->data, 0, textColor); + + 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_DestroySurface(surface); + TTF_CloseFont(ttfont); +} + +void ARC_Text_Render(ARC_Text *text, ARC_Renderer *renderer){ + if(text->texture == NULL){ + return; + } + + SDL_FRect bounds = (SDL_FRect){ text->bounds.x, text->bounds.y, text->bounds.w, text->bounds.h }; + SDL_RenderTexture((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; +} diff --git a/packages/graphics/sdl3/text.h b/packages/graphics/sdl3/text.h new file mode 100644 index 0000000..4c561ba --- /dev/null +++ b/packages/graphics/sdl3/text.h @@ -0,0 +1,20 @@ +#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" + +#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_TEXT_H_ diff --git a/packages/graphics/sdl3/view.c b/packages/graphics/sdl3/view.c new file mode 100644 index 0000000..b581e10 --- /dev/null +++ b/packages/graphics/sdl3/view.c @@ -0,0 +1,35 @@ +#include "arc/graphics/view.h" + +#include "arc/std/errno.h" +#include +#include + +void ARC_View_Create(ARC_View **view, ARC_Renderer *renderer, ARC_Rect bounds){ + *view = (ARC_View *)malloc(sizeof(ARC_View)); + (*view)->renderer = renderer; + (*view)->bounds = bounds; +} + +void ARC_View_Destroy(ARC_View *view){ + free(view); +} + +void ARC_View_Render(ARC_View *view, ARC_View_RenderFn renderFn, void *data){ + int err = SDL_RenderSetViewport((SDL_Renderer *)view->renderer, (const SDL_Rect *)&(view->bounds)); + if(err){ + ARC_DEBUG_LOG(ARC_ERRNO_DATA, "in src/graphics/sdl/view.c ARC_View_Render(view, renderFn), SDL_RenderSetViewport(...) returned: %d", err); + return; + } + + renderFn(data); + + err = SDL_RenderSetViewport((SDL_Renderer *)view->renderer, NULL); + if(err){ + ARC_DEBUG_LOG(ARC_ERRNO_DATA, "in src/graphics/sdl/view.c ARC_View_Render(view, NULL), SDL_RenderSetViewport(...) returned: %d", err); + return; + } +} + +ARC_Rect ARC_View_GetBounds(ARC_View *view){ + return view->bounds; +} \ No newline at end of file diff --git a/packages/graphics/sdl3/window.c b/packages/graphics/sdl3/window.c new file mode 100644 index 0000000..b5ac150 --- /dev/null +++ b/packages/graphics/sdl3/window.c @@ -0,0 +1,26 @@ +#include "arc/graphics/window.h" + +#include "window.h" +#include "arc/std/errno.h" +#include + +void ARC_Window_Create(ARC_Window **window, ARC_WindowInfo *info){ + if(!info){ + arc_errno = ARC_ERRNO_NULL; + ARC_DEBUG_LOG_ERROR("ARC_Window_Create(**window, NULL)"); + return; + } + + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO); + + *window = (ARC_Window *)SDL_CreateWindow((const char *)info->title, info->w, info->h, 0); + + if(window == NULL){ + arc_errno = ARC_ERRNO_NULL; + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("SDL_CreateWindow(%s, %d, %d, %x);", info->title, info->w, info->h, 0); + } +} + +void ARC_Window_Destroy(ARC_Window *window){ + SDL_DestroyWindow((SDL_Window *) window); +} diff --git a/packages/graphics/sdl3/window.h b/packages/graphics/sdl3/window.h new file mode 100644 index 0000000..7933318 --- /dev/null +++ b/packages/graphics/sdl3/window.h @@ -0,0 +1,9 @@ +#ifndef ARC_SDL_WINDOW_H_ +#define ARC_SDL_WINDOW_H_ + +#include "arc/graphics/window.h" +#include + +typedef SDL_Window ARC_WindowType; + +#endif // !ARC_SDL_WINDOW_H_ diff --git a/packages/input/sdl3/input.c b/packages/input/sdl3/input.c new file mode 100644 index 0000000..014e51d --- /dev/null +++ b/packages/input/sdl3/input.c @@ -0,0 +1,45 @@ +#include "arc/input/input.h" +#include "input.h" + +#include "arc/input/mouse.h" +#include "arc/input/keyboard.h" + +#include +#include + +void ARC_Input_CreateWithEngineData(ARC_Input **input, ARC_EngineData *data){ + *input = (ARC_Input *)malloc(sizeof(ARC_Input)); + + (*input)->event = (SDL_Event *)malloc(sizeof(SDL_Event)); + + ARC_Keyboard_CreateWithInput(&((*input)->keyboard), *input); + ARC_Mouse_CreateWithInput(&((*input)->mouse), *input); +} + +void ARC_Input_Destroy(ARC_Input *input){ + ARC_Keyboard_Destroy(input->keyboard); + ARC_Mouse_Destroy(input->mouse); + + free(input->event); + free(input); +} + +ARC_Bool ARC_Input_Update(ARC_Input *input){ + SDL_PollEvent(input->event); + if(input->event->type == SDL_EVENT_QUIT){ + return ARC_False; + } + + ARC_Keyboard_Update(input->keyboard); + ARC_Mouse_Update(input->mouse); + + return ARC_True; +} + +ARC_Keyboard *ARC_Input_GetKeyboard(ARC_Input *input){ + return input->keyboard; +} + +ARC_Mouse *ARC_Input_GetMouse(ARC_Input *input){ + return input->mouse; +} diff --git a/packages/input/sdl3/input.h b/packages/input/sdl3/input.h new file mode 100644 index 0000000..a18f3a0 --- /dev/null +++ b/packages/input/sdl3/input.h @@ -0,0 +1,15 @@ +#ifndef ARC_SDL_INPUT_H_ +#define ARC_SDL_INPUT_H_ + +#include "arc/input/keyboard.h" +#include "arc/input/mouse.h" +#include + +struct ARC_Input { + ARC_Keyboard *keyboard; + ARC_Mouse *mouse; + + SDL_Event *event; +}; + +#endif // !ARC_SDL_INPUT_H_ diff --git a/packages/input/sdl3/keyboard.c b/packages/input/sdl3/keyboard.c new file mode 100644 index 0000000..0c47e7d --- /dev/null +++ b/packages/input/sdl3/keyboard.c @@ -0,0 +1,98 @@ +#include "arc/input/keyboard.h" +#include "keyboard.h" +#include "input.h" +#include "arc/math/point.h" +#include "arc/std/errno.h" +#include +#include +#include +#include + +void ARC_Keyboard_CreateWithInput(ARC_Keyboard **keyboard, ARC_Input *input){ + *keyboard = (ARC_Keyboard *)malloc(sizeof(ARC_Keyboard)); + (*keyboard)->event = input->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_EVENT_KEY_DOWN && keyboard->event->type != SDL_EVENT_KEY_UP){ + return; + } + + if(keyboard->event->key.key >= 239 || keyboard->event->key.key < 0){ + return; + } + + if(keyboard->event->type == SDL_EVENT_KEY_DOWN){ + keyboard->keys[keyboard->event->key.key] = ARC_KEY_PRESSED; + return; + } + + keyboard->keys[keyboard->event->key.key] = ARC_KEY_RELEASED; + keyboard->released = (keyboard->keys + keyboard->event->key.key); +} + +ARC_KeyboardState ARC_Keyboard_GetState(ARC_Keyboard *keyboard, enum ARC_KeyboardKey key){ + switch(key){ + case ARC_KEY_A: return keyboard->keys[SDLK_A]; + case ARC_KEY_B: return keyboard->keys[SDLK_B]; + case ARC_KEY_C: return keyboard->keys[SDLK_C]; + case ARC_KEY_D: return keyboard->keys[SDLK_D]; + case ARC_KEY_E: return keyboard->keys[SDLK_E]; + case ARC_KEY_F: return keyboard->keys[SDLK_F]; + case ARC_KEY_G: return keyboard->keys[SDLK_G]; + case ARC_KEY_H: return keyboard->keys[SDLK_H]; + case ARC_KEY_I: return keyboard->keys[SDLK_I]; + case ARC_KEY_J: return keyboard->keys[SDLK_J]; + case ARC_KEY_K: return keyboard->keys[SDLK_K]; + case ARC_KEY_L: return keyboard->keys[SDLK_L]; + case ARC_KEY_M: return keyboard->keys[SDLK_M]; + case ARC_KEY_N: return keyboard->keys[SDLK_N]; + case ARC_KEY_O: return keyboard->keys[SDLK_O]; + case ARC_KEY_P: return keyboard->keys[SDLK_P]; + case ARC_KEY_Q: return keyboard->keys[SDLK_Q]; + case ARC_KEY_R: return keyboard->keys[SDLK_R]; + case ARC_KEY_S: return keyboard->keys[SDLK_S]; + case ARC_KEY_T: return keyboard->keys[SDLK_T]; + case ARC_KEY_U: return keyboard->keys[SDLK_U]; + case ARC_KEY_V: return keyboard->keys[SDLK_V]; + case ARC_KEY_W: return keyboard->keys[SDLK_W]; + case ARC_KEY_X: return keyboard->keys[SDLK_X]; + case ARC_KEY_Y: return keyboard->keys[SDLK_Y]; + case ARC_KEY_Z: return keyboard->keys[SDLK_Z]; + + 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]; + case ARC_KEY_ENTER: return keyboard->keys[SDLK_RETURN]; + + default: return ARC_KEY_NONE; + } +} diff --git a/packages/input/sdl3/keyboard.h b/packages/input/sdl3/keyboard.h new file mode 100644 index 0000000..c46c1a5 --- /dev/null +++ b/packages/input/sdl3/keyboard.h @@ -0,0 +1,14 @@ +#ifndef ARC_SDL_KEYBOARD_H_ +#define ARC_SDL_KEYBOARD_H_ + +#include "arc/input/keyboard.h" +#include + +struct ARC_Keyboard { + SDL_Event *event; + + ARC_KeyboardState *keys; + ARC_KeyboardState *released; +}; + +#endif // !ARC_SDL_KEYBOARD_H_ diff --git a/packages/input/sdl3/mouse.c b/packages/input/sdl3/mouse.c new file mode 100644 index 0000000..3d5f084 --- /dev/null +++ b/packages/input/sdl3/mouse.c @@ -0,0 +1,105 @@ +#include "arc/input/mouse.h" + +#include "mouse.h" +#include "input.h" +#include "arc/math/point.h" +#include "arc/std/errno.h" +#include +#include +#include +#include + +void ARC_Mouse_CreateWithInput(ARC_Mouse **mouse, ARC_Input *input){ + *mouse = (ARC_Mouse *)malloc(sizeof(ARC_Mouse)); + (*mouse)->event = input->event; + (*mouse)->coords = (ARC_FPoint *)malloc(sizeof(ARC_Point)); + (*mouse)->scrollY = (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_FPoint){0, 0}; + *(*mouse)->scrollY = 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->scrollY); + 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->scrollY = 0; + if(mouse->event->type == SDL_EVENT_MOUSE_WHEEL){ + *mouse->scrollY = mouse->event->wheel.y; + } + + uint32_t buttons = SDL_GetMouseState(&(mouse->coords->x), &(mouse->coords->y)); + + if(mouse->event->type != SDL_EVENT_MOUSE_BUTTON_DOWN && mouse->event->type != SDL_EVENT_MOUSE_BUTTON_UP){ + 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_FPoint *ARC_Mouse_GetCoords(ARC_Mouse *mouse){ + return mouse->coords; +} + +ARC_MouseState ARC_Mouse_GetState(ARC_Mouse *mouse, ARC_MouseButton button){ + return mouse->buttons[button]; +} + +int32_t *ARC_Mouse_GetScrollY(ARC_Mouse *mouse){ + return mouse->scrollY; +} diff --git a/packages/input/sdl3/mouse.h b/packages/input/sdl3/mouse.h new file mode 100644 index 0000000..19b29b7 --- /dev/null +++ b/packages/input/sdl3/mouse.h @@ -0,0 +1,17 @@ +#ifndef ARC_SDL_MOUSE_H_ +#define ARC_SDL_MOUSE_H_ + +#include +#include "arc/input/mouse.h" +#include "arc/math/point.h" + +struct ARC_Mouse { + SDL_Event *event; + ARC_FPoint *coords; + int32_t *scrollY; + + ARC_MouseState *buttons; + uint8_t *buttonsReleased; +}; + +#endif // !ARC_SDL_MOUSE_H_