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