Uninitialized canvas display

This commit is contained in:
2023-02-01 20:31:06 -06:00
parent 910e4b856b
commit 5259d6ee8c
7 changed files with 46 additions and 4 deletions
+8
View File
@@ -10,7 +10,15 @@ crate-type = ["cdylib"]
[dependencies]
vcore = { path = "../vcore" }
vgfx = { path = "../vgfx" }
vasm_core = { path = "../vasm_core" }
wasm-bindgen = "0.2"
serde = { version = "1.0", features = ["derive"] }
serde-wasm-bindgen = "0.4"
[dependencies.web-sys]
version = "0.3.4"
features = [
'CanvasRenderingContext2d',
'ImageData',
]
+17
View File
@@ -0,0 +1,17 @@
import React, { useState, useCallback, useEffect, useRef } from 'react'
import { WasmCPU } from '../pkg/vweb.js'
export default function({}) {
const canvas = useRef(null)
const [ctx, setCtx] = useState(null)
const [cpu, _setCpu] = useState(new WasmCPU())
useEffect(() => {
const c = canvas.current.getContext('2d')
setCtx(c)
cpu.draw_frame(c)
}, [canvas.current])
return (
<canvas ref={canvas} width={640} height={480}></canvas>
)
}
+13 -1
View File
@@ -2,7 +2,10 @@ use wasm_bindgen::prelude::*;
use vcore::{CPU, Word};
use vcore::memory::{PeekPoke, PeekPokeExt};
use vasm_core::parse_error::AssembleError;
use vgfx::display;
use serde::{ Deserialize, Serialize };
use wasm_bindgen::Clamped;
use web_sys::{CanvasRenderingContext2d, ImageData};
#[wasm_bindgen]
pub struct NovaForth;
@@ -65,7 +68,9 @@ pub fn source_map(snippet: String) -> JsValue {
impl WasmCPU {
#[wasm_bindgen(constructor)]
pub fn new() -> WasmCPU {
WasmCPU(CPU::new_random())
let mut cpu = WasmCPU(CPU::new_random());
display::init_gfx(&mut cpu.0);
cpu
}
pub fn push_data(&mut self, data: i32) {
@@ -157,4 +162,11 @@ impl WasmCPU {
pub fn tick(&mut self) {
self.0.tick()
}
pub fn draw_frame(&self, ctx: &CanvasRenderingContext2d) -> Result<(), JsValue> {
let mut buf = [0u8; 640 * 480 * 4];
display::draw(&self.0, &mut buf);
let image_data = ImageData::new_with_u8_clamped_array(Clamped(&buf), 640)?;
ctx.put_image_data(&image_data, 0.0, 0.0)
}
}
+2 -2
View File
@@ -9,13 +9,13 @@ body {
grid-area: 2 / 2 / 3 / 3;
}
.main .snippet {
.main .snippet, .main .display {
display: grid;
grid-template-rows: auto;
grid-template-columns: 1fr auto 1fr;
}
.snippet .snippetEmulator {
.main .snippet .snippetEmulator, .main .display canvas {
grid-area: 1 / 2 / 2 / 3;
}
+1 -1
View File
@@ -21,7 +21,7 @@ export default function({ children, width = 20 }) {
const onChangeSrc = useCallback((e) => setSrc(e.target.value), []) // Callback for the textarea
const [binary, setBinary] = useState(null) // The assembled binary
const [sourceMap, setSourceMap] = useState(null) // A map from byte address to line number
const [cpu, setCpu] = useState(new WasmCPU()) // The actual CPU emulator itself
const [cpu, _setCpu] = useState(new WasmCPU()) // The actual CPU emulator itself
const [activeLine, setActiveLine] = useState(null) // The (0-based) index of the
// Update which line is highlighted. This should be called in most button callbacks.
+1
View File
@@ -15,6 +15,7 @@
Quisque tristique diam et purus sagittis, posuere pharetra orci egestas. Praesent imperdiet sapien vel fermentum
pulvinar. Nulla ac tortor laoreet, fringilla tellus nec, ullamcorper mi.
</p>
<div class="display"></div>
<div class="snippet" data-width="30">
<pre>
.org 0x400
+4
View File
@@ -1,6 +1,7 @@
import { createRoot } from 'react-dom/client'
import React from 'react'
import SnippetEmulator from './snippet_emulator'
import EmulatorDisplay from './emulator_display'
import init, { WasmCPU, assemble_snippet } from '../pkg/vweb.js'
document.addEventListener('DOMContentLoaded', () => {
@@ -9,5 +10,8 @@ document.addEventListener('DOMContentLoaded', () => {
const props = { children: el.innerText, width: el.getAttribute('data-width') }
createRoot(el).render(React.createElement(SnippetEmulator, props))
})
document.querySelectorAll('.display').forEach((el) => {
createRoot(el).render(React.createElement(EmulatorDisplay, {}))
})
})
})