Implement MODE4 rendering, ArmWrestler renders now!
Former-commit-id: 4910a63b454ae9309abc0aa584a7d0bc96143538
This commit is contained in:
parent
1084be52b8
commit
876cdfdcb3
|
@ -1,3 +1,5 @@
|
|||
use std::time::Duration;
|
||||
|
||||
use sdl2::event::Event;
|
||||
use sdl2::pixels::Color;
|
||||
use sdl2::rect::Point;
|
||||
|
@ -20,21 +22,6 @@ pub fn create_render_view(gba: &GameBoyAdvance) {
|
|||
|
||||
let mut canvas = window.into_canvas().build().unwrap();
|
||||
|
||||
canvas.set_draw_color(Color::RGB(0xfa, 0xfa, 0xfa));
|
||||
canvas.clear();
|
||||
|
||||
for y in 0..Lcd::DISPLAY_HEIGHT {
|
||||
for x in 0..Lcd::DISPLAY_WIDTH {
|
||||
let index = (x as usize) + (y as usize) * (256 as usize);
|
||||
let color = gba.lcd.pixeldata[index];
|
||||
let rgb24: Color = color.into();
|
||||
canvas.set_draw_color(rgb24);
|
||||
canvas.draw_point(Point::from((x as i32, y as i32)));
|
||||
}
|
||||
}
|
||||
|
||||
canvas.present();
|
||||
|
||||
let mut event_pump = sdl_context.event_pump().unwrap();
|
||||
'running: loop {
|
||||
for event in event_pump.poll_iter() {
|
||||
|
@ -46,5 +33,22 @@ pub fn create_render_view(gba: &GameBoyAdvance) {
|
|||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
canvas.set_draw_color(Color::RGB(0xfa, 0xfa, 0xfa));
|
||||
canvas.clear();
|
||||
|
||||
for y in 0..Lcd::DISPLAY_HEIGHT {
|
||||
for x in 0..Lcd::DISPLAY_WIDTH {
|
||||
let index = (x as usize) + (y as usize) * (256 as usize);
|
||||
let color = gba.lcd.pixeldata[index];
|
||||
let rgb24: Color = color.into();
|
||||
canvas.set_draw_color(rgb24);
|
||||
canvas.draw_point(Point::from((x as i32, y as i32)));
|
||||
}
|
||||
}
|
||||
|
||||
canvas.present();
|
||||
|
||||
::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::time::Duration;
|
||||
|
||||
use sdl2::event::Event;
|
||||
use sdl2::pixels::Color;
|
||||
use sdl2::rect::{Point, Rect};
|
||||
|
@ -48,6 +50,9 @@ fn draw_tile(
|
|||
}
|
||||
}
|
||||
|
||||
const TILESET_INITIAL_X: i32 = 0x20;
|
||||
const TILESET_INITIAL_Y: i32 = 0x20;
|
||||
|
||||
pub fn create_tile_view(bg: u32, gba: &GameBoyAdvance) {
|
||||
let sdl_context = sdl2::init().unwrap();
|
||||
let video_subsystem = sdl_context.video().unwrap();
|
||||
|
@ -60,9 +65,6 @@ pub fn create_tile_view(bg: u32, gba: &GameBoyAdvance) {
|
|||
|
||||
let mut canvas = window.into_canvas().build().unwrap();
|
||||
|
||||
canvas.set_draw_color(Color::RGB(00, 00, 00));
|
||||
canvas.clear();
|
||||
|
||||
let bgcnt = BgControl::from(gba.sysbus.ioregs.read_reg(REG_BG0CNT + 2 * bg));
|
||||
|
||||
let palette = Palette::from(gba.sysbus.get_bytes(0x0500_0000));
|
||||
|
@ -73,33 +75,53 @@ pub fn create_tile_view(bg: u32, gba: &GameBoyAdvance) {
|
|||
let num_tiles = 0x4000 / tile_size;
|
||||
println!("tileset: {:#x}, tilemap: {:#x}", tileset_addr, tilemap_addr);
|
||||
|
||||
let mut tile_x = 0x20;
|
||||
let mut tile_y = 0x20;
|
||||
for t in 0..num_tiles {
|
||||
let tile_addr = tileset_addr + t * tile_size;
|
||||
if t != 0 && t % tiles_per_row == 0 {
|
||||
tile_y += 10;
|
||||
tile_x = 0x20;
|
||||
}
|
||||
tile_x += 10;
|
||||
draw_tile(
|
||||
gba,
|
||||
tile_addr,
|
||||
pixel_format,
|
||||
Point::from((tile_x, tile_y)),
|
||||
&mut canvas,
|
||||
);
|
||||
}
|
||||
|
||||
canvas.present();
|
||||
|
||||
let mut event_pump = sdl_context.event_pump().unwrap();
|
||||
'running: loop {
|
||||
for event in event_pump.poll_iter() {
|
||||
match event {
|
||||
Event::Quit { .. } => break 'running,
|
||||
Event::MouseButtonDown { x, y, .. } => {
|
||||
let click_point = Point::new(x, y);
|
||||
let mut tile_x = TILESET_INITIAL_X;
|
||||
let mut tile_y = TILESET_INITIAL_Y;
|
||||
for t in 0..num_tiles {
|
||||
let tile_addr = tileset_addr + t * tile_size;
|
||||
if t != 0 && t % tiles_per_row == 0 {
|
||||
tile_y += 10;
|
||||
tile_x = TILESET_INITIAL_Y;
|
||||
}
|
||||
tile_x += 10;
|
||||
if Rect::new(tile_x, tile_y, 8, 8).contains_point(click_point) {
|
||||
println!("tile #{:#x}, addr={:#x}", t, tile_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
canvas.set_draw_color(Color::RGB(00, 00, 00));
|
||||
canvas.clear();
|
||||
|
||||
let mut tile_x = TILESET_INITIAL_X;
|
||||
let mut tile_y = TILESET_INITIAL_Y;
|
||||
for t in 0..num_tiles {
|
||||
let tile_addr = tileset_addr + t * tile_size;
|
||||
if t != 0 && t % tiles_per_row == 0 {
|
||||
tile_y += 10;
|
||||
tile_x = TILESET_INITIAL_Y;
|
||||
}
|
||||
tile_x += 10;
|
||||
draw_tile(
|
||||
gba,
|
||||
tile_addr,
|
||||
pixel_format,
|
||||
Point::from((tile_x, tile_y)),
|
||||
&mut canvas,
|
||||
);
|
||||
}
|
||||
canvas.present();
|
||||
::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60));
|
||||
}
|
||||
}
|
||||
|
|
21
src/lcd.rs
21
src/lcd.rs
|
@ -313,9 +313,25 @@ impl Lcd {
|
|||
}
|
||||
}
|
||||
|
||||
fn scanline_mode4(&mut self, bg: u32, dispcnt: &DisplayControl, sysbus: &mut SysBus) {
|
||||
let page: u32 = match dispcnt.display_frame {
|
||||
0 => 0x0600_0000,
|
||||
1 => 0x0600_a000,
|
||||
_ => unreachable!()
|
||||
};
|
||||
|
||||
let y = self.current_scanline;
|
||||
|
||||
for x in 0..Self::DISPLAY_WIDTH {
|
||||
let bitmap_index = x + y * Self::DISPLAY_WIDTH;
|
||||
let bitmap_addr = page + (bitmap_index as u32);
|
||||
let index = sysbus.read_8(bitmap_addr as Addr) as u32;
|
||||
self.pixeldata[x + y * 256] = self.get_palette_color(sysbus, index, 0);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn scanline(&mut self, sysbus: &mut SysBus) {
|
||||
let dispcnt = DisplayControl::from(sysbus.ioregs.read_reg(REG_DISPCNT));
|
||||
let dispstat = DisplayStatus::from(sysbus.ioregs.read_reg(REG_DISPSTAT));
|
||||
|
||||
match dispcnt.bg_mode {
|
||||
BGMode::BGMode0 | BGMode::BGMode2 => {
|
||||
|
@ -325,6 +341,9 @@ impl Lcd {
|
|||
}
|
||||
}
|
||||
}
|
||||
BGMode::BGMode4 => {
|
||||
self.scanline_mode4(2, &dispcnt, sysbus);
|
||||
}
|
||||
_ => panic!("{:?} not supported", dispcnt.bg_mode),
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue