draw window with tiledata
This commit is contained in:
parent
bec5a0c3d6
commit
805ae0c817
|
@ -1,6 +1,10 @@
|
||||||
|
use minifb::{Window, WindowOptions};
|
||||||
|
|
||||||
use crate::{FACTOR, HEIGHT, WIDTH};
|
use crate::{FACTOR, HEIGHT, WIDTH};
|
||||||
|
|
||||||
use super::{as_signed, clear_bit, get_bit, set_bit, set_or_clear_bit, CPU};
|
use super::{as_signed, get_bit, set_bit, set_or_clear_bit, CPU};
|
||||||
|
|
||||||
|
mod tile_window;
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
enum DrawMode {
|
enum DrawMode {
|
||||||
|
@ -32,8 +36,8 @@ enum TiledataArea {
|
||||||
impl TiledataArea {
|
impl TiledataArea {
|
||||||
fn get_addr(&self, addr: u8) -> u16 {
|
fn get_addr(&self, addr: u8) -> u16 {
|
||||||
match self {
|
match self {
|
||||||
TiledataArea::D8000 => 0x8000 + (addr as u16),
|
TiledataArea::D8000 => 0x8000 + ((addr as u16) * 16),
|
||||||
TiledataArea::D9000 => 0x9000_u16.wrapping_add_signed(as_signed(addr) as i16),
|
TiledataArea::D9000 => 0x9000_u16.wrapping_add_signed((as_signed(addr) as i16) * 16),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,22 +90,44 @@ struct Palette {
|
||||||
three: Colour,
|
three: Colour,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const TILE_WINDOW_EDGE_LENGTH: usize = 16 * 8;
|
||||||
|
const TILE_WINDOW_EDGE_LENGTH_SCALED: usize = TILE_WINDOW_EDGE_LENGTH * FACTOR;
|
||||||
|
|
||||||
pub struct GPU {
|
pub struct GPU {
|
||||||
pub buffer: Vec<u32>,
|
pub buffer: Vec<u32>,
|
||||||
scaled_buffer: Vec<u32>,
|
scaled_buffer: Vec<u32>,
|
||||||
mode: DrawMode,
|
mode: DrawMode,
|
||||||
mode_clock: usize,
|
mode_clock: usize,
|
||||||
scanline: u8,
|
scanline: u8,
|
||||||
|
sprite_buffer: Vec<u32>,
|
||||||
|
sprite_buffer_scaled: Vec<u32>,
|
||||||
|
sprite_window: Window,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for GPU {
|
impl Default for GPU {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
let window = Window::new(
|
||||||
|
"Tiles",
|
||||||
|
TILE_WINDOW_EDGE_LENGTH_SCALED,
|
||||||
|
TILE_WINDOW_EDGE_LENGTH_SCALED,
|
||||||
|
WindowOptions::default(),
|
||||||
|
)
|
||||||
|
.unwrap_or_else(|e| {
|
||||||
|
panic!("{}", e);
|
||||||
|
});
|
||||||
Self {
|
Self {
|
||||||
buffer: vec![0; WIDTH * HEIGHT],
|
buffer: vec![0; WIDTH * HEIGHT],
|
||||||
scaled_buffer: vec![0; WIDTH * HEIGHT * 4],
|
scaled_buffer: vec![0; WIDTH * HEIGHT * 4],
|
||||||
mode: DrawMode::Mode2,
|
mode: DrawMode::Mode2,
|
||||||
mode_clock: 0,
|
mode_clock: 0,
|
||||||
scanline: 0,
|
scanline: 0,
|
||||||
|
sprite_buffer: vec![0; TILE_WINDOW_EDGE_LENGTH * TILE_WINDOW_EDGE_LENGTH],
|
||||||
|
sprite_buffer_scaled: vec![
|
||||||
|
0;
|
||||||
|
TILE_WINDOW_EDGE_LENGTH_SCALED
|
||||||
|
* TILE_WINDOW_EDGE_LENGTH_SCALED
|
||||||
|
],
|
||||||
|
sprite_window: window,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -201,6 +227,10 @@ impl CPU {
|
||||||
fn exit_vblank(&mut self) {
|
fn exit_vblank(&mut self) {
|
||||||
self.gpu.mode = DrawMode::Mode2;
|
self.gpu.mode = DrawMode::Mode2;
|
||||||
self.gpu.scanline = 0;
|
self.gpu.scanline = 0;
|
||||||
|
self.draw_sprite_window(
|
||||||
|
TiledataArea::D8000,
|
||||||
|
byte_to_palette(self.memory.get(0xFF47)),
|
||||||
|
);
|
||||||
// self.memory
|
// self.memory
|
||||||
// .set(0xFF0F, clear_bit(self.memory.get(0xFF0F), 0));
|
// .set(0xFF0F, clear_bit(self.memory.get(0xFF0F), 0));
|
||||||
}
|
}
|
||||||
|
|
50
src/processor/gpu/tile_window.rs
Normal file
50
src/processor/gpu/tile_window.rs
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
use crate::{
|
||||||
|
processor::{get_bit, CPU},
|
||||||
|
FACTOR,
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
bits_to_mapped_colour, scale_buffer, Palette, TiledataArea, TILE_WINDOW_EDGE_LENGTH,
|
||||||
|
TILE_WINDOW_EDGE_LENGTH_SCALED,
|
||||||
|
};
|
||||||
|
|
||||||
|
impl CPU {
|
||||||
|
pub(super) fn draw_sprite_window(&mut self, area: TiledataArea, palette: Palette) {
|
||||||
|
for tile_y in 0..16 {
|
||||||
|
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 = self.memory.get((px_y * 2) + data_begin);
|
||||||
|
let msbs = self.memory.get((px_y * 2) + data_begin + 1);
|
||||||
|
for px_x in 0..8 {
|
||||||
|
let real_px_y = (tile_y as usize * 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);
|
||||||
|
|
||||||
|
// if buself.gpu.b
|
||||||
|
self.gpu.sprite_buffer[real_px_x + (real_px_y * TILE_WINDOW_EDGE_LENGTH)] =
|
||||||
|
colour.to_rgb();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.gpu.sprite_buffer_scaled = scale_buffer(
|
||||||
|
&self.gpu.sprite_buffer,
|
||||||
|
TILE_WINDOW_EDGE_LENGTH,
|
||||||
|
TILE_WINDOW_EDGE_LENGTH,
|
||||||
|
FACTOR,
|
||||||
|
);
|
||||||
|
self.gpu
|
||||||
|
.sprite_window
|
||||||
|
.update_with_buffer(
|
||||||
|
&self.gpu.sprite_buffer_scaled,
|
||||||
|
TILE_WINDOW_EDGE_LENGTH_SCALED,
|
||||||
|
TILE_WINDOW_EDGE_LENGTH_SCALED,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue