This repository has been archived on 2024-12-14. You can view files and clone it, but cannot push or open issues or pull requests.
rustboyadvance-ng/src/debugger/tile_view.rs
Michel Heily c7dd713605 The big ioregs refactoring.
This commit refactors the ioregs:
* Use bitfield crate to implement the GPU ioregs.
* IoRegs are stored in their own variables bindings (i.e, Gpu related ioregs are now fields of the Gpu struct)
  - This optimize performance quiet alot from my testings - since every scanline was accessing deseralizing ioregs from sysbus. (Getting constant 59fps now)
* For now, comment out DMA model

Also, cleaned the code up to eliminate rustc warnings.


Former-commit-id: 9077695c446ebd1a71783acfdd9819245aa02d7a
2019-08-03 00:24:15 +03:00

112 lines
3.5 KiB
Rust

use std::time::Duration;
use sdl2::event::Event;
use sdl2::pixels::Color;
use sdl2::rect::{Point, Rect};
use sdl2::render::Canvas;
use crate::core::gba::GameBoyAdvance;
use crate::core::palette::*;
impl Into<Color> for Rgb15 {
fn into(self) -> Color {
let (r, g, b) = self.get_rgb24();
Color::RGB(r, g, b)
}
}
fn draw_tile(
gba: &GameBoyAdvance,
tile_addr: u32,
pixel_format: PixelFormat,
p: Point,
canvas: &mut Canvas<sdl2::video::Window>,
) {
let io = gba.io.borrow();
for y in 0..8 {
for x in 0..8 {
let index = io
.gpu
.read_pixel_index(&gba.sysbus, tile_addr, x, y, pixel_format);
let color = io.gpu.get_palette_color(&gba.sysbus, index as u32, 0);
let (r, g, b) = color.get_rgb24();
canvas.set_draw_color(Color::RGB(r, g, b));
canvas.draw_point(p.offset(x as i32, y as i32)).unwrap();
}
}
}
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();
let window = video_subsystem
.window("PaletteView", 512, 512)
.position_centered()
.build()
.unwrap();
let mut canvas = window.into_canvas().build().unwrap();
let bgcnt = gba.io.borrow().gpu.bgcnt[bg as usize].clone();
let (tile_size, pixel_format) = bgcnt.tile_format();
let tileset_addr = bgcnt.char_block();
let tilemap_addr = bgcnt.screen_block();
let tiles_per_row = 32;
let num_tiles = 0x4000 / tile_size;
println!("tileset: {:#x}, tilemap: {:#x}", tileset_addr, tilemap_addr);
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));
}
}