gpu: Cleanup #1
Former-commit-id: a40fca25eae76afb4d581d8da1404a5d52c9efab
This commit is contained in:
parent
b13c3026c8
commit
b22388252b
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
});
|
||||
}
|
||||
|
|
Reference in a new issue