cge_nes 0.1.2

Cycle-accurate NES (Nintendo Entertainment System) emulator library: CPU, PPU, cartridge, input, and iNES ROM loading.
Documentation
//! PPU mask register flags and conversions.
//!
//! Defines write-only mask flags for $2001 controlling rendering enable bits
//! and color emphasis. Includes conversions from palette emphasis flags.
use crate::ppu::palette::EmphasisFlags;
use crate::ppu::registers::Registers;
use bitflags::bitflags;
use ringbuffer::RingBuffer;

bitflags! {
    /// PPU Mask Register ($2001) - Write Only
    ///
    /// Controls the rendering of sprites and backgrounds, as well as color effects:
    /// - Bit 7: Emphasize blue
    /// - Bit 6: Emphasize green
    /// - Bit 5: Emphasize red
    /// - Bit 4: Show sprites
    /// - Bit 3: Show background
    /// - Bit 2: Show sprites in leftmost 8 pixels
    /// - Bit 1: Show background in leftmost 8 pixels
    /// - Bit 0: Greyscale (0: normal color, 1: greyscale)
    #[derive(Default, PartialEq, Eq, Copy, Clone, Debug)]
    pub struct PpuMaskFlags: u8 {
        const GREYSCALE =               0b00000001;
        const SHOW_BG_LEFTMOST =        0b00000010;
        const SHOW_SPRITES_LEFTMOST =   0b00000100;
        const SHOW_BG =                 0b00001000;
        const SHOW_SPRITES =            0b00010000;
        const EMPHASIZE_RED =           0b00100000;
        const EMPHASIZE_GREEN =         0b01000000;
        const EMPHASIZE_BLUE =          0b10000000;
    }
}

impl From<EmphasisFlags> for PpuMaskFlags {
    fn from(flags: EmphasisFlags) -> Self {
        let mut mask = PpuMaskFlags::empty();
        if flags.contains(EmphasisFlags::EMPHASIZE_RED) {
            mask.insert(PpuMaskFlags::EMPHASIZE_RED);
        }
        if flags.contains(EmphasisFlags::EMPHASIZE_GREEN) {
            mask.insert(PpuMaskFlags::EMPHASIZE_GREEN);
        }
        if flags.contains(EmphasisFlags::EMPHASIZE_BLUE) {
            mask.insert(PpuMaskFlags::EMPHASIZE_BLUE);
        }
        mask
    }
}

impl From<PpuMaskFlags> for EmphasisFlags {
    fn from(flags: PpuMaskFlags) -> Self {
        let mut emphasis = EmphasisFlags::empty();
        if flags.contains(PpuMaskFlags::EMPHASIZE_RED) {
            emphasis.insert(EmphasisFlags::EMPHASIZE_RED);
        }
        if flags.contains(PpuMaskFlags::EMPHASIZE_GREEN) {
            emphasis.insert(EmphasisFlags::EMPHASIZE_GREEN);
        }
        if flags.contains(PpuMaskFlags::EMPHASIZE_BLUE) {
            emphasis.insert(EmphasisFlags::EMPHASIZE_BLUE);
        }
        emphasis
    }
}

impl Registers {
    /// Returns true if sprites should be rendered
    pub fn show_sprites_flag(&self) -> bool {
        //self.ppu_mask.contains(PpuMaskFlags::SHOW_SPRITES)
        self.show_sprites_buffer[0]
    }

    /// Returns true if background should be rendered
    pub fn show_bg_flag(&self) -> bool {
        //self.ppu_mask.contains(PpuMaskFlags::SHOW_BG)
        self.show_bg_buffer[0]
    }

    /// Returns true if either background or sprites should be rendered
    pub fn rendering_enabled(&self) -> bool {
        self.show_sprites_flag() || self.show_bg_flag()
    }

    /// Returns true if sprites should be shown in the leftmost 8 pixels of the screen
    pub fn show_sprites_leftmost_flag(&self) -> bool {
        self.ppu_mask.contains(PpuMaskFlags::SHOW_SPRITES_LEFTMOST)
    }

    /// Returns true if background should be shown in the leftmost 8 pixels of the screen
    pub fn show_bg_leftmost_flag(&self) -> bool {
        self.ppu_mask.contains(PpuMaskFlags::SHOW_BG_LEFTMOST)
    }

    pub fn update_render_toggle_buffers(&mut self) {
        self.show_bg_buffer
            .push(self.ppu_mask.contains(PpuMaskFlags::SHOW_BG));
        self.show_sprites_buffer
            .push(self.ppu_mask.contains(PpuMaskFlags::SHOW_SPRITES));
    }

    pub fn ppu_mask(&self) -> PpuMaskFlags {
        self.ppu_mask
    }

    pub fn greyscale_flag(&self) -> bool {
        self.ppu_mask.contains(PpuMaskFlags::GREYSCALE)
    }
}