From f19d0c87ed0cfa828f8f1909e311e47c1ae8f9a5 Mon Sep 17 00:00:00 2001 From: Evan Martin Date: Thu, 27 Feb 2025 09:43:09 -0800 Subject: [PATCH] ddraw: show canvas inline in debugger --- web/debugger/ddraw.tsx | 20 +++++++++++--- web/debugger/debugger.tsx | 2 +- web/glue/src/debugger.rs | 58 +++++++++++++++++++++++---------------- web/glue/src/emulator.rs | 4 +-- web/glue/src/host.rs | 4 +-- 5 files changed, 55 insertions(+), 33 deletions(-) diff --git a/web/debugger/ddraw.tsx b/web/debugger/ddraw.tsx index 55ed1122..c7dd0905 100644 --- a/web/debugger/ddraw.tsx +++ b/web/debugger/ddraw.tsx @@ -4,14 +4,25 @@ import { MemoryView, Number } from './memory'; namespace DirectDraw { export interface Props extends MemoryView { - state: wasm.DirectDrawState; + surfaces: wasm.SurfaceDebug[]; + } + export interface State { + hover?: wasm.SurfaceDebug; } } -export class DirectDraw extends preact.Component { +export class DirectDraw extends preact.Component { + canvasContainer = (parent: HTMLElement | null) => { + if (!parent) return; + parent.appendChild(this.state.hover!.canvas); + }; + render() { - const rows = this.props.state.surfaces.map((surface) => { + const rows = this.props.surfaces.map((surface) => { return ( - + this.setState({ hover: surface })} + onMouseLeave={() => this.setState({ hover: undefined })} + > {surface.ptr} @@ -34,6 +45,7 @@ export class DirectDraw extends preact.Component { {rows} + {this.state.hover &&
}
); } diff --git a/web/debugger/debugger.tsx b/web/debugger/debugger.tsx index 61b0e4ec..f567308b 100644 --- a/web/debugger/debugger.tsx +++ b/web/debugger/debugger.tsx @@ -285,7 +285,7 @@ export class Debugger extends preact.Component { /> ), - directdraw: () => , + directdraw: () => , }} selected={this.state.selectedTab} switchTab={(selectedTab) => this.setState({ selectedTab })} diff --git a/web/glue/src/debugger.rs b/web/glue/src/debugger.rs index 1db8016a..44a6a22d 100644 --- a/web/glue/src/debugger.rs +++ b/web/glue/src/debugger.rs @@ -1,6 +1,9 @@ //! API used specifically for debugging the emulator. -use tsify::Tsify; +use tsify::{JsValueSerdeExt, Tsify}; +use wasm_bindgen::prelude::*; + +use crate::host::WebSurface; /// Registers are serialized as a JSON blob. #[derive(Tsify, serde::Serialize)] @@ -51,8 +54,13 @@ impl Registers { } } +#[wasm_bindgen(typescript_custom_section)] +const SURFACE_META_TS: &'static str = r#" +export type SurfaceDebug = DirectDrawSurfaceMeta & { canvas: HTMLCanvasElement }; +"#; + #[derive(Tsify, serde::Serialize)] -pub struct DirectDrawSurface { +pub struct DirectDrawSurfaceMeta { pub ptr: u32, pub width: u32, pub height: u32, @@ -64,27 +72,29 @@ pub struct DirectDrawSurface { // pub attached: u32, } -#[derive(Tsify, serde::Serialize)] -#[tsify(into_wasm_abi)] -pub struct DirectDrawState { - surfaces: Vec, -} +pub fn surfaces_from_machine(machine: &win32::Machine) -> Vec { + machine + .state + .ddraw + .surfaces + .iter() + .map(|(&ptr, s)| { + let meta = DirectDrawSurfaceMeta { + ptr, + width: s.width, + height: s.height, + bytes_per_pixel: s.bytes_per_pixel, + primary: s.primary, + }; -impl DirectDrawState { - pub fn from_machine(machine: &win32::Machine) -> DirectDrawState { - let ddraw = &machine.state.ddraw; - DirectDrawState { - surfaces: ddraw - .surfaces - .iter() - .map(|(&ptr, s)| DirectDrawSurface { - ptr, - width: s.width, - height: s.height, - bytes_per_pixel: s.bytes_per_pixel, - primary: s.primary, - }) - .collect(), - } - } + // Attach canvas property to JS object we create from meta. + let val = JsValue::from_serde(&meta).unwrap(); + let web_surface = + unsafe { &*(s.host.as_ref() as *const dyn win32::Surface as *const WebSurface) }; + js_sys::Reflect::set(&val, &"canvas".into(), &web_surface.canvas.clone().into()) + .unwrap(); + + val + }) + .collect() } diff --git a/web/glue/src/emulator.rs b/web/glue/src/emulator.rs index 80316384..e8db275c 100644 --- a/web/glue/src/emulator.rs +++ b/web/glue/src/emulator.rs @@ -124,8 +124,8 @@ impl Emulator { win32::winapi::trace::set_scheme(scheme); } - pub fn directdraw_state(&self) -> debugger::DirectDrawState { - debugger::DirectDrawState::from_machine(&self.machine) + pub fn direct_draw_surfaces(&self) -> Vec { + debugger::surfaces_from_machine(&self.machine) } } diff --git a/web/glue/src/host.rs b/web/glue/src/host.rs index d23e4c4a..9b6f5749 100644 --- a/web/glue/src/host.rs +++ b/web/glue/src/host.rs @@ -16,9 +16,9 @@ use win32::{Stat, StatKind, WindowsPath}; /// /// https://developer.chrome.com/blog/taking-advantage-of-gpu-acceleration-in-the-2d-canvas /// https://web.dev/articles/canvas-performance -struct WebSurface { +pub struct WebSurface { _hwnd: u32, - canvas: web_sys::HtmlCanvasElement, + pub canvas: web_sys::HtmlCanvasElement, width: u32, ctx: web_sys::CanvasRenderingContext2d, screen: web_sys::CanvasRenderingContext2d,