From f9234dc9a2fe22fb561247c4ded3be23d251940e Mon Sep 17 00:00:00 2001 From: Sara Date: Thu, 18 Sep 2025 12:11:13 +0200 Subject: [PATCH] feat: implemented die images --- src/defs.h | 7 ---- src/dice.c | 43 ++++++++++++++------- src/dice.h | 21 ++++++----- src/dice_container.c | 21 ++++++----- src/main.c | 21 +---------- src/resources.c | 89 ++++++++++++++++++++++++++++++++++++++++++++ src/resources.h | 34 +++++++++++++++++ src/style.c | 20 +++++----- src/style.h | 17 +++++++-- 9 files changed, 200 insertions(+), 73 deletions(-) create mode 100644 src/resources.c create mode 100644 src/resources.h diff --git a/src/defs.h b/src/defs.h index 30e23ad..8349ec7 100644 --- a/src/defs.h +++ b/src/defs.h @@ -6,15 +6,8 @@ #include #include -enum Font { - FONT_DEFAULT = 0, - FONT_BOLD = 1, - FONT_MAX -}; extern SDL_Window *window; extern SDL_Renderer *renderer; -extern TTF_Font *fonts[FONT_MAX]; -extern TTF_TextEngine *textEngine; #endif // !DEFS_H diff --git a/src/dice.c b/src/dice.c index 5f86558..77c4607 100644 --- a/src/dice.c +++ b/src/dice.c @@ -1,58 +1,73 @@ #include "dice.h" #include -int roll_die(enum die_type die) { +int Die_Roll(enum Die_Dice die) { int const max = die; return (rand() % max) + 1; } static int current_active_count = 0; -static enum die_type active_dice_set[MAX_ACTIVE_DICE]; +static enum Die_Dice active_dice_set[MAX_ACTIVE_DICE]; -static struct roll_result_type roll_results[MAX_ACTIVE_DICE]; -static struct roll_result_type roll_total = { +static struct Die_ResultType roll_results[MAX_ACTIVE_DICE]; +static struct Die_ResultType roll_total = { .roll = 0, .string_len = 0 }; -enum die_type const *get_active_dice_set(size_t *out_length) { +static +struct Die_ResultType Die_RollToResultType(int roll, enum Die_Dice die) { + struct Die_ResultType result = { }; + result.roll = roll; + if (die == COIN) { + result.string_len = SDL_snprintf(result.string, MAX_ROLL_STR_LEN, roll == 1 ? "H" : "T"); + } else { + result.string_len = SDL_snprintf(result.string, MAX_ROLL_STR_LEN, "%d", roll); + } + result.clay_string = (Clay_String) { + .chars = result.string, + .length = result.string_len, + .isStaticallyAllocated = false + }; + return result; +} + +enum Die_Dice const *Die_GetActiveSet(size_t *out_length) { if (out_length != nullptr) { *out_length = current_active_count; } return active_dice_set; } -size_t add_die_to_active(enum die_type die) { +size_t Die_AddToActiveSet(enum Die_Dice die) { if (current_active_count >= MAX_ACTIVE_DICE) { return MAX_ACTIVE_DICE; } active_dice_set[current_active_count] = die; - roll_results[current_active_count].roll = die; - roll_results[current_active_count].string_len = SDL_snprintf(roll_results[current_active_count].string, MAX_ROLL_STR_LEN, "%d", die); + roll_results[current_active_count] = Die_RollToResultType(die, die); return current_active_count++; } -void remove_die_from_active(size_t index) { +void Die_RemoveFromActiveSet(size_t index) { memcpy(active_dice_set + index, active_dice_set + index + 1, MAX_ACTIVE_DICE - index - 1); --current_active_count; } -void roll_active_dice_set() { +void Die_RollActiveSet() { for (size_t i = 0; i < current_active_count; ++i) { - roll_results[i].roll = roll_die(active_dice_set[i]); - roll_results[i].string_len = SDL_snprintf(roll_results[i].string, MAX_ROLL_STR_LEN, "%d", roll_results[i].roll); + roll_results[i] = Die_RollToResultType(Die_Roll(active_dice_set[i]), active_dice_set[i]); roll_total.roll += roll_results[i].roll; } roll_total.string_len = SDL_snprintf(roll_total.string, MAX_ROLL_STR_LEN, "%d", roll_total.roll); } -struct roll_result_type *get_current_results(size_t *out_length) { +struct Die_ResultType *Die_GetLastResult(size_t *out_length) { if (out_length != nullptr) { *out_length = current_active_count; } return roll_results; } -Clay_String die_to_str(enum die_type die) { +Clay_String Die_ToString(enum Die_Dice die) { switch (die) { case COIN: return CLAY_STRING("C"); case D4: return CLAY_STRING("4"); diff --git a/src/dice.h b/src/dice.h index 4826d11..fc2874f 100644 --- a/src/dice.h +++ b/src/dice.h @@ -9,10 +9,10 @@ #endif #ifndef MAX_ROLL_STR_LEN - #define MAX_ROLL_STR_LEN 5 + #define MAX_ROLL_STR_LEN 10 #endif -enum die_type { +enum Die_Dice { COIN = 2, D4 = 4, D6 = 6, @@ -23,22 +23,23 @@ enum die_type { D100 = 100 }; -struct roll_result_type { +struct Die_ResultType { int roll; size_t string_len; char string[MAX_ROLL_STR_LEN]; + Clay_String clay_string; }; -extern int roll_die(enum die_type die); +extern int Die_Roll(enum Die_Dice die); -extern enum die_type const *get_active_dice_set(size_t *out_length); -extern size_t add_die_to_active(enum die_type die); -extern void remove_die_from_active(size_t index); +extern enum Die_Dice const *Die_GetActiveSet(size_t *out_length); +extern size_t Die_AddToActiveSet(enum Die_Dice die); +extern void Die_RemoveFromActiveSet(size_t index); -extern struct roll_result_type *get_current_results(size_t *out_length); +extern struct Die_ResultType *Die_GetLastResult(size_t *out_length); -extern void roll_active_dice_set(); +extern void Die_RollActiveSet(); -extern Clay_String die_to_str(enum die_type die); +extern Clay_String Die_ToString(enum Die_Dice die); #endif // !DICE_H diff --git a/src/dice_container.c b/src/dice_container.c index d691b3d..64917ba 100644 --- a/src/dice_container.c +++ b/src/dice_container.c @@ -1,5 +1,6 @@ #include "dice_container.h" #include +#include #include #include #include "elements.h" @@ -9,7 +10,7 @@ static void HandleRollSetButtonInteraction(Clay_ElementId element, Clay_PointerData pointer, intptr_t data) { if (pointer.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME) { - roll_active_dice_set(); + Die_RollActiveSet(); } } @@ -27,21 +28,21 @@ void RollSetButton() { static void HandleAddDieButtonInteraction(Clay_ElementId element, Clay_PointerData pointer, intptr_t die) { if (pointer.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME) { - add_die_to_active((enum die_type)die); + Die_AddToActiveSet((enum Die_Dice)die); } } static inline -void AddDieButton(enum die_type die) { +void AddDieButton(enum Die_Dice die) { CLAY(CLAY_IDI("AddDieButton", die), { .layout = { .sizing = { CLAY_SIZING_FIXED(100), CLAY_SIZING_FIXED(100) }, .childAlignment = { CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER }, }, - .backgroundColor = DieButtonColor(die, Clay_Hovered()), + .image = { GetDiceImage(die) } }) { Clay_OnHover(&HandleAddDieButtonInteraction, die); - CLAY_TEXT(die_to_str(die), CLAY_TEXT_CONFIG({ + CLAY_TEXT(Die_ToString(die), CLAY_TEXT_CONFIG({ .textColor = TextColors(0), .H(2), })); @@ -84,21 +85,21 @@ void DiceSelectorContainer() { static void HandleRemoveDieButtonInteraction(Clay_ElementId element, Clay_PointerData pointer, intptr_t index) { if (pointer.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME) { - remove_die_from_active(index); + Die_RemoveFromActiveSet(index); } } static inline -void RemoveDieButton(enum die_type die, int index) { +void RemoveDieButton(enum Die_Dice die, int index) { CLAY(CLAY_IDI("RemoveDieButton", index), { .layout = { .sizing = { CLAY_SIZING_FIXED(200), CLAY_SIZING_FIXED(200) }, .childAlignment = { CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER }, }, - .backgroundColor = DieButtonColor(die, Clay_Hovered()), + .image = { GetDiceImage(die) }, }) { size_t result_length; - struct roll_result_type const *result = get_current_results(&result_length); + struct Die_ResultType const *result = Die_GetLastResult(&result_length); Clay_String string = { .chars = result[index].string, .length = result[index].string_len, @@ -136,7 +137,7 @@ void ActiveDiceContainer() { }, }) { size_t dice_count = 0; - enum die_type const *dice = get_active_dice_set(&dice_count); + enum Die_Dice const *dice = Die_GetActiveSet(&dice_count); for (size_t i = 0; i < dice_count; ++i) { RemoveDieButton(dice[i], i); } diff --git a/src/main.c b/src/main.c index 8036212..9cbbbde 100644 --- a/src/main.c +++ b/src/main.c @@ -7,6 +7,7 @@ #include "application.h" #include "defs.h" #include "style.h" +#include "resources.h" #define SDL_MAIN_HANDLED #include @@ -33,8 +34,6 @@ bool running = true; uint64_t clayMemorySize = 0; Clay_Arena clayPrimaryArena; -TTF_Font *fonts[FONT_MAX]; -TTF_TextEngine *textEngine = nullptr; Clay_SDL3RendererData backendData = { .renderer = nullptr, @@ -66,22 +65,6 @@ void HandleClayErrors(Clay_ErrorData data) { SDL_LogError(SDL_LOG_CATEGORY_ERROR, "%s", data.errorText.chars); } -static inline void InitFonts() { - fonts[FONT_DEFAULT] = TTF_OpenFont("assets/AdwaitaSans-Regular.ttf", baseFontSize * 5); - if (fonts[FONT_DEFAULT] == nullptr) { - SDL_LogError(SDL_LOG_CATEGORY_ERROR, "TTF_OpenFont failed: Failed to load adwaita sans: %s", SDL_GetError()); - exit(6); - } - TTF_SetFontHinting(fonts[FONT_DEFAULT], TTF_HINTING_LIGHT_SUBPIXEL); - fonts[FONT_BOLD] = TTF_OpenFont("assets/AdwaitaSans-Regular.ttf", baseFontSize * 5); - if (fonts[FONT_BOLD] == nullptr) { - SDL_LogError(SDL_LOG_CATEGORY_ERROR, "TTF_OpenFont failed: Failed to load adwaita sans bold: %s", SDL_GetError()); - exit(7); - } - TTF_SetFontHinting(fonts[FONT_BOLD], TTF_HINTING_LIGHT_SUBPIXEL); - TTF_SetFontStyle(fonts[FONT_BOLD], TTF_STYLE_BOLD); -} - static inline void InitSDL() { SDL_SetHint(SDL_HINT_RENDER_LINE_METHOD, "3"); @@ -124,7 +107,7 @@ extern void HandleEvent(SDL_Event event); int main(int argc, char *argv[]) { InitSDL(); - InitFonts(); + LoadResources(); LogOutputResolution(); InitClay(); backendData = (Clay_SDL3RendererData) { diff --git a/src/resources.c b/src/resources.c new file mode 100644 index 0000000..335e8e5 --- /dev/null +++ b/src/resources.c @@ -0,0 +1,89 @@ +#include "resources.h" +#include "defs.h" +#include "style.h" +#include +#include +#include + +TTF_Font *fonts[FONT_MAX]; +SDL_Texture *diceImages[DICE_IMAGE_MAX]; +TTF_TextEngine *textEngine = nullptr; + +static inline +void LoadFonts() { + fonts[FONT_DEFAULT] = TTF_OpenFont("assets/AdwaitaSans-Regular.ttf", baseFontSize * 5); + if (fonts[FONT_DEFAULT] == nullptr) { + SDL_LogError(SDL_LOG_CATEGORY_ERROR, "TTF_OpenFont failed: Failed to load adwaita sans: %s", SDL_GetError()); + exit(6); + } + TTF_SetFontHinting(fonts[FONT_DEFAULT], TTF_HINTING_LIGHT_SUBPIXEL); + fonts[FONT_BOLD] = TTF_OpenFont("assets/AdwaitaSans-Regular.ttf", baseFontSize * 5); + if (fonts[FONT_BOLD] == nullptr) { + SDL_LogError(SDL_LOG_CATEGORY_ERROR, "TTF_OpenFont failed: Failed to load adwaita sans bold: %s", SDL_GetError()); + exit(6); + } + TTF_SetFontHinting(fonts[FONT_BOLD], TTF_HINTING_LIGHT_SUBPIXEL); + TTF_SetFontStyle(fonts[FONT_BOLD], TTF_STYLE_BOLD); +} + +static inline +void LoadDiceImages() { + if(!(diceImages[COIN_IMAGE] = IMG_LoadTexture(renderer, "assets/icons/d2.svg"))) { + SDL_LogError(SDL_LOG_CATEGORY_ERROR, "IMG_LoadTexture Failed to load die texture: %s", SDL_GetError()); + exit(7); + } + if(!(diceImages[D4_IMAGE] = IMG_LoadTexture(renderer, "assets/icons/d4.svg"))) { + SDL_LogError(SDL_LOG_CATEGORY_ERROR, "IMG_LoadTexture Failed to load die texture: %s", SDL_GetError()); + exit(7); + } + if(!(diceImages[D6_IMAGE] = IMG_LoadTexture(renderer, "assets/icons/d6.svg"))) { + SDL_LogError(SDL_LOG_CATEGORY_ERROR, "IMG_LoadTexture Failed to load die texture: %s", SDL_GetError()); + exit(7); + } + if(!(diceImages[D8_IMAGE] = IMG_LoadTexture(renderer, "assets/icons/d8.svg"))) { + SDL_LogError(SDL_LOG_CATEGORY_ERROR, "IMG_LoadTexture Failed to load die texture: %s", SDL_GetError()); + exit(7); + } + if(!(diceImages[D10_IMAGE] = IMG_LoadTexture(renderer, "assets/icons/d10.svg"))) { + SDL_LogError(SDL_LOG_CATEGORY_ERROR, "IMG_LoadTexture Failed to load die texture: %s", SDL_GetError()); + exit(7); + } + if(!(diceImages[D12_IMAGE] = IMG_LoadTexture(renderer, "assets/icons/d12.svg"))) { + SDL_LogError(SDL_LOG_CATEGORY_ERROR, "IMG_LoadTexture Failed to load die texture: %s", SDL_GetError()); + exit(7); + } + if(!(diceImages[D20_IMAGE] = IMG_LoadTexture(renderer, "assets/icons/d20.svg"))) { + SDL_LogError(SDL_LOG_CATEGORY_ERROR, "IMG_LoadTexture Failed to load die texture: %s", SDL_GetError()); + exit(7); + } + for (size_t i = 0; i < DICE_IMAGE_MAX; ++i) { + Clay_Color color = dieColors[i]; + SDL_SetTextureColorMod(diceImages[i], color.r, color.g, color.b); + } +} + +void LoadResources() { + LoadFonts(); + LoadDiceImages(); +} + +SDL_Texture *GetDiceImage(enum Die_Dice die) { + switch (die) { + case COIN: + return diceImages[COIN_IMAGE]; + case D4: + return diceImages[D4_IMAGE]; + case D6: + return diceImages[D6_IMAGE]; + case D8: + return diceImages[D8_IMAGE]; + case D10: + return diceImages[D10_IMAGE]; + case D12: + return diceImages[D12_IMAGE]; + case D20: + return diceImages[D20_IMAGE]; + case D100: + return diceImages[D10_IMAGE]; + } +} diff --git a/src/resources.h b/src/resources.h new file mode 100644 index 0000000..061e0c0 --- /dev/null +++ b/src/resources.h @@ -0,0 +1,34 @@ +#ifndef RESOURCES_H +#define RESOURCES_H + +#include "dice.h" +#include +#include + +enum Font { + FONT_DEFAULT = 0, + FONT_BOLD = 1, + FONT_MAX +}; + +enum DiceImages { + COIN_IMAGE = 0, + D4_IMAGE = 1, + D6_IMAGE, + D8_IMAGE, + D10_IMAGE, + D12_IMAGE, + D20_IMAGE, + + DICE_IMAGE_MAX +}; + +extern TTF_TextEngine *textEngine; +extern TTF_Font *fonts[FONT_MAX]; +extern SDL_Texture *diceImages[DICE_IMAGE_MAX]; + +extern void LoadResources(); + +extern SDL_Texture *GetDiceImage(enum Die_Dice die); + +#endif // !RESOURCES_H diff --git a/src/style.c b/src/style.c index 8a2e6f8..f300e9b 100644 --- a/src/style.c +++ b/src/style.c @@ -45,21 +45,21 @@ Clay_ElementDeclaration WindowStyle() { }; } -Clay_Color DieColor(enum die_type die) { +Clay_Color DieColor(enum Die_Dice die) { switch(die) { - case COIN: return (Clay_Color) { 230, 184, 48, 255 }; - case D4: return (Clay_Color) { 177, 56, 52, 255 }; - case D6: return (Clay_Color) { 115, 177, 52, 255 }; - case D8: return (Clay_Color) { 52, 177, 125, 255 }; - case D10: return (Clay_Color) { 52, 177, 176, 255 }; - case D12: return (Clay_Color) { 52, 93, 177, 255 }; - case D20: return (Clay_Color) { 177, 52, 140, 255 }; - case D100: return (Clay_Color) { 95, 52, 177, 255 }; + case COIN: return dieColors[0]; + case D4: return dieColors[1]; + case D6: return dieColors[2]; + case D8: return dieColors[3]; + case D10: return dieColors[4]; + case D12: return dieColors[5]; + case D20: return dieColors[6]; + case D100: return dieColors[7]; default: return (Clay_Color) { 0, 0, 0, 255 }; } } -Clay_Color DieButtonColor(enum die_type die, bool selected) { +Clay_Color DieButtonColor(enum Die_Dice die, bool selected) { return selected ? ToHoveredColor(DieColor(die)) : DieColor(die); } diff --git a/src/style.h b/src/style.h index 743f65e..ee01d42 100644 --- a/src/style.h +++ b/src/style.h @@ -2,7 +2,7 @@ #define STYLE_H #include "defs.h" -#include "dice.h" +#include "resources.h" #include #include @@ -81,6 +81,17 @@ constexpr Clay_CornerRadius buttonRadii = { 3, 3, 3, 3 }; +constexpr Clay_Color dieColors[] = { + { 230, 184, 48, 255 }, + { 177, 56, 52, 255 }, + { 115, 177, 52, 255 }, + { 52, 177, 125, 255 }, + { 52, 177, 176, 255 }, + { 52, 93, 177, 255 }, + { 177, 52, 140, 255 }, + { 95, 52, 177, 255 }, +}; + //////////////////////////////////// // COMPILATIONS // | Functions and expressions that combine styling data from the settings above. @@ -101,8 +112,8 @@ extern Clay_Color PanelBackground(size_t idx); extern Clay_Color TextColors(size_t idx); extern Clay_Color WindowBackground(); extern Clay_ElementDeclaration WindowStyle(); -extern Clay_Color DieColor(enum die_type die); -extern Clay_Color DieButtonColor(enum die_type die, bool selected); +extern Clay_Color DieColor(enum Die_Dice die); +extern Clay_Color DieButtonColor(enum Die_Dice die, bool selected); extern Clay_Color ToHoveredColor(Clay_Color color); #endif // !STYLE_H