From c6016856d878c8f68bc5518f3ef0270ea018bc3d Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Fri, 28 Dec 2018 18:35:55 -0500 Subject: [PATCH 1/6] settings: Add custom RTC settings Stored as signed seconds since epoch. --- src/core/settings.h | 3 +++ src/yuzu/configuration/config.cpp | 14 ++++++++++++-- src/yuzu_cmd/config.cpp | 11 +++++++++-- src/yuzu_cmd/default_ini.h | 6 ++++++ 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/core/settings.h b/src/core/settings.h index de01b05c0a..5b211a7162 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -350,6 +350,9 @@ struct Values { bool use_docked_mode; bool enable_nfc; std::optional rng_seed; + std::optional custom_rtc; // Measured in seconds since epoch + s64 custom_rtc_differential; // Set on game boot, reset on stop. Seconds difference between + // current time and `custom_rtc` s32 current_user; s32 language_index; diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 165d70e9cc..6e034ef190 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -419,13 +419,20 @@ void Config::ReadValues() { Settings::values.language_index = qt_config->value("language_index", 1).toInt(); - const auto enabled = qt_config->value("rng_seed_enabled", false).toBool(); - if (enabled) { + const auto rng_seed_enabled = qt_config->value("rng_seed_enabled", false).toBool(); + if (rng_seed_enabled) { Settings::values.rng_seed = qt_config->value("rng_seed", 0).toULongLong(); } else { Settings::values.rng_seed = std::nullopt; } + const auto custom_rtc_enabled = qt_config->value("custom_rtc_enabled", false).toBool(); + if (custom_rtc_enabled) { + Settings::values.custom_rtc = qt_config->value("custom_rtc", 0).toULongLong(); + } else { + Settings::values.custom_rtc = std::nullopt; + } + qt_config->endGroup(); qt_config->beginGroup("Miscellaneous"); @@ -653,6 +660,9 @@ void Config::SaveValues() { qt_config->setValue("rng_seed_enabled", Settings::values.rng_seed.has_value()); qt_config->setValue("rng_seed", Settings::values.rng_seed.value_or(0)); + qt_config->setValue("custom_rtc_enabled", Settings::values.custom_rtc.has_value()); + qt_config->setValue("custom_rtc", Settings::values.custom_rtc.value_or(0)); + qt_config->endGroup(); qt_config->beginGroup("Miscellaneous"); diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp index fe0d1eebf5..8f3b74cdf4 100644 --- a/src/yuzu_cmd/config.cpp +++ b/src/yuzu_cmd/config.cpp @@ -325,13 +325,20 @@ void Config::ReadValues() { Settings::values.current_user = std::clamp( sdl2_config->GetInteger("System", "current_user", 0), 0, Service::Account::MAX_USERS - 1); - const auto enabled = sdl2_config->GetBoolean("System", "rng_seed_enabled", false); - if (enabled) { + const auto rng_seed_enabled = sdl2_config->GetBoolean("System", "rng_seed_enabled", false); + if (rng_seed_enabled) { Settings::values.rng_seed = sdl2_config->GetInteger("System", "rng_seed", 0); } else { Settings::values.rng_seed = std::nullopt; } + const auto custom_rtc_enabled = sdl2_config->GetBoolean("System", "custom_rtc_enabled", false); + if (custom_rtc_enabled) { + Settings::values.custom_rtc = sdl2_config->GetInteger("System", "custom_rtc", 0); + } else { + Settings::values.custom_rtc = std::nullopt; + } + // Core Settings::values.use_cpu_jit = sdl2_config->GetBoolean("Core", "use_cpu_jit", true); Settings::values.use_multi_core = sdl2_config->GetBoolean("Core", "use_multi_core", false); diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h index 0f3f8da502..0a3ea26197 100644 --- a/src/yuzu_cmd/default_ini.h +++ b/src/yuzu_cmd/default_ini.h @@ -183,6 +183,12 @@ enable_nfc = rng_seed_enabled = rng_seed = +# Sets the current time (in seconds since 12:00 AM Jan 1, 1970) that will be used by the time service +# This will auto-increment, with the time set being the time the game is started +# This override will only occur if custom_rtc_enabled is true, otherwise the current time is used +custom_rtc_enabled = +custom_rtc = + # Sets the account username, max length is 32 characters # yuzu (default) username = yuzu From 26c9f122717302bda10e084d8f3c3ed9c388a08d Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Fri, 28 Dec 2018 18:36:14 -0500 Subject: [PATCH 2/6] qt: Provide UI to edit custom RTC settings --- src/yuzu/configuration/configure_system.cpp | 17 +++++ src/yuzu/configuration/configure_system.ui | 79 +++++++++++++-------- 2 files changed, 67 insertions(+), 29 deletions(-) diff --git a/src/yuzu/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp index 445d01ca01..753db75d22 100644 --- a/src/yuzu/configuration/configure_system.cpp +++ b/src/yuzu/configuration/configure_system.cpp @@ -51,6 +51,12 @@ ConfigureSystem::ConfigureSystem(QWidget* parent) : QWidget(parent), ui(new Ui:: ui->rng_seed_edit->setText(QStringLiteral("00000000")); }); + connect(ui->custom_rtc_checkbox, &QCheckBox::stateChanged, this, [this](bool checked) { + ui->custom_rtc_edit->setEnabled(checked); + if (!checked) + ui->custom_rtc_edit->setDateTime(QDateTime::currentDateTime()); + }); + this->setConfiguration(); } @@ -67,6 +73,12 @@ void ConfigureSystem::setConfiguration() { const auto rng_seed = QString("%1").arg(Settings::values.rng_seed.value_or(0), 8, 16, QLatin1Char{'0'}).toUpper(); ui->rng_seed_edit->setText(rng_seed); + + ui->custom_rtc_checkbox->setChecked(Settings::values.custom_rtc.has_value()); + ui->custom_rtc_edit->setEnabled(Settings::values.custom_rtc.has_value()); + + const auto rtc_time = Settings::values.custom_rtc.value_or(QDateTime::currentSecsSinceEpoch()); + ui->custom_rtc_edit->setDateTime(QDateTime::fromSecsSinceEpoch(rtc_time)); } void ConfigureSystem::ReadSystemSettings() {} @@ -82,6 +94,11 @@ void ConfigureSystem::applyConfiguration() { else Settings::values.rng_seed = std::nullopt; + if (ui->custom_rtc_checkbox->isChecked()) + Settings::values.custom_rtc = ui->custom_rtc_edit->dateTime().toSecsSinceEpoch(); + else + Settings::values.custom_rtc = std::nullopt; + Settings::Apply(); } diff --git a/src/yuzu/configuration/configure_system.ui b/src/yuzu/configuration/configure_system.ui index 74e800c2a1..0733272987 100644 --- a/src/yuzu/configuration/configure_system.ui +++ b/src/yuzu/configuration/configure_system.ui @@ -22,6 +22,13 @@ System Settings + + + + Sound output mode + + + @@ -114,27 +121,6 @@ - - - - Console ID: - - - - - - - Sound output mode - - - - - - - Birthday - - - @@ -206,6 +192,20 @@ + + + + Console ID: + + + + + + + Birthday + + + @@ -241,6 +241,13 @@ + + + + RNG Seed + + + @@ -248,14 +255,7 @@ - - - - RNG Seed - - - - + @@ -276,6 +276,27 @@ + + + + Custom RTC + + + + + + + + 1970 + 1 + 1 + + + + d MMM yyyy h:mm:ss AP + + + From 21f1b2889d2d8dc52f406957175d1d10a673128a Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Fri, 28 Dec 2018 18:36:37 -0500 Subject: [PATCH 3/6] core: Set custom RTC differential on game boot --- src/core/core.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/core/core.cpp b/src/core/core.cpp index fd10199ec1..7459c0851e 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -30,6 +30,7 @@ #include "core/hle/service/sm/sm.h" #include "core/loader/loader.h" #include "core/perf_stats.h" +#include "core/settings.h" #include "core/telemetry_session.h" #include "frontend/applets/software_keyboard.h" #include "video_core/debug_utils/debug_utils.h" @@ -94,6 +95,12 @@ struct System::Impl { CoreTiming::Init(); kernel.Initialize(); + const auto current_time = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()) + .count(); + Settings::values.custom_rtc_differential = + Settings::values.custom_rtc.value_or(current_time) - current_time; + // Create a default fs if one doesn't already exist. if (virtual_filesystem == nullptr) virtual_filesystem = std::make_shared(); From dbb1eb9c29e072e77b66efa28ea21e814100d6ee Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Fri, 28 Dec 2018 19:09:57 -0500 Subject: [PATCH 4/6] time: Use custom RTC settings if applicable for game --- src/core/hle/service/time/time.cpp | 16 ++++++++++------ src/yuzu_cmd/default_ini.h | 4 ++-- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index 16564de241..ef8c9f2b77 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp @@ -12,9 +12,17 @@ #include "core/hle/kernel/client_session.h" #include "core/hle/service/time/interface.h" #include "core/hle/service/time/time.h" +#include "core/settings.h" namespace Service::Time { +static s64 GetSecondsSinceEpoch() { + return std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()) + .count() + + Settings::values.custom_rtc_differential; +} + static void PosixToCalendar(u64 posix_time, CalendarTime& calendar_time, CalendarAdditionalInfo& additional_info, [[maybe_unused]] const TimeZoneRule& /*rule*/) { @@ -68,9 +76,7 @@ public: private: void GetCurrentTime(Kernel::HLERequestContext& ctx) { - const s64 time_since_epoch{std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()) - .count()}; + const s64 time_since_epoch{GetSecondsSinceEpoch()}; LOG_DEBUG(Service_Time, "called"); IPC::ResponseBuilder rb{ctx, 4}; @@ -266,9 +272,7 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto initial_type = rp.PopRaw(); - const s64 time_since_epoch{std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()) - .count()}; + const s64 time_since_epoch{GetSecondsSinceEpoch()}; const std::time_t time(time_since_epoch); const std::tm* tm = std::localtime(&time); diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h index 0a3ea26197..ba51a4a512 100644 --- a/src/yuzu_cmd/default_ini.h +++ b/src/yuzu_cmd/default_ini.h @@ -186,8 +186,8 @@ rng_seed = # Sets the current time (in seconds since 12:00 AM Jan 1, 1970) that will be used by the time service # This will auto-increment, with the time set being the time the game is started # This override will only occur if custom_rtc_enabled is true, otherwise the current time is used -custom_rtc_enabled = -custom_rtc = +custom_rtc_enabled = +custom_rtc = # Sets the account username, max length is 32 characters # yuzu (default) From 05dbb47af51fb00826912155da85469cb74022db Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Fri, 28 Dec 2018 20:24:24 -0500 Subject: [PATCH 5/6] settings: Use std::chrono::seconds instead of s64 for RTC --- src/core/core.cpp | 3 +-- src/core/hle/service/time/time.cpp | 10 ++++------ src/core/settings.h | 8 +++++--- src/yuzu/configuration/config.cpp | 6 ++++-- src/yuzu/configuration/configure_system.cpp | 8 +++++--- src/yuzu_cmd/config.cpp | 3 ++- 6 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 7459c0851e..123b114093 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -96,8 +96,7 @@ struct System::Impl { kernel.Initialize(); const auto current_time = std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()) - .count(); + std::chrono::system_clock::now().time_since_epoch()); Settings::values.custom_rtc_differential = Settings::values.custom_rtc.value_or(current_time) - current_time; diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index ef8c9f2b77..c13640ad8f 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp @@ -16,10 +16,9 @@ namespace Service::Time { -static s64 GetSecondsSinceEpoch() { +static std::chrono::seconds GetSecondsSinceEpoch() { return std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()) - .count() + + std::chrono::system_clock::now().time_since_epoch()) + Settings::values.custom_rtc_differential; } @@ -76,7 +75,7 @@ public: private: void GetCurrentTime(Kernel::HLERequestContext& ctx) { - const s64 time_since_epoch{GetSecondsSinceEpoch()}; + const s64 time_since_epoch{GetSecondsSinceEpoch().count()}; LOG_DEBUG(Service_Time, "called"); IPC::ResponseBuilder rb{ctx, 4}; @@ -272,8 +271,7 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto initial_type = rp.PopRaw(); - const s64 time_since_epoch{GetSecondsSinceEpoch()}; - + const s64 time_since_epoch{GetSecondsSinceEpoch().count()}; const std::time_t time(time_since_epoch); const std::tm* tm = std::localtime(&time); if (tm == nullptr) { diff --git a/src/core/settings.h b/src/core/settings.h index 5b211a7162..bb5aafa0c3 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -350,9 +351,10 @@ struct Values { bool use_docked_mode; bool enable_nfc; std::optional rng_seed; - std::optional custom_rtc; // Measured in seconds since epoch - s64 custom_rtc_differential; // Set on game boot, reset on stop. Seconds difference between - // current time and `custom_rtc` + std::optional custom_rtc; // Measured in seconds since epoch + std::chrono::seconds + custom_rtc_differential; // Set on game boot, reset on stop. Seconds difference between + // current time and `custom_rtc` s32 current_user; s32 language_index; diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 6e034ef190..6c5284db5f 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -428,7 +428,8 @@ void Config::ReadValues() { const auto custom_rtc_enabled = qt_config->value("custom_rtc_enabled", false).toBool(); if (custom_rtc_enabled) { - Settings::values.custom_rtc = qt_config->value("custom_rtc", 0).toULongLong(); + Settings::values.custom_rtc = + std::chrono::seconds(qt_config->value("custom_rtc", 0).toULongLong()); } else { Settings::values.custom_rtc = std::nullopt; } @@ -661,7 +662,8 @@ void Config::SaveValues() { qt_config->setValue("rng_seed", Settings::values.rng_seed.value_or(0)); qt_config->setValue("custom_rtc_enabled", Settings::values.custom_rtc.has_value()); - qt_config->setValue("custom_rtc", Settings::values.custom_rtc.value_or(0)); + qt_config->setValue("custom_rtc", + Settings::values.custom_rtc.value_or(std::chrono::seconds{}).count()); qt_config->endGroup(); diff --git a/src/yuzu/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp index 753db75d22..94e27349da 100644 --- a/src/yuzu/configuration/configure_system.cpp +++ b/src/yuzu/configuration/configure_system.cpp @@ -77,8 +77,9 @@ void ConfigureSystem::setConfiguration() { ui->custom_rtc_checkbox->setChecked(Settings::values.custom_rtc.has_value()); ui->custom_rtc_edit->setEnabled(Settings::values.custom_rtc.has_value()); - const auto rtc_time = Settings::values.custom_rtc.value_or(QDateTime::currentSecsSinceEpoch()); - ui->custom_rtc_edit->setDateTime(QDateTime::fromSecsSinceEpoch(rtc_time)); + const auto rtc_time = Settings::values.custom_rtc.value_or( + std::chrono::seconds(QDateTime::currentSecsSinceEpoch())); + ui->custom_rtc_edit->setDateTime(QDateTime::fromSecsSinceEpoch(rtc_time.count())); } void ConfigureSystem::ReadSystemSettings() {} @@ -95,7 +96,8 @@ void ConfigureSystem::applyConfiguration() { Settings::values.rng_seed = std::nullopt; if (ui->custom_rtc_checkbox->isChecked()) - Settings::values.custom_rtc = ui->custom_rtc_edit->dateTime().toSecsSinceEpoch(); + Settings::values.custom_rtc = + std::chrono::seconds(ui->custom_rtc_edit->dateTime().toSecsSinceEpoch()); else Settings::values.custom_rtc = std::nullopt; diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp index 8f3b74cdf4..7a77f76e83 100644 --- a/src/yuzu_cmd/config.cpp +++ b/src/yuzu_cmd/config.cpp @@ -334,7 +334,8 @@ void Config::ReadValues() { const auto custom_rtc_enabled = sdl2_config->GetBoolean("System", "custom_rtc_enabled", false); if (custom_rtc_enabled) { - Settings::values.custom_rtc = sdl2_config->GetInteger("System", "custom_rtc", 0); + Settings::values.custom_rtc = + std::chrono::seconds(sdl2_config->GetInteger("System", "custom_rtc", 0)); } else { Settings::values.custom_rtc = std::nullopt; } From ac7d8983ebc75b1b5e150ea7e03ff54267faf670 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Mon, 7 Jan 2019 19:40:23 -0500 Subject: [PATCH 6/6] settings: Fix comment structure --- src/core/settings.h | 9 +++++---- src/yuzu/configuration/config.cpp | 3 ++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/core/settings.h b/src/core/settings.h index bb5aafa0c3..29ce989830 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -351,10 +351,11 @@ struct Values { bool use_docked_mode; bool enable_nfc; std::optional rng_seed; - std::optional custom_rtc; // Measured in seconds since epoch - std::chrono::seconds - custom_rtc_differential; // Set on game boot, reset on stop. Seconds difference between - // current time and `custom_rtc` + // Measured in seconds since epoch + std::optional custom_rtc; + // Set on game boot, reset on stop. Seconds difference between current time and `custom_rtc` + std::chrono::seconds custom_rtc_differential; + s32 current_user; s32 language_index; diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 6c5284db5f..ddf4cf552a 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -663,7 +663,8 @@ void Config::SaveValues() { qt_config->setValue("custom_rtc_enabled", Settings::values.custom_rtc.has_value()); qt_config->setValue("custom_rtc", - Settings::values.custom_rtc.value_or(std::chrono::seconds{}).count()); + QVariant::fromValue( + Settings::values.custom_rtc.value_or(std::chrono::seconds{}).count())); qt_config->endGroup();