diff --git a/Core/NES/BaseNesPpu.h b/Core/NES/BaseNesPpu.h index dbce3a41..674a5198 100644 --- a/Core/NES/BaseNesPpu.h +++ b/Core/NES/BaseNesPpu.h @@ -130,7 +130,7 @@ public: int32_t GetScanlineCount() { return _vblankEnd + 2; } uint32_t GetFrameCycle() { return ((_scanline + 1) * 341) + _cycle; } - virtual uint16_t* GetScreenBuffer(bool previousBuffer) = 0; + virtual uint16_t* GetScreenBuffer(bool previousBuffer, bool processGrayscaleEmphasisBits = false) = 0; virtual void UpdateTimings(ConsoleRegion region, bool overclockAllowed = true) = 0; void GetState(NesPpuState& state); diff --git a/Core/NES/Debugger/NesEventManager.cpp b/Core/NES/Debugger/NesEventManager.cpp index 33f9cfe2..557cf933 100644 --- a/Core/NES/Debugger/NesEventManager.cpp +++ b/Core/NES/Debugger/NesEventManager.cpp @@ -214,10 +214,10 @@ uint32_t NesEventManager::TakeEventSnapshot(bool forAutoRefresh) uint16_t scanline = ppu->GetCurrentScanline() + 1; if(scanline >= 240 || (scanline == 0 && cycle == 0)) { - memcpy(_ppuBuffer, ppu->GetScreenBuffer(false), NesConstants::ScreenPixelCount * sizeof(uint16_t)); + memcpy(_ppuBuffer, ppu->GetScreenBuffer(false, true), NesConstants::ScreenPixelCount * sizeof(uint16_t)); } else { uint32_t offset = (NesConstants::ScreenWidth * scanline); - memcpy(_ppuBuffer, ppu->GetScreenBuffer(false), offset * sizeof(uint16_t)); + memcpy(_ppuBuffer, ppu->GetScreenBuffer(false, true), offset * sizeof(uint16_t)); memcpy(_ppuBuffer + offset, ppu->GetScreenBuffer(true) + offset, (NesConstants::ScreenPixelCount - offset) * sizeof(uint16_t)); } @@ -271,6 +271,24 @@ void NesEventManager::DrawPixel(uint32_t *buffer, int32_t x, uint32_t y, uint32_ buffer[y * NesConstants::CyclesPerLine * 4 + NesConstants::CyclesPerLine * 2 + x * 2 + 1] = color; } +void NesEventManager::ProcessNtscBorderColorEvents(vector& events, vector& bgColor, uint32_t& currentPos, uint16_t& currentColor) +{ + for(DebugEventInfo& evt : events) { + if(evt.Type == DebugEventType::BgColorChange) { + uint32_t pos = ((evt.Scanline + 1) * NesConstants::CyclesPerLine) + evt.Cycle; + if(evt.Scanline >= 242) { + break; + } + + if(pos >= currentPos) { + std::fill(bgColor.begin() + currentPos, bgColor.begin() + pos, currentColor); + currentPos = pos; + currentColor = evt.Operation.Address; + } + } + } +} + void NesEventManager::DrawNtscBorders(uint32_t *buffer) { //Generate array of bg color for all pixels on the screen @@ -279,17 +297,15 @@ void NesEventManager::DrawNtscBorders(uint32_t *buffer) vector bgColor; bgColor.resize(NesConstants::CyclesPerLine * 243); - //TODO use bg color changes from previous frame when needed - for(DebugEventInfo &evt : _snapshotCurrentFrame) { - if(evt.Type == DebugEventType::BgColorChange) { - uint32_t pos = ((evt.Scanline + 1) * NesConstants::CyclesPerLine) + evt.Cycle; - if(pos >= currentPos && evt.Scanline < 242) { - std::fill(bgColor.begin() + currentPos, bgColor.begin() + pos, currentColor); - currentColor = evt.Operation.Address; - currentPos = pos; - } - } + ProcessNtscBorderColorEvents(_snapshotCurrentFrame, bgColor, currentPos, currentColor); + + if(!_forAutoRefresh && _snapshotScanline < 242) { + uint32_t snapshotPos = (_snapshotScanline * NesConstants::CyclesPerLine) + _snapshotCycle; + std::fill(bgColor.begin() + currentPos, bgColor.begin() + snapshotPos, currentColor); + currentPos = snapshotPos; + ProcessNtscBorderColorEvents(_snapshotPrevFrame, bgColor, currentPos, currentColor); } + std::fill(bgColor.begin() + currentPos, bgColor.end(), currentColor); for(uint32_t y = 1; y < 241; y++) { diff --git a/Core/NES/Debugger/NesEventManager.h b/Core/NES/Debugger/NesEventManager.h index 0893a070..32375872 100644 --- a/Core/NES/Debugger/NesEventManager.h +++ b/Core/NES/Debugger/NesEventManager.h @@ -63,6 +63,8 @@ private: void DrawNtscBorders(uint32_t *buffer); void DrawPixel(uint32_t *buffer, int32_t x, uint32_t y, uint32_t color); + void ProcessNtscBorderColorEvents(vector& events, vector& bgColor, uint32_t& currentPos, uint16_t& currentColor); + protected: void ConvertScanlineCycleToRowColumn(int32_t& x, int32_t& y) override; void DrawScreen(uint32_t* buffer) override; diff --git a/Core/NES/NesPpu.cpp b/Core/NES/NesPpu.cpp index 6f542290..40bd22e4 100644 --- a/Core/NES/NesPpu.cpp +++ b/Core/NES/NesPpu.cpp @@ -1092,8 +1092,11 @@ template void NesPpu::WriteSpriteRam(uint8_t addr, uint8_t value) } } -template uint16_t* NesPpu::GetScreenBuffer(bool previousBuffer) +template uint16_t* NesPpu::GetScreenBuffer(bool previousBuffer, bool processGrayscaleEmphasisBits) { + if(!previousBuffer && processGrayscaleEmphasisBits) { + UpdateGrayscaleAndIntensifyBits(); + } return previousBuffer ? ((_currentOutputBuffer == _outputBuffers[0]) ? _outputBuffers[1] : _outputBuffers[0]) : _currentOutputBuffer; } @@ -1521,21 +1524,21 @@ template void NesPpu::Serialize(Serializer& s) } template NesPpu::NesPpu(NesConsole* console); -template uint16_t* NesPpu::GetScreenBuffer(bool previousBuffer); +template uint16_t* NesPpu::GetScreenBuffer(bool previousBuffer, bool processGrayscaleEmphasisBits); template void NesPpu::Exec(); template uint32_t NesPpu::GetPixelBrightness(uint8_t x, uint8_t y); template NesPpu::NesPpu(NesConsole* console); -template uint16_t* NesPpu::GetScreenBuffer(bool previousBuffer); +template uint16_t* NesPpu::GetScreenBuffer(bool previousBuffer, bool processGrayscaleEmphasisBits); template void NesPpu::Exec(); template uint32_t NesPpu::GetPixelBrightness(uint8_t x, uint8_t y); template NesPpu::NesPpu(NesConsole* console); -template uint16_t* NesPpu::GetScreenBuffer(bool previousBuffer); +template uint16_t* NesPpu::GetScreenBuffer(bool previousBuffer, bool processGrayscaleEmphasisBits); template void NesPpu::Exec(); template uint32_t NesPpu::GetPixelBrightness(uint8_t x, uint8_t y); template NesPpu::NesPpu(NesConsole* console); -template uint16_t* NesPpu::GetScreenBuffer(bool previousBuffer); +template uint16_t* NesPpu::GetScreenBuffer(bool previousBuffer, bool processGrayscaleEmphasisBits); template void NesPpu::Exec(); template uint32_t NesPpu::GetPixelBrightness(uint8_t x, uint8_t y); diff --git a/Core/NES/NesPpu.h b/Core/NES/NesPpu.h index 7ffe4f80..6a4abdb9 100644 --- a/Core/NES/NesPpu.h +++ b/Core/NES/NesPpu.h @@ -105,7 +105,7 @@ public: void Reset(bool softReset) override; - uint16_t* GetScreenBuffer(bool previousBuffer) override; + uint16_t* GetScreenBuffer(bool previousBuffer, bool processGrayscaleEmphasisBits = false) override; void DebugCopyOutputBuffer(uint16_t* target); void DebugUpdateFrameBuffer(bool toGrayscale);