mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	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
					
				
					 7 changed files with 138 additions and 11 deletions
				
			
		|  | @ -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; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue