Back to shtanton's homepage
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/all.c103
-rw-r--r--src/index.html.in18
2 files changed, 97 insertions, 24 deletions
diff --git a/src/all.c b/src/all.c
index a28b8ca..b00f45f 100644
--- a/src/all.c
+++ b/src/all.c
@@ -1,13 +1,6 @@
#include <stddef.h>
#include <stdint.h>
-#if SDL
-#include <string.h>
-#define xmemcpy memcpy
-#else
-#define xmemcpy __builtin_memcpy
-#endif
-
#define MEM_SIZE (1<<24)
#define GRIDWIDTH 16
#define GRIDHEIGHT 16
@@ -36,6 +29,12 @@ typedef struct {
#define new(a, c, t) ((t *) alloc(a, c, sizeof(t), _Alignof(t)))
#define affirm(c) while (!(c)) *(volatile int *)0 = 0
+static void xmemcpy(void *dst, void *src, ptrdiff_t size) {
+ for (ptrdiff_t i = 0; i < size; i++) {
+ ((char *) dst)[i] = ((char *) src)[i];
+ }
+}
+
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);
@@ -77,6 +76,8 @@ enum {
BLACK,
RED,
YELLOW,
+ RED_UP,
+ RED_DOWN,
RED_LEFT,
RED_RIGHT,
N_COLORS,
@@ -109,6 +110,18 @@ static const Color colors[N_COLORS][4] = {
},
{
{255, 0, 0, 255},
+ {255, 0, 0, 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},
{0, 0, 0, 255},
{255, 0, 0, 255},
{0, 0, 0, 255},
@@ -180,23 +193,49 @@ static void update(Game *game, uint64_t now, Arena a) {
for (int x = 0; x < GRIDWIDTH; x++) {
for (int y = 0; y < GRIDHEIGHT; y++) {
switch (lastState->grid[x + y * GRIDWIDTH]) {
+ int reds, red;
case BLACK:
+ reds = 0;
if (
- x < GRIDWIDTH - 1 &&
- lastState->grid[x + 1 + y * GRIDWIDTH] == RED_LEFT
+ x < GRIDWIDTH - 1 && (
+ lastState->grid[x + 1 + y * GRIDWIDTH] == RED_LEFT ||
+ lastState->grid[x + 1 + y * GRIDWIDTH] == RED
+ )
) {
- game->state.grid[x + y * GRIDWIDTH] = RED_LEFT;
- } else if (
- x > 0 &&
- lastState->grid[x - 1 + y * GRIDWIDTH] == RED_RIGHT
+ reds++;
+ red = lastState->grid[x + 1 + y * GRIDWIDTH];
+ }
+ if (
+ x > 0 && (
+ lastState->grid[x - 1 + y * GRIDWIDTH] == RED_RIGHT ||
+ lastState->grid[x - 1 + y * GRIDWIDTH] == RED
+ )
) {
- game->state.grid[x + y * GRIDWIDTH] = RED_RIGHT;
- } else if (
- (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)
+ reds++;
+ red = lastState->grid[x - 1 + y * GRIDWIDTH];
+ }
+ if (
+ y > 0 && (
+ lastState->grid[x + (y - 1) * GRIDWIDTH] == RED_DOWN ||
+ lastState->grid[x + (y - 1) * GRIDWIDTH] == RED
+ )
+ ) {
+ reds++;
+ red = lastState->grid[x + (y - 1) * GRIDWIDTH];
+ }
+ if (
+ y < GRIDHEIGHT - 1 && (
+ lastState->grid[x + (y + 1) * GRIDWIDTH] == RED_UP ||
+ lastState->grid[x + (y + 1) * GRIDWIDTH] == RED
+ )
) {
+ reds++;
+ red = lastState->grid[x + (y + 1) * GRIDWIDTH];
+ }
+
+ if (reds == 1) {
+ game->state.grid[x + y * GRIDWIDTH] = red;
+ } else if (reds >= 2) {
game->state.grid[x + y * GRIDWIDTH] = RED;
}
break;
@@ -210,7 +249,7 @@ static void update(Game *game, uint64_t now, Arena a) {
) {
game->state.grid[x + y * GRIDWIDTH] = YELLOW;
} else {
- game->state.grid[x + y * GRIDWIDTH] = RED_RIGHT;
+ game->state.grid[x + y * GRIDWIDTH] = RED_UP;
}
break;
case RED_RIGHT:
@@ -220,6 +259,26 @@ static void update(Game *game, uint64_t now, Arena a) {
) {
game->state.grid[x + y * GRIDWIDTH] = YELLOW;
} else {
+ game->state.grid[x + y * GRIDWIDTH] = RED_DOWN;
+ }
+ break;
+ case RED_UP:
+ if (
+ y > 0 &&
+ lastState->grid[x + (y - 1) * GRIDWIDTH] == BLACK
+ ) {
+ game->state.grid[x + y * GRIDWIDTH] = YELLOW;
+ } else {
+ game->state.grid[x + y * GRIDWIDTH] = RED_RIGHT;
+ }
+ break;
+ case RED_DOWN:
+ if (
+ y < GRIDHEIGHT - 1 &&
+ lastState->grid[x + (y + 1) * GRIDWIDTH] == BLACK
+ ) {
+ game->state.grid[x + y * GRIDWIDTH] = YELLOW;
+ } else {
game->state.grid[x + y * GRIDWIDTH] = RED_LEFT;
}
break;
@@ -357,11 +416,11 @@ 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
diff --git a/src/index.html.in b/src/index.html.in
index 07bd618..a58354a 100644
--- a/src/index.html.in
+++ b/src/index.html.in
@@ -30,6 +30,7 @@ button {
// Mirror these in src/all.c
const INPUT_NONE = 0;
const INPUT_CLICK = 1;
+const INPUT_PAUSE_PLAY = 2;
const WASM =
#include "../build/main.wasm.b64"
@@ -46,6 +47,11 @@ async function main() {
let ctx = canvas.getContext("2d");
let memory = exports.memory;
+ const start = Date.now();
+ function now() {
+ return Date.now() - start;
+ }
+
function min(a, b) {
return b<a ? b : a;
}
@@ -66,8 +72,10 @@ async function main() {
let op = ops.subarray(6*i, 6*i+6);
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")}`;
+ ctx.globalAlpha = color[3] / 255;
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.globalAlpha = color[7] / 255;
ctx.strokeRect(op[0], op[1], op[2], op[3]);
}
}
@@ -80,14 +88,20 @@ async function main() {
const mousex = e.clientX;
const mousey = e.clientY;
if (e.button == 0) {
- exports.game_update(INPUT_CLICK, mousex, mousey);
+ exports.game_update(INPUT_CLICK, mousex, mousey, now());
+ }
+ });
+
+ document.addEventListener("keydown", function (e) {
+ if (e.key === " ") {
+ exports.game_update(INPUT_PAUSE_PLAY, 0, 0, now());
}
});
function animate() {
// TODO: stop requesting frames when state is static
requestAnimationFrame(animate);
- exports.game_update(INPUT_NONE, 0, 0);
+ exports.game_update(INPUT_NONE, 0, 0, now());
render();
}
requestAnimationFrame(animate);