diff --git a/build/assets/stdlib.h b/build/assets/stdlib.h index c30a6ce..c11f280 100644 --- a/build/assets/stdlib.h +++ b/build/assets/stdlib.h @@ -12,9 +12,9 @@ extern unsigned char __heap_base; #define IMPORT(name) __attribute__((import_module("env"), import_name(#name))) #define EXPORT(name) __attribute__((export_name(#name))) -EXPORT(malloc) void* malloc(size_t); -EXPORT(free) void free(void*); -EXPORT(realloc) void* realloc(void*, size_t); +void* malloc(size_t); +void free(void*); +void* realloc(void*, size_t); void* memset(void* s, uint8_t c, uint32_t n); void* memcpy(void* dest, const void* src, uint32_t n); diff --git a/build/wasmPlugin.ts b/build/wasmPlugin.ts index cd8ad06..4ec48c9 100644 --- a/build/wasmPlugin.ts +++ b/build/wasmPlugin.ts @@ -38,22 +38,23 @@ const wasmPlugin = ({ production, portable }: WasmLoaderConfig = {}): BunPlugin for (const c of format) { if (!isFormat && c !== '%') { buf += c; - } else if (c === '%') { + } else if (!isFormat && c === '%') { isFormat = true; } else switch(c) { case '%': buf += '%'; isFormat = false; break; case 's': align(4); buf += getString(data.getInt32(argsPtr, true)); argsPtr += 4; isFormat = false; break; case 'd': align(w); buf += data[w === 4 ? 'getInt32': 'getBigInt64'](argsPtr, true); argsPtr += w; isFormat = false; break; - case 'x': align(w); buf += data[w === 4 ? 'getInt32': 'getBigInt64'](argsPtr, true).toString(16); argsPtr += w; isFormat = false; break; - case 'o': align(w); buf += data[w === 4 ? 'getInt32': 'getBigInt64'](argsPtr, true).toString(8); argsPtr += w; isFormat = false; break; + case 'x': align(w); buf += data[w === 4 ? 'getUint32': 'getBigUint64'](argsPtr, true).toString(16); argsPtr += w; isFormat = false; break; + case 'o': align(w); buf += data[w === 4 ? 'getUint32': 'getBigUint64'](argsPtr, true).toString(8); argsPtr += w; isFormat = false; break; case 'u': align(w); buf += data[w === 4 ? 'getUint32': 'getBigUint64'](argsPtr, true); argsPtr += w; isFormat = false; break; case 'f': align(8); buf += data.getFloat64(argsPtr, true); argsPtr += 8; isFormat = false; break; case 'c': align(4); buf += String.fromCharCode(data.getInt32(argsPtr, true)); argsPtr += 4; isFormat = false; break; case 'l': w = 8; break; + default: buf += '%' + c; isFormat = false; break; } } - console.log('[wasm] ' + buf); + console.log('[wasm]', buf); }, grow(blocks) { if (blocks > 0) { diff --git a/src/games/playground/awoo.cpp b/src/games/playground/awoo.cpp index fc7e772..7737947 100644 --- a/src/games/playground/awoo.cpp +++ b/src/games/playground/awoo.cpp @@ -1,5 +1,5 @@ #include EXPORT(cpptest) void cpptest() { - printf("Awoo d=%d d2=%d", 69llu, 42ll); + printf("Awoo! %t%%"); } \ No newline at end of file diff --git a/src/games/playground/index.tsx b/src/games/playground/index.tsx index 1e74a32..a2591a4 100644 --- a/src/games/playground/index.tsx +++ b/src/games/playground/index.tsx @@ -2,6 +2,5 @@ import awoo from "./awoo.cpp"; export default function main() { awoo.cpptest(); - // awoo.data.getBig - console.log(awoo.memory); + console.log(awoo.memory.grow); } \ No newline at end of file diff --git a/src/games/wfc/assets/wfc.png b/src/games/wfc/assets/wfc.png deleted file mode 100644 index d07b823..0000000 Binary files a/src/games/wfc/assets/wfc.png and /dev/null differ diff --git a/src/games/wfc/index.ts b/src/games/wfc/index.ts deleted file mode 100644 index 59886a9..0000000 --- a/src/games/wfc/index.ts +++ /dev/null @@ -1,43 +0,0 @@ -import wfc from './wfc.c'; -import wfcImage from './assets/wfc.png'; -import { createCanvas, getImageData } from "@common/display/canvas" - -const width = 256; -const height = 256; - -const canvas = createCanvas(width, height); -const context = canvas.getContext('2d')!; -const imageData = context.createImageData(width, height); -let pixels: Uint8ClampedArray; - -export default function main() { - console.log(wfc); - - const imageData = getImageData(wfcImage); - const dataPtr = wfc.malloc(imageData.data.length); - let buffer = new Uint8ClampedArray(wfc.memory.buffer, dataPtr, imageData.data.length); - buffer.set(imageData.data); - - wfc.init(dataPtr, imageData.width, imageData.height, canvas.width, canvas.height); - pixels = new Uint8ClampedArray(wfc.memory.buffer, wfc.getPixels(), width * height * 4); - requestAnimationFrame(loop); -} - -let sum = 0; -let count = 0; - -async function loop() { - const start = performance.now(); - wfc.step(); - const end = performance.now(); - - sum += end - start; - count++; - - imageData.data.set(pixels); - - context.putImageData(imageData, 0, 0); - context.clearRect(0, 0, 35, 15); - context.fillText(`${(sum / count).toFixed(1)} ms`, 2, 10); - requestAnimationFrame(loop); -} \ No newline at end of file diff --git a/src/games/wfc/wfc.c b/src/games/wfc/wfc.c deleted file mode 100644 index 2f0396b..0000000 --- a/src/games/wfc/wfc.c +++ /dev/null @@ -1,211 +0,0 @@ -#include - -#define PATTERN_SIZE 3 -#define PATTERN_BATCH 8 - -typedef struct { - uint32_t neighbours[9]; -} pattern_t; - -typedef struct { - /** pattern indices */ - uint32_t* possibilities; - uint32_t num_possibilities; -} superposition_t; - -typedef enum { NORTH, EAST, SOUTH, WEST, DIRECTION_MAX } direction_t; - -pattern_t* patterns; -uint32_t num_patterns; - -uint32_t* pixels; -superposition_t* superpositions; -uint32_t width; -uint32_t height; - -void patterns_init(uint32_t* pixel_data, uint16_t image_width, uint16_t image_height); -void superposition_init(void); - -EXPORT(init) void init(uint32_t* pixel_data, uint16_t image_width, uint16_t image_height, uint16_t canvas_width, uint16_t canvas_height) { - width = canvas_width; - height = canvas_height; - - patterns_init(pixel_data, image_width, image_height); - superposition_init(); -} - -pattern_t pattern_extract(uint32_t* pixel_data, uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t batch) { - pattern_t pattern = {0}; - - for (uint8_t i = 0; i < PATTERN_SIZE * PATTERN_SIZE; i++) { - int8_t dx = (i % PATTERN_SIZE) - (PATTERN_SIZE / 2); - int8_t dy = (i / PATTERN_SIZE) - (PATTERN_SIZE / 2); - - int8_t tmp; - - if (batch == 1) { // horizontal flip - dx = PATTERN_SIZE - dx; - } else if (batch == 2) { // vertical flip - dy = PATTERN_SIZE - dy; - } else if (batch == 3) { // both flips - dx = PATTERN_SIZE - dx; - dy = PATTERN_SIZE - dy; - } else if (batch == 4) { // rotate 90 - tmp = dx; - dx = dy; - dy = PATTERN_SIZE - tmp; - } else if (batch == 5) { // rotate 270 - tmp = dy; - dy = dx; - dx = PATTERN_SIZE - tmp; - } else if (batch == 6) { // flip main axis - tmp = dy; - dy = dx; - dx = tmp; - } else if (batch == 7) { // flip secondary axis - tmp = dy; - dy = PATTERN_SIZE - dx; - dx = PATTERN_SIZE - tmp; - } - - uint16_t xx = (x + dx + width) % width; - uint16_t yy = (y + dy + height) % height; - - uint32_t idx = xx + yy * width; - pattern.neighbours[i] = pixel_data[idx]; - } - return pattern; -} - -bool pattern_check(pattern_t pattern) { - for (uint32_t i = 0; i < num_patterns; i++) { - if (memcmp(&pattern, &patterns[i], sizeof(pattern)) == 0) { - return false; // found duplicate - } - } - return true; -} - -void patterns_init(uint32_t* pixel_data, uint16_t image_width, uint16_t image_height) { - uint32_t max_patterns = image_width * image_height * PATTERN_BATCH; - patterns = malloc(max_patterns * sizeof(*patterns)); - - num_patterns = 0; - - for (uint16_t y = 0; y < image_height; y++) { - for (uint16_t x = 0; x < image_width; x++) { - for (uint8_t batch = 0; batch < PATTERN_BATCH; batch++) { - pattern_t pattern = pattern_extract(pixel_data, x, y, image_width, image_height, batch); - if (pattern_check(pattern)) { - patterns[num_patterns++] = pattern; - } - } - } - } - - log("num=%u, max=%u", num_patterns, max_patterns); -} - -void superposition_init(void) { - pixels = malloc(width * height * sizeof(*pixels)); - superpositions = malloc(width * height * sizeof(*superpositions)); - - for (uint32_t i = 0; i < width * height; i++) { - superposition_t superposition = { - .num_possibilities = num_patterns, - .possibilities = malloc(num_patterns * sizeof(uint32_t)), - }; - - for (uint32_t p = 0; p < num_patterns; p++) { - superposition.possibilities[p] = p; - } - - superpositions[i] = superposition; - } -} - -bool pattern_match(pattern_t a, pattern_t b, direction_t direction) { - switch (direction) { - case NORTH: - for (uint8_t x = 0; x < PATTERN_SIZE; x++) { - if (a.neighbours[x] != b.neighbours[PATTERN_SIZE * (PATTERN_SIZE - 1) + x]) { - return false; - } - } - return true; - case EAST: - for (uint8_t y = 0; y < PATTERN_SIZE; y++) { - if (a.neighbours[y * PATTERN_SIZE + PATTERN_SIZE - 1] != b.neighbours[y * PATTERN_SIZE]) { - return false; - } - } - return true; - case SOUTH: - for (uint8_t x = 0; x < PATTERN_SIZE; x++) { - if (a.neighbours[PATTERN_SIZE * (PATTERN_SIZE - 1) + x] != b.neighbours[x]) { - return false; - } - } - return true; - case WEST: - for (uint8_t y = 0; y < PATTERN_SIZE; y++) { - if (a.neighbours[y * PATTERN_SIZE] != b.neighbours[y * PATTERN_SIZE + PATTERN_SIZE - 1]) { - return false; - } - } - return true; - default: - return false; - } -} - -void superposition_remove(superposition_t* superposition, uint32_t pattern) { - uint32_t i; - for (i = 0; i < superposition->num_possibilities; i++) { - if (superposition->possibilities[i] == pattern) - break; - } - - if (i < superposition->num_possibilities) { - for (; i < superposition->num_possibilities - 1; i++) { - superposition->possibilities[i] = superposition->possibilities[i + 1]; - } - superposition->num_possibilities--; - } -} - -void superpositions_draw(void) { - for (uint32_t i = 0; i < width * height; i++) { - uint64_t sum = 0; - superposition_t superposition = superpositions[i]; - for (uint32_t p = 0; p < superposition.num_possibilities; p++) { - sum += patterns[superposition.possibilities[p]].neighbours[(PATTERN_SIZE * PATTERN_SIZE) / 2]; - } - if (superposition.num_possibilities > 0) { - pixels[i] = sum / superposition.num_possibilities; - } else { - pixels[i] = 0; - } - } -} - -void superpositions_propagate(void) { - // TODO -} - -void superposition_collapse(superposition_t* superposition) { - if (superposition->num_possibilities > 1) { - uint32_t choice = rand() % superposition->num_possibilities; - superposition->possibilities[0] = superposition->possibilities[choice]; - superposition->num_possibilities = 1; - - superpositions_propagate(); - } -} - -EXPORT(step) void step(void) { - superposition_collapse(&superpositions[420]); - superpositions_draw(); -} - -EXPORT(getPixels) uint32_t* get_pixels(void) { return pixels; } diff --git a/src/types.d.ts b/src/types.d.ts index 2f8610a..a361b4b 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -44,9 +44,6 @@ declare module "*.c" { const instance: { memory: WebAssembly.Memory; data: DataView; - malloc: (size: number) => number; - free: (ptr: number) => void; - realloc: (ptr: number, size: number) => number; [x: string]: (...args: any) => any; }; @@ -56,9 +53,6 @@ declare module "*.cpp" { const instance: { memory: WebAssembly.Memory; data: DataView; - malloc: (size: number) => void; - free: (ptr: number) => void; - realloc: (ptr: number, size: number) => number; [x: string]: (...args: any) => any; };