Uninitialized canvas display
This commit is contained in:
@@ -10,7 +10,15 @@ crate-type = ["cdylib"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
vcore = { path = "../vcore" }
|
vcore = { path = "../vcore" }
|
||||||
|
vgfx = { path = "../vgfx" }
|
||||||
vasm_core = { path = "../vasm_core" }
|
vasm_core = { path = "../vasm_core" }
|
||||||
wasm-bindgen = "0.2"
|
wasm-bindgen = "0.2"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde-wasm-bindgen = "0.4"
|
serde-wasm-bindgen = "0.4"
|
||||||
|
|
||||||
|
[dependencies.web-sys]
|
||||||
|
version = "0.3.4"
|
||||||
|
features = [
|
||||||
|
'CanvasRenderingContext2d',
|
||||||
|
'ImageData',
|
||||||
|
]
|
||||||
@@ -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
@@ -2,7 +2,10 @@ use wasm_bindgen::prelude::*;
|
|||||||
use vcore::{CPU, Word};
|
use vcore::{CPU, Word};
|
||||||
use vcore::memory::{PeekPoke, PeekPokeExt};
|
use vcore::memory::{PeekPoke, PeekPokeExt};
|
||||||
use vasm_core::parse_error::AssembleError;
|
use vasm_core::parse_error::AssembleError;
|
||||||
|
use vgfx::display;
|
||||||
use serde::{ Deserialize, Serialize };
|
use serde::{ Deserialize, Serialize };
|
||||||
|
use wasm_bindgen::Clamped;
|
||||||
|
use web_sys::{CanvasRenderingContext2d, ImageData};
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub struct NovaForth;
|
pub struct NovaForth;
|
||||||
@@ -65,7 +68,9 @@ pub fn source_map(snippet: String) -> JsValue {
|
|||||||
impl WasmCPU {
|
impl WasmCPU {
|
||||||
#[wasm_bindgen(constructor)]
|
#[wasm_bindgen(constructor)]
|
||||||
pub fn new() -> WasmCPU {
|
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) {
|
pub fn push_data(&mut self, data: i32) {
|
||||||
@@ -157,4 +162,11 @@ impl WasmCPU {
|
|||||||
pub fn tick(&mut self) {
|
pub fn tick(&mut self) {
|
||||||
self.0.tick()
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,13 +9,13 @@ body {
|
|||||||
grid-area: 2 / 2 / 3 / 3;
|
grid-area: 2 / 2 / 3 / 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main .snippet {
|
.main .snippet, .main .display {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-rows: auto;
|
grid-template-rows: auto;
|
||||||
grid-template-columns: 1fr auto 1fr;
|
grid-template-columns: 1fr auto 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
.snippet .snippetEmulator {
|
.main .snippet .snippetEmulator, .main .display canvas {
|
||||||
grid-area: 1 / 2 / 2 / 3;
|
grid-area: 1 / 2 / 2 / 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export default function({ children, width = 20 }) {
|
|||||||
const onChangeSrc = useCallback((e) => setSrc(e.target.value), []) // Callback for the textarea
|
const onChangeSrc = useCallback((e) => setSrc(e.target.value), []) // Callback for the textarea
|
||||||
const [binary, setBinary] = useState(null) // The assembled binary
|
const [binary, setBinary] = useState(null) // The assembled binary
|
||||||
const [sourceMap, setSourceMap] = useState(null) // A map from byte address to line number
|
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
|
const [activeLine, setActiveLine] = useState(null) // The (0-based) index of the
|
||||||
|
|
||||||
// Update which line is highlighted. This should be called in most button callbacks.
|
// Update which line is highlighted. This should be called in most button callbacks.
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
Quisque tristique diam et purus sagittis, posuere pharetra orci egestas. Praesent imperdiet sapien vel fermentum
|
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.
|
pulvinar. Nulla ac tortor laoreet, fringilla tellus nec, ullamcorper mi.
|
||||||
</p>
|
</p>
|
||||||
|
<div class="display"></div>
|
||||||
<div class="snippet" data-width="30">
|
<div class="snippet" data-width="30">
|
||||||
<pre>
|
<pre>
|
||||||
.org 0x400
|
.org 0x400
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { createRoot } from 'react-dom/client'
|
import { createRoot } from 'react-dom/client'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import SnippetEmulator from './snippet_emulator'
|
import SnippetEmulator from './snippet_emulator'
|
||||||
|
import EmulatorDisplay from './emulator_display'
|
||||||
import init, { WasmCPU, assemble_snippet } from '../pkg/vweb.js'
|
import init, { WasmCPU, assemble_snippet } from '../pkg/vweb.js'
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
@@ -9,5 +10,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
const props = { children: el.innerText, width: el.getAttribute('data-width') }
|
const props = { children: el.innerText, width: el.getAttribute('data-width') }
|
||||||
createRoot(el).render(React.createElement(SnippetEmulator, props))
|
createRoot(el).render(React.createElement(SnippetEmulator, props))
|
||||||
})
|
})
|
||||||
|
document.querySelectorAll('.display').forEach((el) => {
|
||||||
|
createRoot(el).render(React.createElement(EmulatorDisplay, {}))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
Reference in New Issue
Block a user