nes/src/Oam.h

77 lines
1.9 KiB
C++

//
// Created by Selim Mustafaev on 24.09.2023.
//
#ifndef NES_OAM_H
#define NES_OAM_H
#include "Shifter.h"
#include <cstdint>
#include <cstddef>
#include <tuple>
namespace nes {
class Ppu;
struct SpriteInfo {
uint8_t y = 0xFF;
uint8_t id = 0x00;
uint8_t attr = 0x00;
uint8_t x = 0xFF;
};
struct SpritePixelInfo {
uint8_t pattern = 0;
uint8_t palette = 0;
uint8_t priority = 0;
};
class Oam {
public:
static constexpr size_t OAM_SIZE = 64;
static constexpr size_t MAX_SPRITES_PER_SCANLINE = 8;
static constexpr uint8_t SPRITE_PALETTE_OFFSET = 4;
public:
explicit Oam(Ppu* ppu);
void setAddress(uint8_t address);
[[nodiscard]] uint8_t read() const;
void write(uint8_t value);
void dmaTick(uint64_t cycles);
void dmaStart(uint8_t page);
bool dmaActive() const;
uint8_t address() const;
public:
bool detectVisibleSprites(int16_t scanline, bool bigSprite);
void loadShifters(int16_t scanline, bool bigSprite, bool patternSprite);
void updateShifters();
[[nodiscard]] SpritePixelInfo getPixel();
[[nodiscard]] bool spriteZeroBeingRendered() const;
private:
[[nodiscard]] uint8_t flipByte(uint8_t byte) const;
private:
Ppu* _ppu;
uint8_t _address = 0x00;
SpriteInfo _data[OAM_SIZE];
SpriteInfo _visibleSprites[MAX_SPRITES_PER_SCANLINE];
Shifter _spriteShifters[MAX_SPRITES_PER_SCANLINE];
uint8_t _visibleSpriteCount = 0;
bool _spriteZeroVisible = false;
bool _firstVisibleSpriteBeingRendered = false;
private:
uint8_t _dmaPage = 0;
uint8_t _dmaAddress = 0;
uint8_t _dmaData = 0;
bool _dmaActive = false;
bool _dmaDummy = true;
};
}
#endif //NES_OAM_H