Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement 3 configurable and toggleable framerate targets #2159

Merged
merged 4 commits into from
Sep 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 (fastforward) emuInstance->curFPS = emuInstance->fastForwardFPS;
else if (!emuInstance->doLimitFPS) emuInstance->curFPS = 1.0 / 1000.0;
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
Loading