Debugger: Event Viewer - NES - Fixed incorrect NTSC borders in some scenarios

This commit is contained in:
Sour 2024-09-13 15:45:27 +09:00
parent e79e655d3b
commit 88da0b0c3f
5 changed files with 40 additions and 19 deletions

View file

@ -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);

View file

@ -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<DebugEventInfo>& events, vector<uint16_t>& 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<uint16_t> 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++) {

View file

@ -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<DebugEventInfo>& events, vector<uint16_t>& bgColor, uint32_t& currentPos, uint16_t& currentColor);
protected:
void ConvertScanlineCycleToRowColumn(int32_t& x, int32_t& y) override;
void DrawScreen(uint32_t* buffer) override;

View file

@ -1092,8 +1092,11 @@ template<class T> void NesPpu<T>::WriteSpriteRam(uint8_t addr, uint8_t value)
}
}
template<class T> uint16_t* NesPpu<T>::GetScreenBuffer(bool previousBuffer)
template<class T> uint16_t* NesPpu<T>::GetScreenBuffer(bool previousBuffer, bool processGrayscaleEmphasisBits)
{
if(!previousBuffer && processGrayscaleEmphasisBits) {
UpdateGrayscaleAndIntensifyBits();
}
return previousBuffer ? ((_currentOutputBuffer == _outputBuffers[0]) ? _outputBuffers[1] : _outputBuffers[0]) : _currentOutputBuffer;
}
@ -1521,21 +1524,21 @@ template<class T> void NesPpu<T>::Serialize(Serializer& s)
}
template NesPpu<DefaultNesPpu>::NesPpu(NesConsole* console);
template uint16_t* NesPpu<DefaultNesPpu>::GetScreenBuffer(bool previousBuffer);
template uint16_t* NesPpu<DefaultNesPpu>::GetScreenBuffer(bool previousBuffer, bool processGrayscaleEmphasisBits);
template void NesPpu<DefaultNesPpu>::Exec();
template uint32_t NesPpu<DefaultNesPpu>::GetPixelBrightness(uint8_t x, uint8_t y);
template NesPpu<NsfPpu>::NesPpu(NesConsole* console);
template uint16_t* NesPpu<NsfPpu>::GetScreenBuffer(bool previousBuffer);
template uint16_t* NesPpu<NsfPpu>::GetScreenBuffer(bool previousBuffer, bool processGrayscaleEmphasisBits);
template void NesPpu<NsfPpu>::Exec();
template uint32_t NesPpu<NsfPpu>::GetPixelBrightness(uint8_t x, uint8_t y);
template NesPpu<HdNesPpu>::NesPpu(NesConsole* console);
template uint16_t* NesPpu<HdNesPpu>::GetScreenBuffer(bool previousBuffer);
template uint16_t* NesPpu<HdNesPpu>::GetScreenBuffer(bool previousBuffer, bool processGrayscaleEmphasisBits);
template void NesPpu<HdNesPpu>::Exec();
template uint32_t NesPpu<HdNesPpu>::GetPixelBrightness(uint8_t x, uint8_t y);
template NesPpu<HdBuilderPpu>::NesPpu(NesConsole* console);
template uint16_t* NesPpu<HdBuilderPpu>::GetScreenBuffer(bool previousBuffer);
template uint16_t* NesPpu<HdBuilderPpu>::GetScreenBuffer(bool previousBuffer, bool processGrayscaleEmphasisBits);
template void NesPpu<HdBuilderPpu>::Exec();
template uint32_t NesPpu<HdBuilderPpu>::GetPixelBrightness(uint8_t x, uint8_t y);

View file

@ -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);