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