tile window shows gbc sprites
This commit is contained in:
parent
59d52ee92f
commit
01dcbbcd53
4 changed files with 101 additions and 20 deletions
|
@ -17,6 +17,7 @@ pub struct WindowRenderer {
|
||||||
gamepad_handler: Option<Gilrs>,
|
gamepad_handler: Option<Gilrs>,
|
||||||
joypad_state: JoypadState,
|
joypad_state: JoypadState,
|
||||||
current_rumble: bool,
|
current_rumble: bool,
|
||||||
|
position: Option<(isize, isize)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowRenderer {
|
impl WindowRenderer {
|
||||||
|
@ -30,6 +31,7 @@ impl WindowRenderer {
|
||||||
gamepad_handler,
|
gamepad_handler,
|
||||||
joypad_state: JoypadState::default(),
|
joypad_state: JoypadState::default(),
|
||||||
current_rumble: false,
|
current_rumble: false,
|
||||||
|
position: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,20 +40,26 @@ impl Renderer<u32> for WindowRenderer {
|
||||||
fn prepare(&mut self, width: usize, height: usize) {
|
fn prepare(&mut self, width: usize, height: usize) {
|
||||||
self.width = width;
|
self.width = width;
|
||||||
self.height = height;
|
self.height = height;
|
||||||
self.window = Some(
|
|
||||||
Window::new(
|
let mut w = Window::new(
|
||||||
"Gameboy",
|
"Gameboy",
|
||||||
width * self.factor,
|
width * self.factor,
|
||||||
height * self.factor,
|
height * self.factor,
|
||||||
WindowOptions::default(),
|
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]) {
|
fn display(&mut self, buffer: &[u32]) {
|
||||||
if let Some(ref mut window) = self.window {
|
if let Some(ref mut window) = self.window {
|
||||||
self.scaled_buf = scale_buffer(buffer, self.width, self.height, self.factor);
|
self.scaled_buf = scale_buffer(buffer, self.width, self.height, self.factor);
|
||||||
|
self.position = Some(window.get_position());
|
||||||
window
|
window
|
||||||
.update_with_buffer(
|
.update_with_buffer(
|
||||||
&self.scaled_buf,
|
&self.scaled_buf,
|
||||||
|
|
|
@ -26,6 +26,10 @@ pub enum RomFile {
|
||||||
pub trait Renderer<Format: From<Colour>> {
|
pub trait Renderer<Format: From<Colour>> {
|
||||||
fn prepare(&mut self, width: usize, height: usize);
|
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 display(&mut self, buffer: &[Format]);
|
||||||
|
|
||||||
fn set_title(&mut self, _title: String) {}
|
fn set_title(&mut self, _title: String) {}
|
||||||
|
|
|
@ -127,8 +127,7 @@ where
|
||||||
{
|
{
|
||||||
pub fn new(cgb: bool, window: R, tile_window_renderer: Option<R>) -> Self {
|
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 {
|
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, cgb))
|
||||||
Some(TileWindow::new(tile_window_renderer))
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
@ -166,9 +165,11 @@ where
|
||||||
window: R,
|
window: R,
|
||||||
tile_window_renderer: Option<R>,
|
tile_window_renderer: Option<R>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let tile_window = if let Some(mut tile_window_renderer) = tile_window_renderer {
|
let tile_window = if let Some(tile_window_renderer) = tile_window_renderer {
|
||||||
tile_window_renderer.prepare(TILE_WINDOW_WIDTH, TILE_WINDOW_HEIGHT);
|
Some(TileWindow::new(
|
||||||
Some(TileWindow::new(tile_window_renderer))
|
tile_window_renderer,
|
||||||
|
state.cgb_data.is_some(),
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
types::{BgAttributes, ColourInner, Vram},
|
types::{BgAttributes, ColourInner, Vram, VramBank},
|
||||||
Colour,
|
Colour,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ where
|
||||||
{
|
{
|
||||||
sprite_buffer: Vec<ColourFormat>,
|
sprite_buffer: Vec<ColourFormat>,
|
||||||
sprite_renderer: R,
|
sprite_renderer: R,
|
||||||
|
currently_cgb: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<ColourFormat, R> TileWindow<ColourFormat, R>
|
impl<ColourFormat, R> TileWindow<ColourFormat, R>
|
||||||
|
@ -23,13 +24,20 @@ where
|
||||||
ColourFormat: From<Colour> + Clone,
|
ColourFormat: From<Colour> + Clone,
|
||||||
R: Renderer<ColourFormat>,
|
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 {
|
Self {
|
||||||
sprite_buffer: vec![
|
sprite_buffer: vec![
|
||||||
ColourInner::Error.rgb_bytes(None, false).into();
|
ColourInner::Error.rgb_bytes(None, false).into();
|
||||||
TILE_WINDOW_WIDTH * TILE_WINDOW_HEIGHT
|
current_width * TILE_WINDOW_HEIGHT
|
||||||
],
|
],
|
||||||
sprite_renderer: window,
|
sprite_renderer: window,
|
||||||
|
currently_cgb: cgb,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +47,20 @@ where
|
||||||
memory: &Vram,
|
memory: &Vram,
|
||||||
is_cgb_mode: bool,
|
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 {
|
for tile_y in 0..16 {
|
||||||
self.draw_row(
|
self.draw_row(
|
||||||
tile_y,
|
tile_y,
|
||||||
|
@ -63,7 +85,6 @@ where
|
||||||
self.sprite_renderer.display(&self.sprite_buffer);
|
self.sprite_renderer.display(&self.sprite_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
|
||||||
fn draw_row(
|
fn draw_row(
|
||||||
&mut self,
|
&mut self,
|
||||||
tile_y: u8,
|
tile_y: u8,
|
||||||
|
@ -72,11 +93,58 @@ where
|
||||||
palette: Palette,
|
palette: Palette,
|
||||||
memory: &Vram,
|
memory: &Vram,
|
||||||
is_cgb_mode: bool,
|
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 {
|
for tile_x in 0..16 {
|
||||||
let tile_num = (tile_y * 16) + tile_x;
|
let tile_num = (tile_y * 16) + tile_x;
|
||||||
let data_begin = area.get_addr(tile_num);
|
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 {
|
for px_y in 0..8_u16 {
|
||||||
let lsbs = memory
|
let lsbs = memory
|
||||||
|
@ -99,7 +167,7 @@ where
|
||||||
palette.map_bits(lsb, msb).0
|
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();
|
colour.rgb_bytes(None, is_cgb_mode).into();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue