PPU: Code refactoring
This commit is contained in:
parent
16cc0653e9
commit
073e7b2bf3
2 changed files with 100 additions and 89 deletions
183
Core/Ppu.cpp
183
Core/Ppu.cpp
|
@ -218,54 +218,6 @@ void Ppu::EvaluateNextLineSprites()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<uint8_t priority, bool forMainScreen>
|
|
||||||
void Ppu::RenderSprites()
|
|
||||||
{
|
|
||||||
uint8_t activeWindowCount = 0;
|
|
||||||
if(forMainScreen) {
|
|
||||||
if(_pixelsDrawn == 256 || (_mainScreenLayers & 0x10) == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(_windowMaskMain[Ppu::SpriteLayerIndex]) {
|
|
||||||
activeWindowCount = (uint8_t)_window[0].ActiveLayers[Ppu::SpriteLayerIndex] + (uint8_t)_window[1].ActiveLayers[Ppu::SpriteLayerIndex];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(_subPixelsDrawn == 256 || (_subScreenLayers & 0x10) == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(_windowMaskSub[Ppu::SpriteLayerIndex]) {
|
|
||||||
activeWindowCount = (uint8_t)_window[0].ActiveLayers[Ppu::SpriteLayerIndex] + (uint8_t)_window[1].ActiveLayers[Ppu::SpriteLayerIndex];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(forMainScreen) {
|
|
||||||
for(int x = 0; x < 256; x++) {
|
|
||||||
if(!_rowPixelFlags[x] && _spritePriority[x] == priority) {
|
|
||||||
if(activeWindowCount && ProcessMaskWindow<Ppu::SpriteLayerIndex>(activeWindowCount, x)) {
|
|
||||||
//This pixel was masked
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
_mainScreenBuffer[x] = _spritePixels[x];
|
|
||||||
_rowPixelFlags[x] |= PixelFlags::Filled | (((_colorMathEnabled & 0x10) && _spritePalette[x] > 3) ? PixelFlags::AllowColorMath : 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for(int x = 0; x < 256; x++) {
|
|
||||||
if(!_subScreenFilled[x] && _spritePriority[x] == priority) {
|
|
||||||
if(activeWindowCount && ProcessMaskWindow<Ppu::SpriteLayerIndex>(activeWindowCount, x)) {
|
|
||||||
//This pixel was masked
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
_subScreenBuffer[x] = _spritePixels[x];
|
|
||||||
_subScreenFilled[x] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<bool forMainScreen>
|
template<bool forMainScreen>
|
||||||
void Ppu::RenderMode0()
|
void Ppu::RenderMode0()
|
||||||
{
|
{
|
||||||
|
@ -464,6 +416,51 @@ void Ppu::RenderBgColor()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<uint8_t priority, bool forMainScreen>
|
||||||
|
void Ppu::RenderSprites()
|
||||||
|
{
|
||||||
|
if(!IsRenderRequired<forMainScreen>(Ppu::SpriteLayerIndex)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t activeWindowCount = 0;
|
||||||
|
if(forMainScreen) {
|
||||||
|
if(_windowMaskMain[Ppu::SpriteLayerIndex]) {
|
||||||
|
activeWindowCount = (uint8_t)_window[0].ActiveLayers[Ppu::SpriteLayerIndex] + (uint8_t)_window[1].ActiveLayers[Ppu::SpriteLayerIndex];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(_windowMaskSub[Ppu::SpriteLayerIndex]) {
|
||||||
|
activeWindowCount = (uint8_t)_window[0].ActiveLayers[Ppu::SpriteLayerIndex] + (uint8_t)_window[1].ActiveLayers[Ppu::SpriteLayerIndex];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(forMainScreen) {
|
||||||
|
for(int x = 0; x < 256; x++) {
|
||||||
|
if(!_rowPixelFlags[x] && _spritePriority[x] == priority) {
|
||||||
|
if(activeWindowCount && ProcessMaskWindow<Ppu::SpriteLayerIndex>(activeWindowCount, x)) {
|
||||||
|
//This pixel was masked
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
_mainScreenBuffer[x] = _spritePixels[x];
|
||||||
|
_rowPixelFlags[x] |= PixelFlags::Filled | (((_colorMathEnabled & 0x10) && _spritePalette[x] > 3) ? PixelFlags::AllowColorMath : 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for(int x = 0; x < 256; x++) {
|
||||||
|
if(!_subScreenFilled[x] && _spritePriority[x] == priority) {
|
||||||
|
if(activeWindowCount && ProcessMaskWindow<Ppu::SpriteLayerIndex>(activeWindowCount, x)) {
|
||||||
|
//This pixel was masked
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
_subScreenBuffer[x] = _spritePixels[x];
|
||||||
|
_subScreenFilled[x] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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 largeTileWidth, bool largeTileHeight, uint8_t activeWindowCount, bool applyMosaic>
|
||||||
void Ppu::RenderTilemap()
|
void Ppu::RenderTilemap()
|
||||||
{
|
{
|
||||||
|
@ -527,16 +524,8 @@ void Ppu::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 largeTileWidth, bool largeTileHeight, uint8_t activeWindowCount, bool applyMosaic, bool directColorMode>
|
||||||
void Ppu::RenderTilemap()
|
void Ppu::RenderTilemap()
|
||||||
{
|
{
|
||||||
if(forMainScreen) {
|
if(!IsRenderRequired<forMainScreen>(layerIndex)) {
|
||||||
if(_pixelsDrawn == 256 || ((_mainScreenLayers >> layerIndex) & 0x01) == 0) {
|
return;
|
||||||
//This screen is disabled, or we've drawn all pixels already
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(_subPixelsDrawn == 256 || ((_subScreenLayers >> layerIndex) & 0x01) == 0) {
|
|
||||||
//This screen is disabled, or we've drawn all pixels already
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Current scanline (in interlaced mode, switches between even and odd rows every frame */
|
/* Current scanline (in interlaced mode, switches between even and odd rows every frame */
|
||||||
|
@ -633,27 +622,7 @@ void Ppu::RenderTilemap()
|
||||||
uint8_t xOffset = (realX + config.HScroll) & 0x07;
|
uint8_t xOffset = (realX + config.HScroll) & 0x07;
|
||||||
uint8_t shift = hMirror ? xOffset : (7 - xOffset);
|
uint8_t shift = hMirror ? xOffset : (7 - xOffset);
|
||||||
|
|
||||||
uint16_t color = 0;
|
uint16_t color = GetTilePixelColor<bpp>(pixelStart, shift);
|
||||||
if(bpp == 2) {
|
|
||||||
color |= (((_vram[pixelStart + 0] >> shift) & 0x01) << 0);
|
|
||||||
color |= (((_vram[pixelStart + 1] >> shift) & 0x01) << 1);
|
|
||||||
} else if(bpp == 4) {
|
|
||||||
color |= (((_vram[pixelStart + 0] >> shift) & 0x01) << 0);
|
|
||||||
color |= (((_vram[pixelStart + 1] >> shift) & 0x01) << 1);
|
|
||||||
color |= (((_vram[pixelStart + 16] >> shift) & 0x01) << 2);
|
|
||||||
color |= (((_vram[pixelStart + 17] >> shift) & 0x01) << 3);
|
|
||||||
} else if(bpp == 8) {
|
|
||||||
color |= (((_vram[pixelStart + 0] >> shift) & 0x01) << 0);
|
|
||||||
color |= (((_vram[pixelStart + 1] >> shift) & 0x01) << 1);
|
|
||||||
color |= (((_vram[pixelStart + 16] >> shift) & 0x01) << 2);
|
|
||||||
color |= (((_vram[pixelStart + 17] >> shift) & 0x01) << 3);
|
|
||||||
color |= (((_vram[pixelStart + 32] >> shift) & 0x01) << 4);
|
|
||||||
color |= (((_vram[pixelStart + 33] >> shift) & 0x01) << 5);
|
|
||||||
color |= (((_vram[pixelStart + 48] >> shift) & 0x01) << 6);
|
|
||||||
color |= (((_vram[pixelStart + 49] >> shift) & 0x01) << 7);
|
|
||||||
} else {
|
|
||||||
throw std::runtime_error("unsupported bpp");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(color > 0) {
|
if(color > 0) {
|
||||||
/* Ignore palette bits for 256-color layers */
|
/* Ignore palette bits for 256-color layers */
|
||||||
|
@ -681,6 +650,50 @@ void Ppu::RenderTilemap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<bool forMainScreen>
|
||||||
|
bool Ppu::IsRenderRequired(uint8_t layerIndex)
|
||||||
|
{
|
||||||
|
if(forMainScreen) {
|
||||||
|
if(_pixelsDrawn == 256 || ((_mainScreenLayers >> layerIndex) & 0x01) == 0) {
|
||||||
|
//This screen is disabled, or we've drawn all pixels already
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(_subPixelsDrawn == 256 || ((_subScreenLayers >> layerIndex) & 0x01) == 0) {
|
||||||
|
//This screen is disabled, or we've drawn all pixels already
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint8_t bpp>
|
||||||
|
uint16_t Ppu::GetTilePixelColor(const uint16_t pixelStart, const uint8_t shift)
|
||||||
|
{
|
||||||
|
uint16_t color;
|
||||||
|
if(bpp == 2) {
|
||||||
|
color = (((_vram[pixelStart + 0] >> shift) & 0x01) << 0);
|
||||||
|
color |= (((_vram[pixelStart + 1] >> shift) & 0x01) << 1);
|
||||||
|
} else if(bpp == 4) {
|
||||||
|
color = (((_vram[pixelStart + 0] >> shift) & 0x01) << 0);
|
||||||
|
color |= (((_vram[pixelStart + 1] >> shift) & 0x01) << 1);
|
||||||
|
color |= (((_vram[pixelStart + 16] >> shift) & 0x01) << 2);
|
||||||
|
color |= (((_vram[pixelStart + 17] >> shift) & 0x01) << 3);
|
||||||
|
} else if(bpp == 8) {
|
||||||
|
color = (((_vram[pixelStart + 0] >> shift) & 0x01) << 0);
|
||||||
|
color |= (((_vram[pixelStart + 1] >> shift) & 0x01) << 1);
|
||||||
|
color |= (((_vram[pixelStart + 16] >> shift) & 0x01) << 2);
|
||||||
|
color |= (((_vram[pixelStart + 17] >> shift) & 0x01) << 3);
|
||||||
|
color |= (((_vram[pixelStart + 32] >> shift) & 0x01) << 4);
|
||||||
|
color |= (((_vram[pixelStart + 33] >> shift) & 0x01) << 5);
|
||||||
|
color |= (((_vram[pixelStart + 48] >> shift) & 0x01) << 6);
|
||||||
|
color |= (((_vram[pixelStart + 49] >> shift) & 0x01) << 7);
|
||||||
|
} else {
|
||||||
|
throw std::runtime_error("unsupported bpp");
|
||||||
|
}
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
template<uint8_t layerIndex, bool forMainScreen, bool processHighPriority>
|
template<uint8_t layerIndex, bool forMainScreen, bool processHighPriority>
|
||||||
void Ppu::RenderTilemapMode7()
|
void Ppu::RenderTilemapMode7()
|
||||||
{
|
{
|
||||||
|
@ -706,16 +719,8 @@ void Ppu::RenderTilemapMode7()
|
||||||
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()
|
||||||
{
|
{
|
||||||
if(forMainScreen) {
|
if(!IsRenderRequired<forMainScreen>(layerIndex)) {
|
||||||
if(_pixelsDrawn == 256 || ((_mainScreenLayers >> layerIndex) & 0x01) == 0) {
|
return;
|
||||||
//This screen is disabled, or we've drawn all pixels already
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(_subPixelsDrawn == 256 || ((_subScreenLayers >> layerIndex) & 0x01) == 0) {
|
|
||||||
//This screen is disabled, or we've drawn all pixels already
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr auto clip = [](int32_t val) { return (val & 0x2000) ? (val | ~0x3ff) : (val & 0x3ff); };
|
constexpr auto clip = [](int32_t val) { return (val & 0x2000) ? (val | ~0x3ff) : (val & 0x3ff); };
|
||||||
|
|
|
@ -167,6 +167,12 @@ private:
|
||||||
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 largeTileWidth, bool largeTileHeight, uint8_t activeWindowCount, bool applyMosaic, bool directColorMode>
|
||||||
void RenderTilemap();
|
void RenderTilemap();
|
||||||
|
|
||||||
|
template<bool forMainScreen>
|
||||||
|
__forceinline bool IsRenderRequired(uint8_t layerIndex);
|
||||||
|
|
||||||
|
template<uint8_t bpp>
|
||||||
|
__forceinline uint16_t GetTilePixelColor(const uint16_t pixelStart, const uint8_t shift);
|
||||||
|
|
||||||
template<uint8_t layerIndex, bool forMainScreen, bool processHighPriority>
|
template<uint8_t layerIndex, bool forMainScreen, bool processHighPriority>
|
||||||
__forceinline void RenderTilemapMode7();
|
__forceinline void RenderTilemapMode7();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue