Optimizations/cleanup in PPU
This commit is contained in:
parent
9db31231ec
commit
62d87d6bab
7 changed files with 35 additions and 35 deletions
|
@ -5,5 +5,5 @@
|
|||
class IVideoDevice
|
||||
{
|
||||
public:
|
||||
virtual void UpdateFrame(uint8_t *outputBuffer) = 0;
|
||||
virtual void UpdateFrame(void *outputBuffer) = 0;
|
||||
};
|
43
Core/PPU.cpp
43
Core/PPU.cpp
|
@ -1,7 +1,6 @@
|
|||
#include "stdafx.h"
|
||||
#include "PPU.h"
|
||||
#include "CPU.h"
|
||||
#include "../Utilities/PNGWriter.h"
|
||||
|
||||
PPU* PPU::Instance = nullptr;
|
||||
IVideoDevice *PPU::VideoDevice = nullptr;
|
||||
|
@ -27,7 +26,7 @@ PPU::PPU(MemoryManager *memoryManager)
|
|||
PPU::Instance = this;
|
||||
|
||||
_memoryManager = memoryManager;
|
||||
_outputBuffer = new uint8_t[256 * 240 * 4];
|
||||
_outputBuffer = new uint32_t[256 * 240];
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
@ -120,7 +119,7 @@ void PPU::WriteRAM(uint16_t addr, uint8_t value)
|
|||
break;
|
||||
case PPURegisters::SpriteData:
|
||||
_spriteRAM[_state.SpriteRamAddr] = value;
|
||||
_state.SpriteRamAddr = (_state.SpriteRamAddr + 1) % 0x100;
|
||||
_state.SpriteRamAddr = (_state.SpriteRamAddr + 1) & 0xFF;
|
||||
break;
|
||||
case PPURegisters::ScrollOffsets:
|
||||
if(_state.WriteToggle) {
|
||||
|
@ -179,18 +178,18 @@ void PPU::WritePaletteRAM(uint16_t addr, uint8_t value)
|
|||
uint32_t PPU::GetBGPaletteEntry(uint32_t paletteOffset, uint32_t pixel)
|
||||
{
|
||||
if(pixel == 0) {
|
||||
return ReadPaletteRAM(0x3F00) % 64;
|
||||
return ReadPaletteRAM(0x3F00) & 0x3F;
|
||||
} else {
|
||||
return ReadPaletteRAM(0x3F00 + paletteOffset + pixel) % 64;
|
||||
return ReadPaletteRAM(0x3F00 + paletteOffset + pixel) & 0x3F;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t PPU::GetSpritePaletteEntry(uint32_t paletteOffset, uint32_t pixel)
|
||||
{
|
||||
if(pixel == 0) {
|
||||
return ReadPaletteRAM(0x3F00) % 64;
|
||||
return ReadPaletteRAM(0x3F00) & 0x3F;
|
||||
} else {
|
||||
return ReadPaletteRAM(0x3F10 + paletteOffset + pixel) % 64;
|
||||
return ReadPaletteRAM(0x3F10 + paletteOffset + pixel) & 0x3F;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -393,7 +392,7 @@ void PPU::DrawPixel()
|
|||
uint8_t offset = _state.XScroll;
|
||||
|
||||
uint32_t backgroundColor = 0;
|
||||
uint32_t &pixel = (((uint32_t*)_outputBuffer)[(_scanline << 8) + _cycle - 1]);
|
||||
uint32_t &pixel = _outputBuffer[(_scanline << 8) + _cycle - 1];
|
||||
|
||||
if((_cycle > 8 || _flags.BackgroundMask) && _flags.BackgroundEnabled) {
|
||||
//BackgroundMask = false: Hide background in leftmost 8 pixels of screen
|
||||
|
@ -433,7 +432,7 @@ void PPU::DrawPixel()
|
|||
}
|
||||
}
|
||||
}
|
||||
pixel = PPU_PALETTE_RGB[GetBGPaletteEntry(offset + ((_cycle - 1) % 8) < 8 ? _previousTile.PaletteOffset : _currentTile.PaletteOffset, backgroundColor)];
|
||||
pixel = PPU_PALETTE_RGB[GetBGPaletteEntry(offset + ((_cycle - 1) & 0x07) < 8 ? _previousTile.PaletteOffset : _currentTile.PaletteOffset, backgroundColor)];
|
||||
}
|
||||
|
||||
void PPU::ProcessPreVBlankScanline()
|
||||
|
@ -441,7 +440,7 @@ void PPU::ProcessPreVBlankScanline()
|
|||
//For pre-render scanline & all visible scanlines
|
||||
if(IsRenderingEnabled()) {
|
||||
//Update video ram address according to scrolling logic
|
||||
if((_cycle > 0 && _cycle < 256 && _cycle % 8 == 0) || _cycle == 328 || _cycle == 336) {
|
||||
if((_cycle > 0 && _cycle < 256 && (_cycle & 0x07) == 0) || _cycle == 328 || _cycle == 336) {
|
||||
IncHorizontalScrolling();
|
||||
} else if(_cycle == 256) {
|
||||
IncVerticalScrolling();
|
||||
|
@ -467,14 +466,14 @@ void PPU::ProcessPrerenderScanline()
|
|||
_statusFlags.VerticalBlank = false;
|
||||
}
|
||||
|
||||
if((_cycle - 1) % 8 == 0 && _cycle < 250) {
|
||||
if(((_cycle - 1) & 0x07) == 0 && _cycle < 250) {
|
||||
LoadTileInfo();
|
||||
} else if(_cycle >= 280 && _cycle <= 304) {
|
||||
if(IsRenderingEnabled()) {
|
||||
//copy vertical scrolling value from t
|
||||
_state.VideoRamAddr = (_state.VideoRamAddr & ~0x7BE0) | (_state.TmpVideoRamAddr & 0x7BE0);
|
||||
}
|
||||
} else if(_cycle == 339 && IsRenderingEnabled() && (_frameCount % 2 == 1)) {
|
||||
} else if(_cycle == 339 && IsRenderingEnabled() && (_frameCount & 0x01)) {
|
||||
//"With rendering enabled, each odd PPU frame is one PPU clock shorter than normal" (skip from 339 to 0, going over 340)
|
||||
_cycle = -1;
|
||||
_scanline = 0;
|
||||
|
@ -485,7 +484,7 @@ void PPU::ProcessPrerenderScanline()
|
|||
}
|
||||
}
|
||||
|
||||
if(_cycle >= 261 && (_cycle - 261) % 8 == 0 && _cycle <= 320) {
|
||||
if(_cycle >= 261 && ((_cycle - 261) & 0x07) == 0 && _cycle <= 320) {
|
||||
//Unused sprite tile fetches, but vital for MMC3 IRQ counter
|
||||
uint32_t spriteIndex = (_cycle - 261) / 8;
|
||||
LoadSpriteTileInfo(spriteIndex);
|
||||
|
@ -495,7 +494,7 @@ void PPU::ProcessPrerenderScanline()
|
|||
void PPU::ProcessVisibleScanline()
|
||||
{
|
||||
if(_cycle > 0 && _cycle <= 256) {
|
||||
if((_cycle - 1) % 8 == 0) {
|
||||
if(((_cycle - 1) & 0x07) == 0) {
|
||||
//Cycle 1, 9, 17, etc.
|
||||
if(_cycle != 1) {
|
||||
LoadNextTile();
|
||||
|
@ -509,14 +508,7 @@ void PPU::ProcessVisibleScanline()
|
|||
if(IsRenderingEnabled()) {
|
||||
CopyOAMData();
|
||||
}
|
||||
|
||||
if(_cycle == 256 && _scanline == 239) {
|
||||
//Send frame to GUI once the last pixel has been output
|
||||
if(PPU::VideoDevice) {
|
||||
PPU::VideoDevice->UpdateFrame(_outputBuffer);
|
||||
}
|
||||
}
|
||||
} else if((_cycle - 261) % 8 == 0 && _cycle <= 320) {
|
||||
} else if(((_cycle - 261) & 0x07) == 0 && _cycle <= 320) {
|
||||
//Cycle 261, 269, etc.
|
||||
uint32_t spriteIndex = (_cycle - 261) / 8;
|
||||
LoadSpriteTileInfo(spriteIndex);
|
||||
|
@ -551,7 +543,7 @@ void PPU::CopyOAMData()
|
|||
_oamCopybuffer = _spriteRAM[_state.SpriteRamAddr & 0xFF];
|
||||
_state.SpriteRamAddr++;
|
||||
} else {
|
||||
if(!_writeOAMData && _state.SpriteRamAddr < 0x100 && _scanline >= _oamCopybuffer && _scanline < _oamCopybuffer + (_flags.LargeSprites ? 16 : 8)) {
|
||||
if(!_writeOAMData && _scanline >= _oamCopybuffer && _scanline < _oamCopybuffer + (_flags.LargeSprites ? 16 : 8) && _state.SpriteRamAddr < 0x100) {
|
||||
_writeOAMData = true;
|
||||
}
|
||||
|
||||
|
@ -604,6 +596,11 @@ void PPU::CopyOAMData()
|
|||
void PPU::BeginVBlank()
|
||||
{
|
||||
if(_cycle == 0) {
|
||||
//Send frame to GUI once the last pixel has been output
|
||||
if(PPU::VideoDevice) {
|
||||
PPU::VideoDevice->UpdateFrame(_outputBuffer);
|
||||
}
|
||||
|
||||
if(!_doNotSetVBFlag) {
|
||||
_statusFlags.VerticalBlank = true;
|
||||
if(_flags.VBlank) {
|
||||
|
|
12
Core/PPU.h
12
Core/PPU.h
|
@ -102,8 +102,8 @@ class PPU : public IMemoryHandler, public Snapshotable
|
|||
uint8_t _spriteRAM[0x100];
|
||||
uint8_t _secondarySpriteRAM[0x20];
|
||||
|
||||
uint8_t *_outputBuffer;
|
||||
|
||||
uint32_t *_outputBuffer;
|
||||
|
||||
PPUControlFlags _flags;
|
||||
PPUStatusFlags _statusFlags;
|
||||
|
||||
|
@ -193,17 +193,13 @@ class PPU : public IMemoryHandler, public Snapshotable
|
|||
void WriteRAM(uint16_t addr, uint8_t value);
|
||||
|
||||
void Exec();
|
||||
static void ExecStatic();
|
||||
|
||||
static void RegisterVideoDevice(IVideoDevice *videoDevice)
|
||||
{
|
||||
PPU::VideoDevice = videoDevice;
|
||||
}
|
||||
|
||||
uint8_t* GetFrameBuffer()
|
||||
{
|
||||
return _outputBuffer;
|
||||
}
|
||||
|
||||
static uint32_t GetFrameCount()
|
||||
{
|
||||
return PPU::Instance->_frameCount;
|
||||
|
@ -223,6 +219,4 @@ class PPU : public IMemoryHandler, public Snapshotable
|
|||
{
|
||||
return PPU::Instance->_scanline;
|
||||
}
|
||||
|
||||
static void ExecStatic();
|
||||
};
|
||||
|
|
|
@ -28,4 +28,11 @@ double Timer::GetElapsedMS()
|
|||
LARGE_INTEGER li;
|
||||
QueryPerformanceCounter(&li);
|
||||
return double(li.QuadPart - _start) / _frequency;
|
||||
}
|
||||
|
||||
uint32_t Timer::GetElapsedTicks()
|
||||
{
|
||||
LARGE_INTEGER li;
|
||||
QueryPerformanceCounter(&li);
|
||||
return uint32_t(li.QuadPart - _start);
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
|
||||
class Timer
|
||||
|
@ -10,4 +11,5 @@ class Timer
|
|||
Timer();
|
||||
void Reset();
|
||||
double GetElapsedMS();
|
||||
uint32_t Timer::GetElapsedTicks();
|
||||
};
|
|
@ -566,7 +566,7 @@ namespace NES
|
|||
_font->DrawString(_spriteBatch.get(), WrapText(toast->GetToastMessage(), _font.get(), 340 - 30 - textLeftMargin).c_str(), XMFLOAT2(dest.left + textLeftMargin - 2.0f, dest.top + 19.0f), color);
|
||||
}
|
||||
|
||||
void Renderer::UpdateFrame(uint8_t* frameBuffer)
|
||||
void Renderer::UpdateFrame(void* frameBuffer)
|
||||
{
|
||||
_frameChanged = true;
|
||||
|
||||
|
|
|
@ -108,7 +108,7 @@ namespace NES {
|
|||
return (_flags & flag) == flag;
|
||||
}
|
||||
|
||||
void UpdateFrame(uint8_t* frameBuffer);
|
||||
void UpdateFrame(void* frameBuffer);
|
||||
void DisplayToast(shared_ptr<ToastInfo> toast);
|
||||
|
||||
void TakeScreenshot(string romFilename);
|
||||
|
|
Loading…
Add table
Reference in a new issue