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::event::Event;
|
||||||
use sdl2::pixels::Color;
|
use sdl2::pixels::Color;
|
||||||
use sdl2::rect::Point;
|
use sdl2::rect::Point;
|
||||||
|
@ -20,6 +22,18 @@ pub fn create_render_view(gba: &GameBoyAdvance) {
|
||||||
|
|
||||||
let mut canvas = window.into_canvas().build().unwrap();
|
let mut canvas = window.into_canvas().build().unwrap();
|
||||||
|
|
||||||
|
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, .. } => {
|
||||||
|
println!("({},{}) {:x}", x, y, x + y * (Lcd::DISPLAY_WIDTH as i32));
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
canvas.set_draw_color(Color::RGB(0xfa, 0xfa, 0xfa));
|
canvas.set_draw_color(Color::RGB(0xfa, 0xfa, 0xfa));
|
||||||
canvas.clear();
|
canvas.clear();
|
||||||
|
|
||||||
|
@ -35,16 +49,6 @@ pub fn create_render_view(gba: &GameBoyAdvance) {
|
||||||
|
|
||||||
canvas.present();
|
canvas.present();
|
||||||
|
|
||||||
let mut event_pump = sdl_context.event_pump().unwrap();
|
::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60));
|
||||||
'running: loop {
|
|
||||||
for event in event_pump.poll_iter() {
|
|
||||||
match event {
|
|
||||||
Event::Quit { .. } => break 'running,
|
|
||||||
Event::MouseButtonDown { x, y, .. } => {
|
|
||||||
println!("({},{}) {:x}", x, y, x + y * (Lcd::DISPLAY_WIDTH as i32));
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use sdl2::event::Event;
|
use sdl2::event::Event;
|
||||||
use sdl2::pixels::Color;
|
use sdl2::pixels::Color;
|
||||||
use sdl2::rect::{Point, Rect};
|
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) {
|
pub fn create_tile_view(bg: u32, gba: &GameBoyAdvance) {
|
||||||
let sdl_context = sdl2::init().unwrap();
|
let sdl_context = sdl2::init().unwrap();
|
||||||
let video_subsystem = sdl_context.video().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();
|
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 bgcnt = BgControl::from(gba.sysbus.ioregs.read_reg(REG_BG0CNT + 2 * bg));
|
||||||
|
|
||||||
let palette = Palette::from(gba.sysbus.get_bytes(0x0500_0000));
|
let palette = Palette::from(gba.sysbus.get_bytes(0x0500_0000));
|
||||||
|
@ -73,13 +75,42 @@ pub fn create_tile_view(bg: u32, gba: &GameBoyAdvance) {
|
||||||
let num_tiles = 0x4000 / tile_size;
|
let num_tiles = 0x4000 / tile_size;
|
||||||
println!("tileset: {:#x}, tilemap: {:#x}", tileset_addr, tilemap_addr);
|
println!("tileset: {:#x}, tilemap: {:#x}", tileset_addr, tilemap_addr);
|
||||||
|
|
||||||
let mut tile_x = 0x20;
|
let mut event_pump = sdl_context.event_pump().unwrap();
|
||||||
let mut tile_y = 0x20;
|
'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 {
|
for t in 0..num_tiles {
|
||||||
let tile_addr = tileset_addr + t * tile_size;
|
let tile_addr = tileset_addr + t * tile_size;
|
||||||
if t != 0 && t % tiles_per_row == 0 {
|
if t != 0 && t % tiles_per_row == 0 {
|
||||||
tile_y += 10;
|
tile_y += 10;
|
||||||
tile_x = 0x20;
|
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;
|
tile_x += 10;
|
||||||
draw_tile(
|
draw_tile(
|
||||||
|
@ -90,16 +121,7 @@ pub fn create_tile_view(bg: u32, gba: &GameBoyAdvance) {
|
||||||
&mut canvas,
|
&mut canvas,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas.present();
|
canvas.present();
|
||||||
|
::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60));
|
||||||
let mut event_pump = sdl_context.event_pump().unwrap();
|
|
||||||
'running: loop {
|
|
||||||
for event in event_pump.poll_iter() {
|
|
||||||
match event {
|
|
||||||
Event::Quit { .. } => break 'running,
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
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) {
|
pub fn scanline(&mut self, sysbus: &mut SysBus) {
|
||||||
let dispcnt = DisplayControl::from(sysbus.ioregs.read_reg(REG_DISPCNT));
|
let dispcnt = DisplayControl::from(sysbus.ioregs.read_reg(REG_DISPCNT));
|
||||||
let dispstat = DisplayStatus::from(sysbus.ioregs.read_reg(REG_DISPSTAT));
|
|
||||||
|
|
||||||
match dispcnt.bg_mode {
|
match dispcnt.bg_mode {
|
||||||
BGMode::BGMode0 | BGMode::BGMode2 => {
|
BGMode::BGMode0 | BGMode::BGMode2 => {
|
||||||
|
@ -325,6 +341,9 @@ impl Lcd {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BGMode::BGMode4 => {
|
||||||
|
self.scanline_mode4(2, &dispcnt, sysbus);
|
||||||
|
}
|
||||||
_ => panic!("{:?} not supported", dispcnt.bg_mode),
|
_ => panic!("{:?} not supported", dispcnt.bg_mode),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue