Skip to content

Commit

Permalink
rework framerate targets to be fully configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
Jaklyy committed Sep 26, 2024
1 parent 2eb6d44 commit 39fe562
Show file tree
Hide file tree
Showing 11 changed files with 417 additions and 55 deletions.
48 changes: 45 additions & 3 deletions src/frontend/qt_sdl/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ DefaultList<int> DefaultInts =
{"Screen.VSyncInterval", 1},
{"3D.Renderer", renderer3D_Software},
{"3D.GL.ScaleFactor", 1},
{"MaxFPS", 1000},
#ifdef JIT_ENABLED
{"JIT.MaxBlockSize", 32},
#endif
Expand Down Expand Up @@ -120,6 +119,13 @@ DefaultList<std::string> DefaultStrings =
{"Instance*.Firmware.Username", "melonDS"}
};

DefaultList<double> DefaultDoubles =
{
{"TargetFPS", 60.0},
{"FastForwardFPS", 1000.0},
{"SlowmoFPS", 30.0},
};

LegacyEntry LegacyFile[] =
{
{"Key_A", 0, "Keyboard.A", true},
Expand Down Expand Up @@ -153,7 +159,7 @@ LegacyEntry LegacyFile[] =
{"HKKey_Pause", 0, "Keyboard.HK_Pause", true},
{"HKKey_Reset", 0, "Keyboard.HK_Reset", true},
{"HKKey_FastForward", 0, "Keyboard.HK_FastForward", true},
{"HKKey_FastForwardToggle", 0, "Keyboard.HK_FastForwardToggle", true},
{"HKKey_FastForwardToggle", 0, "Keyboard.HK_FrameLimitToggle", true},
{"HKKey_FullscreenToggle", 0, "Keyboard.HK_FullscreenToggle", true},
{"HKKey_SwapScreens", 0, "Keyboard.HK_SwapScreens", true},
{"HKKey_SwapScreenEmphasis", 0, "Keyboard.HK_SwapScreenEmphasis", true},
Expand All @@ -169,7 +175,7 @@ LegacyEntry LegacyFile[] =
{"HKJoy_Pause", 0, "Joystick.HK_Pause", true},
{"HKJoy_Reset", 0, "Joystick.HK_Reset", true},
{"HKJoy_FastForward", 0, "Joystick.HK_FastForward", true},
{"HKJoy_FastForwardToggle", 0, "Joystick.HK_FastForwardToggle", true},
{"HKJoy_FastForwardToggle", 0, "Joystick.HK_FrameLimitToggle", true},
{"HKJoy_FullscreenToggle", 0, "Joystick.HK_FullscreenToggle", true},
{"HKJoy_SwapScreens", 0, "Joystick.HK_SwapScreens", true},
{"HKJoy_SwapScreenEmphasis", 0, "Joystick.HK_SwapScreenEmphasis", true},
Expand Down Expand Up @@ -434,6 +440,18 @@ std::string Array::GetString(const int id)
return tval.as_string();
}

double Array::GetDouble(const int id)
{
while (Data.size() < id+1)
Data.push_back(0.0);

toml::value& tval = Data[id];
if (!tval.is_floating())
tval = 0.0;

return tval.as_floating();
}

void Array::SetInt(const int id, int val)
{
while (Data.size() < id+1)
Expand Down Expand Up @@ -470,6 +488,15 @@ void Array::SetString(const int id, const std::string& val)
tval = val;
}

void Array::SetDouble(const int id, double val)
{
while (Data.size() < id+1)
Data.push_back(0.0);

toml::value& tval = Data[id];
tval = val;
}


