Skip to content

Commit

Permalink
Implemented sprite OBP0 and OBP1 palette support
Browse files Browse the repository at this point in the history
  • Loading branch information
velllu committed Dec 13, 2023
1 parent 51c850c commit 4a059db
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 23 deletions.
6 changes: 4 additions & 2 deletions src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ pub(crate) mod bus {
}

pub(crate) mod gpu {
pub(crate) const LY: u16 = 0xFF44;
pub(crate) const LCDC: u16 = 0xFF40;
pub(crate) const SCY: u16 = 0xFF42;
pub(crate) const SCX: u16 = 0xFF43;
pub(crate) const LCDC: u16 = 0xFF40;
pub(crate) const LY: u16 = 0xFF44;
pub(crate) const OBP0: u16 = 0xFF48;
pub(crate) const OBP1: u16 = 0xFF49;
}

pub(crate) mod display {
Expand Down
1 change: 1 addition & 0 deletions src/gpu/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub(crate) mod oam_parser;
pub(crate) mod palette;
pub(crate) mod states;
pub mod tile_parser;

Expand Down
26 changes: 15 additions & 11 deletions src/gpu/oam_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ pub(crate) enum Priority {
}

pub(crate) enum Palette {
_0BP0,
_0BP1,
OBP0,
OBP1,
}

pub(crate) struct SpriteData {
Expand Down Expand Up @@ -40,16 +40,17 @@ impl GameBoy {
true => Priority::AboveLightColor,
},
palette: match flags.get_bit(4) {
false => Palette::_0BP0,
true => Palette::_0BP1,
false => Palette::OBP0,
true => Palette::OBP1,
},
x_flip: flags.get_bit(5),
y_flip: flags.get_bit(6),
}
}

pub(crate) fn get_sprite_fifo(&self, x: u8, y: u8) -> Option<Line> {
let mut sprite_fifo: Option<Line> = None;
pub(crate) fn get_sprite_fifo(&self, x: u8, y: u8) -> Option<(Line, &SpriteData)> {
let mut sprite_fifo: Option<(Line, &SpriteData)> = None;

for sprite in &self.gpu.sprites {
if sprite.y < 16 || sprite.x < 8 {
continue;
Expand All @@ -66,11 +67,14 @@ impl GameBoy {
let y_condition = ((sprite_y)..(sprite_y + 7)).contains(&y);

if x_condition && y_condition {
sprite_fifo = Some(self.get_line_rotation(
sprite.tile_number,
y as u16 % 8,
sprite.x_flip,
sprite.y_flip,
sprite_fifo = Some((
self.get_line_rotation(
sprite.tile_number,
y as u16 % 8,
sprite.x_flip,
sprite.y_flip,
),
sprite,
));
}
}
Expand Down
40 changes: 40 additions & 0 deletions src/gpu/palette.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use crate::{
common::Bit,
consts::gpu::{OBP0, OBP1},
GameBoy,
};

use super::{oam_parser::Palette, tile_parser::Line, Color};

pub(crate) fn bools_to_color(bool1: bool, bool2: bool) -> Color {
match (bool1, bool2) {
(false, false) => Color::Light,
(false, true) => Color::MediumlyLight,
(true, false) => Color::MediumlyDark,
(true, true) => Color::Dark,
}
}

impl GameBoy {
pub(crate) fn apply_palette_to_sprite(&self, line: &mut Line, palette: &Palette) {
let palette = match palette {
Palette::OBP0 => self.bus[OBP0],
Palette::OBP1 => self.bus[OBP1],
};

let id_1 = bools_to_color(palette.get_bit(3), palette.get_bit(2));
let id_2 = bools_to_color(palette.get_bit(5), palette.get_bit(4));
let id_3 = bools_to_color(palette.get_bit(7), palette.get_bit(6));

for pixel in line.colors.iter_mut() {
*pixel = match pixel {
Color::MediumlyLight => id_1,
Color::MediumlyDark => id_2,
Color::Dark => id_3,

// Light will not change because light just means transparent in a sprite
Color::Light => Color::Light,
}
}
}
}
8 changes: 5 additions & 3 deletions src/gpu/states.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
GameBoy,
};

use super::{oam_parser::SpriteData, tile_parser::Line, Color};
use super::{oam_parser::SpriteData, Color};

#[derive(PartialEq)]
pub enum GPUState {
Expand Down Expand Up @@ -96,10 +96,12 @@ impl GameBoy {

// And we get both background/window fifo and the sprite fifo
let background_fifo = self.get_line(self.bus[tile_map_address], self.gpu.y as u16 % 8);
let sprite_fifo: Option<Line> = self.get_sprite_fifo(self.gpu.x, self.gpu.y);
let mut sprite_fifo = self.get_sprite_fifo(self.gpu.x, self.gpu.y);

// TODO: Implement fifo mixing
if let Some(sprite_fifo) = sprite_fifo {
if let Some((sprite_fifo, sprite_data)) = &mut sprite_fifo {
self.apply_palette_to_sprite(sprite_fifo, &sprite_data.palette);

if self.gpu.rendered_sprites_on_line < 10 {
self.draw_line(&sprite_fifo, self.gpu.x as usize, self.gpu.y as usize);
self.gpu.rendered_sprites_on_line += 1;
Expand Down
9 changes: 2 additions & 7 deletions src/gpu/tile_parser.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{common::Bit, consts::gpu::LCDC, GameBoy};

use super::Color;
use super::{palette::bools_to_color, Color};

pub struct Line {
pub colors: [Color; 8],
Expand Down Expand Up @@ -37,12 +37,7 @@ impl Line {
let num1_bit = num1.get_bit(7 - bit_offset);
let num2_bit = num2.get_bit(7 - bit_offset);

self.colors[bit_offset as usize] = match (num1_bit, num2_bit) {
(false, false) => Color::Light,
(false, true) => Color::MediumlyLight,
(true, false) => Color::MediumlyDark,
(true, true) => Color::Dark,
};
self.colors[bit_offset as usize] = bools_to_color(num1_bit, num2_bit);
}
}
}
Expand Down

0 comments on commit 4a059db

Please sign in to comment.