1
0
Fork 0

Fix printf

This commit is contained in:
Pabloader 2025-05-12 17:58:41 +00:00
parent f5a09d3f44
commit 4c17d32e4c
8 changed files with 10 additions and 270 deletions

View File

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

View File

@ -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) {

View File

@ -1,5 +1,5 @@
#include <stdlib.h>
EXPORT(cpptest) void cpptest() {
printf("Awoo d=%d d2=%d", 69llu, 42ll);
printf("Awoo! %t%%");
}

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 204 B

View File

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

View File

@ -1,211 +0,0 @@
#include <stdlib.h>
#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; }

6
src/types.d.ts vendored
View File

@ -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;
};