mirror of
https://github.com/FranLMSP/snes.git
synced 2026-10-03 07:55:17 -04:00
WIP PPU registers and background rendering
This commit is contained in:
@@ -1 +1,2 @@
|
||||
pub mod ppu;
|
||||
pub mod state;
|
||||
@@ -16,6 +16,7 @@ use winit::{
|
||||
use snes_frontend::state::State;
|
||||
extern crate snes_core;
|
||||
use snes_core::emulator::Emulator;
|
||||
use snes_frontend::ppu as ppu_render;
|
||||
|
||||
fn main() {
|
||||
// Windowing state
|
||||
@@ -138,6 +139,12 @@ fn main() {
|
||||
},
|
||||
);
|
||||
let texture_id = renderer.textures.insert(texture);
|
||||
|
||||
for bgdebug in state.ppudebug.backgrounds.iter_mut() {
|
||||
bgdebug.texture_id = Some(
|
||||
ppu_render::background_texture(&device, &mut renderer, bgdebug.background)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Event loop
|
||||
@@ -238,6 +245,15 @@ fn main() {
|
||||
.size([300.0, 100.0], Condition::FirstUseEver)
|
||||
.opened(&mut state.debug_options.show_debug_window)
|
||||
.build(&ui, || {
|
||||
ui.checkbox(
|
||||
"Enable debugging",
|
||||
&mut state.debug_options.is_enabled,
|
||||
);
|
||||
ui.separator();
|
||||
ui.checkbox(
|
||||
"Show PPU debugging options",
|
||||
&mut state.ppudebug.is_enabled,
|
||||
);
|
||||
ui.checkbox(
|
||||
"Show CPU registers",
|
||||
&mut state.debug_options.show_cpu_registers,
|
||||
@@ -245,6 +261,34 @@ fn main() {
|
||||
});
|
||||
}
|
||||
|
||||
// Render all debugging stuff
|
||||
if state.debug_options.is_enabled {
|
||||
if state.ppudebug.is_enabled {
|
||||
let window = imgui::Window::new("PPU Debugging options");
|
||||
window
|
||||
.size([300.0, 400.0], Condition::FirstUseEver)
|
||||
.build(&ui, || {
|
||||
ui.text("Backgrounds:");
|
||||
|
||||
for bgdebug in state.ppudebug.backgrounds.iter_mut() {
|
||||
ui.checkbox(
|
||||
format!("Show {:?}", bgdebug.background),
|
||||
&mut bgdebug.is_enabled,
|
||||
);
|
||||
}
|
||||
});
|
||||
for bgdebug in state.ppudebug.backgrounds.iter_mut() {
|
||||
ppu_render::background_window(
|
||||
bgdebug,
|
||||
&emulator.bus.ppu.registers,
|
||||
&ui,
|
||||
&mut renderer,
|
||||
&queue,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Render emulator framebuffer
|
||||
{
|
||||
let tex = renderer.textures.get_mut(texture_id).unwrap();
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
extern crate snes_core;
|
||||
use snes_core::ppu::registers::{
|
||||
MAX_BG_WIDTH,
|
||||
MAX_BG_HEIGHT,
|
||||
PPURegisters,
|
||||
Background as PPUBg,
|
||||
};
|
||||
use imgui_wgpu::Renderer;
|
||||
use imgui::TextureId;
|
||||
use wgpu::{Device, Queue};
|
||||
use super::state::BgDebug;
|
||||
|
||||
|
||||
pub fn background_texture(
|
||||
device: &Device,
|
||||
renderer: &mut Renderer,
|
||||
background: PPUBg
|
||||
) -> TextureId {
|
||||
let texture = imgui_wgpu::Texture::new(
|
||||
device,
|
||||
renderer,
|
||||
imgui_wgpu::TextureConfig {
|
||||
label: Some(&format!("Background {:?} texture", background)),
|
||||
size: wgpu::Extent3d {
|
||||
width: MAX_BG_WIDTH as u32,
|
||||
height: MAX_BG_HEIGHT as u32,
|
||||
depth_or_array_layers: 1,
|
||||
},
|
||||
format: Some(wgpu::TextureFormat::Rgba8Unorm),
|
||||
..imgui_wgpu::TextureConfig::default()
|
||||
},
|
||||
);
|
||||
renderer.textures.insert(texture)
|
||||
}
|
||||
|
||||
fn render_background(bgdebug: &mut BgDebug, registers: &PPURegisters) {
|
||||
let (tile_width, tile_height) = registers.get_bg_tile_size(bgdebug.background).to_usize();
|
||||
let (bg_width, bg_height) = registers.get_bg_size(bgdebug.background).to_usize();
|
||||
let width = tile_width * bg_width;
|
||||
let height = tile_height * bg_height;
|
||||
for x in 0..width {
|
||||
for y in 0..height {
|
||||
let index = ((y * MAX_BG_WIDTH) + x) * 4;
|
||||
let r = index;
|
||||
let g = index + 1;
|
||||
let b = index + 2;
|
||||
let a = index + 3;
|
||||
|
||||
bgdebug.framebuffer[r] = 0xFF;
|
||||
bgdebug.framebuffer[g] = 0xFF;
|
||||
bgdebug.framebuffer[b] = 0xFF;
|
||||
bgdebug.framebuffer[a] = 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn background_window(bgdebug: &mut BgDebug, registers: &PPURegisters, ui: &imgui::Ui, renderer: &mut Renderer, queue: &Queue) {
|
||||
if !bgdebug.is_enabled {
|
||||
return;
|
||||
}
|
||||
let texture_id = bgdebug.texture_id.unwrap();
|
||||
render_background(bgdebug, registers);
|
||||
|
||||
let tex = renderer.textures.get_mut(texture_id).unwrap();
|
||||
tex.write(queue, &bgdebug.framebuffer, MAX_BG_WIDTH as u32, MAX_BG_HEIGHT as u32);
|
||||
let game_window = imgui::Window::new(format!("BG: {:?}", bgdebug.background));
|
||||
game_window
|
||||
.size([MAX_BG_WIDTH as f32, MAX_BG_HEIGHT as f32], imgui::Condition::FirstUseEver)
|
||||
.opened(&mut bgdebug.is_enabled)
|
||||
.build(ui, || {
|
||||
let game_image = imgui::Image::new(texture_id, [MAX_BG_WIDTH as f32, MAX_BG_HEIGHT as f32]);
|
||||
game_image.build(&ui);
|
||||
});
|
||||
}
|
||||
@@ -1,4 +1,13 @@
|
||||
extern crate snes_core;
|
||||
use snes_core::ppu::registers::{
|
||||
Background as PPUBg,
|
||||
MAX_BG_WIDTH,
|
||||
MAX_BG_HEIGHT,
|
||||
};
|
||||
|
||||
|
||||
pub struct DebugOptions {
|
||||
pub is_enabled: bool,
|
||||
pub show_debug_window: bool,
|
||||
pub show_cpu_registers: bool,
|
||||
pub show_spc700_registers: bool,
|
||||
@@ -8,7 +17,8 @@ pub struct DebugOptions {
|
||||
impl DebugOptions {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
show_debug_window: false,
|
||||
is_enabled: true,
|
||||
show_debug_window: true,
|
||||
show_cpu_registers: true,
|
||||
show_spc700_registers: true,
|
||||
show_cpu_memory: true,
|
||||
@@ -30,9 +40,47 @@ impl ErrorMessage {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BgDebug {
|
||||
pub background: PPUBg,
|
||||
pub is_enabled: bool,
|
||||
pub texture_id: Option<imgui::TextureId>,
|
||||
pub framebuffer: Vec<u8>,
|
||||
}
|
||||
|
||||
impl BgDebug {
|
||||
pub fn new(background: PPUBg) -> Self {
|
||||
Self {
|
||||
background: background,
|
||||
is_enabled: false,
|
||||
texture_id: None,
|
||||
framebuffer: vec![0x00; MAX_BG_WIDTH * MAX_BG_HEIGHT * 4],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PPUDebug {
|
||||
pub is_enabled: bool,
|
||||
pub backgrounds: [BgDebug; 4],
|
||||
}
|
||||
|
||||
impl PPUDebug {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
is_enabled: true,
|
||||
backgrounds: [
|
||||
BgDebug::new(PPUBg::Bg1),
|
||||
BgDebug::new(PPUBg::Bg2),
|
||||
BgDebug::new(PPUBg::Bg3),
|
||||
BgDebug::new(PPUBg::Bg4),
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct State {
|
||||
pub debug_options: DebugOptions,
|
||||
pub error_message: ErrorMessage,
|
||||
pub ppudebug: PPUDebug,
|
||||
}
|
||||
|
||||
impl State {
|
||||
@@ -40,6 +88,7 @@ impl State {
|
||||
Self {
|
||||
debug_options: DebugOptions::new(),
|
||||
error_message: ErrorMessage::new(),
|
||||
ppudebug: PPUDebug::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user