Rendering a basic window with pixels

This commit is contained in:
2021-10-26 17:34:59 -05:00
parent 1444e8b63d
commit 886fc3cd4a
8 changed files with 1911 additions and 12 deletions
+56 -1
View File
@@ -3,7 +3,8 @@ use crate::utils::{
get_bit,
set_bit,
};
use crate::bus::{Bus, BANK_ZERO};
use crate::bus::{Bus, BANK_ZERO, VIDEO_RAM};
use rand::Rng;
struct ColorPalette(u8, u8, u8, u8);
@@ -42,6 +43,10 @@ pub enum LCDStatus {
ModeFlag(LCDStatusModeFlag),
}
pub const WIDTH: u32 = 160;
pub const HEIGHT: u32 = 144;
pub const FRAME_BUFFER_LENGTH: u32 = WIDTH * HEIGHT;
const LCD_CONTROL_ADDRESS: u16 = 0xFF40;
const LCD_STATUS_ADDRESS: u16 = 0xFF41;
@@ -82,11 +87,14 @@ impl Window {
pub struct PPU {
window: Window,
rgba_frame: [[u8; 4]; FRAME_BUFFER_LENGTH as usize],
}
impl PPU {
pub fn new() -> Self {
Self {
rgba_frame: [[0, 0, 0xFF, 0]; FRAME_BUFFER_LENGTH as usize],
window: Window::new(),
}
}
@@ -174,4 +182,51 @@ impl PPU {
};
bus.write(LCD_STATUS_ADDRESS, byte);
}
fn get_rgba_pixel(two_bit_pixel: u8) -> [u8; 4] {
match two_bit_pixel {
0x00 => [255, 255, 255, 255],
0x01 => [192, 192, 192, 0],
0x10 => [128, 128, 128, 0],
0x11 => [0, 0, 0, 0],
_ => [0, 0, 0, 0],
}
}
pub fn draw_background(&mut self, bus: &Bus) {
let mut pointer = VIDEO_RAM.begin();
let mut pixels_drawn: usize = 0;
while pixels_drawn < FRAME_BUFFER_LENGTH as usize {
let byte1 = bus.read(pointer);
let byte2 = bus.read(pointer + 1);
let pixels = PPU::get_byte_pixels(byte1, byte2);
self.rgba_frame[pixels_drawn] = PPU::get_rgba_pixel(pixels[0]);
self.rgba_frame[pixels_drawn + 1] = PPU::get_rgba_pixel(pixels[1]);
self.rgba_frame[pixels_drawn + 2] = PPU::get_rgba_pixel(pixels[2]);
self.rgba_frame[pixels_drawn + 3] = PPU::get_rgba_pixel(pixels[3]);
self.rgba_frame[pixels_drawn + 4] = PPU::get_rgba_pixel(pixels[4]);
self.rgba_frame[pixels_drawn + 5] = PPU::get_rgba_pixel(pixels[5]);
self.rgba_frame[pixels_drawn + 6] = PPU::get_rgba_pixel(pixels[6]);
self.rgba_frame[pixels_drawn + 7] = PPU::get_rgba_pixel(pixels[7]);
pixels_drawn += 8;
pointer += 2;
}
}
fn get_byte_pixels(byte1: u8, byte2: u8) -> [u8; 8] {
let mut pixels: [u8; 8] = [0; 8];
pixels[0] = ((get_bit(byte1, BitIndex::I7) as u8) << 1) | (get_bit(byte2, BitIndex::I7) as u8);
pixels[1] = ((get_bit(byte1, BitIndex::I6) as u8) << 1) | (get_bit(byte2, BitIndex::I6) as u8);
pixels[2] = ((get_bit(byte1, BitIndex::I5) as u8) << 1) | (get_bit(byte2, BitIndex::I5) as u8);
pixels[3] = ((get_bit(byte1, BitIndex::I4) as u8) << 1) | (get_bit(byte2, BitIndex::I4) as u8);
pixels[4] = ((get_bit(byte1, BitIndex::I3) as u8) << 1) | (get_bit(byte2, BitIndex::I3) as u8);
pixels[5] = ((get_bit(byte1, BitIndex::I2) as u8) << 1) | (get_bit(byte2, BitIndex::I2) as u8);
pixels[6] = ((get_bit(byte1, BitIndex::I1) as u8) << 1) | (get_bit(byte2, BitIndex::I1) as u8);
pixels[7] = ((get_bit(byte1, BitIndex::I0) as u8) << 1) | (get_bit(byte2, BitIndex::I0) as u8);
pixels
}
pub fn get_rgba_frame(&self, bus: &Bus) -> &[[u8; 4]; FRAME_BUFFER_LENGTH as usize] {
&self.rgba_frame
}
}