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("HomebrewStore", &g_Config.bHomebrewStore, false, false),
|
||||||
ConfigSetting("CheckForNewVersion", &g_Config.bCheckForNewVersion, true),
|
ConfigSetting("CheckForNewVersion", &g_Config.bCheckForNewVersion, true),
|
||||||
ConfigSetting("Language", &g_Config.sLanguageIni, &DefaultLangRegion),
|
ConfigSetting("Language", &g_Config.sLanguageIni, &DefaultLangRegion),
|
||||||
|
ConfigSetting("ForceLagSync", &g_Config.bForceLagSync, false),
|
||||||
|
|
||||||
ReportedConfigSetting("NumWorkerThreads", &g_Config.iNumWorkerThreads, &DefaultNumWorkers),
|
ReportedConfigSetting("NumWorkerThreads", &g_Config.iNumWorkerThreads, &DefaultNumWorkers),
|
||||||
ConfigSetting("EnableAutoLoad", &g_Config.bEnableAutoLoad, false),
|
ConfigSetting("EnableAutoLoad", &g_Config.bEnableAutoLoad, false),
|
||||||
|
@ -83,6 +83,7 @@ public:
|
|||||||
bool bFastMemory;
|
bool bFastMemory;
|
||||||
bool bJit;
|
bool bJit;
|
||||||
bool bCheckForNewVersion;
|
bool bCheckForNewVersion;
|
||||||
|
bool bForceLagSync;
|
||||||
|
|
||||||
// Definitely cannot be changed while game is running.
|
// Definitely cannot be changed while game is running.
|
||||||
bool bSeparateCPUThread;
|
bool bSeparateCPUThread;
|
||||||
|
@ -20,6 +20,12 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <algorithm>
|
#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
|
// 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
|
// to be dependent on "native", I think. Or maybe should get rid of common
|
||||||
// and move everything into native...
|
// and move everything into native...
|
||||||
@ -79,6 +85,10 @@ static bool framebufIsLatched;
|
|||||||
static int enterVblankEvent = -1;
|
static int enterVblankEvent = -1;
|
||||||
static int leaveVblankEvent = -1;
|
static int leaveVblankEvent = -1;
|
||||||
static int afterFlipEvent = -1;
|
static int afterFlipEvent = -1;
|
||||||
|
static int lagSyncEvent = -1;
|
||||||
|
|
||||||
|
static double lastLagSync = 0.0;
|
||||||
|
static bool lagSyncScheduled = false;
|
||||||
|
|
||||||
// hCount is computed now.
|
// hCount is computed now.
|
||||||
static int vCount;
|
static int vCount;
|
||||||
@ -140,12 +150,21 @@ static int lastFlipsTooFrequent = 0;
|
|||||||
void hleEnterVblank(u64 userdata, int cyclesLate);
|
void hleEnterVblank(u64 userdata, int cyclesLate);
|
||||||
void hleLeaveVblank(u64 userdata, int cyclesLate);
|
void hleLeaveVblank(u64 userdata, int cyclesLate);
|
||||||
void hleAfterFlip(u64 userdata, int cyclesLate);
|
void hleAfterFlip(u64 userdata, int cyclesLate);
|
||||||
|
void hleLagSync(u64 userdata, int cyclesLate);
|
||||||
|
|
||||||
void __DisplayVblankBeginCallback(SceUID threadID, SceUID prevCallbackId);
|
void __DisplayVblankBeginCallback(SceUID threadID, SceUID prevCallbackId);
|
||||||
void __DisplayVblankEndCallback(SceUID threadID, SceUID prevCallbackId);
|
void __DisplayVblankEndCallback(SceUID threadID, SceUID prevCallbackId);
|
||||||
int __DisplayGetFlipCount() { return actualFlips; }
|
int __DisplayGetFlipCount() { return actualFlips; }
|
||||||
int __DisplayGetVCount() { return vCount; }
|
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() {
|
void __DisplayInit() {
|
||||||
gpuStats.Reset();
|
gpuStats.Reset();
|
||||||
hasSetMode = false;
|
hasSetMode = false;
|
||||||
@ -168,6 +187,9 @@ void __DisplayInit() {
|
|||||||
leaveVblankEvent = CoreTiming::RegisterEvent("LeaveVBlank", &hleLeaveVblank);
|
leaveVblankEvent = CoreTiming::RegisterEvent("LeaveVBlank", &hleLeaveVblank);
|
||||||
afterFlipEvent = CoreTiming::RegisterEvent("AfterFlip", &hleAfterFlip);
|
afterFlipEvent = CoreTiming::RegisterEvent("AfterFlip", &hleAfterFlip);
|
||||||
|
|
||||||
|
lagSyncEvent = CoreTiming::RegisterEvent("LagSync", &hleLagSync);
|
||||||
|
ScheduleLagSync();
|
||||||
|
|
||||||
CoreTiming::ScheduleEvent(msToCycles(frameMs - vblankMs), enterVblankEvent, 0);
|
CoreTiming::ScheduleEvent(msToCycles(frameMs - vblankMs), enterVblankEvent, 0);
|
||||||
isVblank = 0;
|
isVblank = 0;
|
||||||
vCount = 0;
|
vCount = 0;
|
||||||
@ -189,7 +211,7 @@ void __DisplayInit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void __DisplayDoState(PointerWrap &p) {
|
void __DisplayDoState(PointerWrap &p) {
|
||||||
auto s = p.Section("sceDisplay", 1, 4);
|
auto s = p.Section("sceDisplay", 1, 5);
|
||||||
if (!s)
|
if (!s)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -226,6 +248,19 @@ void __DisplayDoState(PointerWrap &p) {
|
|||||||
p.Do(afterFlipEvent);
|
p.Do(afterFlipEvent);
|
||||||
CoreTiming::RestoreRegisterEvent(afterFlipEvent, "AfterFlip", &hleAfterFlip);
|
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);
|
p.Do(gstate);
|
||||||
gstate_c.DoState(p);
|
gstate_c.DoState(p);
|
||||||
#ifndef _XBOX
|
#ifndef _XBOX
|
||||||
@ -621,6 +656,11 @@ void hleEnterVblank(u64 userdata, int cyclesLate) {
|
|||||||
void hleAfterFlip(u64 userdata, int cyclesLate)
|
void hleAfterFlip(u64 userdata, int cyclesLate)
|
||||||
{
|
{
|
||||||
gpu->BeginFrame(); // doesn't really matter if begin or end of frame.
|
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) {
|
void hleLeaveVblank(u64 userdata, int cyclesLate) {
|
||||||
@ -632,6 +672,41 @@ void hleLeaveVblank(u64 userdata, int cyclesLate) {
|
|||||||
__DisplayFireVblank();
|
__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() {
|
u32 sceDisplayIsVblank() {
|
||||||
DEBUG_LOG(SCEDISPLAY,"%i=sceDisplayIsVblank()",isVblank);
|
DEBUG_LOG(SCEDISPLAY,"%i=sceDisplayIsVblank()",isVblank);
|
||||||
return 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.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.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()));
|
systemSettings->Add(new PopupSliderChoice(&g_Config.iLockedCPUSpeed, 0, 1000, s->T("Change CPU Clock", "Change CPU Clock (0 = default) (unstable)"), screenManager()));
|
||||||
#ifndef MOBILE_DEVICE
|
#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()));
|
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