From e0e7634aeccc2f69e025a62836ba212e8c61b965 Mon Sep 17 00:00:00 2001 From: Alex Janka Date: Thu, 26 Oct 2023 15:45:01 +1100 Subject: [PATCH] dont asplode stack --- lib/src/processor/memory.rs | 20 +++++++++++----- lib/src/processor/memory/mmio/gpu.rs | 35 +++++++++++++++++++--------- 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/lib/src/processor/memory.rs b/lib/src/processor/memory.rs index 5f42cea..54a5be7 100644 --- a/lib/src/processor/memory.rs +++ b/lib/src/processor/memory.rs @@ -321,12 +321,16 @@ where 0x0..0xFF40 | 0xFF4C..=0xFFFF => unreachable!(), }, IoAddress::Cgb(address) => { - if let WramBanks::Cgb { banks: _, selected } = &self.ram.banks && let Some(cgb_peripherals) = &self.cgb_peripherals { + if let WramBanks::Cgb { banks: _, selected } = &self.ram.banks + && let Some(cgb_peripherals) = &self.cgb_peripherals + { match address { CgbIoAddress::CompatMode => self.gpu.get_compat_byte(), CgbIoAddress::PrepareSpeed => cgb_peripherals.double_speed.get(), CgbIoAddress::VramBank => self.gpu.vram.get_vram_bank(), - CgbIoAddress::VramDma(address) => cgb_peripherals.vram_dma.get_register(address), + CgbIoAddress::VramDma(address) => { + cgb_peripherals.vram_dma.get_register(address) + } CgbIoAddress::Infrared => cgb_peripherals.infrared.get(), CgbIoAddress::Palette(address) => self.gpu.get_cgb_palette(address), CgbIoAddress::ObjPriority => self.gpu.get_obj_priority(), @@ -380,18 +384,22 @@ where 0x0..0xFF40 | 0xFF4C..=0xFFFF => unreachable!(), }, IoAddress::Cgb(address) => { - if let WramBanks::Cgb { banks: _, selected } = &mut self.ram.banks && let Some(cgb_peripherals) = &mut self.cgb_peripherals { + if let WramBanks::Cgb { banks: _, selected } = &mut self.ram.banks + && let Some(cgb_peripherals) = &mut self.cgb_peripherals + { match address { CgbIoAddress::CompatMode => self.gpu.set_compat_byte(data), CgbIoAddress::PrepareSpeed => cgb_peripherals.double_speed.set(data), CgbIoAddress::VramBank => self.gpu.vram.set_vram_bank(data), - CgbIoAddress::VramDma(address) => cgb_peripherals.vram_dma.set_register(address, data), + CgbIoAddress::VramDma(address) => { + cgb_peripherals.vram_dma.set_register(address, data) + } CgbIoAddress::Infrared => cgb_peripherals.infrared.set(data), CgbIoAddress::Palette(address) => self.gpu.set_cgb_palette(address, data), CgbIoAddress::ObjPriority => self.gpu.set_obj_priority(data), CgbIoAddress::WramBank => *selected = (data & 0b111).max(1) as usize, - CgbIoAddress::Pcm12 => {}, - CgbIoAddress::Pcm34 => {}, + CgbIoAddress::Pcm12 => {} + CgbIoAddress::Pcm34 => {} CgbIoAddress::Unused(v) => { eprintln!("attempt to set 0x{v:0>4X} to 0x{data:0>2X}") } diff --git a/lib/src/processor/memory/mmio/gpu.rs b/lib/src/processor/memory/mmio/gpu.rs index 6aef66a..1605607 100644 --- a/lib/src/processor/memory/mmio/gpu.rs +++ b/lib/src/processor/memory/mmio/gpu.rs @@ -25,11 +25,13 @@ mod types; const TILE_WINDOW_WIDTH: usize = 16 * 8; const TILE_WINDOW_HEIGHT: usize = 24 * 8; +type Buffer = Box<[ColourFormat; SIZE]>; + pub struct Gpu where ColourFormat: From + Copy, { - pub buffer: [ColourFormat; WIDTH * HEIGHT], + pub buffer: Buffer, pub vram: Vram, pub oam: Oam, pub window: Sender>, @@ -43,7 +45,7 @@ where tile_window: Option>, layer_window: Option<( Sender>, - [ColourFormat; WIDTH * HEIGHT * 3], + Buffer, )>, window_lc: u8, has_window_been_enabled: bool, @@ -71,7 +73,12 @@ where let tile_window = tile_window_renderer .map(|tile_window_renderer| TileWindow::new(tile_window_renderer, cgb)); - let buffer = [get_blank_colour(cgb); WIDTH * HEIGHT]; + let buffer = { + let mut v: Vec = Vec::new(); + v.resize(WIDTH * HEIGHT, get_blank_colour(cgb)); + let temp = v.into_boxed_slice(); + unsafe { Box::from_raw(Box::into_raw(temp) as *mut [ColourFormat; WIDTH * HEIGHT]) } + }; let layer_window = layer_window_renderer.map(|layer_window_renderer| { layer_window_renderer @@ -80,10 +87,14 @@ where height: HEIGHT * 3, }) .expect("message error"); - ( - layer_window_renderer, - [get_blank_colour(cgb); WIDTH * HEIGHT * 3], - ) + (layer_window_renderer, { + let mut v: Vec = Vec::new(); + v.resize(WIDTH * HEIGHT * 3, get_blank_colour(cgb)); + let temp = v.into_boxed_slice(); + unsafe { + Box::from_raw(Box::into_raw(temp) as *mut [ColourFormat; WIDTH * HEIGHT * 3]) + } + }) }); Self { @@ -224,7 +235,9 @@ where self.window_lc = 0; self.has_window_been_enabled = false; let is_cgb_mode = self.is_cgb_mode(); - if let Some(tile_window) = &mut self.tile_window && output { + if let Some(tile_window) = &mut self.tile_window + && output + { tile_window.draw_sprite_window(self.bg_palette, &self.vram, is_cgb_mode); } } @@ -493,19 +506,19 @@ where fn render_window(&mut self) { let mut buffer = Vec::new(); - buffer.extend_from_slice(&self.buffer); + buffer.extend_from_slice(self.buffer.as_ref()); self.window .send(RendererMessage::display_message(buffer)) .expect("message error"); if let Some((ref mut window, ref mut buffer)) = self.layer_window { let mut new_buffer = Vec::new(); - new_buffer.extend_from_slice(buffer); + new_buffer.extend_from_slice(buffer.as_ref()); window .send(RendererMessage::display_message(new_buffer)) .expect("message error"); - for val in buffer { + for val in buffer.iter_mut() { *val = get_blank_colour(self.cgb_data.is_some()); } }