Support axis flip for tiles

Former-commit-id: daefb380ab2dfcee600297690dcc0c7c1a37f911
This commit is contained in:
Michel Heily 2019-07-29 09:46:12 +03:00
parent 90edebbe82
commit f862209911
2 changed files with 46 additions and 20 deletions

View file

@ -232,11 +232,19 @@ impl Gpu {
&self, &self,
sysbus: &SysBus, sysbus: &SysBus,
addr: Addr, addr: Addr,
x: u32, mut x: u32,
y: u32, mut y: u32,
width: u32, width: u32,
format: PixelFormat, format: PixelFormat,
x_flip: bool,
y_flip: bool,
) -> usize { ) -> usize {
if x_flip {
x = 7 - x;
}
if y_flip {
y = 7 - x;
}
match format { match format {
PixelFormat::BPP4 => { PixelFormat::BPP4 => {
let byte = sysbus.read_8(addr + width * y + x / 2); let byte = sysbus.read_8(addr + width * y + x / 2);
@ -268,13 +276,11 @@ impl Gpu {
let py = self.current_scanline as u32; let py = self.current_scanline as u32;
for tile in 0..tiles_per_row { for tile in 0..tiles_per_row {
let tile_y = py % 8;
let map_index = tile + (py / 8) * tiles_per_row; let map_index = tile + (py / 8) * tiles_per_row;
let map_addr = tilemap_base + 2 * map_index; let map_addr = tilemap_base + 2 * map_index;
let entry = TileMapEntry::from(sysbus.read_16(map_addr)); let entry = TileMapEntry::from(sysbus.read_16(map_addr));
let tile_addr = tileset_base + entry.tile_index * tile_size; let tile_addr = tileset_base + entry.tile_index * tile_size;
let tile_y = py % 8;
for tile_x in 0..=7 { for tile_x in 0..=7 {
let color = match pixel_format { let color = match pixel_format {
PixelFormat::BPP4 => { PixelFormat::BPP4 => {
@ -285,6 +291,8 @@ impl Gpu {
tile_y as u32, tile_y as u32,
4, 4,
pixel_format, pixel_format,
entry.x_flip,
entry.y_flip,
); );
self.get_palette_color(sysbus, index as u32, entry.palette_bank as u32) self.get_palette_color(sysbus, index as u32, entry.palette_bank as u32)
} }
@ -296,12 +304,16 @@ impl Gpu {
tile_y as u32, tile_y as u32,
8, 8,
pixel_format, pixel_format,
entry.x_flip,
entry.y_flip,
); );
self.get_palette_color(sysbus, index as u32, 0) self.get_palette_color(sysbus, index as u32, 0)
} }
}; };
if color.get_rgb24() != (0, 0, 0) {
self.pixeldata[((px + tile_x) as usize) + (py as usize) * 512] = color; self.pixeldata[((px + tile_x) as usize) + (py as usize) * 512] = color;
} }
}
px += 8; px += 8;
if px == bgcnt.screen_width as u32 { if px == bgcnt.screen_width as u32 {
return; return;
@ -340,13 +352,17 @@ impl Gpu {
let dispcnt = DisplayControl::from(sysbus.ioregs.read_reg(REG_DISPCNT)); let dispcnt = DisplayControl::from(sysbus.ioregs.read_reg(REG_DISPCNT));
match dispcnt.bg_mode { match dispcnt.bg_mode {
BGMode::BGMode0 | BGMode::BGMode2 => { BGMode::BGMode0 => {
for bg in 0..3 { for bg in (0..3).rev() {
if dispcnt.disp_bg[bg] { if dispcnt.disp_bg[bg] {
self.scanline_mode0(bg as u32, sysbus); self.scanline_mode0(bg as u32, sysbus);
} }
} }
} }
BGMode::BGMode2 => {
self.scanline_mode0(2, sysbus);
self.scanline_mode0(3, sysbus);
}
BGMode::BGMode3 => { BGMode::BGMode3 => {
self.scanline_mode3(2, sysbus); self.scanline_mode3(2, sysbus);
} }
@ -439,10 +455,6 @@ impl EmuIoDev for Gpu {
} }
} }
// let mut dispcnt = DisplayControl::from(sysbus.ioregs.read_reg(REG_DISPCNT));
// let mut dispstat = DisplayStatus::from(sysbus.ioregs.read_reg(REG_DISPSTAT));
// TODO
(0, None) (0, None)
} }
} }

View file

@ -30,22 +30,36 @@ fn draw_tile(
for x in 0..8 { for x in 0..8 {
let color = match pixel_format { let color = match pixel_format {
PixelFormat::BPP4 => { PixelFormat::BPP4 => {
let index = let index = gba.gpu.read_pixel_index(
gba.gpu &gba.sysbus,
.read_pixel_index(&gba.sysbus, tile_addr, x, y, 4, pixel_format); tile_addr,
gba.gpu.get_palette_color(&gba.sysbus, index as u32, 3) x,
y,
4,
pixel_format,
false,
false,
);
gba.gpu.get_palette_color(&gba.sysbus, index as u32, 0xf)
} }
PixelFormat::BPP8 => { PixelFormat::BPP8 => {
let index = let index = gba.gpu.read_pixel_index(
gba.gpu &gba.sysbus,
.read_pixel_index(&gba.sysbus, tile_addr, x, y, 8, pixel_format); tile_addr,
x,
y,
8,
pixel_format,
false,
false,
);
gba.gpu.get_palette_color(&gba.sysbus, index as u32, 0) gba.gpu.get_palette_color(&gba.sysbus, index as u32, 0)
} }
}; };
let (r, g, b) = color.get_rgb24(); let (r, g, b) = color.get_rgb24();
canvas.set_draw_color(Color::RGB(r, g, b)); canvas.set_draw_color(Color::RGB(r, g, b));
canvas.draw_point(p.offset(x as i32, y as i32)); canvas.draw_point(p.offset(x as i32, y as i32)).unwrap();
} }
} }
} }