mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-24 16:49:50 +00:00
Merge pull request #6220 from unknownbrackets/lagsync
Add option for less timing lag (spin on Windows)
This commit is contained in:
commit
318f641c63
@ -265,6 +265,7 @@ static ConfigSetting generalSettings[] = {
|
||||
ConfigSetting("HomebrewStore", &g_Config.bHomebrewStore, false, false),
|
||||
ConfigSetting("CheckForNewVersion", &g_Config.bCheckForNewVersion, true),
|
||||
ConfigSetting("Language", &g_Config.sLanguageIni, &DefaultLangRegion),
|
||||
ConfigSetting("ForceLagSync", &g_Config.bForceLagSync, false),
|
||||
|
||||
ReportedConfigSetting("NumWorkerThreads", &g_Config.iNumWorkerThreads, &DefaultNumWorkers),
|
||||
ConfigSetting("EnableAutoLoad", &g_Config.bEnableAutoLoad, false),
|
||||
|
@ -83,6 +83,7 @@ public:
|
||||
bool bFastMemory;
|
||||
bool bJit;
|
||||
bool bCheckForNewVersion;
|
||||
bool bForceLagSync;
|
||||
|
||||
// Definitely cannot be changed while game is running.
|
||||
bool bSeparateCPUThread;
|
||||
|
@ -20,6 +20,12 @@
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
// TODO: Move this somewhere else, cleanup.
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
// TODO: Move the relevant parts into common. Don't want the core
|
||||
// to be dependent on "native", I think. Or maybe should get rid of common
|
||||
// and move everything into native...
|
||||
@ -79,6 +85,10 @@ static bool framebufIsLatched;
|
||||
static int enterVblankEvent = -1;
|
||||
static int leaveVblankEvent = -1;
|
||||
static int afterFlipEvent = -1;
|
||||
static int lagSyncEvent = -1;
|
||||
|
||||
static double lastLagSync = 0.0;
|
||||
static bool lagSyncScheduled = false;
|
||||
|
||||
// hCount is computed now.
|
||||
static int vCount;
|
||||
@ -140,12 +150,21 @@ static int lastFlipsTooFrequent = 0;
|
||||
void hleEnterVblank(u64 userdata, int cyclesLate);
|
||||
void hleLeaveVblank(u64 userdata, int cyclesLate);
|
||||
void hleAfterFlip(u64 userdata, int cyclesLate);
|
||||
void hleLagSync(u64 userdata, int cyclesLate);
|
||||
|
||||
void __DisplayVblankBeginCallback(SceUID threadID, SceUID prevCallbackId);
|
||||
void __DisplayVblankEndCallback(SceUID threadID, SceUID prevCallbackId);
|
||||
int __DisplayGetFlipCount() { return actualFlips; }
|
||||
int __DisplayGetVCount() { return vCount; }
|
||||
|
||||
static void ScheduleLagSync(int over = 0) {
|
||||
lagSyncScheduled = g_Config.bForceLagSync;
|
||||
if (lagSyncScheduled) {
|
||||
CoreTiming::ScheduleEvent(msToCycles(1), lagSyncEvent, 0);
|
||||
lastLagSync = real_time_now() - (over / 1000000.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void __DisplayInit() {
|
||||
gpuStats.Reset();
|
||||
hasSetMode = false;
|
||||
@ -168,6 +187,9 @@ void __DisplayInit() {
|
||||
leaveVblankEvent = CoreTiming::RegisterEvent("LeaveVBlank", &hleLeaveVblank);
|
||||
afterFlipEvent = CoreTiming::RegisterEvent("AfterFlip", &hleAfterFlip);
|
||||
|
||||
lagSyncEvent = CoreTiming::RegisterEvent("LagSync", &hleLagSync);
|
||||
ScheduleLagSync();
|
||||
|
||||
CoreTiming::ScheduleEvent(msToCycles(frameMs - vblankMs), enterVblankEvent, 0);
|
||||
isVblank = 0;
|
||||
vCount = 0;
|
||||
@ -189,7 +211,7 @@ void __DisplayInit() {
|
||||
}
|
||||
|
||||
void __DisplayDoState(PointerWrap &p) {
|
||||
auto s = p.Section("sceDisplay", 1, 4);
|
||||
auto s = p.Section("sceDisplay", 1, 5);
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
@ -226,6 +248,19 @@ void __DisplayDoState(PointerWrap &p) {
|
||||
p.Do(afterFlipEvent);
|
||||
CoreTiming::RestoreRegisterEvent(afterFlipEvent, "AfterFlip", &hleAfterFlip);
|
||||
|
||||
if (s >= 5) {
|
||||
p.Do(lagSyncEvent);
|
||||
p.Do(lagSyncScheduled);
|
||||
CoreTiming::RestoreRegisterEvent(lagSyncEvent, "LagSync", &hleLagSync);
|
||||
lastLagSync = real_time_now();
|
||||
if (lagSyncScheduled != g_Config.bForceLagSync) {
|
||||
ScheduleLagSync();
|
||||
}
|
||||
} else {
|
||||
lagSyncEvent = CoreTiming::RegisterEvent("LagSync", &hleLagSync);
|
||||
ScheduleLagSync();
|
||||
}
|
||||
|
||||
p.Do(gstate);
|
||||
gstate_c.DoState(p);
|
||||
#ifndef _XBOX
|
||||
@ -621,6 +656,11 @@ void hleEnterVblank(u64 userdata, int cyclesLate) {
|
||||
void hleAfterFlip(u64 userdata, int cyclesLate)
|
||||
{
|
||||
gpu->BeginFrame(); // doesn't really matter if begin or end of frame.
|
||||
|
||||
// This seems like as good a time as any to check if the config changed.
|
||||
if (lagSyncScheduled != g_Config.bForceLagSync) {
|
||||
ScheduleLagSync();
|
||||
}
|
||||
}
|
||||
|
||||
void hleLeaveVblank(u64 userdata, int cyclesLate) {
|
||||
@ -632,6 +672,41 @@ void hleLeaveVblank(u64 userdata, int cyclesLate) {
|
||||
__DisplayFireVblank();
|
||||
}
|
||||
|
||||
void hleLagSync(u64 userdata, int cyclesLate) {
|
||||
// The goal here is to prevent network, audio, and input lag from the real world.
|
||||
// Our normal timing is very "stop and go". This is efficient, but causes real world lag.
|
||||
// This event (optionally) runs every 1ms to sync with the real world.
|
||||
|
||||
if (PSP_CoreParameter().unthrottle) {
|
||||
lagSyncScheduled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
float scale = 1.0f;
|
||||
if (PSP_CoreParameter().fpsLimit == FPS_LIMIT_CUSTOM) {
|
||||
if (g_Config.iFpsLimit == 0) {
|
||||
lagSyncScheduled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
scale = 60.0f / g_Config.iFpsLimit;
|
||||
}
|
||||
|
||||
const double goal = lastLagSync + (scale / 1000.0f);
|
||||
time_update();
|
||||
while (time_now_d() < goal) {
|
||||
const double left = goal - time_now_d();
|
||||
#ifndef _WIN32
|
||||
usleep((long)(left * 1000000));
|
||||
#endif
|
||||
time_update();
|
||||
}
|
||||
|
||||
const int emuOver = (int)cyclesToUs(cyclesLate);
|
||||
const int over = (int)((time_now_d() - goal) * 1000000);
|
||||
ScheduleLagSync(over - emuOver);
|
||||
}
|
||||
|
||||
u32 sceDisplayIsVblank() {
|
||||
DEBUG_LOG(SCEDISPLAY,"%i=sceDisplayIsVblank()",isVblank);
|
||||
return isVblank;
|
||||
|
@ -304,6 +304,7 @@ void GameSettingsScreen::CreateViews() {
|
||||
|
||||
systemSettings->Add(new CheckBox(&g_Config.bSeparateCPUThread, s->T("Multithreaded (experimental)")))->SetEnabled(!PSP_IsInited());
|
||||
systemSettings->Add(new CheckBox(&g_Config.bSeparateIOThread, s->T("I/O on thread (experimental)")))->SetEnabled(!PSP_IsInited());
|
||||
systemSettings->Add(new CheckBox(&g_Config.bForceLagSync, s->T("Force real clock sync (slower, less lag)")));
|
||||
systemSettings->Add(new PopupSliderChoice(&g_Config.iLockedCPUSpeed, 0, 1000, s->T("Change CPU Clock", "Change CPU Clock (0 = default) (unstable)"), screenManager()));
|
||||
#ifndef MOBILE_DEVICE
|
||||
systemSettings->Add(new PopupSliderChoice(&g_Config.iRewindFlipFrequency, 0, 1800, s->T("Rewind Snapshot Frequency", "Rewind Snapshot Frequency (0 = off, mem hog)"), screenManager()));
|
||||
|
Loading…
Reference in New Issue
Block a user