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); | 
