cgb priority works almost 100%

This commit is contained in:
Alex Janka 2023-04-23 18:24:44 +10:00
parent e916ce7259
commit 7287d61f15
2 changed files with 24 additions and 18 deletions

View file

@ -11,10 +11,7 @@ use self::{
}; };
use crate::{ use crate::{
connect::Renderer, connect::Renderer,
processor::{ processor::memory::addresses::{OamAddress, VramAddress},
memory::addresses::{OamAddress, VramAddress},
SplitRegister,
},
util::{clear_bit, get_bit}, util::{clear_bit, get_bit},
HEIGHT, WIDTH, HEIGHT, WIDTH,
}; };
@ -39,6 +36,7 @@ where
pub oam: Oam, pub oam: Oam,
pub window: R, pub window: R,
is_bg_zero: Vec<bool>, is_bg_zero: Vec<bool>,
is_bg_priority: Vec<bool>,
lcdc: Lcdc, lcdc: Lcdc,
stat: Stat, stat: Stat,
mode_clock: usize, mode_clock: usize,
@ -68,6 +66,7 @@ where
vram: Vram, vram: Vram,
oam: Oam, oam: Oam,
is_bg_zero: Vec<bool>, is_bg_zero: Vec<bool>,
is_bg_priority: Vec<bool>,
lcdc: Lcdc, lcdc: Lcdc,
stat: Stat, stat: Stat,
mode_clock: usize, mode_clock: usize,
@ -99,6 +98,7 @@ where
vram: gpu.vram.clone(), vram: gpu.vram.clone(),
oam: gpu.oam, oam: gpu.oam,
is_bg_zero: gpu.is_bg_zero.clone(), is_bg_zero: gpu.is_bg_zero.clone(),
is_bg_priority: gpu.is_bg_priority.clone(),
lcdc: gpu.lcdc, lcdc: gpu.lcdc,
stat: gpu.stat, stat: gpu.stat,
mode_clock: gpu.mode_clock, mode_clock: gpu.mode_clock,
@ -140,6 +140,7 @@ where
oam: Oam::default(), oam: Oam::default(),
window, window,
is_bg_zero: vec![true; WIDTH], is_bg_zero: vec![true; WIDTH],
is_bg_priority: vec![false; WIDTH],
lcdc: Lcdc::default(), lcdc: Lcdc::default(),
stat: Stat::default(), stat: Stat::default(),
mode_clock: 0, mode_clock: 0,
@ -178,6 +179,7 @@ where
oam: state.oam, oam: state.oam,
window, window,
is_bg_zero: state.is_bg_zero, is_bg_zero: state.is_bg_zero,
is_bg_priority: state.is_bg_priority,
lcdc: state.lcdc, lcdc: state.lcdc,
stat: state.stat, stat: state.stat,
mode_clock: state.mode_clock, mode_clock: state.mode_clock,
@ -320,7 +322,7 @@ where
for e in &mut self.is_bg_zero { for e in &mut self.is_bg_zero {
*e = true; *e = true;
} }
if self.lcdc.bg_window_enable { if self.lcdc.bg_window_enable || self.is_cgb_mode() {
self.render_scanline_bg(scanline); self.render_scanline_bg(scanline);
if self.lcdc.window_enable { if self.lcdc.window_enable {
if !self.has_window_been_enabled { if !self.has_window_been_enabled {
@ -337,7 +339,7 @@ where
} }
} }
if self.lcdc.obj_enable { if self.lcdc.obj_enable {
self.render_scanline_obj(scanline); self.render_scanline_obj(scanline, !self.lcdc.bg_window_enable && self.is_cgb_mode());
} }
} }
@ -369,10 +371,10 @@ where
} }
} }
fn render_scanline_obj(&mut self, scanline: u8) { fn render_scanline_obj(&mut self, scanline: u8, obj_priority: bool) {
let objs = self.parse_oam(scanline); let objs = self.parse_oam(scanline);
for object in objs { for object in objs {
self.render_object(scanline, object); self.render_object(scanline, object, obj_priority);
} }
} }
@ -413,22 +415,21 @@ where
}, },
oam_location: (i - 0xFE00) as u8, oam_location: (i - 0xFE00) as u8,
}); });
if objs.len() >= 10 {
break;
}
} }
} }
objs.sort_by_key(|o| { objs.sort_by_key(|o| {
let mut v: u16 = 0x0; if self.is_cgb_mode() {
v.set_high(o.x); o.oam_location
v.set_low(o.oam_location); } else {
v o.x
}
}); });
objs.truncate(10);
objs.reverse(); objs.reverse();
objs objs
} }
fn render_object(&mut self, scanline: u8, object: Object) { fn render_object(&mut self, scanline: u8, object: Object, obj_priority: bool) {
let mut object_row = scanline.wrapping_sub(object.y.wrapping_sub(16)); let mut object_row = scanline.wrapping_sub(object.y.wrapping_sub(16));
if object.flags.y_flip { if object.flags.y_flip {
object_row = self.lcdc.obj_size.get_height() - (object_row + 1); object_row = self.lcdc.obj_size.get_height() - (object_row + 1);
@ -471,7 +472,11 @@ where
let x_coord = x_coord_uncorrected - 8; let x_coord = x_coord_uncorrected - 8;
if x_coord < WIDTH { if x_coord < WIDTH {
let buffer_index = (scanline as usize * WIDTH) + x_coord; let buffer_index = (scanline as usize * WIDTH) + x_coord;
if !object.flags.behind_bg_and_window || self.is_bg_zero[x_coord] { if (!object.flags.behind_bg_and_window && !self.is_bg_priority[x_coord])
|| self.is_bg_zero[x_coord]
|| (self.is_cgb_mode() && !self.lcdc.bg_window_enable)
|| obj_priority
{
let cgb_data = self.cgb_data.as_ref().map(|v| { let cgb_data = self.cgb_data.as_ref().map(|v| {
( (
v.palettes.obj, v.palettes.obj,
@ -555,6 +560,7 @@ where
self.bg_palette.map_bits(lsb, msb) self.bg_palette.map_bits(lsb, msb)
}; };
self.is_bg_zero[x] = is_zero; self.is_bg_zero[x] = is_zero;
self.is_bg_priority[x] = attributes.bg_priority;
let cgb_data = self let cgb_data = self
.cgb_data .cgb_data

View file

@ -25,7 +25,7 @@ impl Default for CgbData {
} }
} }
#[derive(Serialize, Deserialize, Clone, Copy)] #[derive(Serialize, Deserialize, Clone, Copy, PartialEq)]
pub(super) enum ObjectPriorityMode { pub(super) enum ObjectPriorityMode {
OamLocation = 0, OamLocation = 0,
Coordinate = 1, Coordinate = 1,