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[0] = new uint16_t[512 * 478];
|
||||||
_outputBuffers[1] = 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];
|
_currentBuffer = _outputBuffers[0];
|
||||||
|
|
||||||
|
@ -351,6 +353,7 @@ void Ppu::RenderScanline()
|
||||||
|
|
||||||
if(_forcedVblank) {
|
if(_forcedVblank) {
|
||||||
RenderBgColor<true>();
|
RenderBgColor<true>();
|
||||||
|
RenderBgColor<false>();
|
||||||
ApplyHiResMode();
|
ApplyHiResMode();
|
||||||
return;
|
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>
|
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(_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>
|
|
||||||
void Ppu::RenderTilemap()
|
void Ppu::RenderTilemap()
|
||||||
{
|
{
|
||||||
if(!IsRenderRequired<forMainScreen>(layerIndex)) {
|
if(!IsRenderRequired<forMainScreen>(layerIndex)) {
|
||||||
|
@ -573,7 +516,7 @@ void Ppu::RenderTilemap()
|
||||||
for(int x = 0; x < 256; x++) {
|
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) */
|
/* 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;
|
uint16_t realX;
|
||||||
if(largeTileWidth && !largeTileHeight) {
|
if(hiResMode) {
|
||||||
realX = (x << 1) + (forMainScreen ? 1 : 0);
|
realX = (x << 1) + (forMainScreen ? 1 : 0);
|
||||||
} else {
|
} else {
|
||||||
realX = x;
|
realX = x;
|
||||||
|
@ -706,28 +649,6 @@ uint16_t Ppu::GetTilePixelColor(const uint16_t pixelStart, const uint8_t shift)
|
||||||
return color;
|
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>
|
template<uint8_t layerIndex, bool forMainScreen, bool processHighPriority, bool applyMosaic, bool directColorMode>
|
||||||
void Ppu::RenderTilemapMode7()
|
void Ppu::RenderTilemapMode7()
|
||||||
{
|
{
|
||||||
|
@ -957,7 +878,7 @@ void Ppu::ApplyHiResMode()
|
||||||
{
|
{
|
||||||
uint32_t screenY = _screenInterlace ? ((_frameCount & 0x01) ? ((_scanline << 1) + 1) : (_scanline << 1)) : _scanline;
|
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>();
|
ApplyBrightness<false>();
|
||||||
for(int i = 0; i < 512; i += 2) {
|
for(int i = 0; i < 512; i += 2) {
|
||||||
_currentBuffer[(screenY << 9) + i] = _subScreenBuffer[i >> 1];
|
_currentBuffer[(screenY << 9) + i] = _subScreenBuffer[i >> 1];
|
||||||
|
@ -1007,7 +928,7 @@ void Ppu::SendFrame()
|
||||||
|
|
||||||
uint16_t width;
|
uint16_t width;
|
||||||
uint16_t height;
|
uint16_t height;
|
||||||
if(_hiresMode || _bgMode == 5 || _bgMode == 6) {
|
if(_hiResMode || _bgMode == 5 || _bgMode == 6) {
|
||||||
width = 512;
|
width = 512;
|
||||||
} else {
|
} else {
|
||||||
width = 256;
|
width = 256;
|
||||||
|
@ -1466,7 +1387,7 @@ void Ppu::Write(uint32_t addr, uint8_t value)
|
||||||
//SETINI - Screen Mode/Video Select
|
//SETINI - Screen Mode/Video Select
|
||||||
//_externalSync = (value & 0x80) != 0; //NOT USED
|
//_externalSync = (value & 0x80) != 0; //NOT USED
|
||||||
_mode7.ExtBgEnabled = (value & 0x40) != 0;
|
_mode7.ExtBgEnabled = (value & 0x40) != 0;
|
||||||
_hiresMode = (value & 0x08) != 0;
|
_hiResMode = (value & 0x08) != 0;
|
||||||
_overscanMode = (value & 0x04) != 0;
|
_overscanMode = (value & 0x04) != 0;
|
||||||
//_objInterlace = (value & 0x02) != 0; //TODO
|
//_objInterlace = (value & 0x02) != 0; //TODO
|
||||||
_screenInterlace = (value & 0x01) != 0;
|
_screenInterlace = (value & 0x01) != 0;
|
||||||
|
@ -1477,3 +1398,96 @@ void Ppu::Write(uint32_t addr, uint8_t value)
|
||||||
break;
|
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>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
15
Core/Ppu.h
15
Core/Ppu.h
|
@ -112,7 +112,7 @@ private:
|
||||||
bool _timeOver = false;
|
bool _timeOver = false;
|
||||||
bool _rangeOver = false;
|
bool _rangeOver = false;
|
||||||
|
|
||||||
bool _hiresMode = false;
|
bool _hiResMode = false;
|
||||||
bool _screenInterlace = false;
|
bool _screenInterlace = false;
|
||||||
bool _overscanMode = false;
|
bool _overscanMode = false;
|
||||||
bool _directColorMode = false;
|
bool _directColorMode = false;
|
||||||
|
@ -155,17 +155,20 @@ private:
|
||||||
|
|
||||||
template<uint8_t layerIndex, uint8_t bpp, bool processHighPriority, bool forMainScreen, uint16_t basePaletteOffset = 0>
|
template<uint8_t layerIndex, uint8_t bpp, bool processHighPriority, bool forMainScreen, uint16_t basePaletteOffset = 0>
|
||||||
__forceinline void RenderTilemap();
|
__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();
|
__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();
|
__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();
|
__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();
|
void RenderTilemap();
|
||||||
|
|
||||||
template<bool forMainScreen>
|
template<bool forMainScreen>
|
||||||
|
|
Loading…
Add table
Reference in a new issue