Back to shtanton's homepage
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharlie Stanton <charlie@shtanton.xyz>2025-04-05 13:27:26 +0100
committerCharlie Stanton <charlie@shtanton.xyz>2025-04-05 13:27:26 +0100
commit87392b4465ff2aa2f988b07365bf6b0fa5ea3d09 (patch)
tree74f852af2b7da8e473174bbaf1b4ab632a11f9a7
parentb851d1dee56a191b3eabee957af4bb35f0a3e2cb (diff)
downloadldjam57-87392b4465ff2aa2f988b07365bf6b0fa5ea3d09.tar
red
-rw-r--r--src/all.c67
-rw-r--r--src/index.html.in29
2 files changed, 72 insertions, 24 deletions
diff --git a/src/all.c b/src/all.c
index 4fe3d5b..130bf27 100644
--- a/src/all.c
+++ b/src/all.c
@@ -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);