2019-02-13 13:32:21 -05:00
|
|
|
#pragma once
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include "PpuTypes.h"
|
|
|
|
|
2019-02-13 18:44:39 -05:00
|
|
|
class Console;
|
2019-02-17 15:37:31 -05:00
|
|
|
class InternalRegisters;
|
2019-02-13 18:44:39 -05:00
|
|
|
|
2019-02-19 23:37:27 -05:00
|
|
|
struct SpriteInfo
|
|
|
|
{
|
|
|
|
int16_t X;
|
|
|
|
bool HorizontalMirror;
|
|
|
|
bool VerticalMirror;
|
|
|
|
uint8_t Priority;
|
|
|
|
|
|
|
|
uint8_t TileColumn;
|
|
|
|
uint8_t TileRow;
|
|
|
|
uint8_t Palette;
|
|
|
|
bool UseSecondTable;
|
|
|
|
uint8_t LargeSprite;
|
|
|
|
};
|
|
|
|
|
2019-02-13 13:32:21 -05:00
|
|
|
class Ppu
|
|
|
|
{
|
2019-02-15 21:33:13 -05:00
|
|
|
public:
|
|
|
|
constexpr static uint32_t SpriteRamSize = 544;
|
|
|
|
constexpr static uint32_t CgRamSize = 512;
|
|
|
|
constexpr static uint32_t VideoRamSize = 0x10000;
|
|
|
|
|
2019-02-13 13:32:21 -05:00
|
|
|
private:
|
2019-02-17 22:44:57 -05:00
|
|
|
constexpr static const uint8_t _oamSizes[8][2][2] = {
|
|
|
|
{ { 1, 1 }, { 2, 2 } }, //8x8 + 16x16
|
|
|
|
{ { 1, 1 }, { 4, 4 } }, //8x8 + 32x32
|
|
|
|
{ { 1, 1 }, { 8, 8 } }, //8x8 + 64x64
|
|
|
|
{ { 2, 2 }, { 4, 4 } }, //16x16 + 32x32
|
|
|
|
{ { 2, 2 }, { 8, 8 } }, //16x16 + 64x64
|
|
|
|
{ { 4, 4 }, { 8, 8 } }, //32x32 + 64x64
|
|
|
|
{ { 2, 4 }, { 4, 8 } }, //16x32 + 32x64
|
|
|
|
{ { 2, 4 }, { 4, 4 } } //16x32 + 32x32
|
|
|
|
};
|
|
|
|
|
2019-02-13 18:44:39 -05:00
|
|
|
shared_ptr<Console> _console;
|
2019-02-17 15:37:31 -05:00
|
|
|
shared_ptr<InternalRegisters> _regs;
|
2019-02-13 18:44:39 -05:00
|
|
|
|
2019-02-19 18:01:27 -05:00
|
|
|
bool _forcedVblank = false;
|
|
|
|
uint8_t _screenBrightness = 0;
|
|
|
|
|
2019-02-13 13:32:21 -05:00
|
|
|
uint16_t _cycle = 0;
|
|
|
|
uint16_t _scanline = 0;
|
|
|
|
uint32_t _frameCount = 0;
|
2019-02-17 01:09:47 -05:00
|
|
|
|
2019-02-17 00:32:41 -05:00
|
|
|
uint8_t _bgMode = 0;
|
2019-02-19 01:26:48 -05:00
|
|
|
bool _mode1Bg3Priority = false;
|
2019-02-17 23:26:49 -05:00
|
|
|
|
|
|
|
uint8_t _mainScreenLayers = 0;
|
2019-02-19 01:26:48 -05:00
|
|
|
uint8_t _subScreenLayers = 0;
|
2019-02-17 00:32:41 -05:00
|
|
|
LayerConfig _layerConfig[4];
|
|
|
|
|
2019-02-13 18:44:39 -05:00
|
|
|
uint8_t *_vram;
|
|
|
|
uint16_t _vramAddress;
|
|
|
|
uint8_t _vramIncrementValue;
|
|
|
|
uint8_t _vramAddressRemapping;
|
|
|
|
bool _vramAddrIncrementOnSecondReg;
|
2019-02-21 07:27:47 -05:00
|
|
|
uint8_t _vramReadBuffer = 0;
|
2019-02-13 18:44:39 -05:00
|
|
|
|
|
|
|
uint16_t _cgramAddress;
|
2019-02-15 21:33:13 -05:00
|
|
|
uint8_t _cgram[Ppu::CgRamSize];
|
|
|
|
|
2019-02-13 18:44:39 -05:00
|
|
|
uint16_t *_outputBuffers[2];
|
2019-02-19 23:35:43 -05:00
|
|
|
|
2019-02-19 23:37:27 -05:00
|
|
|
SpriteInfo _sprites[32] = {};
|
|
|
|
uint8_t _spriteCount = 0;
|
|
|
|
uint8_t _spritePriority[256] = {};
|
|
|
|
uint8_t _spritePalette[256] = {};
|
|
|
|
uint16_t _spritePixels[256] = {};
|
|
|
|
|
2019-02-19 23:35:43 -05:00
|
|
|
uint8_t _rowPixelFlags[256];
|
2019-02-13 18:44:39 -05:00
|
|
|
uint16_t *_currentBuffer;
|
2019-02-13 13:32:21 -05:00
|
|
|
|
2019-02-19 01:26:48 -05:00
|
|
|
bool _subScreenFilled[256];
|
|
|
|
uint16_t *_subScreenBuffer;
|
|
|
|
|
2019-02-20 17:39:14 -05:00
|
|
|
uint16_t _mosaicColor[256] = {};
|
|
|
|
uint8_t _mosaicSize = 0;
|
|
|
|
uint8_t _mosaicEnabled = 0;
|
|
|
|
uint16_t _mosaicStartScanline = 0;
|
|
|
|
|
2019-02-17 21:09:33 -05:00
|
|
|
uint8_t _oamMode = 0;
|
2019-02-17 22:44:57 -05:00
|
|
|
uint16_t _oamBaseAddress = 0;
|
|
|
|
uint16_t _oamAddressOffset = 0;
|
2019-02-17 21:09:33 -05:00
|
|
|
|
|
|
|
uint8_t _oamRam[Ppu::SpriteRamSize];
|
|
|
|
uint16_t _oamRamAddress = 0;
|
|
|
|
bool _enableOamPriority = false;
|
|
|
|
|
|
|
|
uint16_t _internalOamAddress = 0;
|
|
|
|
uint8_t _oamWriteBuffer = 0;
|
|
|
|
|
2019-02-19 18:01:27 -05:00
|
|
|
bool _timeOver = false;
|
|
|
|
bool _rangeOver = false;
|
|
|
|
|
2019-02-18 22:27:22 -05:00
|
|
|
bool _directColorMode = false;
|
|
|
|
|
2019-02-17 23:53:19 -05:00
|
|
|
uint8_t _colorMathClipMode = 0;
|
|
|
|
uint8_t _colorMathPreventMode = 0;
|
|
|
|
bool _colorMathAddSubscreen = false;
|
|
|
|
uint8_t _colorMathEnabled = 0;
|
|
|
|
bool _colorMathSubstractMode = false;
|
|
|
|
bool _colorMathHalveResult = false;
|
2019-02-19 23:35:43 -05:00
|
|
|
uint16_t _fixedColor = 0;
|
2019-02-17 23:53:19 -05:00
|
|
|
|
2019-02-19 17:23:21 -05:00
|
|
|
uint8_t _hvScrollLatchValue = 0;
|
|
|
|
uint8_t _hScrollLatchValue = 0;
|
|
|
|
|
2019-02-21 07:27:47 -05:00
|
|
|
uint16_t _horizontalLocation = 0;
|
|
|
|
bool _horizontalLocToggle = false;
|
|
|
|
|
|
|
|
uint16_t _verticalLocation = 0;
|
|
|
|
bool _verticalLocationToggle = false;
|
|
|
|
|
2019-02-21 08:15:00 -05:00
|
|
|
uint16_t _mode7MatrixA = 0;
|
|
|
|
uint16_t _mode7MatrixB = 0;
|
|
|
|
uint8_t _mode7Latch = 0;
|
|
|
|
|
2019-02-19 01:26:48 -05:00
|
|
|
template<bool forMainScreen>
|
|
|
|
void RenderBgColor();
|
|
|
|
|
2019-02-19 22:44:05 -05:00
|
|
|
template<uint8_t layerIndex, uint8_t bpp, bool processHighPriority, bool forMainScreen, uint16_t basePaletteOffset = 0>
|
2019-02-19 01:26:48 -05:00
|
|
|
void RenderTilemap();
|
|
|
|
|
|
|
|
template<uint8_t priority, bool forMainScreen>
|
2019-02-17 23:26:49 -05:00
|
|
|
void DrawSprites();
|
2019-02-13 23:03:01 -05:00
|
|
|
|
2019-02-19 01:26:48 -05:00
|
|
|
void RenderScanline();
|
|
|
|
void ApplyColorMath();
|
|
|
|
void SendFrame();
|
|
|
|
|
2019-02-13 18:44:39 -05:00
|
|
|
public:
|
|
|
|
Ppu(shared_ptr<Console> console);
|
2019-02-16 01:16:57 -05:00
|
|
|
~Ppu();
|
2019-02-13 13:32:21 -05:00
|
|
|
|
2019-02-17 19:54:29 -05:00
|
|
|
uint32_t GetFrameCount();
|
2019-02-13 18:44:39 -05:00
|
|
|
PpuState GetState();
|
2019-02-13 13:32:21 -05:00
|
|
|
|
2019-02-13 18:44:39 -05:00
|
|
|
void Exec();
|
2019-02-13 13:32:21 -05:00
|
|
|
|
2019-02-15 21:33:13 -05:00
|
|
|
uint8_t* GetVideoRam();
|
|
|
|
uint8_t* GetCgRam();
|
|
|
|
uint8_t* GetSpriteRam();
|
|
|
|
|
2019-02-21 07:27:47 -05:00
|
|
|
void LatchLocationValues();
|
|
|
|
|
2019-02-13 18:44:39 -05:00
|
|
|
uint8_t Read(uint16_t addr);
|
|
|
|
void Write(uint32_t addr, uint8_t value);
|
2019-02-13 13:32:21 -05:00
|
|
|
};
|