Merge pull request #30 from NovaSquirrel/master

Changes from Mesen-X
This commit is contained in:
mkwong98 2023-01-06 19:13:16 +08:00 committed by GitHub
commit 5c7fd5167c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 63 additions and 31 deletions

View file

@ -56,7 +56,7 @@ void BaseVideoFilter::SendFrame(uint16_t *ppuOutputBuffer, uint32_t frameNumber)
{
_frameLock.Acquire();
_overscan = _console->GetSettings()->GetOverscanDimensions();
_isOddFrame = frameNumber % 2;
_isOddFrame = frameNumber & 0x01;
UpdateBufferSize();
OnBeforeApplyFilter();
ApplyFilter(ppuOutputBuffer);

View file

@ -23,13 +23,13 @@ protected:
virtual void ApplyFilter(uint16_t *ppuOutputBuffer) = 0;
virtual void OnBeforeApplyFilter();
bool IsOddFrame();
public:
BaseVideoFilter(shared_ptr<Console> console);
virtual ~BaseVideoFilter();
uint32_t* GetOutputBuffer();
bool IsOddFrame();
void SendFrame(uint16_t *ppuOutputBuffer, uint32_t frameNumber);
void TakeScreenshot(string romName, VideoFilterType filterType);
void TakeScreenshot(VideoFilterType filterType, string filename, std::stringstream *stream = nullptr, bool rawScreenshot = false);

View file

@ -50,8 +50,7 @@ BisqwitNtscFilter::BisqwitNtscFilter(shared_ptr<Console> console, int resDivider
} else {
outputBuffer += GetOverscan().GetScreenWidth() * 64 / _resDivider / _resDivider * (120 - GetOverscan().Top);
}
DecodeFrame(120, 239 - GetOverscan().Bottom, _ppuOutputBuffer, outputBuffer, (IsOddFrame() ? 8 : 0) + 327360);
DecodeFrame(120, 239 - GetOverscan().Bottom, _ppuOutputBuffer, outputBuffer, ((_console->GetModel() == NesModel::NTSC ? _console->GetStartingPhase() : 0) * 4) + 327360);
_workDone = true;
}
@ -71,7 +70,7 @@ void BisqwitNtscFilter::ApplyFilter(uint16_t *ppuOutputBuffer)
_workDone = false;
_waitWork.Signal();
DecodeFrame(GetOverscan().Top, 120, ppuOutputBuffer, GetOutputBuffer(), (IsOddFrame() ? 8 : 0) + GetOverscan().Top*341*8);
DecodeFrame(GetOverscan().Top, 120, ppuOutputBuffer, GetOutputBuffer(), ((_console->GetModel() == NesModel::NTSC ? _console->GetStartingPhase() : 0) * 4) + GetOverscan().Top * 341 * 8);
while(!_workDone) {}
}

View file

@ -568,6 +568,11 @@ uint32_t Console::GetFrameCount()
return _ppu ? _ppu->GetFrameCount() : 0;
}
uint8_t Console::GetStartingPhase()
{
return _ppu ? _ppu->GetStartingPhase() : 0;
}
NesModel Console::GetModel()
{
return _model;

View file

@ -204,6 +204,8 @@ public:
VirtualFile GetPatchFile();
RomInfo GetRomInfo();
uint32_t GetFrameCount();
// https://forums.nesdev.org/viewtopic.php?p=30625#p30625
uint8_t GetStartingPhase();
NesModel GetModel();
uint32_t GetLagCounter();

View file

@ -9,7 +9,7 @@ NtscFilter::NtscFilter(shared_ptr<Console> console) : BaseVideoFilter(console)
memset(_palette, 0, sizeof(_palette));
memset(&_ntscData, 0, sizeof(_ntscData));
_ntscSetup = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
_ntscBuffer = new uint32_t[NES_NTSC_OUT_WIDTH(256) * 240];
_ntscBuffer = new uint32_t[NES_NTSC_OUT_WIDTH(256) * 240]();
}
FrameInfo NtscFilter::GetFrameInfo()
@ -55,14 +55,7 @@ void NtscFilter::OnBeforeApplyFilter()
}
}
if (_console->GetModel() == NesModel::NTSC) {
// BG color borders on NTSC machines
_ntsc_border = _console->GetPpu()->GetCurrentBgColor();
}
else {
// black borders on other machines
_ntsc_border = 15;
}
_ntscBorder = (_console->GetModel() == NesModel::NTSC);
PictureSettings pictureSettings = _console->GetSettings()->GetPictureSettings();
NtscFilterSettings ntscSettings = _console->GetSettings()->GetNtscFilterSettings();
@ -132,7 +125,22 @@ void NtscFilter::OnBeforeApplyFilter()
void NtscFilter::ApplyFilter(uint16_t *ppuOutputBuffer)
{
nes_ntsc_blit(&_ntscData, ppuOutputBuffer, _ntsc_border, PPU::ScreenWidth, IsOddFrame() ? 0 : 1, PPU::ScreenWidth, 240, _ntscBuffer, NES_NTSC_OUT_WIDTH(PPU::ScreenWidth)*4);
uint8_t phase = _console->GetModel() == NesModel::NTSC ? _console->GetStartingPhase() : 0;
for (int i = 0; i < 240; i++) {
nes_ntsc_blit(&_ntscData,
// input += in_row_width;
ppuOutputBuffer + PPU::ScreenWidth * i,
_ntscBorder ? _console->GetPpu()->GetCurrentBgColor() : 0x0F,
PPU::ScreenWidth,
phase,
PPU::ScreenWidth,
1,
// rgb_out = (char*) rgb_out + out_pitch;
reinterpret_cast<char*>(_ntscBuffer) + (NES_NTSC_OUT_WIDTH(PPU::ScreenWidth) * 4 * i),
NES_NTSC_OUT_WIDTH(PPU::ScreenWidth) * 4);
phase = (phase + 1) % 3;
}
GenerateArgbFrame(_ntscBuffer);
}

