Back to shtanton's homepage
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/all.c38
-rw-r--r--src/img.c95
-rw-r--r--src/index.html.in13
-rw-r--r--src/types.c1
4 files changed, 146 insertions, 1 deletions
diff --git a/src/all.c b/src/all.c
index d2536b9..e5c86db 100644
--- a/src/all.c
+++ b/src/all.c
@@ -139,6 +139,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) {
@@ -218,6 +219,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;
@@ -254,6 +265,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();
@@ -289,6 +317,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,
@@ -314,6 +343,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);
@@ -336,7 +369,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 8e8ba1d..bfe0d7d 100644
--- a/src/types.c
+++ b/src/types.c
@@ -17,6 +17,7 @@ typedef struct {
int x, y, w, h;
Color fill;
Color border;
+ int image;
} DrawElement;
typedef struct {