smsgg.rsannotatedsmsgg.rssource134 lines · 4.2 KB · raw
1use crate::{DebugRenderContext, DebugRenderFn};
2use egui::{Grid, Pos2, ScrollArea, Vec2, Window};
3use jgenesis_common::frontend::Color;
4use smsgg_core::SmsGgEmulator;
5
6struct State {
7    vram_palette: u8,
8    cram_texture: Option<(wgpu::Texture, egui::TextureId)>,
9    vram_texture: Option<(wgpu::Texture, egui::TextureId)>,
10    cram_buffer: Box<[Color; 32]>,
11    vram_buffer: Box<[Color; 512 * 64]>,
12}
13
14impl State {
15    fn new() -> Self {
16        Self {
17            vram_palette: 0,
18            cram_texture: None,
19            vram_texture: None,
20            cram_buffer: vec![Color::default(); 32].into_boxed_slice().try_into().unwrap(),
21            vram_buffer: vec![Color::default(); 512 * 64].into_boxed_slice().try_into().unwrap(),
22        }
23    }
24}
25
26#[must_use]
27pub fn render_fn() -> Box<DebugRenderFn<SmsGgEmulator>> {
28    let mut state = State::new();
29    Box::new(move |ctx, emulator| render(ctx, emulator, &mut state))
30}
31
32fn render(mut ctx: DebugRenderContext<'_>, emulator: &mut SmsGgEmulator, state: &mut State) {
33    update_cram_texture(&mut ctx, emulator, state);
34    update_vram_texture(&mut ctx, emulator, state);
35
36    let screen_width = crate::screen_width(ctx.egui_ui);
37
38    Window::new("CRAM").default_width(screen_width * 0.95).show(ctx.egui_ui, |ui| {
39        let mut height = ui.available_width() * 0.125;
40        if height > ui.available_height() {
41            height = ui.available_height();
42        }
43        let width = height * 8.0;
44
45        let cram_texture = state.cram_texture.as_ref().unwrap().1;
46        ui.image((cram_texture, Vec2::new(width, height)));
47    });
48
49    Window::new("VRAM").default_width(screen_width * 0.95).show(ctx.egui_ui, |ui| {
50        ui.horizontal(|ui| {
51            ui.label("Palette");
52
53            ui.radio_value(&mut state.vram_palette, 0, "0");
54            ui.radio_value(&mut state.vram_palette, 1, "1");
55        });
56
57        ui.add_space(5.0);
58
59        let mut height = ui.available_width() * 0.5;
60        if height > ui.available_height() {
61            height = ui.available_height();
62        }
63        let width = height * 2.0;
64
65        let vram_texture = state.vram_texture.as_ref().unwrap().1;
66        ui.image((vram_texture, Vec2::new(width, height)));
67    });
68
69    Window::new("VDP Registers").default_open(false).default_pos(Pos2::new(5.0, 5.0)).show(
70        ctx.egui_ui,
71        |ui| {
72            ScrollArea::vertical().show(ui, |ui| {
73                Grid::new("smsgg_vdp_registers").num_columns(2).show(ui, |ui| {
74                    emulator.dump_vdp_registers(|register, fields| {
75                        ui.heading(format!("Register #{register}"));
76                        ui.end_row();
77
78                        for &(name, value) in fields {
79                            ui.label(format!("  {name}:"));
80                            ui.label(value);
81                            ui.end_row();
82                        }
83                    });
84                });
85            });
86        },
87    );
88}
89
90fn update_cram_texture(
91    ctx: &mut DebugRenderContext<'_>,
92    emulator: &mut SmsGgEmulator,
93    state: &mut State,
94) {
95    emulator.copy_cram(state.cram_buffer.as_mut());
96
97    if state.cram_texture.is_none() {
98        let (wgpu_texture, egui_texture) =
99            crate::create_texture("debug_smsgg_cram", 16, 2, ctx.device, ctx.renderer);
100        state.cram_texture = Some((wgpu_texture, egui_texture));
101    }
102
103    let (wgpu_texture, egui_texture) = state.cram_texture.as_ref().unwrap();
104
105    crate::write_textures(
106        wgpu_texture,
107        *egui_texture,
108        bytemuck::cast_slice(state.cram_buffer.as_ref()),
109        ctx,
110    );
111}
112
113fn update_vram_texture(
114    ctx: &mut DebugRenderContext<'_>,
115    emulator: &mut SmsGgEmulator,
116    state: &mut State,
117) {
118    emulator.copy_vram(state.vram_buffer.as_mut(), state.vram_palette, 32);
119
120    if state.vram_texture.is_none() {
121        let (wgpu_texture, egui_texture) =
122            crate::create_texture("debug_smsgg_vram", 32 * 8, 16 * 8, ctx.device, ctx.renderer);
123        state.vram_texture = Some((wgpu_texture, egui_texture));
124    }
125
126    let (wgpu_texture, egui_texture) = state.vram_texture.as_ref().unwrap();
127
128    crate::write_textures(
129        wgpu_texture,
130        *egui_texture,
131        bytemuck::cast_slice(state.vram_buffer.as_ref()),
132        ctx,
133    );
134}