diff options
-rw-r--r-- | src/all.c | 67 | ||||
-rw-r--r-- | src/index.html.in | 29 |
2 files changed, 72 insertions, 24 deletions
@@ -19,6 +19,7 @@ typedef struct { #define MEM_SIZE (1<<16) #define GRIDWIDTH 16 #define GRIDHEIGHT 16 +#define TICK_LENGTH 1000 typedef struct { char *start; @@ -45,6 +46,8 @@ typedef struct { } UI; typedef struct { + uint64_t lastTick; + char playing; int grid[GRIDWIDTH * GRIDHEIGHT]; } State; @@ -52,6 +55,7 @@ typedef struct { enum { INPUT_NONE, INPUT_CLICK, + INPUT_PAUSE_PLAY, }; typedef struct { @@ -61,9 +65,19 @@ typedef struct { int mousex, mousey; } Game; -static const Color colors[] = { +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} }; static DrawList *render(State *state, UI *ui, Arena *a) { @@ -90,7 +104,7 @@ static DrawList *render(State *state, UI *ui, Arena *a) { return drawList; } -static void update(Game *game, Arena a) { +static void update(Game *game, uint64_t now, Arena a) { switch (game->input) { int x, y; case INPUT_CLICK: @@ -98,9 +112,41 @@ static void update(Game *game, Arena a) { 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; + case INPUT_PAUSE_PLAY: + game->state.playing = !game->state.playing; + break; default: break; } + + if (game->state.playing && game->state.lastTick + TICK_LENGTH <= now) { + game->state.lastTick = now; + State *lastState = new(&a, 1, State); + __builtin_memcpy(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; + } + } + } + } } #if SDL @@ -118,7 +164,8 @@ int main(int argc, char **argv) { }; Game *game = new(&a, 1, Game); - game->state.grid[0] = 1; + game->state.grid[0] = 0; + game->state.playing = 0; game->ui = (UI) { .width = 640, .height = 480, @@ -138,6 +185,7 @@ int main(int argc, char **argv) { SDL_DestroyProperties(renderProps); for (;;) { + uint64_t now = SDL_GetTicks(); game->input = INPUT_NONE; SDL_Event e = {0}; while (SDL_PollEvent(&e)) { @@ -149,6 +197,13 @@ int main(int argc, char **argv) { game->mousex = (int) e.button.x; game->mousey = (int) e.button.y; break; + case SDL_EVENT_KEY_DOWN: + switch (e.key.key) { + case SDLK_SPACE: + game->input = INPUT_PAUSE_PLAY; + break; + } + break; } } @@ -183,7 +238,7 @@ int main(int argc, char **argv) { SDL_RenderRect(r, &rect); } - update(game, a); + update(game, now, a); SDL_RenderPresent(r); } @@ -215,8 +270,10 @@ DrawList *game_render(int width, int height) { } __attribute((export_name("game_update"))) -void game_update(int input) { +void game_update(int input, int mousex, int mousey) { game->input = input; + game->mousex = mousex; + game->mousey = mousey; update(game, perm); } diff --git a/src/index.html.in b/src/index.html.in index bd4343d..07bd618 100644 --- a/src/index.html.in +++ b/src/index.html.in @@ -29,10 +29,7 @@ button { <script> // Mirror these in src/all.c const INPUT_NONE = 0; -const INPUT_UP = 1; -const INPUT_DOWN = 2; -const INPUT_LEFT = 3; -const INPUT_RIGHT = 4; +const INPUT_CLICK = 1; const WASM = #include "../build/main.wasm.b64" @@ -65,12 +62,10 @@ async function main() { let len = dl[0]; let ops = dl.subarray(1); - console.log(new Uint32Array(ops.subarray(6, 12))); for (let i = 0; i < len; i++) { let op = ops.subarray(6*i, 6*i+6); - const color = new Uint8Array(new Uint32Array(ops.subarray(4, 6)).buffer); + const color = new Uint8Array(new Uint32Array(op.subarray(4, 6)).buffer); ctx.fillStyle = `#${color[0].toString(16).padStart(2, "0")}${color[1].toString(16).padStart(2, "0")}${color[2].toString(16).padStart(2, "0")}`; - // console.log(color); ctx.fillRect(op[0], op[1], op[2], op[3]); ctx.strokeStyle = `#${color[4].toString(16).padStart(2, "0")}${color[5].toString(16).padStart(2, "0")}${color[6].toString(16).padStart(2, "0")}`; ctx.strokeRect(op[0], op[1], op[2], op[3]); @@ -81,22 +76,18 @@ async function main() { window.addEventListener("resize", onresize); onresize(); - document.addEventListener("keydown", function(e) { - if (e.key == "w") { - exports.game_update(INPUT_UP); - } else if (e.key == "a") { - exports.game_update(INPUT_LEFT); - } else if (e.key == "s") { - exports.game_update(INPUT_DOWN); - } else if (e.key == "d") { - exports.game_update(INPUT_RIGHT); - } - }) + canvas.addEventListener("mousedown", function(e) { + const mousex = e.clientX; + const mousey = e.clientY; + if (e.button == 0) { + exports.game_update(INPUT_CLICK, mousex, mousey); + } + }); function animate() { // TODO: stop requesting frames when state is static requestAnimationFrame(animate); - exports.game_update(INPUT_NONE); + exports.game_update(INPUT_NONE, 0, 0); render(); } requestAnimationFrame(animate); |