cge_nes 0.1.0

Cycle-accurate NES (Nintendo Entertainment System) emulator library: CPU, PPU, cartridge, input, and iNES ROM loading.
Documentation
//! Raw byte-backed OAM array implementation.
//!
//! `OamArrayRaw` represents OAM as a contiguous byte buffer (4 bytes per
//! entry) and exposes the same public API as `OamArray`. This implementation is
//! selected when the `oam_array_raw` feature is enabled and is useful for
//! reproducing the hardware layout or when working with raw memory.

use crate::ppu::oam::entry::{Attributes, TileIndexNumber};
use crate::ppu::oam::{Entry, Iter, OAM_ARRAY_ENTRIES_COUNT};

const OAM_ARRAY_ENTRY_SIZE: usize = 4;

/// Raw byte-backed OAM storage (4 bytes per sprite entry).
pub struct OamArrayRaw {
    data: [u8; OAM_ARRAY_ENTRY_SIZE * OAM_ARRAY_ENTRIES_COUNT],
}

impl Default for OamArrayRaw {
    fn default() -> Self {
        Self {
            data: [u8::default(); OAM_ARRAY_ENTRY_SIZE * OAM_ARRAY_ENTRIES_COUNT],
        }
    }
}

#[allow(dead_code)]
impl OamArrayRaw {
    /// Create a new, zero-initialized raw OAM array.
    pub fn new() -> Self {
        Self::default()
    }

    /// Read a raw byte from the underlying OAM buffer.
    pub fn data(&self, addr: u8) -> u8 {
        self.data[addr as usize]
    }

    /// Write a raw byte into the underlying OAM buffer.
    pub fn write_data(&mut self, addr: u8, data: u8) {
        self.data[addr as usize] = data;
    }

    /// Get the Y coordinate for the given sprite index.
    pub fn y(&self, sprite_index: u8) -> u8 {
        let addr = (sprite_index << 2) as usize;
        self.data[addr]
    }

    /// Get the tile number for the given sprite index.
    pub fn tile_number(&self, sprite_index: u8) -> TileIndexNumber {
        let addr = (sprite_index << 2) as usize;
        self.data[addr + 1].into()
    }

    /// Get the attribute flags for the given sprite index.
    pub fn attributes(&self, sprite_index: u8) -> Attributes {
        let addr = (sprite_index << 2) as usize;
        Attributes::from_bits_truncate(self.data[addr + 2])
    }

    /// Get the X coordinate for the given sprite index.
    pub fn x(&self, sprite_index: u8) -> u8 {
        let addr = (sprite_index << 2) as usize;
        self.data[addr + 3]
    }

    /// Return a typed `Entry` constructed from the raw bytes for an index.
    pub fn entry(&self, sprite_index: u8) -> Entry {
        let addr = (sprite_index << 2) as usize;
        Entry::with_data(
            self.data[addr],
            self.data[addr + 1],
            Attributes::from_bits_truncate(self.data[addr + 2]),
            self.data[addr + 3],
        )
    }

    /// Iterate over all entries in the raw OAM buffer.
    pub fn iter(&self) -> Iter<'_> {
        Iter {
            array: self,
            index: 0,
        }
    }
}