diff --git a/bsnes/emulator/emulator.hpp b/bsnes/emulator/emulator.hpp index 607b0fa7..9cb3fd1f 100644 --- a/bsnes/emulator/emulator.hpp +++ b/bsnes/emulator/emulator.hpp @@ -29,7 +29,7 @@ using namespace nall; namespace Emulator { static const string Name = "bsnes"; - static const string Version = "111.4"; + static const string Version = "111.5"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "https://byuu.org"; diff --git a/bsnes/sfc/cpu/timing.cpp b/bsnes/sfc/cpu/timing.cpp index cd20e2e8..0c9cfe0f 100644 --- a/bsnes/sfc/cpu/timing.cpp +++ b/bsnes/sfc/cpu/timing.cpp @@ -123,6 +123,15 @@ auto CPU::scanline() -> void { overclocking.target = clocks * overclock - clocks; } } + + //handle video frame events from the CPU core to prevent a race condition between + //games polling inputs during NMI and the PPU thread not being 100% synchronized. + if(vcounter() == ppu.vdisp()) { + if(auto device = controllerPort2.device) device->latch(); //light guns + synchronizePPU(); + if(system.fastPPU()) PPUfast::Line::flush(); + scheduler.leave(Scheduler::Event::Frame); + } } auto CPU::aluEdge() -> void { diff --git a/bsnes/sfc/ppu-fast/ppu.cpp b/bsnes/sfc/ppu-fast/ppu.cpp index 0d1d8eb4..1be718b3 100644 --- a/bsnes/sfc/ppu-fast/ppu.cpp +++ b/bsnes/sfc/ppu-fast/ppu.cpp @@ -118,15 +118,9 @@ auto PPU::scanline() -> void { } if(vcounter() == vdisp()) { - if(auto device = controllerPort2.device) device->latch(); //light guns if(!io.displayDisable) oamAddressReset(); } - if(vcounter() == vdisp()) { //240 - Line::flush(); - scheduler.leave(Scheduler::Event::Frame); - } - if(vcounter() == 240) { Line::flush(); } diff --git a/bsnes/sfc/ppu/main.cpp b/bsnes/sfc/ppu/main.cpp index 598ac2ba..144dff66 100644 --- a/bsnes/sfc/ppu/main.cpp +++ b/bsnes/sfc/ppu/main.cpp @@ -17,14 +17,6 @@ auto PPU::main() -> void { window.scanline(); screen.scanline(); - if(vcounter() == vdisp()) { - if(auto device = controllerPort2.device) device->latch(); //light guns - } - - if(vcounter() == vdisp()) { //240 - scheduler.leave(Scheduler::Event::Frame); - } - if(vcounter() > 240) { step(hperiod()); return; diff --git a/bsnes/target-bsnes/input/hotkeys.cpp b/bsnes/target-bsnes/input/hotkeys.cpp index 7b6f3e88..1aff93e1 100644 --- a/bsnes/target-bsnes/input/hotkeys.cpp +++ b/bsnes/target-bsnes/input/hotkeys.cpp @@ -123,10 +123,9 @@ auto InputManager::bindHotkeys() -> void { if(!presentation.frameAdvance.checked()) { //start frame advance if not currently frame advancing presentation.frameAdvance.setChecked().doActivate(); - } else { - //advance to the next video frame otherwise - program.frameAdvanceLock = false; } + //advance one frame, even if we were currently paused when starting frame advance mode + program.frameAdvanceLock = false; })); hotkeys.append(InputHotkey("Increase HD Mode 7").onPress([] {