77 lines
1.9 KiB
C++
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
|