gpu: Cleanup #1

Former-commit-id: a40fca25eae76afb4d581d8da1404a5d52c9efab
This commit is contained in:
Michel Heily 2019-12-28 21:13:44 +02:00
parent b13c3026c8
commit b22388252b
3 changed files with 44 additions and 49 deletions

View file

@ -8,6 +8,7 @@ use crate::num::FromPrimitive;
mod mosaic; mod mosaic;
mod obj; mod obj;
use obj::ObjInfo;
mod sfx; mod sfx;
pub mod regs; pub mod regs;
@ -82,31 +83,6 @@ impl Default for GpuState {
} }
use GpuState::*; use GpuState::*;
pub struct FrameBuffer([u32; DISPLAY_WIDTH * DISPLAY_HEIGHT]);
impl fmt::Debug for FrameBuffer {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "FrameBuffer: ")?;
for i in 0..6 {
write!(f, "#{:06x}, ", self[i])?;
}
write!(f, "...")
}
}
impl std::ops::Index<usize> for FrameBuffer {
type Output = u32;
fn index(&self, index: usize) -> &Self::Output {
&self.0[index]
}
}
impl std::ops::IndexMut<usize> for FrameBuffer {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
&mut self.0[index]
}
}
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct Scanline<T>([T; DISPLAY_WIDTH]); pub struct Scanline<T>([T; DISPLAY_WIDTH]);
@ -200,7 +176,7 @@ pub struct BgAffine {
pub y: i32, pub y: i32,
} }
#[derive(Debug)] #[derive(DebugStub)]
pub struct Gpu { pub struct Gpu {
pub state: GpuState, pub state: GpuState,
cycles: usize, cycles: usize,
@ -223,9 +199,11 @@ pub struct Gpu {
pub bldalpha: BlendAlpha, pub bldalpha: BlendAlpha,
pub bldy: u16, pub bldy: u16,
pub obj_line: Scanline<Rgb15>, #[debug_stub = "Sprite Buffer"]
pub obj_line_priorities: Scanline<u16>, pub obj_buffer: [ObjInfo; DISPLAY_WIDTH],
pub frame_buffer: FrameBuffer,
#[debug_stub = "Frame Buffer"]
pub frame_buffer: [u32; DISPLAY_WIDTH * DISPLAY_HEIGHT],
} }
impl Gpu { impl Gpu {
@ -247,9 +225,8 @@ impl Gpu {
state: HDraw, state: HDraw,
vcount: 0, vcount: 0,
cycles: 0, cycles: 0,
obj_line: Scanline::default(), obj_buffer: [Default::default(); DISPLAY_WIDTH],
obj_line_priorities: Scanline([3; DISPLAY_WIDTH]), frame_buffer: [0; DISPLAY_WIDTH * DISPLAY_HEIGHT],
frame_buffer: FrameBuffer([0; DISPLAY_WIDTH * DISPLAY_HEIGHT]),
} }
} }
@ -293,7 +270,7 @@ impl Gpu {
} }
fn render_pixel(&mut self, x: i32, y: i32, p: Rgb15) { fn render_pixel(&mut self, x: i32, y: i32, p: Rgb15) {
self.frame_buffer.0[index2d!(usize, x, y, DISPLAY_WIDTH)] = p.to_rgb24(); self.frame_buffer[index2d!(usize, x, y, DISPLAY_WIDTH)] = p.to_rgb24();
} }
fn scanline_reg_bg(&mut self, bg: usize, sb: &mut SysBus) { fn scanline_reg_bg(&mut self, bg: usize, sb: &mut SysBus) {
@ -446,13 +423,12 @@ impl Gpu {
self.mosaic_sfx(); self.mosaic_sfx();
let post_sfx_line = self.composite_sfx(sb); let post_sfx_line = self.composite_sfx(sb);
for x in 0..DISPLAY_WIDTH { for x in 0..DISPLAY_WIDTH {
self.frame_buffer.0[x + self.vcount * DISPLAY_WIDTH] = self.frame_buffer[x + self.vcount * DISPLAY_WIDTH] = post_sfx_line[x].to_rgb24();
post_sfx_line[x].to_rgb24();
} }
} }
pub fn get_framebuffer(&self) -> &[u32] { pub fn get_framebuffer(&self) -> &[u32] {
&self.frame_buffer.0 &self.frame_buffer
} }
fn update_vcount(&mut self, value: usize, irqs: &mut IrqBitmask) { fn update_vcount(&mut self, value: usize, irqs: &mut IrqBitmask) {

View file

@ -145,7 +145,7 @@ impl Gpu {
if screen_x >= screen_width { if screen_x >= screen_width {
break; break;
} }
if self.obj_line_priorities[screen_x as usize] <= obj.2.priority() { if self.obj_buffer[screen_x as usize].priority <= obj.2.priority() {
continue; continue;
} }
@ -169,8 +169,9 @@ impl Gpu {
let pixel_color = let pixel_color =
self.get_palette_color(sb, pixel_index as u32, palette_bank, PALRAM_OFS_FG); self.get_palette_color(sb, pixel_index as u32, palette_bank, PALRAM_OFS_FG);
if pixel_color != Rgb15::TRANSPARENT { if pixel_color != Rgb15::TRANSPARENT {
self.obj_line[screen_x as usize] = pixel_color; let mut current_obj = &mut self.obj_buffer[screen_x as usize];
self.obj_line_priorities[screen_x as usize] = obj.2.priority(); current_obj.color = pixel_color;
current_obj.priority = obj.2.priority();
} }
} }
} }
@ -216,7 +217,7 @@ impl Gpu {
if screen_x >= screen_width { if screen_x >= screen_width {
break; break;
} }
if self.obj_line_priorities[screen_x as usize] <= obj.2.priority() { if self.obj_buffer[screen_x as usize].priority <= obj.2.priority() {
continue; continue;
} }
let mut sprite_y = screen_y - ref_y; let mut sprite_y = screen_y - ref_y;
@ -240,16 +241,16 @@ impl Gpu {
let pixel_color = let pixel_color =
self.get_palette_color(sb, pixel_index as u32, palette_bank, PALRAM_OFS_FG); self.get_palette_color(sb, pixel_index as u32, palette_bank, PALRAM_OFS_FG);
if pixel_color != Rgb15::TRANSPARENT { if pixel_color != Rgb15::TRANSPARENT {
self.obj_line[screen_x as usize] = pixel_color; let mut current_obj = &mut self.obj_buffer[screen_x as usize];
self.obj_line_priorities[screen_x as usize] = obj.2.priority(); current_obj.color = pixel_color;
current_obj.priority = obj.2.priority();
} }
} }
} }
pub fn render_objs(&mut self, sb: &SysBus) { pub fn render_objs(&mut self, sb: &SysBus) {
// reset the scanline // reset the scanline
self.obj_line = Scanline::default(); self.obj_buffer = [Default::default(); DISPLAY_WIDTH];
self.obj_line_priorities = Scanline([3; DISPLAY_WIDTH]);
for obj_num in 0..128 { for obj_num in 0..128 {
let obj = read_obj_attrs(sb, obj_num); let obj = read_obj_attrs(sb, obj_num);
match obj.0.objtype() { match obj.0.objtype() {
@ -263,8 +264,25 @@ impl Gpu {
} }
} }
#[derive(Debug, Copy, Clone)]
pub struct ObjInfo {
pub(super) color: Rgb15,
pub(super) priority: u16,
pub(super) mode: ObjMode,
}
impl Default for ObjInfo {
fn default() -> ObjInfo {
ObjInfo {
mode: ObjMode::Normal,
color: Rgb15::TRANSPARENT,
priority: 3,
}
}
}
#[derive(Debug, Primitive, Copy, Clone, PartialEq)] #[derive(Debug, Primitive, Copy, Clone, PartialEq)]
enum ObjMode { pub enum ObjMode {
Normal = 0b00, Normal = 0b00,
Sfx = 0b01, Sfx = 0b01,
Window = 0b10, Window = 0b10,

View file

@ -51,11 +51,11 @@ impl Gpu {
'outer: for priority in 0..4 { 'outer: for priority in 0..4 {
if bflags.contains(BlendFlags::OBJ) if bflags.contains(BlendFlags::OBJ)
&& wflags.contains(WindowFlags::OBJ) && wflags.contains(WindowFlags::OBJ)
&& !self.obj_line[screen_x].is_transparent() && !self.obj_buffer[screen_x].color.is_transparent()
&& self.obj_line_priorities[screen_x] == priority && self.obj_buffer[screen_x].priority == priority
{ {
return Some(Layer { return Some(Layer {
color: self.obj_line[screen_x], color: self.obj_buffer[screen_x].color,
blend_flag: BlendFlags::OBJ, blend_flag: BlendFlags::OBJ,
}); });
} }
@ -75,9 +75,10 @@ impl Gpu {
} }
} }
} }
let backdrop = sb.palette_ram.read_16(0);
if bflags.contains(BlendFlags::BACKDROP) { if bflags.contains(BlendFlags::BACKDROP) {
return Some(Layer { return Some(Layer {
color: Rgb15(sb.palette_ram.read_16(0)), color: Rgb15(backdrop),
blend_flag: BlendFlags::BACKDROP, blend_flag: BlendFlags::BACKDROP,
}); });
} }