mirror of
https://github.com/FranLMSP/snes.git
synced 2026-08-03 08:30:01 -04:00
placeholder to compute the current pixel
This commit is contained in:
@@ -12,7 +12,7 @@ pub struct PPU {
|
||||
impl PPU {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
framebuffer: vec![0; FRAMEBUFFER_SIZE],
|
||||
framebuffer: vec![0xFF; FRAMEBUFFER_SIZE],
|
||||
registers: PPURegisters::new(),
|
||||
was_vblank_nmi_set: false,
|
||||
is_irq_set: false,
|
||||
@@ -26,6 +26,9 @@ impl PPU {
|
||||
}
|
||||
|
||||
pub fn dot_cycle(&mut self) {
|
||||
if !self.registers.is_vblanking() && !self.registers.is_hblanking() {
|
||||
self.put_pixel(self.compute_pixel())
|
||||
}
|
||||
self.increment_hv_count();
|
||||
}
|
||||
|
||||
@@ -51,6 +54,29 @@ impl PPU {
|
||||
pub fn framebuffer(&self) -> &[u8] {
|
||||
&self.framebuffer
|
||||
}
|
||||
|
||||
fn compute_pixel(&self) -> (u8, u8, u8) {
|
||||
if self.registers.is_hblanking() || self.registers.is_hblanking() {
|
||||
return (0x00, 0x00, 0x00)
|
||||
}
|
||||
(0xFF, 0x00, 0xFF)
|
||||
}
|
||||
|
||||
fn put_pixel(&mut self, pixel: (u8, u8, u8)) {
|
||||
let fb_index = self.get_pixel_index();
|
||||
self.framebuffer[fb_index] = pixel.0;
|
||||
self.framebuffer[fb_index + 1] = pixel.1;
|
||||
self.framebuffer[fb_index + 2] = pixel.2;
|
||||
}
|
||||
|
||||
fn get_pixel_index(&self) -> usize {
|
||||
let h_count = self.registers.h_count as usize;
|
||||
let v_count = self.registers.v_count as usize;
|
||||
return (
|
||||
(h_count - 22) +
|
||||
((v_count - 1) * MAX_TV_WIDTH)
|
||||
) * 4
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for PPU {
|
||||
@@ -81,4 +107,38 @@ mod ppu_general_test {
|
||||
assert_eq!(ppu.registers.h_count, 0);
|
||||
assert_eq!(ppu.registers.v_count, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_current_pixel_index() {
|
||||
let mut ppu = PPU::new();
|
||||
ppu.registers.v_count = 1;
|
||||
ppu.registers.h_count = 22;
|
||||
assert_eq!(ppu.get_pixel_index(), 0);
|
||||
ppu.registers.v_count = 1;
|
||||
ppu.registers.h_count = 23;
|
||||
assert_eq!(ppu.get_pixel_index(), 4);
|
||||
ppu.registers.v_count = 1;
|
||||
ppu.registers.h_count = 24;
|
||||
assert_eq!(ppu.get_pixel_index(), 8);
|
||||
ppu.registers.v_count = 2;
|
||||
ppu.registers.h_count = 22;
|
||||
assert_eq!(ppu.get_pixel_index(), 2048);
|
||||
ppu.registers.v_count = 2;
|
||||
ppu.registers.h_count = 23;
|
||||
assert_eq!(ppu.get_pixel_index(), 2052);
|
||||
ppu.registers.v_count = 2;
|
||||
ppu.registers.h_count = 24;
|
||||
assert_eq!(ppu.get_pixel_index(), 2056);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_put_pixel() {
|
||||
let mut ppu = PPU::new();
|
||||
ppu.registers.v_count = 2;
|
||||
ppu.registers.h_count = 22;
|
||||
ppu.put_pixel((11, 22, 33));
|
||||
assert_eq!(ppu.framebuffer[2048], 11);
|
||||
assert_eq!(ppu.framebuffer[2049], 22);
|
||||
assert_eq!(ppu.framebuffer[2050], 33);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -375,10 +375,26 @@ impl PPURegisters {
|
||||
}
|
||||
|
||||
pub fn is_vblanking(&self) -> bool {
|
||||
if self.v_count >= 1 && self.v_count <= 224 {
|
||||
return false
|
||||
}
|
||||
true
|
||||
!(self.v_count >= 1 && self.v_count <= 224)
|
||||
}
|
||||
|
||||
pub fn is_hblanking(&self) -> bool {
|
||||
!(self.h_count >= 22 && self.h_count <= 277)
|
||||
}
|
||||
|
||||
pub fn get_current_res(&self) -> (u16, u16) {
|
||||
let w = if self.is_true_high_res_mode_enabled() {512} else {256};
|
||||
let h = if self.is_interlace_mode_enabled() {448} else {224};
|
||||
(w, h)
|
||||
}
|
||||
|
||||
pub fn is_interlace_mode_enabled(&self) -> bool {
|
||||
self._read(SETINI) & 0x01 == 0b1
|
||||
}
|
||||
|
||||
pub fn is_true_high_res_mode_enabled(&self) -> bool {
|
||||
let current_bg_mode = self._read(BGMODE);
|
||||
current_bg_mode == 5 || current_bg_mode == 6
|
||||
}
|
||||
}
|
||||
|
||||
@@ -590,4 +606,70 @@ mod ppu_registers_test {
|
||||
registers.v_count = 50;
|
||||
assert!(!registers.is_vblanking());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_hblanking() {
|
||||
let mut registers = PPURegisters::new();
|
||||
registers.h_count = 0;
|
||||
assert!(registers.is_hblanking());
|
||||
registers.h_count = 20;
|
||||
assert!(registers.is_hblanking());
|
||||
registers.h_count = 21;
|
||||
assert!(registers.is_hblanking());
|
||||
registers.h_count = 278;
|
||||
assert!(registers.is_hblanking());
|
||||
registers.h_count = 300;
|
||||
assert!(registers.is_hblanking());
|
||||
registers.h_count = 22;
|
||||
assert!(!registers.is_hblanking());
|
||||
registers.h_count = 100;
|
||||
assert!(!registers.is_hblanking());
|
||||
registers.h_count = 277;
|
||||
assert!(!registers.is_hblanking());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_interlace_mode_enabled() {
|
||||
let mut registers = PPURegisters::new();
|
||||
registers._write(SETINI, 0x01);
|
||||
assert!(registers.is_interlace_mode_enabled());
|
||||
registers._write(SETINI, 0x00);
|
||||
assert!(!registers.is_interlace_mode_enabled());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_true_high_res_mode_enabled() {
|
||||
let mut registers = PPURegisters::new();
|
||||
registers._write(BGMODE, 1);
|
||||
assert!(!registers.is_true_high_res_mode_enabled());
|
||||
registers._write(BGMODE, 2);
|
||||
assert!(!registers.is_true_high_res_mode_enabled());
|
||||
registers._write(BGMODE, 3);
|
||||
assert!(!registers.is_true_high_res_mode_enabled());
|
||||
registers._write(BGMODE, 4);
|
||||
assert!(!registers.is_true_high_res_mode_enabled());
|
||||
registers._write(BGMODE, 5);
|
||||
assert!(registers.is_true_high_res_mode_enabled());
|
||||
registers._write(BGMODE, 6);
|
||||
assert!(registers.is_true_high_res_mode_enabled());
|
||||
registers._write(BGMODE, 7);
|
||||
assert!(!registers.is_true_high_res_mode_enabled());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_current_res() {
|
||||
let mut registers = PPURegisters::new();
|
||||
registers._write(BGMODE, 1);
|
||||
registers._write(SETINI, 0x00);
|
||||
assert_eq!(registers.get_current_res(), (256, 224));
|
||||
registers._write(BGMODE, 1);
|
||||
registers._write(SETINI, 0x01);
|
||||
assert_eq!(registers.get_current_res(), (256, 448));
|
||||
registers._write(BGMODE, 5);
|
||||
registers._write(SETINI, 0x00);
|
||||
assert_eq!(registers.get_current_res(), (512, 224));
|
||||
registers._write(BGMODE, 6);
|
||||
registers._write(SETINI, 0x01);
|
||||
assert_eq!(registers.get_current_res(), (512, 448));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user