Skip to content
Snippets Groups Projects
Verified Commit ce859537 authored by João Magalhães's avatar João Magalhães :rocket:
Browse files

feat: initial working WASM for web

parent 5ac8f130
No related branches found
No related tags found
1 merge request!4Support for WASM 🤖
Pipeline #638 passed
......@@ -26,6 +26,10 @@ export class Chip8Neo {
*/
reset_hard_ws(): void;
/**
* @returns {Uint8Array}
*/
vram_ws(): Uint8Array;
/**
*/
clock_ws(): void;
}
......@@ -41,8 +45,11 @@ export interface InitOutput {
readonly chip8neo_load_rom_ws: (a: number, b: number, c: number) => void;
readonly chip8neo_reset_ws: (a: number) => void;
readonly chip8neo_reset_hard_ws: (a: number) => void;
readonly chip8neo_vram_ws: (a: number, b: number) => void;
readonly chip8neo_clock_ws: (a: number) => void;
readonly __wbindgen_malloc: (a: number) => number;
readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
readonly __wbindgen_free: (a: number, b: number) => void;
readonly __wbindgen_exn_store: (a: number) => void;
}
......
......@@ -67,6 +67,18 @@ function passArray8ToWasm0(arg, malloc) {
return ptr;
}
let cachedInt32Memory0;
function getInt32Memory0() {
if (cachedInt32Memory0.byteLength === 0) {
cachedInt32Memory0 = new Int32Array(wasm.memory.buffer);
}
return cachedInt32Memory0;
}
function getArrayU8FromWasm0(ptr, len) {
return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);
}
function logError(f, args) {
try {
return f.apply(this, args);
......@@ -90,10 +102,6 @@ function handleError(f, args) {
wasm.__wbindgen_exn_store(addHeapObject(e));
}
}
function getArrayU8FromWasm0(ptr, len) {
return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);
}
/**
*/
export class Chip8Classic {
......@@ -176,6 +184,24 @@ export class Chip8Neo {
wasm.chip8neo_reset_hard_ws(this.ptr);
}
/**
* @returns {Uint8Array}
*/
vram_ws() {
try {
if (this.ptr == 0) throw new Error('Attempt to use a moved value');
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
_assertNum(this.ptr);
wasm.chip8neo_vram_ws(retptr, this.ptr);
var r0 = getInt32Memory0()[retptr / 4 + 0];
var r1 = getInt32Memory0()[retptr / 4 + 1];
var v0 = getArrayU8FromWasm0(r0, r1).slice();
wasm.__wbindgen_free(r0, r1 * 1);
return v0;
} finally {
wasm.__wbindgen_add_to_stack_pointer(16);
}
}
/**
*/
clock_ws() {
if (this.ptr == 0) throw new Error('Attempt to use a moved value');
......@@ -341,6 +367,7 @@ function initMemory(imports, maybe_memory) {
function finalizeInit(instance, module) {
wasm = instance.exports;
init.__wbindgen_wasm_module = module;
cachedInt32Memory0 = new Int32Array(wasm.memory.buffer);
cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer);
......
No preview for this file type
......@@ -8,6 +8,9 @@ export function chip8neo_new(): number;
export function chip8neo_load_rom_ws(a: number, b: number, c: number): void;
export function chip8neo_reset_ws(a: number): void;
export function chip8neo_reset_hard_ws(a: number): void;
export function chip8neo_vram_ws(a: number, b: number): void;
export function chip8neo_clock_ws(a: number): void;
export function __wbindgen_malloc(a: number): number;
export function __wbindgen_add_to_stack_pointer(a: number): number;
export function __wbindgen_free(a: number, b: number): void;
export function __wbindgen_exn_store(a: number): void;
......@@ -4,6 +4,7 @@
<title>CHIP-Ahoyto</title>
</head>
<body>
<canvas id="chip-canvas" width="960" height="480"></canvas>
<script type="module" src="./index.js"></script>
</body>
</html>
import { default as wasm, Chip8Neo } from "./chip_ahoyto.js";
import {
default as wasm,
Chip8Neo
} from "./chip_ahoyto.js";
const PIXEL_SET_COLOR = 0x50cb93ff;
const PIXEL_UNSET_COLOR = 0x1b1a17ff;
const state = {
canvas: null,
canvasScaled: null,
canvasCtx: null,
canvasScaledCtx: null,
image: null,
videoBuff: null
};
(async () => {
// initializes the WASM module, this is required
......@@ -7,8 +22,10 @@ import { default as wasm, Chip8Neo } from "./chip_ahoyto.js";
const ROM = "roms/ibm_logo.ch8";
console.info("LOADED");
console.info("System Loaded!");
// loads the ROM data and converts it into the
// target u8 array bufffer
const response = await fetch(ROM);
const blob = await response.blob();
const arrayBuffer = await blob.arrayBuffer();
......@@ -19,7 +36,43 @@ import { default as wasm, Chip8Neo } from "./chip_ahoyto.js";
chip8.reset_hard_ws();
chip8.load_rom_ws(data);
console.info(`Loaded ${ROM}`);
console.info(`ROM Loaded ${ROM}`);
chip8.clock_ws();
initCanvas();
while (true) {
chip8.clock_ws();
updateCanvas(chip8.vram_ws());
// hack
await new Promise((resolve, reject) => {
setTimeout(resolve, 100);
})
}
})();
const initCanvas = () => {
// initializes the off-screen canvas that is going to be
// used in the drawing proces
state.canvas = document.createElement("canvas");
state.canvas.width = 64;
state.canvas.height = 32;
state.canvasCtx = state.canvas.getContext("2d");
state.canvasScaled = document.getElementById("chip-canvas");
state.canvasScaledCtx = state.canvasScaled.getContext("2d");
state.canvasScaledCtx.scale(state.canvasScaled.width / state.canvas.width, state.canvasScaled.height / state.canvas.height);
state.canvasScaledCtx.imageSmoothingEnabled = false;
state.image = state.canvasCtx.createImageData(state.canvas.width, state.canvas.height);
state.videoBuff = new DataView(state.image.data.buffer);
}
const updateCanvas = (pixels) => {
for (let i = 0; i < pixels.length; i++) {
state.videoBuff.setUint32(i * 4, pixels[i] ? PIXEL_SET_COLOR : PIXEL_UNSET_COLOR);
}
state.canvasCtx.putImageData(state.image, 0, 0);
state.canvasScaledCtx.drawImage(state.canvas, 0, 0);
}
......@@ -378,6 +378,10 @@ impl Chip8Neo {
self.reset_hard()
}
pub fn vram_ws(&self) -> Vec<u8> {
self.vram()
}
pub fn clock_ws(&mut self) {
self.clock()
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment