diff --git a/frontend/Cargo.toml b/frontend/Cargo.toml index 5965dbd..3b27ead 100644 --- a/frontend/Cargo.toml +++ b/frontend/Cargo.toml @@ -20,6 +20,7 @@ emu = { path = "../emu" } egui = "0.20.1" eframe = { version = "0.20.1", features = ["persistence"] } +egui_memory_editor = "0.1.0" # serde = { version = "1", features = ["derive"] } # You only need this if you want app persistence # native: diff --git a/frontend/src/app.rs b/frontend/src/app.rs index e079089..79b6f1a 100644 --- a/frontend/src/app.rs +++ b/frontend/src/app.rs @@ -97,9 +97,7 @@ impl eframe::App for App { // debug stuff - crate::debug::palette::palette_window(&ctx, &self.emu); - - self.debug.vram.render(&ctx, &self.emu); + self.debug.render(&ctx, &self.emu); egui::CentralPanel::default().show(ctx, |ui| { egui::warn_if_debug_build(ui); @@ -119,63 +117,7 @@ impl eframe::App for App { if self.test_vec.len() > 60 { self.test_vec.pop_front(); } - - use egui::plot::{ - Bar, BarChart, Legend, Plot, - }; - let chart = BarChart::new( - self.test_vec - .iter() - .enumerate() - .map(|(i, x)| Bar::new((i + 1) as _, *x as f64)) - .collect() - - ) - .color(egui::Color32::LIGHT_BLUE) - .name("Normal Distribution"); - // if !self.vertical { - // chart = chart.horizontal(); - // } - - Plot::new("Normal Distribution Demo") - .width(200.) - .height(100.) - .legend(Legend::default()) - .data_aspect(1.0) - .show(ui, |plot_ui| plot_ui.bar_chart(chart)) - .response }); - // TODO debug module - - egui::Window::new("cpu") - .min_width(800.) - .show(ctx, |ui| { - let mut debug = String::new(); - debug.push_str(&format!("PC: {:X}\n\n", self.emu.core.pc)); - - - // let v = self.emu.core.mem.vdp.VSRAM.iter().map(|x|format!("{:X}", x)).collect::>().join(" "); - // debug.push_str(&format!("VSRAM: {}\n\n", v)); - - debug.push_str(&format!("D ")); - for i in 0..=7 { - debug.push_str(&format!("{:X} ", self.emu.core.dar[i])); - } - debug.push_str(&format!("\n")); - - debug.push_str(&format!("A ")); - for i in 0..=7 { - debug.push_str(&format!("{:X} ", self.emu.core.dar[i + 8])); - } - debug.push_str(&format!("\n")); - debug.push_str(&format!("\n")); - - for (pc, opcode) in emu::debug::disasm_demo(&self.emu) { - debug.push_str(&format!("0x{:X}\t{}\n", pc, opcode)); - } - ui.label(&debug); - }); - } } diff --git a/frontend/src/debug/cpu.rs b/frontend/src/debug/cpu.rs new file mode 100644 index 0000000..3838513 --- /dev/null +++ b/frontend/src/debug/cpu.rs @@ -0,0 +1,30 @@ +pub fn cpu_window(ctx: &egui::Context, emu: &emu::Megadrive) { + egui::Window::new("cpu") + .min_width(800.) + .show(ctx, |ui| { + let mut debug = String::new(); + debug.push_str(&format!("PC: {:X}\n\n", emu.core.pc)); + + + // let v = emu.core.mem.vdp.VSRAM.iter().map(|x|format!("{:X}", x)).collect::>().join(" "); + // debug.push_str(&format!("VSRAM: {}\n\n", v)); + + debug.push_str(&format!("D ")); + for i in 0..=7 { + debug.push_str(&format!("{:X} ", emu.core.dar[i])); + } + debug.push_str(&format!("\n")); + + debug.push_str(&format!("A ")); + for i in 0..=7 { + debug.push_str(&format!("{:X} ", emu.core.dar[i + 8])); + } + debug.push_str(&format!("\n")); + debug.push_str(&format!("\n")); + + for (pc, opcode) in emu::debug::disasm_demo(&emu) { + debug.push_str(&format!("0x{:X}\t{}\n", pc, opcode)); + } + ui.label(&debug); + }); +} diff --git a/frontend/src/debug/mod.rs b/frontend/src/debug/mod.rs index b71d702..6ca1bb8 100644 --- a/frontend/src/debug/mod.rs +++ b/frontend/src/debug/mod.rs @@ -1,4 +1,8 @@ pub mod palette; +pub mod vram; +pub mod cpu; + +use vram::VRAM; pub struct Debug { pub vram: VRAM, @@ -12,74 +16,10 @@ impl Default for Debug { } } -pub struct VRAM { - palette_line: usize, -} - -impl Default for VRAM { - fn default() -> Self { - Self { - palette_line: 0, - } - } -} - -impl VRAM { +impl Debug { pub fn render(&mut self, ctx: &egui::Context, emu: &emu::Megadrive) { - egui::Window::new("vram") - .vscroll(true) - // TODO: only show onscreen ram" - // TODO: show_rows - .show(ctx, |ui| { - ui.horizontal(|ui| { - ui.radio_value(&mut self.palette_line, 0, "0"); - ui.radio_value(&mut self.palette_line, 1, "1"); - ui.radio_value(&mut self.palette_line, 2, "2"); - ui.radio_value(&mut self.palette_line, 3, "3"); - }); - - const WIDTH: usize = 16; - const HEIGHT: usize = 128; - const PIXEL_QTY: usize = (WIDTH * 8) * (HEIGHT * 8); - // TODO use retained buffer - let mut pixels: [egui::Color32; PIXEL_QTY] = [ egui::Color32::from_rgb(0, 0, 0); PIXEL_QTY]; - - let palette_offset = self.palette_line * 0x10; - for x_tile in 0..WIDTH { - for y_tile in 0..HEIGHT { - let offset = x_tile + (y_tile * WIDTH); - let vram_offset = offset * 32; - let mut view_offset = (x_tile * 8) + (y_tile * 8 * (WIDTH * 8)); - - for duxel in &emu.core.mem.vdp.VRAM[vram_offset..vram_offset+32] { - let pixel = (*duxel & 0xF0) >> 4; - - let (r, g, b) = emu.core.mem.vdp.cram_rgb[palette_offset + pixel as usize]; - pixels[view_offset] = egui::Color32::from_rgb(r, g, b); - view_offset += 1; - let pixel = *duxel & 0xF; - let (r, g, b) = emu.core.mem.vdp.cram_rgb[palette_offset + pixel as usize]; - pixels[view_offset] = egui::Color32::from_rgb(r, g, b); - view_offset += 1; - if view_offset % 8 == 0 { - view_offset += (WIDTH-1) * 8; - } - } - - } - } - - let texture: &egui::TextureHandle = &ui.ctx().load_texture( - "vram", - egui::ColorImage { - size: [WIDTH*8, HEIGHT*8], - pixels: pixels.to_vec(), - }, - egui::TextureOptions::NEAREST - ); - let img = egui::Image::new(texture, texture.size_vec2() * 2.); - - ui.add(img); - }); + cpu::cpu_window(&ctx, &emu); + palette::palette_window(&ctx, &emu); + self.vram.render(&ctx, &emu); } } diff --git a/frontend/src/debug/vram.rs b/frontend/src/debug/vram.rs new file mode 100644 index 0000000..367ff30 --- /dev/null +++ b/frontend/src/debug/vram.rs @@ -0,0 +1,71 @@ +pub struct VRAM { + palette_line: usize, +} + +impl Default for VRAM { + fn default() -> Self { + Self { + palette_line: 0, + } + } +} + +impl VRAM { + pub fn render(&mut self, ctx: &egui::Context, emu: &emu::Megadrive) { + egui::Window::new("vram") + .vscroll(true) + // TODO: only show onscreen ram" + // TODO: show_rows + .show(ctx, |ui| { + ui.horizontal(|ui| { + ui.radio_value(&mut self.palette_line, 0, "0"); + ui.radio_value(&mut self.palette_line, 1, "1"); + ui.radio_value(&mut self.palette_line, 2, "2"); + ui.radio_value(&mut self.palette_line, 3, "3"); + }); + + const WIDTH: usize = 16; + const HEIGHT: usize = 128; + const PIXEL_QTY: usize = (WIDTH * 8) * (HEIGHT * 8); + // TODO use retained buffer + let mut pixels: [egui::Color32; PIXEL_QTY] = [ egui::Color32::from_rgb(0, 0, 0); PIXEL_QTY]; + + let palette_offset = self.palette_line * 0x10; + for x_tile in 0..WIDTH { + for y_tile in 0..HEIGHT { + let offset = x_tile + (y_tile * WIDTH); + let vram_offset = offset * 32; + let mut view_offset = (x_tile * 8) + (y_tile * 8 * (WIDTH * 8)); + + for duxel in &emu.core.mem.vdp.VRAM[vram_offset..vram_offset+32] { + let pixel = (*duxel & 0xF0) >> 4; + + let (r, g, b) = emu.core.mem.vdp.cram_rgb[palette_offset + pixel as usize]; + pixels[view_offset] = egui::Color32::from_rgb(r, g, b); + view_offset += 1; + let pixel = *duxel & 0xF; + let (r, g, b) = emu.core.mem.vdp.cram_rgb[palette_offset + pixel as usize]; + pixels[view_offset] = egui::Color32::from_rgb(r, g, b); + view_offset += 1; + if view_offset % 8 == 0 { + view_offset += (WIDTH-1) * 8; + } + } + + } + } + + let texture: &egui::TextureHandle = &ui.ctx().load_texture( + "vram", + egui::ColorImage { + size: [WIDTH*8, HEIGHT*8], + pixels: pixels.to_vec(), + }, + egui::TextureOptions::NEAREST + ); + let img = egui::Image::new(texture, texture.size_vec2() * 2.); + + ui.add(img); + }); + } +}