diff options
-rw-r--r-- | src/all.c | 132 |
1 files changed, 126 insertions, 6 deletions
@@ -8,11 +8,27 @@ #define xmemcpy __builtin_memcpy #endif - typedef struct { unsigned char r, g, b, a; } Color; +typedef enum { + BUTTON_STATE_IDLE, + BUTTON_STATE_HOVERED, + BUTTON_STATE_PRESSED +} ButtonState; + +typedef struct { + int idle_colour; + int hover_colour; + int pressed_colour; +} ButtonStyle; + +typedef struct { + int x, y, w, h; + ButtonState state; +} Button; + typedef struct { int x, y, w, h; Color fill; @@ -20,14 +36,20 @@ typedef struct { } DrawElement; typedef struct { + DrawElement bg; +} SidePanel; + +typedef struct { int len; DrawElement els[512]; + SidePanel panel; } DrawList; #define MEM_SIZE (1<<16) #define GRIDWIDTH 16 #define GRIDHEIGHT 16 #define TICK_LENGTH 1000 +#define GRID_OFFSET_X 256 typedef struct { char *start; @@ -88,18 +110,35 @@ static const Color colors[N_COLORS] = { {255, 255, 0, 255} }; +static const ButtonStyle button_style = { + .idle_colour = BLACK, + .hover_colour = RED, + .pressed_colour = YELLOW +}; + +enum { + BUTTON_RETRY, + BUTTON_BACK, + N_BUTTONS, +}; + +static Button buttons[N_BUTTONS] = { + {.x = 64, .y = 64, .w = 128, .h = 32, .state = BUTTON_STATE_IDLE}, + {.x = 64, .y = 114, .w = 128, .h = 32, .state = BUTTON_STATE_IDLE}, +}; + static DrawList *render(State *state, UI *ui, Arena *a) { (void) ui; DrawList *drawList = new(a, 1, DrawList); - int cellWidth = ui->width / GRIDWIDTH; + int cellWidth = (ui->width - GRID_OFFSET_X) / GRIDWIDTH; int cellHeight = ui->height / GRIDHEIGHT; for (int x = 0; x < GRIDWIDTH; x++) { for (int y = 0; y < GRIDHEIGHT; y++) { drawList->els[drawList->len++] = (DrawElement) { - .x = cellWidth * x, + .x = cellWidth * x + GRID_OFFSET_X, .y = cellHeight * y, .w = cellWidth, .h = cellHeight, @@ -109,14 +148,45 @@ static DrawList *render(State *state, UI *ui, Arena *a) { } } + drawList->panel = (SidePanel) { + .bg = (DrawElement) { + .x = 0, + .y = 0, + .w = GRID_OFFSET_X, + .h = ui->height, + .fill = colors[YELLOW], + .border = {0, 0, 0, 255} + } + }; + return drawList; } +static void update_buttons(const int mx, const int my, const int mstate) { + for (int i = 0; i < N_BUTTONS; i++) { + if ( + mx > buttons[i].x && mx < buttons[i].x + buttons[i].w && + my > buttons[i].y && my < buttons[i].y + buttons[i].h + ) { + if (mstate == 1) { + buttons[i].state = BUTTON_STATE_PRESSED; + } + else + buttons[i].state = BUTTON_STATE_HOVERED; + } + else { + buttons[i].state = BUTTON_STATE_IDLE; + } + } +} + static void update(Game *game, uint64_t now, Arena a) { + const int offset_width = game->ui.width - GRID_OFFSET_X; + switch (game->input) { int x, y; case INPUT_CLICK: - x = game->mousex * GRIDWIDTH / game->ui.width; + x = game->mousex * GRIDWIDTH / offset_width; y = game->mousey * GRIDHEIGHT / game->ui.height; game->state.grid[x + y * GRIDWIDTH] = (game->state.grid[x + y * GRIDWIDTH] + 1) % (sizeof(colors) / sizeof(colors[0])); break; @@ -161,6 +231,45 @@ static void update(Game *game, uint64_t now, Arena a) { #include <SDL3/SDL.h> +void render_button(SDL_Renderer* r, const Button* b) { + Color colour = colors[BLACK]; + switch (b->state) { + case BUTTON_STATE_IDLE: + colour = colors[button_style.idle_colour]; + break; + case BUTTON_STATE_HOVERED: + colour = colors[button_style.hover_colour]; + break; + case BUTTON_STATE_PRESSED: + colour = colors[button_style.pressed_colour]; + break; + } + SDL_SetRenderDrawColor(r, colour.r, colour.g, colour.b, colour.a); + SDL_FRect rect = { + .x = (float) b->x, + .y = (float) b->y, + .w = (float) b->w, + .h = (float) b->h + }; + SDL_RenderFillRect(r, &rect); +} + +void render_side_panel(SDL_Renderer* r, SidePanel* panel) { + Color* bg_colour = &panel->bg.fill; + SDL_FRect rect = { + .x = (float) panel->bg.x, + .y = (float) panel->bg.y, + .w = (float) panel->bg.w, + .h = (float) panel->bg.h, + }; + SDL_SetRenderDrawColor(r, bg_colour->r, bg_colour->g, bg_colour->b, bg_colour->a); + SDL_RenderFillRect(r, &rect); + + for (int i = 0; i < N_BUTTONS; i++) { + render_button(r, &buttons[i]); + } +} + int main(int argc, char **argv) { (void) argc; (void) argv; @@ -191,7 +300,8 @@ int main(int argc, char **argv) { SDL_SetNumberProperty(renderProps, SDL_PROP_RENDERER_CREATE_PRESENT_VSYNC_NUMBER, 1); SDL_Renderer *r = SDL_CreateRendererWithProperties(renderProps); SDL_DestroyProperties(renderProps); - + + int mousex = 0, mousey = 0, mousestate = 0; for (;;) { uint64_t now = SDL_GetTicks(); game->input = INPUT_NONE; @@ -202,8 +312,16 @@ int main(int argc, char **argv) { return 0; case SDL_EVENT_MOUSE_BUTTON_DOWN: game->input = INPUT_CLICK; - game->mousex = (int) e.button.x; + game->mousex = (int) e.button.x - GRID_OFFSET_X; game->mousey = (int) e.button.y; + mousestate = SDL_BUTTON_MASK(e.motion.state); + break; + case SDL_EVENT_MOUSE_BUTTON_UP: + mousestate = 0; + break; + case SDL_EVENT_MOUSE_MOTION: + mousex = (int) e.motion.x; + mousey = (int) e.motion.y; break; case SDL_EVENT_KEY_DOWN: switch (e.key.key) { @@ -216,6 +334,7 @@ int main(int argc, char **argv) { SDL_GetWindowSize(w, &game->ui.width, &game->ui.height); break; } + update_buttons(mousex, mousey, mousestate); } Arena scratch = a; @@ -248,6 +367,7 @@ int main(int argc, char **argv) { ); SDL_RenderRect(r, &rect); } + render_side_panel(r, &drawList->panel); update(game, now, a); |