cgb priority works almost 100%
This commit is contained in:
parent
e916ce7259
commit
7287d61f15
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue