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 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) {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue