Instance sync: Count milliseconds in emulated time, not cycles

The barrier divided the cycle count by the current clock's cycles per millisecond, so a game that
changes the CPU clock (Pangya: Fantasy Golf does on its network screens) jumped its count by up to a
fifth of everything so far, and from then on ran in lockstep at the wrong ratio: the other instance
waited for up to half a minute, then the two ran 266:222 apart in emulated time.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Henrik RydgårdandClaude Opus 5.5 committed 2026-10-31 19:02:56 +01:00
1 parent 3626497c76
commit 422f5ed3e5
1 file changed
+6 -5
+6 -5
View File
@@ -460,9 +460,10 @@ void Advance(MIPSState *mips) {
// Keep in step with the other instances. Before the deadline below, so one stopping there has
// still told the others it got this far.
const s64 syncTicks = InstanceSyncEnabled() ? usToCycles(1000) : 0;
if (syncTicks && globalTimer / syncTicks != lastInstanceSyncMs) {
lastInstanceSyncMs = globalTimer / syncTicks;
// Counted in time, not cycles: a game can change the CPU clock, and the instances wouldn't agree.
const bool instanceSync = InstanceSyncEnabled();
if (instanceSync && (s64)(GetGlobalTimeUs() / 1000) != lastInstanceSyncMs) {
lastInstanceSyncMs = (s64)(GetGlobalTimeUs() / 1000);
InstanceSyncReached(lastInstanceSyncMs);
}
@@ -505,8 +506,8 @@ void Advance(MIPSState *mips) {
}
// Likewise come back at the next millisecond, for the instance sync.
if (syncTicks) {
const s64 remaining = (lastInstanceSyncMs + 1) * syncTicks - globalTimer;
if (instanceSync) {
const s64 remaining = usToCycles((lastInstanceSyncMs + 1) * 1000 - (s64)GetGlobalTimeUs());
if (remaining > 0 && remaining < slicelength) {
const int diff = (int)remaining - slicelength;
slicelength += diff;