Newer
Older
// track on the number of object drawn
draw_count += 1;
/// Runs an update operation on the LCD STAT interrupt meaning
/// that the flag that control will be updated in case the conditions
/// required for the LCD STAT interrupt to be triggered are met.
self.int_stat = self.stat_level();
}
/// Obtains the current level of the LCD STAT interrupt by
/// checking the current PPU state in various sections.
self.stat_lyc && self.lyc == self.ly
|| self.stat_oam && self.mode == PpuMode::OamRead
|| self.stat_vblank && self.mode == PpuMode::VBlank
|| self.stat_hblank && self.mode == PpuMode::HBlank
/// Computes the values for all of the palettes, this method
/// is useful to "flush" color computation whenever the base
/// palette colors are changed.
fn compute_palettes(&mut self) {
// re-computes the complete set of palettes according to
// the currently set palette colors (that may have changed)
Self::compute_palette(&mut self.palette, &self.palette_colors, self.palettes[0]);
Self::compute_palette(
&mut self.palette_obj_0,
&self.palette_colors,
self.palettes[1],
);
Self::compute_palette(
&mut self.palette_obj_1,
&self.palette_colors,
self.palettes[2],
);
// clears the frame buffer to allow the new background
// color to be used
self.clear_frame_buffer();
}
/// Static method used for the base logic of computation of RGB
/// based palettes from the internal Game Boy color indexes.
/// This method should be called whenever the palette indexes
/// are changed.
fn compute_palette(palette: &mut Palette, palette_colors: &Palette, value: u8) {
for (index, palette_item) in palette.iter_mut().enumerate() {
let color_index: usize = (value as usize >> (index * 2)) & 3;
match color_index {
0..=3 => *palette_item = palette_colors[color_index],
color_index => panic!("Invalid palette color index {:04x}", color_index),
}
}
}
impl Default for Ppu {
fn default() -> Self {
Self::new()
}
}
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
#[test]
fn test_update_tile_simple() {
let mut ppu = Ppu::new();
ppu.vram[0x0000] = 0xff;
ppu.vram[0x0001] = 0xff;
let result = ppu.tiles()[0].get(0, 0);
assert_eq!(result, 0);
ppu.update_tile(0x8000, 0x00);
let result = ppu.tiles()[0].get(0, 0);
assert_eq!(result, 3);
}
#[test]
fn test_update_tile_upper() {
let mut ppu = Ppu::new();
ppu.vram[0x1000] = 0xff;
ppu.vram[0x1001] = 0xff;
let result = ppu.tiles()[256].get(0, 0);
assert_eq!(result, 0);
ppu.update_tile(0x9000, 0x00);
let result = ppu.tiles()[256].get(0, 0);
assert_eq!(result, 3);
}