diff options
Diffstat (limited to 'src/all.c')
-rw-r--r-- | src/all.c | 280 |
1 files changed, 135 insertions, 145 deletions
@@ -1,114 +1,94 @@ +#ifndef INCLUDE_ALL_C +#define INCLUDE_ALL_C + #include <stddef.h> #include <stdint.h> -#if SDL -#include <string.h> -#define xmemcpy memcpy -#else -#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 x, y, w, h; - Color fill; - Color border; -} DrawElement; - -typedef struct { - DrawElement bg; -} SidePanel; - -typedef struct { - int len; - DrawElement els[512]; -} 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; - char *end; -} Arena; - -#define new(a, c, t) ((t *) alloc(a, c, sizeof(t), _Alignof(t))) -#define affirm(c) while (!(c)) *(volatile int *)0 = 0 - -static void *alloc(Arena *a, ptrdiff_t count, ptrdiff_t size, ptrdiff_t align) { - ptrdiff_t pad = -(size_t) a->start & (align - 1); - affirm(count < (a->end - a->start - pad) / size); - char *r = a->start + pad; - a->start += pad + size * count; - for (ptrdiff_t i = 0; i < count * size; i++) { - r[i] = 0; - } - - return r; -} - -typedef struct { - int width, height; -} UI; - -enum { - BUTTON_RETRY, - BUTTON_BACK, - N_BUTTONS, +#include "types.c" +#include "levels.c" +#include "tick.c" + +static const Color colors[N_COLORS][4] = { + { + {255, 255, 255, 255}, + {255, 255, 255, 255}, + {255, 255, 255, 255}, + {255, 255, 255, 255}, + }, + { + {0, 0, 0, 255}, + {0, 0, 0, 255}, + {0, 0, 0, 255}, + {0, 0, 0, 255}, + }, + { + {255, 0, 0, 255}, + {255, 0, 0, 255}, + {255, 0, 0, 255}, + {255, 0, 0, 255}, + }, + { + {255, 255, 0, 255}, + {255, 255, 0, 255}, + {255, 255, 0, 255}, + {255, 255, 0, 255}, + }, + { + {255, 0, 0, 255}, + {255, 0, 0, 255}, + {255, 255, 0, 255}, + {255, 255, 0, 255}, + }, + { + {255, 255, 0, 255}, + {255, 255, 0, 255}, + {255, 0, 0, 255}, + {255, 0, 0, 255}, + }, + { + {255, 0, 0, 255}, + {255, 255, 0, 255}, + {255, 0, 0, 255}, + {255, 255, 0, 255}, + }, + { + {255, 255, 0, 255}, + {255, 0, 0, 255}, + {255, 255, 0, 255}, + {255, 0, 0, 255}, + }, + { + {0, 0, 255, 255}, + {0, 0, 255, 255}, + {0, 0, 255, 255}, + {0, 0, 255, 255}, + }, + { + {0, 0, 255, 255}, + {0, 0, 255, 255}, + {255, 255, 255, 255}, + {255, 255, 255, 255}, + }, + { + {255, 255, 255, 255}, + {255, 255, 255, 255}, + {0, 0, 255, 255}, + {0, 0, 255, 255}, + }, + { + {0, 0, 255, 255}, + {255, 255, 255, 255}, + {0, 0, 255, 255}, + {255, 255, 255, 255}, + }, + { + {255, 255, 255, 255}, + {0, 0, 255, 255}, + {255, 255, 255, 255}, + {0, 0, 255, 255}, + }, }; -typedef struct { - uint64_t lastTick; - char playing; - int grid[GRIDWIDTH * GRIDHEIGHT]; - ButtonState buttonStates[N_BUTTONS]; -} State; - -// Mirror these in src/index.html.in -enum { - INPUT_NONE, - INPUT_CLICK, - INPUT_PAUSE_PLAY, -}; - -typedef struct { - State state; - UI ui; - int input; - int mousex, mousey; -} Game; - -enum { - EMPTY, - BLACK, - RED, - YELLOW, - N_COLORS, -}; - -static const Color colors[N_COLORS] = { - {255, 255, 255, 255}, - {0, 0, 0, 255}, - {255, 0, 0, 255}, - {255, 255, 0, 255} -}; - -typedef struct { - int x, y, w, h; -} Button; - static const Button buttons[N_BUTTONS] = { [BUTTON_RETRY] = {.x = 16, .y = 16, .w = 128, .h = 32}, [BUTTON_BACK] = {.x = 16, .y = 48, .w = 128, .h = 32}, @@ -129,32 +109,53 @@ static DrawList *render(State *state, UI *ui, Arena *a) { .y = cellHeight * y, .w = cellWidth, .h = cellHeight, - .fill = colors[state->grid[x + GRIDWIDTH * y]], + .fill = {0, 0, 0, 0}, .border = {0, 0, 0, 255}, }; + for (int subx = 0; subx < 2; subx++) { + for (int suby = 0; suby < 2; suby++) { + drawList->els[drawList->len++] = (DrawElement) { + .x = cellWidth * x + subx * cellWidth / 2, + .y = cellHeight * y + suby * cellHeight / 2, + .w = cellWidth / 2, + .h = cellHeight / 2, + .fill = colors[state->grid[x + GRIDWIDTH * y]][subx + 2 * suby], + .border = {0, 0, 0, 0}, + }; + } + } } } drawList->els[drawList->len++] = (DrawElement) { + .x = cellWidth * state->goalx, + .y = cellHeight * state->goaly, + .w = cellWidth, + .h = cellHeight, + .fill = {255, 0, 0, 63}, + .border = {255, 0, 0, 255}, + }; + + drawList->els[drawList->len++] = (DrawElement) { .x = 0, .y = 0, .w = GRID_OFFSET_X, .h = ui->height, - .fill = colors[YELLOW], - .border = {0, 0, 0, 255} + .fill = {255, 255, 0, 255}, + .border = {0, 0, 0, 255}, }; for (int i = 0; i < N_BUTTONS; i++) { - int colour = BLACK; + Color colour = {0, 0, 0, 255}; switch (state->buttonStates[i]) { case BUTTON_STATE_IDLE: - colour = BLACK; + colour = (Color) {0, 0, 0, 255}; break; case BUTTON_STATE_HOVERED: - colour = YELLOW; + colour = (Color) {255, 255, 0, 255}; break; case BUTTON_STATE_PRESSED: - colour = RED; + colour = (Color) {255, 0, 0, 255}; break; } drawList->els[drawList->len++] = (DrawElement) { @@ -162,7 +163,7 @@ static DrawList *render(State *state, UI *ui, Arena *a) { .y = buttons[i].y, .w = buttons[i].w, .h = buttons[i].h, - .fill = colors[colour], + .fill = colour, .border = {0, 0, 0, 255} }; } @@ -189,6 +190,11 @@ static void update(Game *game, uint64_t now, Arena a) { } } break; + case INPUT_RCLICK: + x = game->mousex * GRIDWIDTH / game->ui.width; + y = game->mousey * GRIDHEIGHT / game->ui.height; + game->state.grid[x + y * GRIDWIDTH] = EMPTY; + break; case INPUT_PAUSE_PLAY: game->state.playing = !game->state.playing; break; @@ -198,31 +204,8 @@ static void update(Game *game, uint64_t now, Arena a) { if (game->state.playing && game->state.lastTick + TICK_LENGTH <= now) { game->state.lastTick = now; - State *lastState = new(&a, 1, State); - xmemcpy(lastState, game, sizeof(State)); - - for (int x = 0; x < GRIDWIDTH; x++) { - for (int y = 0; y < GRIDHEIGHT; y++) { - if ( - lastState->grid[x + y * GRIDWIDTH] == BLACK && ( - (x > 0 && lastState->grid[x - 1 + y * GRIDWIDTH] == RED) || - (x < GRIDWIDTH - 1 && lastState->grid[x + 1 + y * GRIDWIDTH] == RED) || - (y > 0 && lastState->grid[x + (y - 1) * GRIDWIDTH] == RED) || - (y < GRIDHEIGHT - 1 && lastState->grid[x + (y + 1) * GRIDWIDTH] == RED) - ) - ) { - game->state.grid[x + y * GRIDWIDTH] = RED; - } - - if (lastState->grid[x + y * GRIDWIDTH] == RED) { - game->state.grid[x + y * GRIDWIDTH] = YELLOW; - } - if (lastState->grid[x + y * GRIDWIDTH] == YELLOW) { - game->state.grid[x + y * GRIDWIDTH] = BLACK; - } - } - } + tick(game, a); } } @@ -241,7 +224,9 @@ int main(int argc, char **argv) { }; Game *game = new(&a, 1, Game); - game->state.grid[0] = 0; + xmemcpy(&game->state.grid, &levels[0].grid, sizeof(game->state.grid)); + game->state.goalx = levels[0].goalx; + game->state.goaly = levels[0].goaly; game->state.playing = 0; game->ui = (UI) { .width = 640, @@ -263,7 +248,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); - + SDL_SetRenderDrawBlendMode(r, SDL_BLENDMODE_BLEND); + for (;;) { uint64_t now = SDL_GetTicks(); game->input = INPUT_NONE; @@ -273,9 +259,13 @@ int main(int argc, char **argv) { case SDL_EVENT_QUIT: return 0; case SDL_EVENT_MOUSE_BUTTON_DOWN: - game->input = INPUT_CLICK; game->mousex = (int) e.button.x; game->mousey = (int) e.button.y; + if (e.button.button == 1) { + game->input = INPUT_CLICK; + } else if (e.button.button == 3) { + game->input = INPUT_RCLICK; + } break; case SDL_EVENT_KEY_DOWN: switch (e.key.key) { @@ -290,8 +280,6 @@ int main(int argc, char **argv) { } } - SDL_Log("Button 1 state: %d", game->state.buttonStates[0]); - Arena scratch = a; DrawList *drawList = render(&game->state, &game->ui, &scratch); SDL_SetRenderDrawColor(r, 0, 0, 0, 255); @@ -355,11 +343,13 @@ DrawList *game_render(int width, int height) { } __attribute((export_name("game_update"))) -void game_update(int input, int mousex, int mousey) { +void game_update(int input, int mousex, int mousey, int now) { game->input = input; game->mousex = mousex; game->mousey = mousey; - update(game, perm); + update(game, now, perm); } #endif + +#endif |