/*Table::Table()// : Data(toml::value())
{
Expand Down Expand Up @@ -562,6 +589,15 @@ std::string Table::GetString(const std::string& path)
return tval.as_string();
}

double Table::GetDouble(const std::string& path)
{
toml::value& tval = ResolvePath(path);
if (!tval.is_floating())
tval = FindDefault(path, 0.0, DefaultDoubles);

return tval.as_floating();
}

void Table::SetInt(const std::string& path, int val)
{
std::string rngkey = GetDefaultKey(PathPrefix+path);
Expand Down Expand Up @@ -593,6 +629,12 @@ void Table::SetString(const std::string& path, const std::string& val)
tval = val;
}

void Table::SetDouble(const std::string& path, double val)
{
toml::value& tval = ResolvePath(path);
tval = val;
}

toml::value& Table::ResolvePath(const std::string& path)
{
toml::value* ret = &Data;
Expand Down
4 changes: 4 additions & 0 deletions src/frontend/qt_sdl/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,13 @@ class Array
int64_t GetInt64(const int id);
bool GetBool(const int id);
std::string GetString(const int id);
double GetDouble(const int id);

void SetInt(const int id, int val);
void SetInt64(const int id, int64_t val);
void SetBool(const int id, bool val);
void SetString(const int id, const std::string& val);
void SetDouble(const int id, double val);

// convenience

Expand Down Expand Up @@ -99,11 +101,13 @@ class Table
int64_t GetInt64(const std::string& path);
bool GetBool(const std::string& path);
std::string GetString(const std::string& path);
double GetDouble(const std::string& path);

void SetInt(const std::string& path, int val);
void SetInt64(const std::string& path, int64_t val);
void SetBool(const std::string& path, bool val);
void SetString(const std::string& path, const std::string& val);
void SetDouble(const std::string& path, double val);

// convenience

Expand Down
26 changes: 25 additions & 1 deletion src/frontend/qt_sdl/EmuInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,31 @@ EmuInstance::EmuInstance(int inst) : deleting(false),
cheatsOn = localCfg.GetBool("EnableCheats");

doLimitFPS = globalCfg.GetBool("LimitFPS");
maxFPS = globalCfg.GetInt("MaxFPS");

double val = globalCfg.GetDouble("TargetFPS");
if (val == 0.0)
{
Platform::Log(Platform::LogLevel::Error, "Target FPS in config invalid\n");
targetFPS = 1.0 / 60.0;
}
else targetFPS = 1.0 / val;

val = globalCfg.GetDouble("FastForwardFPS");
if (val == 0.0)
{
Platform::Log(Platform::LogLevel::Error, "Fast-Forward FPS in config invalid\n");
fastForwardFPS = 1.0 / 60.0;
}
else fastForwardFPS = 1.0 / val;

val = globalCfg.GetDouble("SlowmoFPS");
if (val == 0.0)
{
Platform::Log(Platform::LogLevel::Error, "Slow-Mo FPS in config invalid\n");
slowmoFPS = 1.0 / 60.0;
}
else slowmoFPS = 1.0 / val;

doAudioSync = globalCfg.GetBool("AudioSync");

mpAudioMode = globalCfg.GetInt("MP.AudioMode");
Expand Down
12 changes: 10 additions & 2 deletions src/frontend/qt_sdl/EmuInstance.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ enum
HK_Pause,
HK_Reset,
HK_FastForward,
HK_FastForwardToggle,
HK_FrameLimitToggle,
HK_FullscreenToggle,
HK_SwapScreens,
HK_SwapScreenEmphasis,
Expand All @@ -46,6 +46,9 @@ enum
HK_PowerButton,
HK_VolumeUp,
HK_VolumeDown,
HK_SlowMo,
HK_FastForwardToggle,
HK_SlowMoToggle,
HK_MAX
};

Expand Down Expand Up @@ -252,7 +255,12 @@ class EmuInstance
std::unique_ptr<SaveManager> firmwareSave;

bool doLimitFPS;
int maxFPS;
double curFPS;
double targetFPS;
double fastForwardFPS;
double slowmoFPS;
bool fastForwardToggled;
bool slowmoToggled;
bool doAudioSync;
private:

Expand Down
7 changes: 5 additions & 2 deletions src/frontend/qt_sdl/EmuInstanceInput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const char* EmuInstance::hotkeyNames[HK_MAX] =
"HK_Pause",
"HK_Reset",
"HK_FastForward",
"HK_FastForwardToggle",
"HK_FrameLimitToggle",
"HK_FullscreenToggle",
"HK_SwapScreens",
"HK_SwapScreenEmphasis",
Expand All @@ -56,7 +56,10 @@ const char* EmuInstance::hotkeyNames[HK_MAX] =
"HK_FrameStep",
"HK_PowerButton",
"HK_VolumeUp",
"HK_VolumeDown"
"HK_VolumeDown",
"HK_SlowMo",
"HK_FastForwardToggle",
"HK_SlowMoToggle"
};


Expand Down
43 changes: 28 additions & 15 deletions src/frontend/qt_sdl/EmuThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,12 +149,17 @@ void EmuThread::run()

char melontitle[100];

bool fastforward = false;
bool slowmo = false;
emuInstance->fastForwardToggled = false;
emuInstance->slowmoToggled = false;

while (emuStatus != emuStatus_Exit)
{
MPInterface::Get().Process();
emuInstance->inputProcess();

if (emuInstance->hotkeyPressed(HK_FastForwardToggle)) emit windowLimitFPSChange();
if (emuInstance->hotkeyPressed(HK_FrameLimitToggle)) emit windowLimitFPSChange();

if (emuInstance->hotkeyPressed(HK_Pause)) emuTogglePause();
if (emuInstance->hotkeyPressed(HK_Reset)) emuReset();
Expand Down Expand Up @@ -332,22 +337,34 @@ void EmuThread::run()
emit windowUpdate();
winUpdateCount = 0;
}

if (emuInstance->hotkeyPressed(HK_FastForwardToggle)) emuInstance->fastForwardToggled = !emuInstance->fastForwardToggled;
if (emuInstance->hotkeyPressed(HK_SlowMoToggle)) emuInstance->slowmoToggled = !emuInstance->slowmoToggled;

bool fastforward = emuInstance->hotkeyDown(HK_FastForward);
bool enablefastforward = emuInstance->hotkeyDown(HK_FastForward) | emuInstance->fastForwardToggled;
bool enableslowmo = emuInstance->hotkeyDown(HK_SlowMo) | emuInstance->slowmoToggled;

if (useOpenGL)
{
// when using OpenGL: when toggling fast-forward, change the vsync interval
if (emuInstance->hotkeyPressed(HK_FastForward))
// when using OpenGL: when toggling fast-forward or slowmo, change the vsync interval
if ((enablefastforward || enableslowmo) && !(fastforward || slowmo))
{
emuInstance->setVSyncGL(false);
}
else if (emuInstance->hotkeyReleased(HK_FastForward))
else if (!(enablefastforward || enableslowmo) && (fastforward || slowmo))
{
emuInstance->setVSyncGL(true);
}
}

fastforward = enablefastforward;
slowmo = enableslowmo;

if (slowmo) emuInstance->curFPS = emuInstance->slowmoFPS;
else if (!emuInstance->doLimitFPS) emuInstance->curFPS = 1.0 / 1000.0;
else if (fastforward) emuInstance->curFPS = emuInstance->fastForwardFPS;
else emuInstance->curFPS = emuInstance->targetFPS;

if (emuInstance->audioDSiVolumeSync && emuInstance->nds->ConsoleType == 1)
{
DSi* dsi = static_cast<DSi*>(emuInstance->nds);
Expand All @@ -361,23 +378,19 @@ void EmuThread::run()
emuInstance->audioVolume = volumeLevel * (256.0 / 31.0);
}

if (emuInstance->doAudioSync && !fastforward)
if (emuInstance->doAudioSync && !(fastforward || slowmo))
emuInstance->audioSync();

double frametimeStep = nlines / (60.0 * 263.0);

{
bool limitfps = emuInstance->doLimitFPS && !fastforward;

double practicalFramelimit = limitfps ? frametimeStep : 1.0 / emuInstance->maxFPS;

double curtime = SDL_GetPerformanceCounter() * perfCountsSec;

frameLimitError += practicalFramelimit - (curtime - lastTime);
if (frameLimitError < -practicalFramelimit)
frameLimitError = -practicalFramelimit;
if (frameLimitError > practicalFramelimit)
frameLimitError = practicalFramelimit;
frameLimitError += emuInstance->curFPS - (curtime - lastTime);
if (frameLimitError < -emuInstance->curFPS)
frameLimitError = -emuInstance->curFPS;
if (frameLimitError > emuInstance->curFPS)
frameLimitError = emuInstance->curFPS;

if (round(frameLimitError * 1000.0) > 0.0)
{
Expand Down
6 changes: 6 additions & 0 deletions src/frontend/qt_sdl/InputConfig/InputConfigDialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ static constexpr std::initializer_list<int> hk_general =
HK_FrameStep,
HK_FastForward,
HK_FastForwardToggle,
HK_SlowMo,
HK_SlowMoToggle,
HK_FrameLimitToggle,
HK_FullscreenToggle,
HK_Lid,
HK_Mic,
Expand All @@ -65,6 +68,9 @@ static constexpr std::initializer_list<const char*> hk_general_labels =
"Reset",
"Frame step",
"Fast forward",
"Toggle fast forward",
"Slow mo",
"Toggle slow mo",
"Toggle FPS limit",
"Toggle fullscreen",
"Close/open lid",
Expand Down
52 changes: 50 additions & 2 deletions src/frontend/qt_sdl/InterfaceSettingsDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ InterfaceSettingsDialog::InterfaceSettingsDialog(QWidget* parent) : QDialog(pare
ui->spinMouseHideSeconds->setEnabled(ui->cbMouseHide->isChecked());
ui->spinMouseHideSeconds->setValue(cfg.GetInt("MouseHideSeconds"));
ui->cbPauseLostFocus->setChecked(cfg.GetBool("PauseLostFocus"));
ui->spinMaxFPS->setValue(cfg.GetInt("MaxFPS"));
ui->spinTargetFPS->setValue(cfg.GetDouble("TargetFPS"));
ui->spinFFW->setValue(cfg.GetDouble("FastForwardFPS"));
ui->spinSlow->setValue(cfg.GetDouble("SlowmoFPS"));

const QList<QString> themeKeys = QStyleFactory::keys();
const QString currentTheme = qApp->style()->objectName();
Expand All @@ -65,6 +67,41 @@ void InterfaceSettingsDialog::on_cbMouseHide_clicked()
ui->spinMouseHideSeconds->setEnabled(ui->cbMouseHide->isChecked());
}

void InterfaceSettingsDialog::on_pbClean_clicked()
{
ui->spinTargetFPS->setValue(60.0000);
}

void InterfaceSettingsDialog::on_pbAccurate_clicked()
{
ui->spinTargetFPS->setValue(59.8261);
}

void InterfaceSettingsDialog::on_pb2x_clicked()
{
ui->spinFFW->setValue(ui->spinTargetFPS->value() * 2.0);
}

void InterfaceSettingsDialog::on_pb3x_clicked()
{
ui->spinFFW->setValue(ui->spinTargetFPS->value() * 3.0);
}

void InterfaceSettingsDialog::on_pbMAX_clicked()
{
ui->spinFFW->setValue(1000.0);
}

void InterfaceSettingsDialog::on_pbHalf_clicked()
{
ui->spinSlow->setValue(ui->spinTargetFPS->value() / 2.0);
}

void InterfaceSettingsDialog::on_pbQuarter_clicked()
{
ui->spinSlow->setValue(ui->spinTargetFPS->value() / 4.0);
}

void InterfaceSettingsDialog::done(int r)
{
if (r == QDialog::Accepted)
Expand All @@ -74,7 +111,18 @@ void InterfaceSettingsDialog::done(int r)
cfg.SetBool("MouseHide", ui->cbMouseHide->isChecked());
cfg.SetInt("MouseHideSeconds", ui->spinMouseHideSeconds->value());
cfg.SetBool("PauseLostFocus", ui->cbPauseLostFocus->isChecked());
cfg.SetInt("MaxFPS", ui->spinMaxFPS->value());

double val = ui->spinTargetFPS->value();
if (val == 0.0) cfg.SetDouble("TargetFPS", 0.0001);
else cfg.SetDouble("TargetFPS", val);

val = ui->spinFFW->value();
if (val == 0.0) cfg.SetDouble("FastForwardFPS", 0.0001);
else cfg.SetDouble("FastForwardFPS", val);

val = ui->spinSlow->value();
if (val == 0.0) cfg.SetDouble("SlowmoFPS", 0.0001);
else cfg.SetDouble("SlowmoFPS", val);

QString themeName = ui->cbxUITheme->currentData().toString();
cfg.SetQString("UITheme", themeName);
Expand Down
Loading

0 comments on commit 39fe562

Please sign in to comment.