View file

@ -14,7 +14,7 @@ private:
bool _useExternalPalette = true;
uint8_t _palette[512 * 3];
uint32_t* _ntscBuffer;
uint16_t _ntsc_border;
bool _ntscBorder = true;
void GenerateArgbFrame(uint32_t *outputBuffer);

View file

@ -105,6 +105,8 @@ void PPU::Reset()
memset(_oamDecayCycles, 0, sizeof(_oamDecayCycles));
_enableOamDecay = _settings->CheckFlag(EmulationFlags::EnableOamDecay);
_startingPhase = 0;
UpdateMinimumDrawCycles();
}
@ -112,30 +114,37 @@ void PPU::SetNesModel(NesModel model)
{
_nesModel = model;
// https://www.nesdev.org/wiki/Cycle_reference_chart
switch(_nesModel) {
case NesModel::Auto:
//Should never be Auto
break;
case NesModel::NTSC:
_nmiScanline = 241;
_vblankEnd = 260;
_standardNmiScanline = 241;
_standardVblankEnd = 260;
// picture height + postrender blanking lines
_nmiScanline = 240 + 1;
// picture height + (postrender blanking lines - 1) + vblank length
_vblankEnd = 240 + 20;
_standardNmiScanline = _nmiScanline;
_standardVblankEnd = _vblankEnd;
_masterClockDivider = 4;
break;
case NesModel::PAL:
_nmiScanline = 241;
_vblankEnd = 310;
_standardNmiScanline = 241;
_standardVblankEnd = 310;
// (picture height + border line) + postrender blanking lines
_nmiScanline = 240 + 1;
// (picture height + border line) + (postrender blanking lines - 1) + vblank length + 50
_vblankEnd = 240 + 20 + 50;
_standardNmiScanline = _nmiScanline;
_standardVblankEnd = _vblankEnd;
_masterClockDivider = 5;
break;
case NesModel::Dendy:
_nmiScanline = 291;
_vblankEnd = 310;
_standardNmiScanline = 291;
_standardVblankEnd = 310;
// (picture height + border line) + postrender blanking lines + 50
_nmiScanline = 240 + 1 + 50;
// (picture height + border line) + (postrender blanking lines - 1) + 50 + vblank length
_vblankEnd = 240 + 50 + 20;
_standardNmiScanline = _nmiScanline;
_standardVblankEnd = _vblankEnd;
_masterClockDivider = 5;
break;
}
@ -999,10 +1008,9 @@ void PPU::ProcessScanline()
LoadTileInfo();
}
} else if(_cycle == 337 || _cycle == 339) {
if(IsRenderingEnabled()) {
if (IsRenderingEnabled()) {
ReadVram(GetNameTableAddr());
if(_scanline == -1 && _cycle == 339 && (_frameCount & 0x01) && _nesModel == NesModel::NTSC && _settings->GetPpuModel() == PpuModel::Ppu2C02) {
if (_scanline == -1 && _cycle == 339 && (_frameCount & 0x01) && _nesModel == NesModel::NTSC && _settings->GetPpuModel() == PpuModel::Ppu2C02) {
//This behavior is NTSC-specific - PAL frames are always the same number of cycles
//"With rendering enabled, each odd PPU frame is one PPU clock shorter than normal" (skip from 339 to 0, going over 340)
_cycle = 340;
@ -1347,6 +1355,8 @@ void PPU::Exec()
if(_needStateUpdate) {
UpdateState();
}
_startingPhase = _cycle % 3;
}
void PPU::UpdateState()

View file

@ -109,6 +109,9 @@ class PPU : public IMemoryHandler, public Snapshotable
bool _enableOamDecay;
bool _corruptOamRow[32];
// https://forums.nesdev.org/viewtopic.php?p=30625#p30625
uint8_t _startingPhase;
void UpdateStatusFlag();
void SetControlRegister(uint8_t value);
@ -217,6 +220,11 @@ class PPU : public IMemoryHandler, public Snapshotable
return _frameCount;
}
uint8_t GetStartingPhase()
{
return _startingPhase;
}
uint32_t GetFrameCycle()
{
return ((_scanline + 1) * 341) + _cycle;