Skip to content

Commit

Permalink
ddraw: show canvas inline in debugger
Browse files Browse the repository at this point in the history
  • Loading branch information
evmar committed Feb 27, 2025
1 parent 1c69df0 commit f19d0c8
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 33 deletions.
20 changes: 16 additions & 4 deletions web/debugger/ddraw.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<DirectDraw.Props> {
export class DirectDraw extends preact.Component<DirectDraw.Props, DirectDraw.State> {
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 (
<tr>
<tr
onMouseEnter={() => this.setState({ hover: surface })}
onMouseLeave={() => this.setState({ hover: undefined })}
>
<td style={{ textAlign: 'right' }}>
<Number digits={8} {...this.props}>{surface.ptr}</Number>
</td>
Expand All @@ -34,6 +45,7 @@ export class DirectDraw extends preact.Component<DirectDraw.Props> {
</tr>
{rows}
</table>
{this.state.hover && <div ref={this.canvasContainer} />}
</div>
);
}
Expand Down
2 changes: 1 addition & 1 deletion web/debugger/debugger.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ export class Debugger extends preact.Component<Debugger.Props, Debugger.State> {
/>
),

directdraw: () => <DirectDraw state={emulator.emu.directdraw_state()} {...this.memoryView} />,
directdraw: () => <DirectDraw surfaces={emulator.emu.direct_draw_surfaces()} {...this.memoryView} />,
}}
selected={this.state.selectedTab}
switchTab={(selectedTab) => this.setState({ selectedTab })}
Expand Down
58 changes: 34 additions & 24 deletions web/glue/src/debugger.rs
Original file line number Diff line number Diff line change
@@ -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)]
Expand Down Expand Up @@ -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,
Expand All @@ -64,27 +72,29 @@ pub struct DirectDrawSurface {
// pub attached: u32,
}

#[derive(Tsify, serde::Serialize)]
#[tsify(into_wasm_abi)]
pub struct DirectDrawState {
surfaces: Vec<DirectDrawSurface>,
}
pub fn surfaces_from_machine(machine: &win32::Machine) -> Vec<JsValue> {
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()
}
4 changes: 2 additions & 2 deletions web/glue/src/emulator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<JsValue> {
debugger::surfaces_from_machine(&self.machine)
}
}

Expand Down
4 changes: 2 additions & 2 deletions web/glue/src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit f19d0c8

Please sign in to comment.