From 5259d6ee8cd588f59d7753f1366d710f8a377862 Mon Sep 17 00:00:00 2001 From: Ross Andrews Date: Wed, 1 Feb 2023 20:31:06 -0600 Subject: [PATCH] Uninitialized canvas display --- vweb/Cargo.toml | 8 ++++++++ vweb/src/emulator_display.jsx | 17 +++++++++++++++++ vweb/src/lib.rs | 14 +++++++++++++- vweb/src/snippet_emulator.css | 4 ++-- vweb/src/snippet_emulator.jsx | 2 +- vweb/src/snippet_emulator_demo.html | 1 + vweb/src/snippet_emulator_demo.jsx | 4 ++++ 7 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 vweb/src/emulator_display.jsx diff --git a/vweb/Cargo.toml b/vweb/Cargo.toml index 8ff522c..5cb5aea 100644 --- a/vweb/Cargo.toml +++ b/vweb/Cargo.toml @@ -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', +] \ No newline at end of file diff --git a/vweb/src/emulator_display.jsx b/vweb/src/emulator_display.jsx new file mode 100644 index 0000000..57bf35b --- /dev/null +++ b/vweb/src/emulator_display.jsx @@ -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 ( + + ) +} \ No newline at end of file diff --git a/vweb/src/lib.rs b/vweb/src/lib.rs index 1d2419b..9cb4f79 100644 --- a/vweb/src/lib.rs +++ b/vweb/src/lib.rs @@ -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) + } } diff --git a/vweb/src/snippet_emulator.css b/vweb/src/snippet_emulator.css index 105c88c..e35ac33 100644 --- a/vweb/src/snippet_emulator.css +++ b/vweb/src/snippet_emulator.css @@ -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; } diff --git a/vweb/src/snippet_emulator.jsx b/vweb/src/snippet_emulator.jsx index 3aaf09d..a3b9ef4 100644 --- a/vweb/src/snippet_emulator.jsx +++ b/vweb/src/snippet_emulator.jsx @@ -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. diff --git a/vweb/src/snippet_emulator_demo.html b/vweb/src/snippet_emulator_demo.html index 109a7ba..be991c2 100644 --- a/vweb/src/snippet_emulator_demo.html +++ b/vweb/src/snippet_emulator_demo.html @@ -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.

+
         .org 0x400
diff --git a/vweb/src/snippet_emulator_demo.jsx b/vweb/src/snippet_emulator_demo.jsx
index 3669628..cd60ed3 100644
--- a/vweb/src/snippet_emulator_demo.jsx
+++ b/vweb/src/snippet_emulator_demo.jsx
@@ -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, {}))
+        })
     })
 })
\ No newline at end of file