PPU: Fixed mode 5 when using 16x16 tiles
This commit is contained in:
parent
e80d6fcd7f
commit
75dee8b8e4
2 changed files with 110 additions and 93 deletions
188
Core/Ppu.cpp
188
Core/Ppu.cpp
|
@ -16,6 +16,8 @@ Ppu::Ppu(shared_ptr<Console> console)
|
|||
|
||||
_outputBuffers[0] = new uint16_t[512 * 478];
|
||||
_outputBuffers[1] = new uint16_t[512 * 478];
|
||||
memset(_outputBuffers[0], 0, 512 * 478);
|
||||
memset(_outputBuffers[1], 0, 512 * 478);
|
||||
|
||||
_currentBuffer = _outputBuffers[0];
|
||||
|
||||
|
@ -351,6 +353,7 @@ void Ppu::RenderScanline()
|
|||
|
||||
if(_forcedVblank) {
|
||||
RenderBgColor<true>();
|
||||
RenderBgColor<false>();
|
||||
ApplyHiResMode();
|
||||
return;
|
||||
}
|
||||
|
@ -473,67 +476,7 @@ void Ppu::RenderSprites()
|
|||
}
|
||||
}
|
||||
|
||||
template<uint8_t layerIndex, uint8_t bpp, bool processHighPriority, bool forMainScreen, uint16_t basePaletteOffset, bool largeTileWidth, bool largeTileHeight, uint8_t activeWindowCount, bool applyMosaic>
|
||||
void Ppu::RenderTilemap()
|
||||
{
|
||||
if(_directColorMode) {
|
||||
RenderTilemap<layerIndex, bpp, processHighPriority, forMainScreen, basePaletteOffset, largeTileWidth, largeTileHeight, activeWindowCount, applyMosaic, true>();
|
||||
} else {
|
||||
RenderTilemap<layerIndex, bpp, processHighPriority, forMainScreen, basePaletteOffset, largeTileWidth, largeTileHeight, activeWindowCount, applyMosaic, false>();
|
||||
}
|
||||
}
|
||||
|
||||
template<uint8_t layerIndex, uint8_t bpp, bool processHighPriority, bool forMainScreen, uint16_t basePaletteOffset, bool largeTileWidth, bool largeTileHeight, uint8_t activeWindowCount>
|
||||
void Ppu::RenderTilemap()
|
||||
{
|
||||
bool applyMosaic = forMainScreen && ((_mosaicEnabled >> layerIndex) & 0x01) != 0;
|
||||
|
||||
if(applyMosaic) {
|
||||
RenderTilemap<layerIndex, bpp, processHighPriority, forMainScreen, basePaletteOffset, largeTileWidth, largeTileHeight, activeWindowCount, true>();
|
||||
} else {
|
||||
RenderTilemap<layerIndex, bpp, processHighPriority, forMainScreen, basePaletteOffset, largeTileWidth, largeTileHeight, activeWindowCount, false>();
|
||||
}
|
||||
}
|
||||
|
||||
template<uint8_t layerIndex, uint8_t bpp, bool processHighPriority, bool forMainScreen, uint16_t basePaletteOffset, bool largeTileWidth, bool largeTileHeight>
|
||||
void Ppu::RenderTilemap()
|
||||
{
|
||||
uint8_t activeWindowCount = 0;
|
||||
if((forMainScreen && _windowMaskMain[layerIndex]) || (!forMainScreen && _windowMaskSub[layerIndex])) {
|
||||
activeWindowCount = (uint8_t)_window[0].ActiveLayers[layerIndex] + (uint8_t)_window[1].ActiveLayers[layerIndex];
|
||||
}
|
||||
|
||||
if(activeWindowCount == 0) {
|
||||
RenderTilemap<layerIndex, bpp, processHighPriority, forMainScreen, basePaletteOffset, largeTileWidth, largeTileHeight, 0>();
|
||||
} else if(activeWindowCount == 1) {
|
||||
RenderTilemap<layerIndex, bpp, processHighPriority, forMainScreen, basePaletteOffset, largeTileWidth, largeTileHeight, 1>();
|
||||
} else {
|
||||
RenderTilemap<layerIndex, bpp, processHighPriority, forMainScreen, basePaletteOffset, largeTileWidth, largeTileHeight, 2>();
|
||||
}
|
||||
}
|
||||
|
||||
template<uint8_t layerIndex, uint8_t bpp, bool processHighPriority, bool forMainScreen, uint16_t basePaletteOffset>
|
||||
void Ppu::RenderTilemap()
|
||||
{
|
||||
bool largeTileWidth = _layerConfig[layerIndex].LargeTiles || _bgMode == 5;
|
||||
bool largeTileHeight = _layerConfig[layerIndex].LargeTiles;
|
||||
|
||||
if(largeTileWidth) {
|
||||
if(largeTileHeight) {
|
||||
RenderTilemap<layerIndex, bpp, processHighPriority, forMainScreen, basePaletteOffset, true, true>();
|
||||
} else {
|
||||
RenderTilemap<layerIndex, bpp, processHighPriority, forMainScreen, basePaletteOffset, true, false>();
|
||||
}
|
||||
} else {
|
||||
if(largeTileHeight) {
|
||||
RenderTilemap<layerIndex, bpp, processHighPriority, forMainScreen, basePaletteOffset, false, true>();
|
||||
} else {
|
||||
RenderTilemap<layerIndex, bpp, processHighPriority, forMainScreen, basePaletteOffset, false, false>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<uint8_t layerIndex, uint8_t bpp, bool processHighPriority, bool forMainScreen, uint16_t basePaletteOffset, bool largeTileWidth, bool largeTileHeight, uint8_t activeWindowCount, bool applyMosaic, bool directColorMode>
|
||||
template<uint8_t layerIndex, uint8_t bpp, bool processHighPriority, bool forMainScreen, uint16_t basePaletteOffset, bool hiResMode, bool largeTileWidth, bool largeTileHeight, uint8_t activeWindowCount, bool applyMosaic, bool directColorMode>
|
||||
void Ppu::RenderTilemap()
|
||||
{
|
||||
if(!IsRenderRequired<forMainScreen>(layerIndex)) {
|
||||
|
@ -573,7 +516,7 @@ void Ppu::RenderTilemap()
|
|||
for(int x = 0; x < 256; x++) {
|
||||
/* The current pixel x position (normally 0-255, but 0-511 in hi-res mode - even on subscreen, odd on main screen) */
|
||||
uint16_t realX;
|
||||
if(largeTileWidth && !largeTileHeight) {
|
||||
if(hiResMode) {
|
||||
realX = (x << 1) + (forMainScreen ? 1 : 0);
|
||||
} else {
|
||||
realX = x;
|
||||
|
@ -706,28 +649,6 @@ uint16_t Ppu::GetTilePixelColor(const uint16_t pixelStart, const uint8_t shift)
|
|||
return color;
|
||||
}
|
||||
|
||||
template<uint8_t layerIndex, bool forMainScreen, bool processHighPriority>
|
||||
void Ppu::RenderTilemapMode7()
|
||||
{
|
||||
bool applyMosaic = forMainScreen && ((_mosaicEnabled >> layerIndex) & 0x01) != 0;
|
||||
|
||||
if(applyMosaic) {
|
||||
RenderTilemapMode7<layerIndex, forMainScreen, processHighPriority, true>();
|
||||
} else {
|
||||
RenderTilemapMode7<layerIndex, forMainScreen, processHighPriority, false>();
|
||||
}
|
||||
}
|
||||
|
||||
template<uint8_t layerIndex, bool forMainScreen, bool processHighPriority, bool applyMosaic>
|
||||
void Ppu::RenderTilemapMode7()
|
||||
{
|
||||
if(_directColorMode) {
|
||||
RenderTilemapMode7<layerIndex, forMainScreen, processHighPriority, applyMosaic, true>();
|
||||
} else {
|
||||
RenderTilemapMode7<layerIndex, forMainScreen, processHighPriority, applyMosaic, false>();
|
||||
}
|
||||
}
|
||||
|
||||
template<uint8_t layerIndex, bool forMainScreen, bool processHighPriority, bool applyMosaic, bool directColorMode>
|
||||
void Ppu::RenderTilemapMode7()
|
||||
{
|
||||
|
@ -957,7 +878,7 @@ void Ppu::ApplyHiResMode()
|
|||
{
|
||||
uint32_t screenY = _screenInterlace ? ((_frameCount & 0x01) ? ((_scanline << 1) + 1) : (_scanline << 1)) : _scanline;
|
||||
|
||||
if(_hiresMode || _bgMode == 5 || _bgMode == 6) {
|
||||
if(_hiResMode || _bgMode == 5 || _bgMode == 6) {
|
||||
ApplyBrightness<false>();
|
||||
for(int i = 0; i < 512; i += 2) {
|
||||
_currentBuffer[(screenY << 9) + i] = _subScreenBuffer[i >> 1];
|
||||
|
@ -1007,7 +928,7 @@ void Ppu::SendFrame()
|
|||
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
if(_hiresMode || _bgMode == 5 || _bgMode == 6) {
|
||||
if(_hiResMode || _bgMode == 5 || _bgMode == 6) {
|
||||
width = 512;
|
||||
} else {
|
||||
width = 256;
|
||||
|
@ -1466,7 +1387,7 @@ void Ppu::Write(uint32_t addr, uint8_t value)
|
|||
//SETINI - Screen Mode/Video Select
|
||||
//_externalSync = (value & 0x80) != 0; //NOT USED
|
||||
_mode7.ExtBgEnabled = (value & 0x40) != 0;
|
||||
_hiresMode = (value & 0x08) != 0;
|
||||
_hiResMode = (value & 0x08) != 0;
|
||||
_overscanMode = (value & 0x04) != 0;
|
||||
//_objInterlace = (value & 0x02) != 0; //TODO
|
||||
_screenInterlace = (value & 0x01) != 0;
|
||||
|
@ -1477,3 +1398,96 @@ void Ppu::Write(uint32_t addr, uint8_t value)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Everything below this point is used to select the proper arguments for templates */
|
||||
template<uint8_t layerIndex, uint8_t bpp, bool processHighPriority, bool forMainScreen, uint16_t basePaletteOffset, bool hiResMode, bool largeTileWidth, bool largeTileHeight, uint8_t activeWindowCount, bool applyMosaic>
|
||||
void Ppu::RenderTilemap()
|
||||
{
|
||||
if(_directColorMode) {
|
||||
RenderTilemap<layerIndex, bpp, processHighPriority, forMainScreen, basePaletteOffset, hiResMode, largeTileWidth, largeTileHeight, activeWindowCount, applyMosaic, true>();
|
||||
} else {
|
||||
RenderTilemap<layerIndex, bpp, processHighPriority, forMainScreen, basePaletteOffset, hiResMode, largeTileWidth, largeTileHeight, activeWindowCount, applyMosaic, false>();
|
||||
}
|
||||
}
|
||||
|
||||
template<uint8_t layerIndex, uint8_t bpp, bool processHighPriority, bool forMainScreen, uint16_t basePaletteOffset, bool hiResMode, bool largeTileWidth, bool largeTileHeight, uint8_t activeWindowCount>
|
||||
void Ppu::RenderTilemap()
|
||||
{
|
||||
bool applyMosaic = forMainScreen && ((_mosaicEnabled >> layerIndex) & 0x01) != 0;
|
||||
|
||||
if(applyMosaic) {
|
||||
RenderTilemap<layerIndex, bpp, processHighPriority, forMainScreen, basePaletteOffset, hiResMode, largeTileWidth, largeTileHeight, activeWindowCount, true>();
|
||||
} else {
|
||||
RenderTilemap<layerIndex, bpp, processHighPriority, forMainScreen, basePaletteOffset, hiResMode, largeTileWidth, largeTileHeight, activeWindowCount, false>();
|
||||
}
|
||||
}
|
||||
|
||||
template<uint8_t layerIndex, uint8_t bpp, bool processHighPriority, bool forMainScreen, uint16_t basePaletteOffset, bool hiResMode, bool largeTileWidth, bool largeTileHeight>
|
||||
void Ppu::RenderTilemap()
|
||||
{
|
||||
uint8_t activeWindowCount = 0;
|
||||
if((forMainScreen && _windowMaskMain[layerIndex]) || (!forMainScreen && _windowMaskSub[layerIndex])) {
|
||||
activeWindowCount = (uint8_t)_window[0].ActiveLayers[layerIndex] + (uint8_t)_window[1].ActiveLayers[layerIndex];
|
||||
}
|
||||
|
||||
if(activeWindowCount == 0) {
|
||||
RenderTilemap<layerIndex, bpp, processHighPriority, forMainScreen, basePaletteOffset, hiResMode, largeTileWidth, largeTileHeight, 0>();
|
||||
} else if(activeWindowCount == 1) {
|
||||
RenderTilemap<layerIndex, bpp, processHighPriority, forMainScreen, basePaletteOffset, hiResMode, largeTileWidth, largeTileHeight, 1>();
|
||||
} else {
|
||||
RenderTilemap<layerIndex, bpp, processHighPriority, forMainScreen, basePaletteOffset, hiResMode, largeTileWidth, largeTileHeight, 2>();
|
||||
}
|
||||
}
|
||||
|
||||
template<uint8_t layerIndex, uint8_t bpp, bool processHighPriority, bool forMainScreen, uint16_t basePaletteOffset, bool hiResMode>
|
||||
void Ppu::RenderTilemap()
|
||||
{
|
||||
bool largeTileWidth = _layerConfig[layerIndex].LargeTiles | hiResMode;
|
||||
bool largeTileHeight = _layerConfig[layerIndex].LargeTiles;
|
||||
|
||||
if(largeTileWidth) {
|
||||
if(largeTileHeight) {
|
||||
RenderTilemap<layerIndex, bpp, processHighPriority, forMainScreen, basePaletteOffset, hiResMode, true, true>();
|
||||
} else {
|
||||
RenderTilemap<layerIndex, bpp, processHighPriority, forMainScreen, basePaletteOffset, hiResMode, true, false>();
|
||||
}
|
||||
} else {
|
||||
if(largeTileHeight) {
|
||||
RenderTilemap<layerIndex, bpp, processHighPriority, forMainScreen, basePaletteOffset, hiResMode, false, true>();
|
||||
} else {
|
||||
RenderTilemap<layerIndex, bpp, processHighPriority, forMainScreen, basePaletteOffset, hiResMode, false, false>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<uint8_t layerIndex, uint8_t bpp, bool processHighPriority, bool forMainScreen, uint16_t basePaletteOffset>
|
||||
void Ppu::RenderTilemap()
|
||||
{
|
||||
if(_hiResMode || _bgMode == 5 || _bgMode == 6) {
|
||||
RenderTilemap<layerIndex, bpp, processHighPriority, forMainScreen, basePaletteOffset, true>();
|
||||
} else {
|
||||
RenderTilemap<layerIndex, bpp, processHighPriority, forMainScreen, basePaletteOffset, false>();
|
||||
}
|
||||
}
|
||||
|
||||
template<uint8_t layerIndex, bool forMainScreen, bool processHighPriority>
|
||||
void Ppu::RenderTilemapMode7()
|
||||
{
|
||||
bool applyMosaic = forMainScreen && ((_mosaicEnabled >> layerIndex) & 0x01) != 0;
|
||||
|
||||
if(applyMosaic) {
|
||||
RenderTilemapMode7<layerIndex, forMainScreen, processHighPriority, true>();
|
||||
} else {
|
||||
RenderTilemapMode7<layerIndex, forMainScreen, processHighPriority, false>();
|
||||
}
|
||||
}
|
||||
|
||||
template<uint8_t layerIndex, bool forMainScreen, bool processHighPriority, bool applyMosaic>
|
||||
void Ppu::RenderTilemapMode7()
|
||||
{
|
||||
if(_directColorMode) {
|
||||
RenderTilemapMode7<layerIndex, forMainScreen, processHighPriority, applyMosaic, true>();
|
||||
} else {
|
||||
RenderTilemapMode7<layerIndex, forMainScreen, processHighPriority, applyMosaic, false>();
|
||||
}
|
||||
}
|
||||
|
|
13
Core/Ppu.h
13
Core/Ppu.h
|
@ -112,7 +112,7 @@ private:
|
|||
bool _timeOver = false;
|
||||
bool _rangeOver = false;
|
||||
|
||||
bool _hiresMode = false;
|
||||
bool _hiResMode = false;
|
||||
bool _screenInterlace = false;
|
||||
bool _overscanMode = false;
|
||||
bool _directColorMode = false;
|
||||
|
@ -156,16 +156,19 @@ private:
|
|||
template<uint8_t layerIndex, uint8_t bpp, bool processHighPriority, bool forMainScreen, uint16_t basePaletteOffset = 0>
|
||||
__forceinline void RenderTilemap();
|
||||
|
||||
template<uint8_t layerIndex, uint8_t bpp, bool processHighPriority, bool forMainScreen, uint16_t basePaletteOffset, bool largeTileWidth, bool largeTileHeight>
|
||||
template<uint8_t layerIndex, uint8_t bpp, bool processHighPriority, bool forMainScreen, uint16_t basePaletteOffset, bool hiResMode>
|
||||
__forceinline void RenderTilemap();
|
||||
|
||||
template<uint8_t layerIndex, uint8_t bpp, bool processHighPriority, bool forMainScreen, uint16_t basePaletteOffset, bool largeTileWidth, bool largeTileHeight, uint8_t activeWindowCount>
|
||||
template<uint8_t layerIndex, uint8_t bpp, bool processHighPriority, bool forMainScreen, uint16_t basePaletteOffset, bool hiResMode, bool largeTileWidth, bool largeTileHeight>
|
||||
__forceinline void RenderTilemap();
|
||||
|
||||
template<uint8_t layerIndex, uint8_t bpp, bool processHighPriority, bool forMainScreen, uint16_t basePaletteOffset, bool largeTileWidth, bool largeTileHeight, uint8_t activeWindowCount, bool applyMosaic>
|
||||
template<uint8_t layerIndex, uint8_t bpp, bool processHighPriority, bool forMainScreen, uint16_t basePaletteOffset, bool hiResMode, bool largeTileWidth, bool largeTileHeight, uint8_t activeWindowCount>
|
||||
__forceinline void RenderTilemap();
|
||||
|
||||
template<uint8_t layerIndex, uint8_t bpp, bool processHighPriority, bool forMainScreen, uint16_t basePaletteOffset, bool largeTileWidth, bool largeTileHeight, uint8_t activeWindowCount, bool applyMosaic, bool directColorMode>
|
||||
template<uint8_t layerIndex, uint8_t bpp, bool processHighPriority, bool forMainScreen, uint16_t basePaletteOffset, bool hiResMode, bool largeTileWidth, bool largeTileHeight, uint8_t activeWindowCount, bool applyMosaic>
|
||||
__forceinline void RenderTilemap();
|
||||
|
||||
template<uint8_t layerIndex, uint8_t bpp, bool processHighPriority, bool forMainScreen, uint16_t basePaletteOffset, bool hiResMode, bool largeTileWidth, bool largeTileHeight, uint8_t activeWindowCount, bool applyMosaic, bool directColorMode>
|
||||
void RenderTilemap();
|
||||
|
||||
template<bool forMainScreen>
|
||||
|
|
Loading…
Add table
Reference in a new issue