tile window shows gbc sprites

This commit is contained in:
Alex Janka 2023-04-25 10:08:22 +10:00
parent 59d52ee92f
commit 01dcbbcd53
4 changed files with 101 additions and 20 deletions

View file

@ -17,6 +17,7 @@ pub struct WindowRenderer {
gamepad_handler: Option<Gilrs>,
joypad_state: JoypadState,
current_rumble: bool,
position: Option<(isize, isize)>,
}
impl WindowRenderer {
@ -30,6 +31,7 @@ impl WindowRenderer {
gamepad_handler,
joypad_state: JoypadState::default(),
current_rumble: false,
position: None,
}
}
}
@ -38,20 +40,26 @@ impl Renderer<u32> for WindowRenderer {
fn prepare(&mut self, width: usize, height: usize) {
self.width = width;
self.height = height;
self.window = Some(
Window::new(
let mut w = Window::new(
"Gameboy",
width * self.factor,
height * self.factor,
WindowOptions::default(),
)
.unwrap(),
);
.unwrap();
if let Some((x, y)) = self.position {
w.set_position(x, y);
}
self.window = Some(w);
}
fn display(&mut self, buffer: &[u32]) {
if let Some(ref mut window) = self.window {
self.scaled_buf = scale_buffer(buffer, self.width, self.height, self.factor);
self.position = Some(window.get_position());
window
.update_with_buffer(
&self.scaled_buf,

View file

@ -26,6 +26,10 @@ pub enum RomFile {
pub trait Renderer<Format: From<Colour>> {
fn prepare(&mut self, width: usize, height: usize);
fn resize(&mut self, width: usize, height: usize) {
self.prepare(width, height)
}
fn display(&mut self, buffer: &[Format]);
fn set_title(&mut self, _title: String) {}

View file

@ -127,8 +127,7 @@ where
{
pub fn new(cgb: bool, window: R, tile_window_renderer: Option<R>) -> Self {
let tile_window = if let Some(mut tile_window_renderer) = tile_window_renderer {
tile_window_renderer.prepare(TILE_WINDOW_WIDTH, TILE_WINDOW_HEIGHT);
Some(TileWindow::new(tile_window_renderer))
Some(TileWindow::new(tile_window_renderer, cgb))
} else {
None
};
@ -166,9 +165,11 @@ where
window: R,
tile_window_renderer: Option<R>,
) -> Self {
let tile_window = if let Some(mut tile_window_renderer) = tile_window_renderer {
tile_window_renderer.prepare(TILE_WINDOW_WIDTH, TILE_WINDOW_HEIGHT);
Some(TileWindow::new(tile_window_renderer))
let tile_window = if let Some(tile_window_renderer) = tile_window_renderer {
Some(TileWindow::new(
tile_window_renderer,
state.cgb_data.is_some(),
))
} else {
None
};

View file

@ -5,7 +5,7 @@ use crate::{
};
use super::{
types::{BgAttributes, ColourInner, Vram},
types::{BgAttributes, ColourInner, Vram, VramBank},
Colour,
};
@ -16,6 +16,7 @@ where
{
sprite_buffer: Vec<ColourFormat>,
sprite_renderer: R,
currently_cgb: bool,
}
impl<ColourFormat, R> TileWindow<ColourFormat, R>
@ -23,13 +24,20 @@ where
ColourFormat: From<Colour> + Clone,
R: Renderer<ColourFormat>,
{
pub(super) fn new(window: R) -> Self {
pub(super) fn new(mut window: R, cgb: bool) -> Self {
let current_width = if cgb {
TILE_WINDOW_WIDTH * 2
} else {
TILE_WINDOW_WIDTH
};
window.prepare(current_width, TILE_WINDOW_HEIGHT);
Self {
sprite_buffer: vec![
ColourInner::Error.rgb_bytes(None, false).into();
TILE_WINDOW_WIDTH * TILE_WINDOW_HEIGHT
current_width * TILE_WINDOW_HEIGHT
],
sprite_renderer: window,
currently_cgb: cgb,
}
}
@ -39,6 +47,20 @@ where
memory: &Vram,
is_cgb_mode: bool,
) {
if self.currently_cgb != is_cgb_mode {
self.currently_cgb = is_cgb_mode;
let current_width = if is_cgb_mode {
TILE_WINDOW_WIDTH * 2
} else {
TILE_WINDOW_WIDTH
};
self.sprite_renderer
.resize(current_width, TILE_WINDOW_HEIGHT);
self.sprite_buffer = vec![
ColourInner::Error.rgb_bytes(None, false).into();
current_width * TILE_WINDOW_HEIGHT
];
}
for tile_y in 0..16 {
self.draw_row(
tile_y,
@ -63,7 +85,6 @@ where
self.sprite_renderer.display(&self.sprite_buffer);
}
#[allow(clippy::too_many_arguments)]
fn draw_row(
&mut self,
tile_y: u8,
@ -72,11 +93,58 @@ where
palette: Palette,
memory: &Vram,
is_cgb_mode: bool,
) {
let line_width = if is_cgb_mode {
TILE_WINDOW_WIDTH * 2
} else {
TILE_WINDOW_WIDTH
};
self.draw_row_from_bank(
tile_y,
display_y,
area,
palette,
memory,
is_cgb_mode,
VramBank::Bank0,
0,
line_width,
);
if is_cgb_mode {
self.draw_row_from_bank(
tile_y,
display_y,
area,
palette,
memory,
is_cgb_mode,
VramBank::Bank1,
TILE_WINDOW_WIDTH,
line_width,
);
}
}
#[allow(clippy::too_many_arguments)]
fn draw_row_from_bank(
&mut self,
tile_y: u8,
display_y: usize,
area: TiledataArea,
palette: Palette,
memory: &Vram,
is_cgb_mode: bool,
bank: VramBank,
offset: usize,
line_width: usize,
) {
for tile_x in 0..16 {
let tile_num = (tile_y * 16) + tile_x;
let data_begin = area.get_addr(tile_num);
let attributes = BgAttributes::default();
let attributes = BgAttributes {
tile_bank: bank,
..Default::default()
};
for px_y in 0..8_u16 {
let lsbs = memory
@ -99,7 +167,7 @@ where
palette.map_bits(lsb, msb).0
};
self.sprite_buffer[real_px_x + (real_px_y * TILE_WINDOW_WIDTH)] =
self.sprite_buffer[offset + real_px_x + (real_px_y * line_width)] =
colour.rgb_bytes(None, is_cgb_mode).into();
}
}