feat: implemented die images

This commit is contained in:
Sara 2025-09-18 12:11:13 +02:00
parent bdca66b4fd
commit f9234dc9a2
9 changed files with 200 additions and 73 deletions

View file

@ -6,15 +6,8 @@
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <SDL3_ttf/SDL_ttf.h> #include <SDL3_ttf/SDL_ttf.h>
enum Font {
FONT_DEFAULT = 0,
FONT_BOLD = 1,
FONT_MAX
};
extern SDL_Window *window; extern SDL_Window *window;
extern SDL_Renderer *renderer; extern SDL_Renderer *renderer;
extern TTF_Font *fonts[FONT_MAX];
extern TTF_TextEngine *textEngine;
#endif // !DEFS_H #endif // !DEFS_H

View file

@ -1,58 +1,73 @@
#include "dice.h" #include "dice.h"
#include <memory.h> #include <memory.h>
int roll_die(enum die_type die) { int Die_Roll(enum Die_Dice die) {
int const max = die; int const max = die;
return (rand() % max) + 1; return (rand() % max) + 1;
} }
static int current_active_count = 0; 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 Die_ResultType roll_results[MAX_ACTIVE_DICE];
static struct roll_result_type roll_total = { static struct Die_ResultType roll_total = {
.roll = 0, .string_len = 0 .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) { if (out_length != nullptr) {
*out_length = current_active_count; *out_length = current_active_count;
} }
return active_dice_set; 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) { if (current_active_count >= MAX_ACTIVE_DICE) {
return MAX_ACTIVE_DICE; return MAX_ACTIVE_DICE;
} }
active_dice_set[current_active_count] = die; active_dice_set[current_active_count] = die;
roll_results[current_active_count].roll = die; roll_results[current_active_count] = Die_RollToResultType(die, die);
roll_results[current_active_count].string_len = SDL_snprintf(roll_results[current_active_count].string, MAX_ROLL_STR_LEN, "%d", die);
return current_active_count++; 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); memcpy(active_dice_set + index, active_dice_set + index + 1, MAX_ACTIVE_DICE - index - 1);
--current_active_count; --current_active_count;
} }
void roll_active_dice_set() { void Die_RollActiveSet() {
for (size_t i = 0; i < current_active_count; ++i) { for (size_t i = 0; i < current_active_count; ++i) {
roll_results[i].roll = roll_die(active_dice_set[i]); roll_results[i] = Die_RollToResultType(Die_Roll(active_dice_set[i]), 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_total.roll += roll_results[i].roll; roll_total.roll += roll_results[i].roll;
} }
roll_total.string_len = SDL_snprintf(roll_total.string, MAX_ROLL_STR_LEN, "%d", roll_total.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) { if (out_length != nullptr) {
*out_length = current_active_count; *out_length = current_active_count;
} }
return roll_results; return roll_results;
} }
Clay_String die_to_str(enum die_type die) { Clay_String Die_ToString(enum Die_Dice die) {
switch (die) { switch (die) {
case COIN: return CLAY_STRING("C"); case COIN: return CLAY_STRING("C");
case D4: return CLAY_STRING("4"); case D4: return CLAY_STRING("4");

View file

@ -9,10 +9,10 @@
#endif #endif
#ifndef MAX_ROLL_STR_LEN #ifndef MAX_ROLL_STR_LEN
#define MAX_ROLL_STR_LEN 5 #define MAX_ROLL_STR_LEN 10
#endif #endif
enum die_type { enum Die_Dice {
COIN = 2, COIN = 2,
D4 = 4, D4 = 4,
D6 = 6, D6 = 6,
@ -23,22 +23,23 @@ enum die_type {
D100 = 100 D100 = 100
}; };
struct roll_result_type { struct Die_ResultType {
int roll; int roll;
size_t string_len; size_t string_len;
char string[MAX_ROLL_STR_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 enum Die_Dice const *Die_GetActiveSet(size_t *out_length);
extern size_t add_die_to_active(enum die_type die); extern size_t Die_AddToActiveSet(enum Die_Dice die);
extern void remove_die_from_active(size_t index); 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 #endif // !DICE_H

View file

@ -1,5 +1,6 @@
#include "dice_container.h" #include "dice_container.h"
#include <SDL3/SDL_mouse.h> #include <SDL3/SDL_mouse.h>
#include <SDL3_image/SDL_image.h>
#include <clay/clay.h> #include <clay/clay.h>
#include <stdint.h> #include <stdint.h>
#include "elements.h" #include "elements.h"
@ -9,7 +10,7 @@
static static
void HandleRollSetButtonInteraction(Clay_ElementId element, Clay_PointerData pointer, intptr_t data) { void HandleRollSetButtonInteraction(Clay_ElementId element, Clay_PointerData pointer, intptr_t data) {
if (pointer.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME) { if (pointer.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME) {
roll_active_dice_set(); Die_RollActiveSet();
} }
} }
@ -27,21 +28,21 @@ void RollSetButton() {
static static
void HandleAddDieButtonInteraction(Clay_ElementId element, Clay_PointerData pointer, intptr_t die) { void HandleAddDieButtonInteraction(Clay_ElementId element, Clay_PointerData pointer, intptr_t die) {
if (pointer.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME) { 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 static inline
void AddDieButton(enum die_type die) { void AddDieButton(enum Die_Dice die) {
CLAY(CLAY_IDI("AddDieButton", die), { CLAY(CLAY_IDI("AddDieButton", die), {
.layout = { .layout = {
.sizing = { CLAY_SIZING_FIXED(100), CLAY_SIZING_FIXED(100) }, .sizing = { CLAY_SIZING_FIXED(100), CLAY_SIZING_FIXED(100) },
.childAlignment = { CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER }, .childAlignment = { CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER },
}, },
.backgroundColor = DieButtonColor(die, Clay_Hovered()), .image = { GetDiceImage(die) }
}) { }) {
Clay_OnHover(&HandleAddDieButtonInteraction, 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), .textColor = TextColors(0),
.H(2), .H(2),
})); }));
@ -84,21 +85,21 @@ void DiceSelectorContainer() {
static static
void HandleRemoveDieButtonInteraction(Clay_ElementId element, Clay_PointerData pointer, intptr_t index) { void HandleRemoveDieButtonInteraction(Clay_ElementId element, Clay_PointerData pointer, intptr_t index) {
if (pointer.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME) { if (pointer.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME) {
remove_die_from_active(index); Die_RemoveFromActiveSet(index);
} }
} }
static inline static inline
void RemoveDieButton(enum die_type die, int index) { void RemoveDieButton(enum Die_Dice die, int index) {
CLAY(CLAY_IDI("RemoveDieButton", index), { CLAY(CLAY_IDI("RemoveDieButton", index), {
.layout = { .layout = {
.sizing = { CLAY_SIZING_FIXED(200), CLAY_SIZING_FIXED(200) }, .sizing = { CLAY_SIZING_FIXED(200), CLAY_SIZING_FIXED(200) },
.childAlignment = { CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER }, .childAlignment = { CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER },
}, },
.backgroundColor = DieButtonColor(die, Clay_Hovered()), .image = { GetDiceImage(die) },
}) { }) {
size_t result_length; 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 = { Clay_String string = {
.chars = result[index].string, .chars = result[index].string,
.length = result[index].string_len, .length = result[index].string_len,
@ -136,7 +137,7 @@ void ActiveDiceContainer() {
}, },
}) { }) {
size_t dice_count = 0; 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) { for (size_t i = 0; i < dice_count; ++i) {
RemoveDieButton(dice[i], i); RemoveDieButton(dice[i], i);
} }

View file

@ -7,6 +7,7 @@
#include "application.h" #include "application.h"
#include "defs.h" #include "defs.h"
#include "style.h" #include "style.h"
#include "resources.h"
#define SDL_MAIN_HANDLED #define SDL_MAIN_HANDLED
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
@ -33,8 +34,6 @@ bool running = true;
uint64_t clayMemorySize = 0; uint64_t clayMemorySize = 0;
Clay_Arena clayPrimaryArena; Clay_Arena clayPrimaryArena;
TTF_Font *fonts[FONT_MAX];
TTF_TextEngine *textEngine = nullptr;
Clay_SDL3RendererData backendData = { Clay_SDL3RendererData backendData = {
.renderer = nullptr, .renderer = nullptr,
@ -66,22 +65,6 @@ void HandleClayErrors(Clay_ErrorData data) {
SDL_LogError(SDL_LOG_CATEGORY_ERROR, "%s", data.errorText.chars); 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 static inline
void InitSDL() { void InitSDL() {
SDL_SetHint(SDL_HINT_RENDER_LINE_METHOD, "3"); SDL_SetHint(SDL_HINT_RENDER_LINE_METHOD, "3");
@ -124,7 +107,7 @@ extern void HandleEvent(SDL_Event event);
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
InitSDL(); InitSDL();
InitFonts(); LoadResources();
LogOutputResolution(); LogOutputResolution();
InitClay(); InitClay();
backendData = (Clay_SDL3RendererData) { backendData = (Clay_SDL3RendererData) {

89
src/resources.c Normal file
View file

@ -0,0 +1,89 @@
#include "resources.h"
#include "defs.h"
#include "style.h"
#include <SDL3/SDL_log.h>
#include <SDL3/SDL_render.h>
#include <SDL3_image/SDL_image.h>
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];
}
}

34
src/resources.h Normal file
View file

@ -0,0 +1,34 @@
#ifndef RESOURCES_H
#define RESOURCES_H
#include "dice.h"
#include <SDL3/SDL_render.h>
#include <SDL3_ttf/SDL_ttf.h>
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

View file

@ -45,21 +45,21 @@ Clay_ElementDeclaration WindowStyle() {
}; };
} }
Clay_Color DieColor(enum die_type die) { Clay_Color DieColor(enum Die_Dice die) {
switch(die) { switch(die) {
case COIN: return (Clay_Color) { 230, 184, 48, 255 }; case COIN: return dieColors[0];
case D4: return (Clay_Color) { 177, 56, 52, 255 }; case D4: return dieColors[1];
case D6: return (Clay_Color) { 115, 177, 52, 255 }; case D6: return dieColors[2];
case D8: return (Clay_Color) { 52, 177, 125, 255 }; case D8: return dieColors[3];
case D10: return (Clay_Color) { 52, 177, 176, 255 }; case D10: return dieColors[4];
case D12: return (Clay_Color) { 52, 93, 177, 255 }; case D12: return dieColors[5];
case D20: return (Clay_Color) { 177, 52, 140, 255 }; case D20: return dieColors[6];
case D100: return (Clay_Color) { 95, 52, 177, 255 }; case D100: return dieColors[7];
default: return (Clay_Color) { 0, 0, 0, 255 }; 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); return selected ? ToHoveredColor(DieColor(die)) : DieColor(die);
} }

View file

@ -2,7 +2,7 @@
#define STYLE_H #define STYLE_H
#include "defs.h" #include "defs.h"
#include "dice.h" #include "resources.h"
#include <clay/clay.h> #include <clay/clay.h>
#include <stdint.h> #include <stdint.h>
@ -81,6 +81,17 @@ constexpr Clay_CornerRadius buttonRadii = {
3, 3, 3, 3 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 // COMPILATIONS
// | Functions and expressions that combine styling data from the settings above. // | 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 TextColors(size_t idx);
extern Clay_Color WindowBackground(); extern Clay_Color WindowBackground();
extern Clay_ElementDeclaration WindowStyle(); extern Clay_ElementDeclaration WindowStyle();
extern Clay_Color DieColor(enum die_type die); extern Clay_Color DieColor(enum Die_Dice die);
extern Clay_Color DieButtonColor(enum die_type die, bool selected); extern Clay_Color DieButtonColor(enum Die_Dice die, bool selected);
extern Clay_Color ToHoveredColor(Clay_Color color); extern Clay_Color ToHoveredColor(Clay_Color color);
#endif // !STYLE_H #endif // !STYLE_H