core/gpu: Impl bitmap mode 5 and properly handle wraparound for bitmap modes.
resolves #90 Former-commit-id: 633580870e2d44d95a8b53b6311232f0fad48bd9 Former-commit-id: aa2ba32116900f635f12f9dcc9d29344367711eb
This commit is contained in:
parent
90e492d81a
commit
1b1b855702
|
@ -384,6 +384,10 @@ impl Gpu {
|
|||
self.render_mode4(2);
|
||||
self.finalize_scanline(2, 2);
|
||||
}
|
||||
5 => {
|
||||
self.render_mode5(2);
|
||||
self.finalize_scanline(2, 2);
|
||||
}
|
||||
_ => panic!("{:?} not supported", self.dispcnt.mode()),
|
||||
}
|
||||
// self.mosaic_sfx();
|
||||
|
|
|
@ -36,6 +36,11 @@ pub(super) static SCREEN_VIEWPORT: ViewPort = ViewPort {
|
|||
w: DISPLAY_WIDTH as i32,
|
||||
h: DISPLAY_HEIGHT as i32,
|
||||
};
|
||||
pub(super) static MODE5_VIEWPORT: ViewPort = ViewPort {
|
||||
origin: (0, 0),
|
||||
w: 160,
|
||||
h: 128,
|
||||
};
|
||||
|
||||
pub(super) mod utils {
|
||||
use super::Point;
|
||||
|
|
|
@ -4,7 +4,7 @@ use super::super::consts::*;
|
|||
use super::super::Gpu;
|
||||
use super::super::Rgb15;
|
||||
|
||||
use super::{utils, SCREEN_VIEWPORT};
|
||||
use super::{utils, MODE5_VIEWPORT, SCREEN_VIEWPORT};
|
||||
|
||||
use crate::Bus;
|
||||
|
||||
|
@ -16,13 +16,19 @@ impl Gpu {
|
|||
let pc = self.bg_aff[bg - 2].pc as i32;
|
||||
let ref_point = self.get_ref_point(bg);
|
||||
|
||||
for x in 0..DISPLAY_WIDTH {
|
||||
let t = utils::transform_bg_point(ref_point, x as i32, pa, pc);
|
||||
if !SCREEN_VIEWPORT.contains_point(t) {
|
||||
self.backgrounds[bg].line[x] = Rgb15::TRANSPARENT;
|
||||
continue;
|
||||
}
|
||||
let wraparound = self.backgrounds[bg].bgcnt.affine_wraparound();
|
||||
|
||||
for x in 0..DISPLAY_WIDTH {
|
||||
let mut t = utils::transform_bg_point(ref_point, x as i32, pa, pc);
|
||||
if !SCREEN_VIEWPORT.contains_point(t) {
|
||||
if wraparound {
|
||||
t.0 = t.0.rem_euclid(SCREEN_VIEWPORT.w);
|
||||
t.1 = t.1.rem_euclid(SCREEN_VIEWPORT.h);
|
||||
} else {
|
||||
self.backgrounds[bg].line[x] = Rgb15::TRANSPARENT;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
let pixel_index = index2d!(u32, t.0, t.1, DISPLAY_WIDTH);
|
||||
let pixel_ofs = 2 * pixel_index;
|
||||
let color = Rgb15(self.vram.read_16(pixel_ofs));
|
||||
|
@ -43,11 +49,18 @@ impl Gpu {
|
|||
let pc = self.bg_aff[bg - 2].pc as i32;
|
||||
let ref_point = self.get_ref_point(bg);
|
||||
|
||||
let wraparound = self.backgrounds[bg].bgcnt.affine_wraparound();
|
||||
|
||||
for x in 0..DISPLAY_WIDTH {
|
||||
let t = utils::transform_bg_point(ref_point, x as i32, pa, pc);
|
||||
let mut t = utils::transform_bg_point(ref_point, x as i32, pa, pc);
|
||||
if !SCREEN_VIEWPORT.contains_point(t) {
|
||||
self.backgrounds[bg].line[x] = Rgb15::TRANSPARENT;
|
||||
continue;
|
||||
if wraparound {
|
||||
t.0 = t.0.rem_euclid(SCREEN_VIEWPORT.w);
|
||||
t.1 = t.1.rem_euclid(SCREEN_VIEWPORT.h);
|
||||
} else {
|
||||
self.backgrounds[bg].line[x] = Rgb15::TRANSPARENT;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
let bitmap_index = index2d!(u32, t.0, t.1, DISPLAY_WIDTH);
|
||||
let bitmap_ofs = page_ofs + (bitmap_index as u32);
|
||||
|
@ -56,4 +69,36 @@ impl Gpu {
|
|||
self.backgrounds[bg].line[x] = color;
|
||||
}
|
||||
}
|
||||
|
||||
pub(in super::super) fn render_mode5(&mut self, bg: usize) {
|
||||
let page_ofs: u32 = match self.dispcnt.display_frame() {
|
||||
0 => 0x0600_0000 - VRAM_ADDR,
|
||||
1 => 0x0600_a000 - VRAM_ADDR,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let _y = self.vcount;
|
||||
|
||||
let pa = self.bg_aff[bg - 2].pa as i32;
|
||||
let pc = self.bg_aff[bg - 2].pc as i32;
|
||||
let ref_point = self.get_ref_point(bg);
|
||||
|
||||
let wraparound = self.backgrounds[bg].bgcnt.affine_wraparound();
|
||||
|
||||
for x in 0..DISPLAY_WIDTH {
|
||||
let mut t = utils::transform_bg_point(ref_point, x as i32, pa, pc);
|
||||
if !MODE5_VIEWPORT.contains_point(t) {
|
||||
if wraparound {
|
||||
t.0 = t.0.rem_euclid(MODE5_VIEWPORT.w);
|
||||
t.1 = t.1.rem_euclid(MODE5_VIEWPORT.h);
|
||||
} else {
|
||||
self.backgrounds[bg].line[x] = Rgb15::TRANSPARENT;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
let pixel_ofs = page_ofs + 2 * index2d!(u32, t.0, t.1, MODE5_VIEWPORT.w);
|
||||
let color = Rgb15(self.vram.read_16(pixel_ofs));
|
||||
self.backgrounds[bg].line[x] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue