diff --git a/build/html.ts b/build/html.ts
index e06727c..5bc4851 100644
--- a/build/html.ts
+++ b/build/html.ts
@@ -56,24 +56,27 @@ export async function buildHTML(game: string, { production = false, portable = f
if (!await pwaIconFile.exists()) {
pwaIconFile = Bun.file(path.resolve(import.meta.dir, 'assets', 'pwa_icon.png'));
}
- const pwaIcon = `data:;base64,${Buffer.from(await pwaIconFile.arrayBuffer()).toString('base64')}`;
- const publishURL = process.env.PUBLISH_URL ? `${process.env.PUBLISH_URL}${game}`: '.';
- const manifestJSON = JSON.stringify({
- name: title,
- short_name: title,
- start_url: publishURL,
- id: `/${game}`,
- display_override: ["window-controls-overlay"],
- display: "fullscreen",
- background_color: "#ffffff",
- theme_color: "#000000",
- icons: [{
- src: pwaIcon,
- sizes: '192x192',
- type: 'image/png'
- }]
- });
- const manifest = ``;
+ let manifest = '';
+ if (production) {
+ const pwaIcon = `data:;base64,${Buffer.from(await pwaIconFile.arrayBuffer()).toString('base64')}`;
+ const publishURL = process.env.PUBLISH_URL ? `${process.env.PUBLISH_URL}${game}` : '.';
+ const manifestJSON = JSON.stringify({
+ name: title,
+ short_name: title,
+ start_url: publishURL,
+ id: `/${game}`,
+ display_override: ["window-controls-overlay"],
+ display: "fullscreen",
+ background_color: "#ffffff",
+ theme_color: "#000000",
+ icons: [{
+ src: pwaIcon,
+ sizes: '192x192',
+ type: 'image/png'
+ }]
+ });
+ manifest = ``;
+ }
let script = await scriptFile.text();
const inits = new Set();
script = script.replace(/var (init_[^ ]+) = __esm\(\(\)/g, (_, $1) => {
diff --git a/src/common/display/canvas.ts b/src/common/display/canvas.ts
index f4bda24..61197e1 100644
--- a/src/common/display/canvas.ts
+++ b/src/common/display/canvas.ts
@@ -14,32 +14,46 @@ export function createCanvas(width: number, height: number) {
canvas.width = width;
canvas.height = height;
- canvas.style.height = '100%';
+ canvas.style.width = '100dvw';
+ canvas.style.height = '100dvh';
+ canvas.style.objectFit = 'contain';
canvas.style.imageRendering = 'pixelated';
document.body.style.display = 'flex';
document.body.style.justifyContent = 'center';
+ document.body.style.alignItems = 'center';
document.body.append(canvas);
return canvas;
}
-export function createWasmCanvas(dataView: DataView, pointer: number, onFrame?: () => void) {
- const imageData = loadImageData(dataView, pointer);
- const canvas = createCanvas(imageData.width, imageData.height);
- const context = canvas.getContext('bitmaprenderer');
+interface WasmModule {
+ data: DataView;
+ init?: (width: number, height: number) => number;
+ frame?: () => void;
+}
- if (context) {
- const frame = async () => {
- onFrame?.();
- const imageBitmap = await createImageBitmap(imageData);
- context.transferFromImageBitmap(imageBitmap);
- requestAnimationFrame(frame);
- };
- frame();
+export function createWasmCanvas(module: WasmModule, width: number, height: number) {
+ const pointer = module.init?.(width, height);
+
+ if (pointer) {
+ const imageData = loadImageData(module.data, pointer);
+ const canvas = createCanvas(imageData.width, imageData.height);
+ const context = canvas.getContext('2d');
+
+ if (context) {
+ const frame = () => {
+ module.frame?.();
+ context.putImageData(imageData, 0, 0);
+ requestAnimationFrame(frame);
+ };
+ frame();
+ }
+
+ return canvas;
}
-
- return canvas;
+ console.error(`[createWasmCanvas] WASM init's function should return pointer to image data`);
+ return createCanvas(width, height);
}
export function getImageData(image: HTMLImageElement): ImageData {
diff --git a/src/games/playground/awoo.cpp b/src/games/playground/awoo.cpp
index 301b233..a332479 100644
--- a/src/games/playground/awoo.cpp
+++ b/src/games/playground/awoo.cpp
@@ -1,209 +1,7 @@
-#include
-#include
#include
-static image_data_t image;
+EXPORT(main) void init() {
+ uint32_t result = 42;
-// D E F I N E S ///////////////////////////////////////////////////////////
-
-#define NUM_ASTEROIDS 10
-#define ERASE 0
-#define DRAW 1
-
-// T Y P E D E F S ///////////////////////////////////////////////////////////
-
-// the structure for a vertex
-
-typedef struct vertex_typ {
- float x, y; // a single point in the 2-D plane.
-} vertex, *vertex_ptr;
-
-// the structure for an object
-
-typedef struct object_typ {
- int num_vertices; // number of vertices in this object
- uint32_t color; // color of object
- float xo, yo; // position of object
- float x_velocity; // x velocity of object
- float y_velocity; // y velocity of object
- float scale; // scale factor
- float angle; // rotation rate
- vertex vertices[16]; // 16 vertices
-} object, *object_ptr;
-
-object asteroids[NUM_ASTEROIDS];
-
-void Scale_Object(object_ptr object, float scale) {
- int index;
-
- // for all vertices scale the x and y component
-
- for (index = 0; index < object->num_vertices; index++) {
- object->vertices[index].x *= scale;
- object->vertices[index].y *= scale;
- } // end for index
-
-} // end Scale_Object
-
-//////////////////////////////////////////////////////////////////////////////
-
-void Rotate_Object(object_ptr object, float angle) {
- int index;
- float x_new, y_new, cs, sn;
-
- // pre-compute sin and cos
- cs = cos(angle);
- sn = sin(angle);
-
- // for each vertex rotate it by angle
- for (index = 0; index < object->num_vertices; index++) {
- // rotate the vertex
- x_new = object->vertices[index].x * cs - object->vertices[index].y * sn;
- y_new = object->vertices[index].y * cs + object->vertices[index].x * sn;
-
- // store the rotated vertex back into structure
- object->vertices[index].x = x_new;
- object->vertices[index].y = y_new;
-
- } // end for index
-
-} // end Rotate_Object
-
-//////////////////////////////////////////////////////////////////////////////
-
-void Create_Field(void) {
-
- int index;
-
- for (index = 0; index < NUM_ASTEROIDS; index++) {
-
- // fill in the fields
-
- asteroids[index].num_vertices = 6;
- asteroids[index].color = 0xFF000000 | (rand());
- asteroids[index].xo = 21 + rand() % (image.width - 42);
- asteroids[index].yo = 21 + rand() % (image.height - 42);
-
- asteroids[index].x_velocity = -3 + rand() % 6;
- asteroids[index].y_velocity = -3 + rand() % 6;
- asteroids[index].scale = (float)(rand() % 30) / 10;
- asteroids[index].angle = (float)(-5 + (float)(rand() % 10)) / 100;
-
- asteroids[index].vertices[0].x = 4.0;
- asteroids[index].vertices[0].y = 3.5;
- asteroids[index].vertices[1].x = 8.5;
- asteroids[index].vertices[1].y = -3.0;
- asteroids[index].vertices[2].x = 6;
- asteroids[index].vertices[2].y = -5;
- asteroids[index].vertices[3].x = 2;
- asteroids[index].vertices[3].y = -3;
- asteroids[index].vertices[4].x = -4;
- asteroids[index].vertices[4].y = -6;
- asteroids[index].vertices[5].x = -3.5;
- asteroids[index].vertices[5].y = 5.5;
-
- // now scale the asteroid to proper size
-
- Scale_Object((object_ptr)&asteroids[index], asteroids[index].scale);
-
- } // end for index
-
-} // end Create_Field
-
-//////////////////////////////////////////////////////////////////////////////
-
-void Draw_Asteroids(int erase) {
- image_color_t color = {0xFF000000};
-
- for (int index = 0; index < NUM_ASTEROIDS; index++) {
-
- // draw the asteroid
-
- if (erase == DRAW) {
- color.color = asteroids[index].color;
- }
-
- // get position of object
- float xo = asteroids[index].xo;
- float yo = asteroids[index].yo;
-
- // moveto first vertex
-
- for (int startVertex = 0; startVertex < asteroids[index].num_vertices; startVertex++) {
- int endVertex = (startVertex + 1) % asteroids[index].num_vertices;
- int x1 = (int)(xo + asteroids[index].vertices[startVertex].x);
- int y1 = (int)(yo + asteroids[index].vertices[startVertex].y);
- int x2 = (int)(xo + asteroids[index].vertices[endVertex].x);
- int y2 = (int)(yo + asteroids[index].vertices[endVertex].y);
- image_draw_line(image, x1, y1, x2, y2, color);
-
- } // end for vertex
-
- } // end for index
-
-} // end Draw_Asteroids
-
-//////////////////////////////////////////////////////////////////////////////
-
-void Translate_Asteroids() {
-
- int index;
-
- for (index = 0; index < NUM_ASTEROIDS; index++) {
- // translate current asteroid
-
- asteroids[index].xo += asteroids[index].x_velocity;
- asteroids[index].yo += asteroids[index].y_velocity;
- // collision detection i.e. bounds check
-
- if (asteroids[index].xo > image.width - 20 || asteroids[index].xo < 20) {
- asteroids[index].x_velocity = -asteroids[index].x_velocity;
- asteroids[index].xo += asteroids[index].x_velocity;
- }
-
- if (asteroids[index].yo > image.height - 20 || asteroids[index].yo < 20) {
- asteroids[index].y_velocity = -asteroids[index].y_velocity;
- asteroids[index].yo += asteroids[index].y_velocity;
- }
-
- } // end for index
-
-} // end Translate_Asteroids
-
-//////////////////////////////////////////////////////////////////////////////
-
-void Rotate_Asteroids(void) {
-
- int index;
-
- for (index = 0; index < NUM_ASTEROIDS; index++) {
- // rotate current asteroid
- Rotate_Object((object_ptr)&asteroids[index], asteroids[index].angle);
-
- } // end for index
-
-} // end Rotate_Asteroids
-
-EXPORT(cpptest) image_data_t* cpptest(uint16_t w, uint16_t h) {
- image = image_create(w, h);
-
- image_fill_rect(image, 0, 0, w, h, {0xFF000000});
-
- Create_Field();
-
- return ℑ
-}
-
-EXPORT(step) void step() {
- Draw_Asteroids(ERASE);
-
- // transform field
-
- Rotate_Asteroids();
-
- Translate_Asteroids();
-
- // draw field
-
- Draw_Asteroids(DRAW);
+ printf("%d\n", result);
}
\ No newline at end of file
diff --git a/src/games/playground/index.tsx b/src/games/playground/index.tsx
index 46f5084..4267bd1 100644
--- a/src/games/playground/index.tsx
+++ b/src/games/playground/index.tsx
@@ -1,8 +1,5 @@
-import { createWasmCanvas } from "@common/display/canvas";
import awoo from "./awoo.cpp";
export default function main() {
- const data = awoo.cpptest(window.innerWidth >> 2, window.innerHeight >> 2);
- const canvas = createWasmCanvas(awoo.data, data, awoo.step);
- console.log(awoo, canvas.width, canvas.height);
+ console.log(awoo, awoo.main());
}
\ No newline at end of file