feat: add system time offset setting (#6139)
* Add setting for system time offset Add a setting to displace citra system time by days, hours, minutes or seconds Add UI for the setting which is only visible when clock is set to system time Change core/settings.h to include the setting * Add system time offset to kernel Actually makes use of the time offset. * Fix time offset calculatioon in core/movie.cpp * Replace C++20 chrono::days with seconds Hopefully fixes the build.
This commit is contained in:
parent
3b6ffd9c27
commit
64062162c6
|
@ -242,6 +242,58 @@ void Config::ReadValues() {
|
|||
.count();
|
||||
}
|
||||
|
||||
{
|
||||
constexpr const char* default_init_time_offset = "0 00:00:00";
|
||||
|
||||
std::string offset_string =
|
||||
sdl2_config->GetString("System", "init_time_offset", default_init_time_offset);
|
||||
|
||||
size_t sep_index = offset_string.find(' ');
|
||||
|
||||
if (sep_index == std::string::npos) {
|
||||
LOG_ERROR(Config, "Failed to parse init_time_offset. Using 0 00:00:00");
|
||||
offset_string = default_init_time_offset;
|
||||
|
||||
sep_index = offset_string.find(' ');
|
||||
}
|
||||
|
||||
std::string day_string = offset_string.substr(0, sep_index);
|
||||
long long days = 0;
|
||||
|
||||
try {
|
||||
days = std::stoll(day_string);
|
||||
} catch (std::exception& e) {
|
||||
LOG_ERROR(Config, "Failed to parse days in init_time_offset. Using 0");
|
||||
days = 0;
|
||||
}
|
||||
|
||||
long long days_in_seconds = days * 86400;
|
||||
|
||||
std::tm t;
|
||||
t.tm_sec = 0;
|
||||
t.tm_min = 0;
|
||||
t.tm_hour = 0;
|
||||
t.tm_mday = 1;
|
||||
t.tm_mon = 0;
|
||||
t.tm_year = 100;
|
||||
t.tm_isdst = 0;
|
||||
|
||||
std::istringstream string_stream(offset_string.substr(sep_index + 1));
|
||||
string_stream >> std::get_time(&t, "%H:%M:%S");
|
||||
|
||||
if (string_stream.fail()) {
|
||||
LOG_ERROR(Config,
|
||||
"Failed to parse hours, minutes and seconds in init_time_offset. 00:00:00");
|
||||
}
|
||||
|
||||
auto time_offset =
|
||||
std::chrono::system_clock::from_time_t(std::mktime(&t)).time_since_epoch();
|
||||
|
||||
auto secs = std::chrono::duration_cast<std::chrono::seconds>(time_offset).count();
|
||||
|
||||
Settings::values.init_time_offset = static_cast<long long>(secs) + days_in_seconds;
|
||||
}
|
||||
|
||||
// Camera
|
||||
using namespace Service::CAM;
|
||||
Settings::values.camera_name[OuterRightCamera] =
|
||||
|
|
|
@ -547,6 +547,8 @@ void Config::ReadSystemValues() {
|
|||
.toInt());
|
||||
Settings::values.init_time =
|
||||
ReadSetting(QStringLiteral("init_time"), 946681277ULL).toULongLong();
|
||||
Settings::values.init_time_offset =
|
||||
ReadSetting(QStringLiteral("init_time_offset"), 0LL).toLongLong();
|
||||
|
||||
qt_config->endGroup();
|
||||
}
|
||||
|
@ -1057,6 +1059,8 @@ void Config::SaveSystemValues() {
|
|||
static_cast<u32>(Settings::InitClock::SystemTime));
|
||||
WriteSetting(QStringLiteral("init_time"),
|
||||
static_cast<unsigned long long>(Settings::values.init_time), 946681277ULL);
|
||||
WriteSetting(QStringLiteral("init_time_offset"),
|
||||
static_cast<long long>(Settings::values.init_time_offset), 0LL);
|
||||
|
||||
qt_config->endGroup();
|
||||
}
|
||||
|
|
|
@ -266,6 +266,14 @@ void ConfigureSystem::SetConfiguration() {
|
|||
date_time.setTime_t(Settings::values.init_time);
|
||||
ui->edit_init_time->setDateTime(date_time);
|
||||
|
||||
long long init_time_offset = Settings::values.init_time_offset;
|
||||
long long days_offset = init_time_offset / 86400;
|
||||
ui->edit_init_time_offset_days->setValue(days_offset);
|
||||
|
||||
unsigned long long time_offset = std::abs(init_time_offset) - std::abs(days_offset * 86400);
|
||||
QTime time = QTime::fromMSecsSinceStartOfDay(time_offset * 1000);
|
||||
ui->edit_init_time_offset_time->setTime(time);
|
||||
|
||||
if (!enabled) {
|
||||
cfg = Service::CFG::GetModule(Core::System::GetInstance());
|
||||
ASSERT_MSG(cfg, "CFG Module missing!");
|
||||
|
@ -382,6 +390,14 @@ void ConfigureSystem::ApplyConfiguration() {
|
|||
static_cast<Settings::InitClock>(ui->combo_init_clock->currentIndex());
|
||||
Settings::values.init_time = ui->edit_init_time->dateTime().toTime_t();
|
||||
|
||||
s64 time_offset_time = ui->edit_init_time_offset_time->time().msecsSinceStartOfDay() / 1000;
|
||||
s64 time_offset_days = ui->edit_init_time_offset_days->value() * 86400;
|
||||
|
||||
if (time_offset_days < 0) {
|
||||
time_offset_time = -time_offset_time;
|
||||
}
|
||||
|
||||
Settings::values.init_time_offset = time_offset_days + time_offset_time;
|
||||
Settings::values.is_new_3ds = ui->toggle_new_3ds->isChecked();
|
||||
}
|
||||
|
||||
|
@ -415,10 +431,10 @@ void ConfigureSystem::UpdateBirthdayComboBox(int birthmonth_index) {
|
|||
}
|
||||
|
||||
void ConfigureSystem::ConfigureTime() {
|
||||
ui->edit_init_time->setCalendarPopup(true);
|
||||
QDateTime dt;
|
||||
dt.fromString(QStringLiteral("2000-01-01 00:00:01"), QStringLiteral("yyyy-MM-dd hh:mm:ss"));
|
||||
ui->edit_init_time->setMinimumDateTime(dt);
|
||||
ui->edit_init_time->setCalendarPopup(true);
|
||||
|
||||
SetConfiguration();
|
||||
|
||||
|
@ -428,8 +444,13 @@ void ConfigureSystem::ConfigureTime() {
|
|||
void ConfigureSystem::UpdateInitTime(int init_clock) {
|
||||
const bool is_fixed_time =
|
||||
static_cast<Settings::InitClock>(init_clock) == Settings::InitClock::FixedTime;
|
||||
|
||||
ui->label_init_time->setVisible(is_fixed_time);
|
||||
ui->edit_init_time->setVisible(is_fixed_time);
|
||||
|
||||
ui->label_init_time_offset->setVisible(!is_fixed_time);
|
||||
ui->edit_init_time_offset_days->setVisible(!is_fixed_time);
|
||||
ui->edit_init_time_offset_time->setVisible(!is_fixed_time);
|
||||
}
|
||||
|
||||
void ConfigureSystem::RefreshConsoleID() {
|
||||
|
|
|
@ -258,6 +258,44 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QDateTimeEdit" name="edit_init_time">
|
||||
<property name="displayFormat">
|
||||
<string>yyyy-MM-ddTHH:mm:ss</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_init_time_offset">
|
||||
<property name="text">
|
||||
<string>Offset time</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<layout class="QGridLayout" name="edit_init_time_offset_grid">
|
||||
<item column="0">
|
||||
<widget class="QSpinBox" name="edit_init_time_offset_days">
|
||||
<property name="suffix">
|
||||
<string> days</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-2147483648</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>2147483647</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item column="1">
|
||||
<widget class="QTimeEdit" name="edit_init_time_offset_time">
|
||||
<property name="displayFormat">
|
||||
<string>HH:mm:ss</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QSpinBox" name="spinBox_play_coins">
|
||||
<property name="maximum">
|
||||
|
@ -295,13 +333,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QDateTimeEdit" name="edit_init_time">
|
||||
<property name="displayFormat">
|
||||
<string>yyyy-MM-ddTHH:mm:ss</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="toggle_new_3ds">
|
||||
<property name="text">
|
||||
|
|
|
@ -45,6 +45,16 @@ static std::chrono::seconds GetInitTime() {
|
|||
std::tm* now_tm = std::localtime(&now_time_t);
|
||||
if (now_tm && now_tm->tm_isdst > 0)
|
||||
now = now + std::chrono::hours(1);
|
||||
|
||||
// add the offset
|
||||
s64 init_time_offset = Settings::values.init_time_offset;
|
||||
long long days_offset = init_time_offset / 86400;
|
||||
long long days_offset_in_seconds = days_offset * 86400; // h/m/s truncated
|
||||
unsigned long long seconds_offset =
|
||||
std::abs(init_time_offset) - std::abs(days_offset_in_seconds);
|
||||
|
||||
now = now + std::chrono::seconds(seconds_offset);
|
||||
now = now + std::chrono::seconds(days_offset_in_seconds);
|
||||
return std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch());
|
||||
}
|
||||
case Settings::InitClock::FixedTime:
|
||||
|
|
|
@ -601,9 +601,17 @@ void Movie::PrepareForPlayback(const std::string& movie_file) {
|
|||
}
|
||||
|
||||
void Movie::PrepareForRecording() {
|
||||
init_time = (Settings::values.init_clock == Settings::InitClock::SystemTime
|
||||
? Common::Timer::GetTimeSinceJan1970().count()
|
||||
: Settings::values.init_time);
|
||||
if (Settings::values.init_clock == Settings::InitClock::SystemTime) {
|
||||
long long init_time_offset = Settings::values.init_time_offset;
|
||||
long long days_offset = init_time_offset / 86400;
|
||||
unsigned long long seconds_offset =
|
||||
std::abs(init_time_offset) - std::abs(days_offset * 86400);
|
||||
|
||||
init_time =
|
||||
Common::Timer::GetTimeSinceJan1970().count() + seconds_offset + (days_offset * 86400);
|
||||
} else {
|
||||
init_time = Settings::values.init_time;
|
||||
}
|
||||
}
|
||||
|
||||
Movie::ValidationResult Movie::ValidateMovie(const std::string& movie_file) const {
|
||||
|
|
|
@ -163,6 +163,7 @@ struct Values {
|
|||
int region_value;
|
||||
InitClock init_clock;
|
||||
u64 init_time;
|
||||
s64 init_time_offset;
|
||||
|
||||
// Renderer
|
||||
bool use_gles;
|
||||
|
|
Reference in New Issue