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 obj;
use obj::ObjInfo;
mod sfx;
pub mod regs;
@ -82,31 +83,6 @@ impl Default for 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)]
pub struct Scanline<T>([T; DISPLAY_WIDTH]);
@ -200,7 +176,7 @@ pub struct BgAffine {
pub y: i32,
}
#[derive(Debug)]
#[derive(DebugStub)]
pub struct Gpu {
pub state: GpuState,
cycles: usize,
@ -223,9 +199,11 @@ pub struct Gpu {
pub bldalpha: BlendAlpha,
pub bldy: u16,
pub obj_line: Scanline<Rgb15>,
pub obj_line_priorities: Scanline<u16>,
pub frame_buffer: FrameBuffer,
#[debug_stub = "Sprite Buffer"]
pub obj_buffer: [ObjInfo; DISPLAY_WIDTH],
#[debug_stub = "Frame Buffer"]
pub frame_buffer: [u32; DISPLAY_WIDTH * DISPLAY_HEIGHT],
}
impl Gpu {
@ -247,9 +225,8 @@ impl Gpu {
state: HDraw,
vcount: 0,
cycles: 0,
obj_line: Scanline::default(),
obj_line_priorities: Scanline([3; DISPLAY_WIDTH]),
frame_buffer: FrameBuffer([0; DISPLAY_WIDTH * DISPLAY_HEIGHT]),
obj_buffer: [Default::default(); DISPLAY_WIDTH],
frame_buffer: [0; DISPLAY_WIDTH * DISPLAY_HEIGHT],
}
}
@ -293,7 +270,7 @@ impl Gpu {
}
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) {
@ -446,13 +423,12 @@ impl Gpu {
self.mosaic_sfx();
let post_sfx_line = self.composite_sfx(sb);
for x in 0..DISPLAY_WIDTH {
self.frame_buffer.0[x + self.vcount * DISPLAY_WIDTH] =
post_sfx_line[x].to_rgb24();
self.frame_buffer[x + self.vcount * DISPLAY_WIDTH] = post_sfx_line[x].to_rgb24();
}
}
pub fn get_framebuffer(&self) -> &[u32] {
&self.frame_buffer.0
&self.frame_buffer
}
fn update_vcount(&mut self, value: usize, irqs: &mut IrqBitmask) {

View file

@ -145,7 +145,7 @@ impl Gpu {
if screen_x >= screen_width {
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;
}
@ -169,8 +169,9 @@ impl Gpu {
let pixel_color =
self.get_palette_color(sb, pixel_index as u32, palette_bank, PALRAM_OFS_FG);
if pixel_color != Rgb15::TRANSPARENT {
self.obj_line[screen_x as usize] = pixel_color;
self.obj_line_priorities[screen_x as usize] = obj.2.priority();
let mut current_obj = &mut self.obj_buffer[screen_x as usize];
current_obj.color = pixel_color;
current_obj.priority = obj.2.priority();
}
}
}
@ -216,7 +217,7 @@ impl Gpu {
if screen_x >= screen_width {
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;
}
let mut sprite_y = screen_y - ref_y;
@ -240,16 +241,16 @@ impl Gpu {
let pixel_color =
self.get_palette_color(sb, pixel_index as u32, palette_bank, PALRAM_OFS_FG);
if pixel_color != Rgb15::TRANSPARENT {
self.obj_line[screen_x as usize] = pixel_color;
self.obj_line_priorities[screen_x as usize] = obj.2.priority();
let mut current_obj = &mut self.obj_buffer[screen_x as usize];
current_obj.color = pixel_color;
current_obj.priority = obj.2.priority();
}
}
}
pub fn render_objs(&mut self, sb: &SysBus) {
// reset the scanline
self.obj_line = Scanline::default();
self.obj_line_priorities = Scanline([3; DISPLAY_WIDTH]);
self.obj_buffer = [Default::default(); DISPLAY_WIDTH];
for obj_num in 0..128 {
let obj = read_obj_attrs(sb, obj_num);
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)]
enum ObjMode {
pub enum ObjMode {
Normal = 0b00,
Sfx = 0b01,
Window = 0b10,

View file

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