Merge pull request #1959 from DarkLordZach/custom-rtc
settings: Add support for setting the RTC manually
This commit is contained in:
commit
c9ef8b0af1
|
@ -30,6 +30,7 @@
|
||||||
#include "core/hle/service/sm/sm.h"
|
#include "core/hle/service/sm/sm.h"
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
#include "core/perf_stats.h"
|
#include "core/perf_stats.h"
|
||||||
|
#include "core/settings.h"
|
||||||
#include "core/telemetry_session.h"
|
#include "core/telemetry_session.h"
|
||||||
#include "frontend/applets/profile_select.h"
|
#include "frontend/applets/profile_select.h"
|
||||||
#include "frontend/applets/software_keyboard.h"
|
#include "frontend/applets/software_keyboard.h"
|
||||||
|
@ -96,6 +97,11 @@ struct System::Impl {
|
||||||
CoreTiming::Init();
|
CoreTiming::Init();
|
||||||
kernel.Initialize();
|
kernel.Initialize();
|
||||||
|
|
||||||
|
const auto current_time = std::chrono::duration_cast<std::chrono::seconds>(
|
||||||
|
std::chrono::system_clock::now().time_since_epoch());
|
||||||
|
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.
|
// Create a default fs if one doesn't already exist.
|
||||||
if (virtual_filesystem == nullptr)
|
if (virtual_filesystem == nullptr)
|
||||||
virtual_filesystem = std::make_shared<FileSys::RealVfsFilesystem>();
|
virtual_filesystem = std::make_shared<FileSys::RealVfsFilesystem>();
|
||||||
|
|
|
@ -12,9 +12,16 @@
|
||||||
#include "core/hle/kernel/client_session.h"
|
#include "core/hle/kernel/client_session.h"
|
||||||
#include "core/hle/service/time/interface.h"
|
#include "core/hle/service/time/interface.h"
|
||||||
#include "core/hle/service/time/time.h"
|
#include "core/hle/service/time/time.h"
|
||||||
|
#include "core/settings.h"
|
||||||
|
|
||||||
namespace Service::Time {
|
namespace Service::Time {
|
||||||
|
|
||||||
|
static std::chrono::seconds GetSecondsSinceEpoch() {
|
||||||
|
return std::chrono::duration_cast<std::chrono::seconds>(
|
||||||
|
std::chrono::system_clock::now().time_since_epoch()) +
|
||||||
|
Settings::values.custom_rtc_differential;
|
||||||
|
}
|
||||||
|
|
||||||
static void PosixToCalendar(u64 posix_time, CalendarTime& calendar_time,
|
static void PosixToCalendar(u64 posix_time, CalendarTime& calendar_time,
|
||||||
CalendarAdditionalInfo& additional_info,
|
CalendarAdditionalInfo& additional_info,
|
||||||
[[maybe_unused]] const TimeZoneRule& /*rule*/) {
|
[[maybe_unused]] const TimeZoneRule& /*rule*/) {
|
||||||
|
@ -68,9 +75,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void GetCurrentTime(Kernel::HLERequestContext& ctx) {
|
void GetCurrentTime(Kernel::HLERequestContext& ctx) {
|
||||||
const s64 time_since_epoch{std::chrono::duration_cast<std::chrono::seconds>(
|
const s64 time_since_epoch{GetSecondsSinceEpoch().count()};
|
||||||
std::chrono::system_clock::now().time_since_epoch())
|
|
||||||
.count()};
|
|
||||||
LOG_DEBUG(Service_Time, "called");
|
LOG_DEBUG(Service_Time, "called");
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 4};
|
IPC::ResponseBuilder rb{ctx, 4};
|
||||||
|
@ -266,10 +271,7 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const auto initial_type = rp.PopRaw<u8>();
|
const auto initial_type = rp.PopRaw<u8>();
|
||||||
|
|
||||||
const s64 time_since_epoch{std::chrono::duration_cast<std::chrono::seconds>(
|
const s64 time_since_epoch{GetSecondsSinceEpoch().count()};
|
||||||
std::chrono::system_clock::now().time_since_epoch())
|
|
||||||
.count()};
|
|
||||||
|
|
||||||
const std::time_t time(time_since_epoch);
|
const std::time_t time(time_since_epoch);
|
||||||
const std::tm* tm = std::localtime(&time);
|
const std::tm* tm = std::localtime(&time);
|
||||||
if (tm == nullptr) {
|
if (tm == nullptr) {
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <chrono>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -350,6 +351,11 @@ struct Values {
|
||||||
bool use_docked_mode;
|
bool use_docked_mode;
|
||||||
bool enable_nfc;
|
bool enable_nfc;
|
||||||
std::optional<u32> rng_seed;
|
std::optional<u32> rng_seed;
|
||||||
|
// Measured in seconds since epoch
|
||||||
|
std::optional<std::chrono::seconds> 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 current_user;
|
||||||
s32 language_index;
|
s32 language_index;
|
||||||
|
|
||||||
|
|
|
@ -419,13 +419,21 @@ void Config::ReadValues() {
|
||||||
|
|
||||||
Settings::values.language_index = qt_config->value("language_index", 1).toInt();
|
Settings::values.language_index = qt_config->value("language_index", 1).toInt();
|
||||||
|
|
||||||
const auto enabled = qt_config->value("rng_seed_enabled", false).toBool();
|
const auto rng_seed_enabled = qt_config->value("rng_seed_enabled", false).toBool();
|
||||||
if (enabled) {
|
if (rng_seed_enabled) {
|
||||||
Settings::values.rng_seed = qt_config->value("rng_seed", 0).toULongLong();
|
Settings::values.rng_seed = qt_config->value("rng_seed", 0).toULongLong();
|
||||||
} else {
|
} else {
|
||||||
Settings::values.rng_seed = std::nullopt;
|
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 =
|
||||||
|
std::chrono::seconds(qt_config->value("custom_rtc", 0).toULongLong());
|
||||||
|
} else {
|
||||||
|
Settings::values.custom_rtc = std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
qt_config->endGroup();
|
qt_config->endGroup();
|
||||||
|
|
||||||
qt_config->beginGroup("Miscellaneous");
|
qt_config->beginGroup("Miscellaneous");
|
||||||
|
@ -653,6 +661,11 @@ void Config::SaveValues() {
|
||||||
qt_config->setValue("rng_seed_enabled", Settings::values.rng_seed.has_value());
|
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("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",
|
||||||
|
QVariant::fromValue<long long>(
|
||||||
|
Settings::values.custom_rtc.value_or(std::chrono::seconds{}).count()));
|
||||||
|
|
||||||
qt_config->endGroup();
|
qt_config->endGroup();
|
||||||
|
|
||||||
qt_config->beginGroup("Miscellaneous");
|
qt_config->beginGroup("Miscellaneous");
|
||||||
|
|
|
@ -51,6 +51,12 @@ ConfigureSystem::ConfigureSystem(QWidget* parent) : QWidget(parent), ui(new Ui::
|
||||||
ui->rng_seed_edit->setText(QStringLiteral("00000000"));
|
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();
|
this->setConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,6 +73,13 @@ void ConfigureSystem::setConfiguration() {
|
||||||
const auto rng_seed =
|
const auto rng_seed =
|
||||||
QString("%1").arg(Settings::values.rng_seed.value_or(0), 8, 16, QLatin1Char{'0'}).toUpper();
|
QString("%1").arg(Settings::values.rng_seed.value_or(0), 8, 16, QLatin1Char{'0'}).toUpper();
|
||||||
ui->rng_seed_edit->setText(rng_seed);
|
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(
|
||||||
|
std::chrono::seconds(QDateTime::currentSecsSinceEpoch()));
|
||||||
|
ui->custom_rtc_edit->setDateTime(QDateTime::fromSecsSinceEpoch(rtc_time.count()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureSystem::ReadSystemSettings() {}
|
void ConfigureSystem::ReadSystemSettings() {}
|
||||||
|
@ -82,6 +95,12 @@ void ConfigureSystem::applyConfiguration() {
|
||||||
else
|
else
|
||||||
Settings::values.rng_seed = std::nullopt;
|
Settings::values.rng_seed = std::nullopt;
|
||||||
|
|
||||||
|
if (ui->custom_rtc_checkbox->isChecked())
|
||||||
|
Settings::values.custom_rtc =
|
||||||
|
std::chrono::seconds(ui->custom_rtc_edit->dateTime().toSecsSinceEpoch());
|
||||||
|
else
|
||||||
|
Settings::values.custom_rtc = std::nullopt;
|
||||||
|
|
||||||
Settings::Apply();
|
Settings::Apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,13 @@
|
||||||
<string>System Settings</string>
|
<string>System Settings</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_sound">
|
||||||
|
<property name="text">
|
||||||
|
<string>Sound output mode</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="1" column="1">
|
||||||
<widget class="QComboBox" name="combo_language">
|
<widget class="QComboBox" name="combo_language">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
|
@ -114,27 +121,6 @@
|
||||||
</item>
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QLabel" name="label_console_id">
|
|
||||||
<property name="text">
|
|
||||||
<string>Console ID:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QLabel" name="label_sound">
|
|
||||||
<property name="text">
|
|
||||||
<string>Sound output mode</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="label_birthday">
|
|
||||||
<property name="text">
|
|
||||||
<string>Birthday</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_birthday2">
|
<layout class="QHBoxLayout" name="horizontalLayout_birthday2">
|
||||||
<item>
|
<item>
|
||||||
|
@ -206,6 +192,20 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label_console_id">
|
||||||
|
<property name="text">
|
||||||
|
<string>Console ID:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_birthday">
|
||||||
|
<property name="text">
|
||||||
|
<string>Birthday</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="3" column="1">
|
<item row="3" column="1">
|
||||||
<widget class="QPushButton" name="button_regenerate_console_id">
|
<widget class="QPushButton" name="button_regenerate_console_id">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
|
@ -241,6 +241,13 @@
|
||||||
</item>
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QCheckBox" name="rng_seed_checkbox">
|
||||||
|
<property name="text">
|
||||||
|
<string>RNG Seed</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QLabel" name="label_language">
|
<widget class="QLabel" name="label_language">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
@ -248,14 +255,7 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="0">
|
<item row="5" column="1">
|
||||||
<widget class="QCheckBox" name="rng_seed_checkbox">
|
|
||||||
<property name="text">
|
|
||||||
<string>RNG Seed</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="1">
|
|
||||||
<widget class="QLineEdit" name="rng_seed_edit">
|
<widget class="QLineEdit" name="rng_seed_edit">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||||
|
@ -276,6 +276,27 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QCheckBox" name="custom_rtc_checkbox">
|
||||||
|
<property name="text">
|
||||||
|
<string>Custom RTC</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QDateTimeEdit" name="custom_rtc_edit">
|
||||||
|
<property name="minimumDate">
|
||||||
|
<date>
|
||||||
|
<year>1970</year>
|
||||||
|
<month>1</month>
|
||||||
|
<day>1</day>
|
||||||
|
</date>
|
||||||
|
</property>
|
||||||
|
<property name="displayFormat">
|
||||||
|
<string>d MMM yyyy h:mm:ss AP</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
@ -325,13 +325,21 @@ void Config::ReadValues() {
|
||||||
Settings::values.current_user = std::clamp<int>(
|
Settings::values.current_user = std::clamp<int>(
|
||||||
sdl2_config->GetInteger("System", "current_user", 0), 0, Service::Account::MAX_USERS - 1);
|
sdl2_config->GetInteger("System", "current_user", 0), 0, Service::Account::MAX_USERS - 1);
|
||||||
|
|
||||||
const auto enabled = sdl2_config->GetBoolean("System", "rng_seed_enabled", false);
|
const auto rng_seed_enabled = sdl2_config->GetBoolean("System", "rng_seed_enabled", false);
|
||||||
if (enabled) {
|
if (rng_seed_enabled) {
|
||||||
Settings::values.rng_seed = sdl2_config->GetInteger("System", "rng_seed", 0);
|
Settings::values.rng_seed = sdl2_config->GetInteger("System", "rng_seed", 0);
|
||||||
} else {
|
} else {
|
||||||
Settings::values.rng_seed = std::nullopt;
|
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 =
|
||||||
|
std::chrono::seconds(sdl2_config->GetInteger("System", "custom_rtc", 0));
|
||||||
|
} else {
|
||||||
|
Settings::values.custom_rtc = std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
// Core
|
// Core
|
||||||
Settings::values.use_cpu_jit = sdl2_config->GetBoolean("Core", "use_cpu_jit", true);
|
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);
|
Settings::values.use_multi_core = sdl2_config->GetBoolean("Core", "use_multi_core", false);
|
||||||
|
|
|
@ -183,6 +183,12 @@ enable_nfc =
|
||||||
rng_seed_enabled =
|
rng_seed_enabled =
|
||||||
rng_seed =
|
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
|
# Sets the account username, max length is 32 characters
|
||||||
# yuzu (default)
|
# yuzu (default)
|
||||||
username = yuzu
|
username = yuzu
|
||||||
|
|
Reference in New Issue