diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/all.c | 38 | ||||
| -rw-r--r-- | src/img.c | 95 | ||||
| -rw-r--r-- | src/index.html.in | 13 | ||||
| -rw-r--r-- | src/types.c | 1 | 
4 files changed, 146 insertions, 1 deletions
| @@ -134,6 +134,7 @@ static DrawList *render(State *state, UI *ui, Arena *a) {  		.h = cellHeight,  		.fill = {255, 0, 0, 63},  		.border = {255, 0, 0, 255}, +		.image = 1,  	};  	drawList->els[drawList->len++] = (DrawElement) { @@ -213,6 +214,16 @@ static void update(Game *game, uint64_t now, Arena a) {  #include <SDL3/SDL.h> +typedef struct { +	int width, height; +	Color colors[16]; +	const char *pixels; +} Image; + +#include "../build/images.c" + +SDL_Texture *textures[sizeof(images) / sizeof(images[0])]; +  int main(int argc, char **argv) {  	(void) argc;  	(void) argv; @@ -249,6 +260,23 @@ int main(int argc, char **argv) {  	SDL_Renderer *r = SDL_CreateRendererWithProperties(renderProps);  	SDL_DestroyProperties(renderProps);  	SDL_SetRenderDrawBlendMode(r, SDL_BLENDMODE_BLEND); + +	for (int j = 1; j < (int) (sizeof(images) / sizeof(images[0])); j++) { +		textures[j] = SDL_CreateTexture( +			r, +			SDL_PIXELFORMAT_ABGR8888, +			SDL_TEXTUREACCESS_STATIC, +			images[j].width, +			images[j].height +		); +		SDL_SetTextureScaleMode(textures[j], SDL_SCALEMODE_NEAREST); +		Arena scratch = a; +		Color *pixels = new(&scratch, images[j].width * images[j].height, Color); +		for (int i = 0; i < images[j].width * images[j].height; i++) { +			pixels[i] = images[j].colors[(int) images[j].pixels[i]]; +		} +		SDL_UpdateTexture(textures[j], NULL, pixels, images[j].width * 4); +	}  	for (;;) {  		uint64_t now = SDL_GetTicks(); @@ -284,6 +312,7 @@ int main(int argc, char **argv) {  		DrawList *drawList = render(&game->state, &game->ui, &scratch);  		SDL_SetRenderDrawColor(r, 0, 0, 0, 255);  		SDL_RenderFillRect(r, NULL); +  		for (int i = 0; i < drawList->len; i++) {  			SDL_FRect rect = {  				.x = (float) drawList->els[i].x, @@ -309,6 +338,10 @@ int main(int argc, char **argv) {  				drawList->els[i].border.a  			);  			SDL_RenderRect(r, &rect); + +			if (drawList->els[i].image != 0) { +				SDL_RenderTexture(r, textures[drawList->els[i].image], NULL, &rect); +			}  		}  		update(game, now, a); @@ -331,7 +364,10 @@ void game_init(void) {  	perm.end = heap + MEM_SIZE;  	game = new(&perm, 1, Game); -	game->state.grid[0] = 1; +	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;  }  __attribute((export_name("game_render"))) diff --git a/src/img.c b/src/img.c new file mode 100644 index 0000000..09f000b --- /dev/null +++ b/src/img.c @@ -0,0 +1,95 @@ +#define QOI_IMPLEMENTATION +#include "../lib/qoi/qoi.h" + +#include <stdio.h> + +typedef struct { +	unsigned char r, g, b, a; +} Color; + +int pixels(char *index, char *filename) { +	qoi_desc desc; +	Color *pixels = qoi_read(filename, &desc, 4); + +	Color colors[16]; +	int colorsLen = 0; +	char *compressed = malloc(desc.width * desc.height); + +	for (int i = 0; i < (int) (desc.width * desc.height); i++) { +		char c = -1; +		for (int j = 0; j < colorsLen; j++) { +			if (*((int *) &colors[j]) == *((int *) pixels + i)) { +				c = j; +				break; +			} +		} +		if (c == -1) { +			c = colorsLen; +			if (colorsLen >= 16) { +				return 1; +			} +			colors[colorsLen++] = pixels[i]; +		} +		compressed[i] = c; +	} + +	printf("const char imagePixels%s[%d * %d] = {\n", index, desc.width, desc.height); +	for (int y = 0; y < (int) desc.height; y++) { +		for (int x = 0; x < (int) desc.width; x++) { +			printf("%d,", compressed[x + y * desc.width]); +		} +		printf("\n"); +	} +	printf("};\n"); + +	return 0; +} + +int image(char *index, char *filename) { +	qoi_desc desc; +	Color *pixels = qoi_read(filename, &desc, 4); + +	Color colors[16]; +	int colorsLen = 0; +	char *compressed = malloc(desc.width * desc.height); + +	for (int i = 0; i < (int) (desc.width * desc.height); i++) { +		char c = -1; +		for (int j = 0; j < colorsLen; j++) { +			if (*((int *) &colors[j]) == *((int *) pixels + i)) { +				c = j; +				break; +			} +		} +		if (c == -1) { +			c = colorsLen; +			if (colorsLen >= 16) { +				return 1; +			} +			colors[colorsLen++] = pixels[i]; +		} +		compressed[i] = c; +	} + +	printf("{\n.width = %d,\n.height = %d,\n.colors = {\n", desc.width, desc.height); +	for (int i = 0; i < colorsLen; i++) { +		printf("\t{%u, %u, %u, %u},\n", colors[i].r, colors[i].g, colors[i].b, colors[i].a); +	} +	printf("},\n.pixels = imagePixels%s,\n},\n", index); + +	return 0; +} + +int main(int argc, char **argv) { +	if (argc != 4) { +		return 1; +	} + +	if (!strcmp(argv[1], "pixels")) { +		return pixels(argv[3], argv[2]); +	} else if (!strcmp(argv[1], "image")) { +		return image(argv[3], argv[2]); +	} else { +		return 1; +	} +} diff --git a/src/index.html.in b/src/index.html.in index 8d0ccea..aca8b6d 100644 --- a/src/index.html.in +++ b/src/index.html.in @@ -36,6 +36,9 @@ const INPUT_PAUSE_PLAY = 3;  const WASM =  #include "../build/main.wasm.b64" +const MUSIC = +#include "../build/music.mp3.b64" +  async function main() {      let bytes   = Uint8Array.from(atob(WASM), function(c) {          return c.charCodeAt(0); @@ -48,6 +51,12 @@ async function main() {      let ctx     = canvas.getContext("2d");      let memory  = exports.memory; +	const audio = new Audio(); +	audio.src = MUSIC; +	audio.volume = 0.2; +	audio.loop = true; +	let musicPlaying = false; +  	const start = Date.now();  	function now() {  		return Date.now() - start; @@ -94,6 +103,10 @@ async function main() {  			e.preventDefault();  			exports.game_update(INPUT_RCLICK, mousex, mousey, now());  		} +		if (!musicPlaying) { +			musicPlaying = true; +			audio.play(); +		}  	});  	canvas.addEventListener("contextmenu", function (e) { diff --git a/src/types.c b/src/types.c index cbd9315..fde4ab4 100644 --- a/src/types.c +++ b/src/types.c @@ -14,6 +14,7 @@ typedef struct {  	int x, y, w, h;  	Color fill;  	Color border; +	int image;  } DrawElement;  typedef struct { | 
