use minifb::Window; use crate::{ processor::{ get_bit, gpu::{ bits_to_mapped_colour, scale_buffer, Palette, TiledataArea, TILE_WINDOW_HEIGHT, TILE_WINDOW_HEIGHT_SCALED, TILE_WINDOW_WIDTH, TILE_WINDOW_WIDTH_SCALED, }, memory::Memory, }, FACTOR, }; pub(super) struct TileWindow { sprite_buffer: Vec, sprite_buffer_scaled: Vec, sprite_window: Window, } impl TileWindow { pub(super) fn new(window: Window) -> Self { Self { sprite_buffer: vec![0; TILE_WINDOW_WIDTH * TILE_WINDOW_HEIGHT], sprite_buffer_scaled: vec![0; TILE_WINDOW_WIDTH_SCALED * TILE_WINDOW_HEIGHT_SCALED], sprite_window: window, } } } impl TileWindow { pub(super) fn draw_sprite_window(&mut self, palette: Palette, memory: &Memory) { for tile_y in 0..16 { self.draw_row( tile_y, tile_y as usize, TiledataArea::D8000, palette, memory, ); } for tile_y in 0..8 { self.draw_row( tile_y, (tile_y as usize) + 16, TiledataArea::D9000, palette, memory, ); } self.sprite_buffer_scaled = scale_buffer( &self.sprite_buffer, TILE_WINDOW_WIDTH, TILE_WINDOW_HEIGHT, FACTOR, ); self.sprite_window .update_with_buffer( &self.sprite_buffer_scaled, TILE_WINDOW_WIDTH_SCALED, TILE_WINDOW_HEIGHT_SCALED, ) .unwrap(); } fn draw_row( &mut self, tile_y: u8, display_y: usize, area: TiledataArea, palette: Palette, memory: &Memory, ) { for tile_x in 0..16 { let tile_num = (tile_y * 16) + tile_x; let data_begin = area.get_addr(tile_num); for px_y in 0..8 { let lsbs = memory.get((px_y * 2) + data_begin); let msbs = memory.get((px_y * 2) + data_begin + 1); for px_x in 0..8 { let real_px_y = (display_y * 8) + px_y as usize; let real_px_x = (tile_x as usize * 8) + px_x as usize; let lsb = get_bit(lsbs, 7 - px_x); let msb = get_bit(msbs, 7 - px_x); let colour = bits_to_mapped_colour(lsb, msb, palette); self.sprite_buffer[real_px_x + (real_px_y * TILE_WINDOW_WIDTH)] = colour.as_rgb(); } } } } }