Permalink
Browse files

Core: Allow toggle between 2 custom speeds.

In addition to virtual keys for each speed separately.
  • Loading branch information...
unknownbrackets committed Jun 17, 2018
1 parent 23ecd2a commit 95f270778e35d8200a046228a0bb97b57019b41d
@@ -645,7 +645,8 @@ const KeyMap_IntStrPair psp_button_names[] = {
{VIRTKEY_RAPID_FIRE, "RapidFire"},
{VIRTKEY_UNTHROTTLE, "Unthrottle"},
{VIRTKEY_SPEED_TOGGLE, "SpeedToggle"},
{VIRTKEY_SPEED_PRESS, "Speed toggle hold"},
{VIRTKEY_SPEED_CUSTOM1, "Alt speed 1"},
{VIRTKEY_SPEED_CUSTOM2, "Alt speed 2"},
{VIRTKEY_PAUSE, "Pause"},
#ifndef MOBILE_DEVICE
{VIRTKEY_FRAME_ADVANCE, "Frame Advance"},
@@ -52,7 +52,8 @@ enum {
VIRTKEY_DEVMENU = 0x40000014,
VIRTKEY_FRAME_ADVANCE = 0x40000015,
VIRTKEY_RECORD = 0x40000016,
VIRTKEY_SPEED_PRESS = 0x40000017,
VIRTKEY_SPEED_CUSTOM1 = 0x40000017,
VIRTKEY_SPEED_CUSTOM2 = 0x40000018,
VIRTKEY_LAST,
VIRTKEY_COUNT = VIRTKEY_LAST - VIRTKEY_FIRST
};
@@ -525,7 +525,8 @@ static ConfigSetting graphicsSettings[] = {
ReportedConfigSetting("HighQualityDepth", &g_Config.bHighQualityDepth, true, true, true),
ReportedConfigSetting("FrameSkip", &g_Config.iFrameSkip, 0, true, true),
ReportedConfigSetting("AutoFrameSkip", &g_Config.bAutoFrameSkip, false, true, true),
ConfigSetting("FrameRate", &g_Config.iFpsLimit, 0, true, true),
ConfigSetting("FrameRate", &g_Config.iFpsLimit1, 0, true, true),
ConfigSetting("FrameRate2", &g_Config.iFpsLimit2, -1, true, true),
ConfigSetting("FrameSkipUnthrottle", &g_Config.bFrameSkipUnthrottle, &DefaultFrameskipUnthrottle, true, false),
#if defined(USING_WIN_UI)
ConfigSetting("RestartRequired", &g_Config.bRestartRequired, false, false),
@@ -160,7 +160,8 @@ struct Config {
int iTexScalingLevel; // 0 = auto, 1 = off, 2 = 2x, ..., 5 = 5x
int iTexScalingType; // 0 = xBRZ, 1 = Hybrid
bool bTexDeposterize;
int iFpsLimit;
int iFpsLimit1;
int iFpsLimit2;
int iForceMaxEmulatedFPS;
int iMaxRecent;
int iCurrentStateSlot;
@@ -31,6 +31,12 @@ enum GPUCore {
GPUCORE_VULKAN,
};
enum class FPSLimit {
NORMAL = 0,
CUSTOM1 = 1,
CUSTOM2 = 2,
};
class FileLoader;
class GraphicsContext;
@@ -42,13 +48,13 @@ enum class CPUCore;
// PSP_CoreParameter()
struct CoreParameter {
CoreParameter() : thin3d(nullptr), collectEmuLog(0), unthrottle(false), fpsLimit(0), updateRecent(true), freezeNext(false), frozen(false), mountIsoLoader(nullptr) {}
CoreParameter() {}
CPUCore cpuCore;
GPUCore gpuCore;
GraphicsContext *graphicsContext; // TODO: Find a better place.
Draw::DrawContext *thin3d;
GraphicsContext *graphicsContext = nullptr; // TODO: Find a better place.
Draw::DrawContext *thin3d = nullptr;
bool enableSound; // there aren't multiple sound cores.
std::string fileToStart;
@@ -58,7 +64,7 @@ struct CoreParameter {
bool startPaused;
bool printfEmuLog; // writes "emulator:" logging to stdout
std::string *collectEmuLog;
std::string *collectEmuLog = nullptr;
bool headLess; // Try to avoid messageboxes etc
// Internal PSP resolution
@@ -70,16 +76,16 @@ struct CoreParameter {
int pixelHeight;
// Can be modified at runtime.
bool unthrottle;
int fpsLimit;
bool unthrottle = false;
FPSLimit fpsLimit = FPSLimit::NORMAL;
bool updateRecent;
bool updateRecent = true;
// Freeze-frame. For nvidia perfhud profiling. Developers only.
bool freezeNext;
bool frozen;
bool freezeNext = false;
bool frozen = false;
FileLoader *mountIsoLoader;
FileLoader *mountIsoLoader = nullptr;
Compatibility compat;
};
@@ -476,17 +476,17 @@ void __DisplayGetDebugStats(char *stats, size_t bufsize) {
statbuf);
}
enum {
FPS_LIMIT_NORMAL = 0,
FPS_LIMIT_CUSTOM = 1,
};
void __DisplaySetWasPaused() {
wasPaused = true;
}
static bool FrameTimingThrottled() {
if (PSP_CoreParameter().fpsLimit == FPS_LIMIT_CUSTOM && g_Config.iFpsLimit == 0) {
if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1 && g_Config.iFpsLimit1 == 0) {
return false;
}
if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM2 && g_Config.iFpsLimit2 == 0) {
return false;
}
return !PSP_CoreParameter().unthrottle;
@@ -505,7 +505,7 @@ static void DoFrameDropLogging(float scaledTimestep) {
// Let's collect all the throttling and frameskipping logic here.
static void DoFrameTiming(bool &throttle, bool &skipFrame, float timestep) {
PROFILE_THIS_SCOPE("timing");
int fpsLimiter = PSP_CoreParameter().fpsLimit;
FPSLimit fpsLimiter = PSP_CoreParameter().fpsLimit;
throttle = FrameTimingThrottled();
skipFrame = false;
@@ -528,8 +528,10 @@ static void DoFrameTiming(bool &throttle, bool &skipFrame, float timestep) {
time_update();
float scaledTimestep = timestep;
if (fpsLimiter == FPS_LIMIT_CUSTOM && g_Config.iFpsLimit != 0) {
scaledTimestep *= 60.0f / g_Config.iFpsLimit;
if (fpsLimiter == FPSLimit::CUSTOM1 && g_Config.iFpsLimit1 > 0) {
scaledTimestep *= 60.0f / g_Config.iFpsLimit1;
} else if (fpsLimiter == FPSLimit::CUSTOM2 && g_Config.iFpsLimit2 > 0) {
scaledTimestep *= 60.0f / g_Config.iFpsLimit2;
}
if (lastFrameTime == 0.0 || wasPaused) {
@@ -549,7 +551,8 @@ static void DoFrameTiming(bool &throttle, bool &skipFrame, float timestep) {
// Auto-frameskip automatically if speed limit is set differently than the default.
bool useAutoFrameskip = g_Config.bAutoFrameSkip && g_Config.iRenderingMode != FB_NON_BUFFERED_MODE;
if (g_Config.bAutoFrameSkip || (g_Config.iFrameSkip == 0 && fpsLimiter == FPS_LIMIT_CUSTOM && g_Config.iFpsLimit > 60)) {
bool forceFrameskip = (fpsLimiter == FPSLimit::CUSTOM1 && g_Config.iFpsLimit1 > 60) || (fpsLimiter == FPSLimit::CUSTOM2 && g_Config.iFpsLimit2 > 60);
if (g_Config.bAutoFrameSkip || forceFrameskip) {
// autoframeskip
// Argh, we are falling behind! Let's skip a frame and see if we catch up.
if (curFrameTime > nextFrameTime && doFrameSkip) {
@@ -601,9 +604,11 @@ static void DoFrameIdleTiming() {
}
float scaledVblank = timePerVblank;
if (PSP_CoreParameter().fpsLimit == FPS_LIMIT_CUSTOM) {
if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1 && g_Config.iFpsLimit1 > 0) {
// 0 is handled in FrameTimingThrottled().
scaledVblank *= 60.0f / g_Config.iFpsLimit;
scaledVblank *= 60.0f / g_Config.iFpsLimit1;
} else if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM2 && g_Config.iFpsLimit2 > 0) {
scaledVblank *= 60.0f / g_Config.iFpsLimit2;
}
// If we have over at least a vblank of spare time, maintain at least 30fps in delay.
@@ -695,7 +700,7 @@ void __DisplayFlip(int cyclesLate) {
// Let the user know if we're running slow, so they know to adjust settings.
// Sometimes users just think the sound emulation is broken.
static bool hasNotifiedSlow = false;
if (!g_Config.bHideSlowWarnings && !hasNotifiedSlow && PSP_CoreParameter().fpsLimit == FPS_LIMIT_NORMAL && IsRunningSlow()) {
if (!g_Config.bHideSlowWarnings && !hasNotifiedSlow && PSP_CoreParameter().fpsLimit == FPSLimit::NORMAL && IsRunningSlow()) {
#ifndef _DEBUG
I18NCategory *err = GetI18NCategory("Error");
if (g_Config.bSoftwareRendering) {
@@ -787,9 +792,11 @@ void hleLagSync(u64 userdata, int cyclesLate) {
}
float scale = 1.0f;
if (PSP_CoreParameter().fpsLimit == FPS_LIMIT_CUSTOM) {
if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1 && g_Config.iFpsLimit1 > 0) {
// 0 is handled in FrameTimingThrottled().
scale = 60.0f / g_Config.iFpsLimit;
scale = 60.0f / g_Config.iFpsLimit1;
} else if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM2 && g_Config.iFpsLimit2 > 0) {
scale = 60.0f / g_Config.iFpsLimit2;
}
const double goal = lastLagSync + (scale / 1000.0f);
@@ -211,7 +211,7 @@ void GPU_DX9::ReapplyGfxState() {
void GPU_DX9::BeginFrame() {
// Turn off vsync when unthrottled
int desiredVSyncInterval = g_Config.bVSync ? 1 : 0;
if ((PSP_CoreParameter().unthrottle) || (PSP_CoreParameter().fpsLimit == 1))
if (PSP_CoreParameter().unthrottle || PSP_CoreParameter().fpsLimit != FPSLimit::NORMAL)
desiredVSyncInterval = 0;
if (desiredVSyncInterval != lastVsync_) {
dxstate.SetVSyncInterval(desiredVSyncInterval);
@@ -392,9 +392,10 @@ inline void GPU_GLES::UpdateVsyncInterval(bool force) {
if (PSP_CoreParameter().unthrottle) {
desiredVSyncInterval = 0;
}
if (PSP_CoreParameter().fpsLimit == 1) {
if (PSP_CoreParameter().fpsLimit != FPSLimit::NORMAL) {
int limit = PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1 ? g_Config.iFpsLimit1 : g_Config.iFpsLimit2;
// For an alternative speed that is a clean factor of 60, the user probably still wants vsync.
if (g_Config.iFpsLimit == 0 || (g_Config.iFpsLimit != 15 && g_Config.iFpsLimit != 30 && g_Config.iFpsLimit != 60)) {
if (limit == 0 || (limit >= 0 && limit != 15 && limit != 30 && limit != 60)) {
desiredVSyncInterval = 0;
}
}
@@ -472,21 +472,31 @@ void EmuScreen::onVKeyDown(int virtualKeyCode) {
break;
case VIRTKEY_SPEED_TOGGLE:
if (PSP_CoreParameter().fpsLimit == 0) {
PSP_CoreParameter().fpsLimit = 1;
// Cycle through enabled speeds.
if (PSP_CoreParameter().fpsLimit == FPSLimit::NORMAL && g_Config.iFpsLimit1 >= 0) {
PSP_CoreParameter().fpsLimit = FPSLimit::CUSTOM1;
osm.Show(sc->T("fixed", "Speed: alternate"), 1.0);
} else if (PSP_CoreParameter().fpsLimit == 1) {
PSP_CoreParameter().fpsLimit = 0;
} else if (PSP_CoreParameter().fpsLimit != FPSLimit::CUSTOM2 && g_Config.iFpsLimit2 >= 0) {
PSP_CoreParameter().fpsLimit = FPSLimit::CUSTOM2;
osm.Show(sc->T("SpeedCustom2", "Speed: alternate 2"), 1.0);
} else if (PSP_CoreParameter().fpsLimit != FPSLimit::NORMAL) {
PSP_CoreParameter().fpsLimit = FPSLimit::NORMAL;
osm.Show(sc->T("standard", "Speed: standard"), 1.0);
}
break;
case VIRTKEY_SPEED_PRESS:
if (PSP_CoreParameter().fpsLimit == 0) {
PSP_CoreParameter().fpsLimit = 1;
case VIRTKEY_SPEED_CUSTOM1:
if (PSP_CoreParameter().fpsLimit == FPSLimit::NORMAL) {
PSP_CoreParameter().fpsLimit = FPSLimit::CUSTOM1;
osm.Show(sc->T("fixed", "Speed: alternate"), 1.0);
}
break;
case VIRTKEY_SPEED_CUSTOM2:
if (PSP_CoreParameter().fpsLimit == FPSLimit::NORMAL) {
PSP_CoreParameter().fpsLimit = FPSLimit::CUSTOM2;
osm.Show(sc->T("SpeedCustom2", "Speed: alternate 2"), 1.0);
}
break;
case VIRTKEY_PAUSE:
pauseTrigger_ = true;
@@ -594,9 +604,15 @@ void EmuScreen::onVKeyUp(int virtualKeyCode) {
PSP_CoreParameter().unthrottle = false;
break;
case VIRTKEY_SPEED_PRESS:
if (PSP_CoreParameter().fpsLimit == 1) {
PSP_CoreParameter().fpsLimit = 0;
case VIRTKEY_SPEED_CUSTOM1:
if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1) {
PSP_CoreParameter().fpsLimit = FPSLimit::NORMAL;
osm.Show(sc->T("standard", "Speed: standard"), 1.0);
}
break;
case VIRTKEY_SPEED_CUSTOM2:
if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM2) {
PSP_CoreParameter().fpsLimit = FPSLimit::NORMAL;
osm.Show(sc->T("standard", "Speed: standard"), 1.0);
}
break;
@@ -1022,11 +1038,6 @@ void EmuScreen::update() {
// Virtual keys.
__CtrlSetRapidFire(virtKeys[VIRTKEY_RAPID_FIRE - VIRTKEY_FIRST]);
// Make sure fpsLimit starts at 0
if (PSP_CoreParameter().fpsLimit != 0 && PSP_CoreParameter().fpsLimit != 1) {
PSP_CoreParameter().fpsLimit = 0;
}
// This is here to support the iOS on screen back button.
if (pauseTrigger_) {
pauseTrigger_ = false;
@@ -127,7 +127,8 @@ void GameSettingsScreen::CreateViews() {
cap60FPS_ = g_Config.iForceMaxEmulatedFPS == 60;
iAlternateSpeedPercent_ = (g_Config.iFpsLimit * 100) / 60;
iAlternateSpeedPercent1_ = g_Config.iFpsLimit1 < 0 ? -1 : (g_Config.iFpsLimit1 * 100) / 60;
iAlternateSpeedPercent2_ = g_Config.iFpsLimit2 < 0 ? -1 : (g_Config.iFpsLimit2 * 100) / 60;
bool vertical = UseVerticalLayout();
@@ -271,9 +272,15 @@ void GameSettingsScreen::CreateViews() {
frameSkipAuto_->OnClick.Handle(this, &GameSettingsScreen::OnAutoFrameskip);
graphicsSettings->Add(new CheckBox(&cap60FPS_, gr->T("Force max 60 FPS (helps GoW)")));
PopupSliderChoice *altSpeed = graphicsSettings->Add(new PopupSliderChoice(&iAlternateSpeedPercent_, 0, 1000, gr->T("Alternative Speed", "Alternative speed"), 5, screenManager(), gr->T("%, 0:unlimited")));
altSpeed->SetFormat("%i%%");
altSpeed->SetZeroLabel(gr->T("Unlimited"));
PopupSliderChoice *altSpeed1 = graphicsSettings->Add(new PopupSliderChoice(&iAlternateSpeedPercent1_, 0, 1000, gr->T("Alternative Speed", "Alternative speed"), 5, screenManager(), gr->T("%, 0:unlimited")));
altSpeed1->SetFormat("%i%%");
altSpeed1->SetZeroLabel(gr->T("Unlimited"));
altSpeed1->SetNegativeDisable(gr->T("Disabled"));
PopupSliderChoice *altSpeed2 = graphicsSettings->Add(new PopupSliderChoice(&iAlternateSpeedPercent2_, 0, 1000, gr->T("Alternative Speed 2", "Alternative speed 2 (in %, 0 = unlimited)"), 5, screenManager(), gr->T("%, 0:unlimited")));
altSpeed2->SetFormat("%i%%");
altSpeed2->SetZeroLabel(gr->T("Unlimited"));
altSpeed2->SetNegativeDisable(gr->T("Disabled"));
graphicsSettings->Add(new ItemHeader(gr->T("Features")));
// Hide postprocess option on unsupported backends to avoid confusion.
@@ -1033,7 +1040,8 @@ void GameSettingsScreen::update() {
UIScreen::update();
g_Config.iForceMaxEmulatedFPS = cap60FPS_ ? 60 : 0;
g_Config.iFpsLimit = (iAlternateSpeedPercent_ * 60) / 100;
g_Config.iFpsLimit1 = iAlternateSpeedPercent1_ < 0 ? -1 : (iAlternateSpeedPercent1_ * 60) / 100;
g_Config.iFpsLimit2 = iAlternateSpeedPercent2_ < 0 ? -1 : (iAlternateSpeedPercent2_ * 60) / 100;
bool vertical = UseVerticalLayout();
if (vertical != lastVertical_) {
@@ -106,7 +106,8 @@ class GameSettingsScreen : public UIDialogScreenWithGameBackground {
// Temporaries to convert bools to int settings
bool cap60FPS_;
int iAlternateSpeedPercent_;
int iAlternateSpeedPercent1_;
int iAlternateSpeedPercent2_;
bool enableReports_;
//edit the game-specific settings and restore the global settings after exiting
@@ -515,10 +515,6 @@ namespace MainWindow {
NativeMessageReceived("gpu_resized", "");
}
static void setFpsLimit(int fps) {
g_Config.iFpsLimit = fps;
}
static void setFrameSkipping(int framesToSkip = -1) {
if (framesToSkip >= FRAMESKIP_OFF)
g_Config.iFrameSkip = framesToSkip;

0 comments on commit 95f2707

Please sign in to comment.