Merge pull request #5757 from blubberdiblub/wx-fix-custom-rtc

Fix date and time handling for custom RTC in wxWidgets.
This commit is contained in:
Leo Lam 2017-07-08 10:53:05 +02:00 committed by GitHub
commit 51bb10d371
2 changed files with 45 additions and 28 deletions

View File

@ -36,6 +36,12 @@ void AdvancedConfigPane::InitializeGUI()
m_custom_rtc_checkbox = new wxCheckBox(this, wxID_ANY, _("Enable Custom RTC")); m_custom_rtc_checkbox = new wxCheckBox(this, wxID_ANY, _("Enable Custom RTC"));
m_custom_rtc_date_picker = new wxDatePickerCtrl(this, wxID_ANY); m_custom_rtc_date_picker = new wxDatePickerCtrl(this, wxID_ANY);
// The Wii System Menu only allows configuring a year between 2000 and 2035.
// However, the GameCube main menu (IPL) allows setting a year between 2000 and 2099,
// which is why we use that range here. The Wii still deals OK with dates beyond 2035
// and simply clamps them to 2035-12-31.
m_custom_rtc_date_picker->SetRange(wxDateTime(1, wxDateTime::Jan, 2000),
wxDateTime(31, wxDateTime::Dec, 2099));
m_custom_rtc_time_picker = new wxTimePickerCtrl(this, wxID_ANY); m_custom_rtc_time_picker = new wxTimePickerCtrl(this, wxID_ANY);
wxStaticText* const clock_override_description = wxStaticText* const clock_override_description =
@ -155,9 +161,20 @@ void AdvancedConfigPane::OnClockOverrideSliderChanged(wxCommandEvent& event)
UpdateCPUClock(); UpdateCPUClock();
} }
static u32 ToSeconds(wxDateTime date) static wxDateTime GetCustomRTCDateTime()
{ {
return static_cast<u32>(date.GetValue().GetValue() / 1000); time_t timestamp = SConfig::GetInstance().m_customRTCValue;
return wxDateTime(timestamp).ToUTC();
}
static wxDateTime CombineDateAndTime(const wxDateTime& date, const wxDateTime& time)
{
wxDateTime datetime = date;
datetime.SetHour(time.GetHour());
datetime.SetMinute(time.GetMinute());
datetime.SetSecond(time.GetSecond());
return datetime;
} }
void AdvancedConfigPane::OnCustomRTCCheckBoxChanged(wxCommandEvent& event) void AdvancedConfigPane::OnCustomRTCCheckBoxChanged(wxCommandEvent& event)
@ -168,16 +185,16 @@ void AdvancedConfigPane::OnCustomRTCCheckBoxChanged(wxCommandEvent& event)
m_custom_rtc_time_picker->Enable(checked); m_custom_rtc_time_picker->Enable(checked);
} }
void AdvancedConfigPane::OnCustomRTCDateChanged(wxCommandEvent& event) void AdvancedConfigPane::OnCustomRTCDateChanged(wxDateEvent& event)
{ {
m_temp_date = ToSeconds(m_custom_rtc_date_picker->GetValue()); wxDateTime datetime = CombineDateAndTime(event.GetDate(), GetCustomRTCDateTime());
UpdateCustomRTC(m_temp_date, m_temp_time); UpdateCustomRTC(datetime);
} }
void AdvancedConfigPane::OnCustomRTCTimeChanged(wxCommandEvent& event) void AdvancedConfigPane::OnCustomRTCTimeChanged(wxDateEvent& event)
{ {
m_temp_time = ToSeconds(m_custom_rtc_time_picker->GetValue()) - m_temp_date; wxDateTime datetime = CombineDateAndTime(GetCustomRTCDateTime(), event.GetDate());
UpdateCustomRTC(m_temp_date, m_temp_time); UpdateCustomRTC(datetime);
} }
void AdvancedConfigPane::UpdateCPUClock() void AdvancedConfigPane::UpdateCPUClock()
@ -192,28 +209,28 @@ void AdvancedConfigPane::UpdateCPUClock()
void AdvancedConfigPane::LoadCustomRTC() void AdvancedConfigPane::LoadCustomRTC()
{ {
wxDateTime custom_rtc(static_cast<time_t>(SConfig::GetInstance().m_customRTCValue));
custom_rtc = custom_rtc.ToUTC();
bool custom_rtc_enabled = SConfig::GetInstance().bEnableCustomRTC; bool custom_rtc_enabled = SConfig::GetInstance().bEnableCustomRTC;
m_custom_rtc_checkbox->SetValue(custom_rtc_enabled); m_custom_rtc_checkbox->SetValue(custom_rtc_enabled);
if (custom_rtc.IsValid())
wxDateTime datetime = GetCustomRTCDateTime();
if (datetime.IsValid())
{ {
m_custom_rtc_date_picker->SetValue(custom_rtc); m_custom_rtc_date_picker->SetValue(datetime);
m_custom_rtc_time_picker->SetValue(custom_rtc); m_custom_rtc_time_picker->SetValue(datetime);
} }
m_temp_date = ToSeconds(m_custom_rtc_date_picker->GetValue());
m_temp_time = ToSeconds(m_custom_rtc_time_picker->GetValue()) - m_temp_date; // Make sure we have a valid custom RTC date and time
// Limit dates to a valid range (Jan 1/2000 to Dec 31/2099) // both when it was out of range as well as when it was invalid to begin with.
m_custom_rtc_date_picker->SetRange(wxDateTime(1, wxDateTime::Jan, 2000), datetime = CombineDateAndTime(m_custom_rtc_date_picker->GetValue(),
wxDateTime(31, wxDateTime::Dec, 2099)); m_custom_rtc_time_picker->GetValue());
UpdateCustomRTC(datetime);
} }
void AdvancedConfigPane::UpdateCustomRTC(time_t date, time_t time) void AdvancedConfigPane::UpdateCustomRTC(const wxDateTime& datetime)
{ {
wxDateTime custom_rtc(date + time); // We need GetValue() as GetTicks() only works up to 0x7ffffffe, which is in 2038.
SConfig::GetInstance().m_customRTCValue = ToSeconds(custom_rtc.FromUTC()); u32 timestamp = datetime.FromUTC().GetValue().GetValue() / 1000;
m_custom_rtc_date_picker->SetValue(custom_rtc); SConfig::GetInstance().m_customRTCValue = timestamp;
m_custom_rtc_time_picker->SetValue(custom_rtc);
} }
void AdvancedConfigPane::OnUpdateCPUClockControls(wxUpdateUIEvent& event) void AdvancedConfigPane::OnUpdateCPUClockControls(wxUpdateUIEvent& event)

View File

@ -11,6 +11,8 @@
class DolphinSlider; class DolphinSlider;
class wxCheckBox; class wxCheckBox;
class wxDateEvent;
class wxDateTime;
class wxDatePickerCtrl; class wxDatePickerCtrl;
class wxStaticText; class wxStaticText;
class wxTimePickerCtrl; class wxTimePickerCtrl;
@ -31,16 +33,14 @@ private:
void OnClockOverrideCheckBoxChanged(wxCommandEvent&); void OnClockOverrideCheckBoxChanged(wxCommandEvent&);
void OnClockOverrideSliderChanged(wxCommandEvent&); void OnClockOverrideSliderChanged(wxCommandEvent&);
void OnCustomRTCCheckBoxChanged(wxCommandEvent&); void OnCustomRTCCheckBoxChanged(wxCommandEvent&);
void OnCustomRTCDateChanged(wxCommandEvent&); void OnCustomRTCDateChanged(wxDateEvent&);
void OnCustomRTCTimeChanged(wxCommandEvent&); void OnCustomRTCTimeChanged(wxDateEvent&);
void UpdateCPUClock(); void UpdateCPUClock();
// Custom RTC // Custom RTC
void LoadCustomRTC(); void LoadCustomRTC();
void UpdateCustomRTC(time_t date, time_t time); void UpdateCustomRTC(const wxDateTime&);
u32 m_temp_date;
u32 m_temp_time;
wxCheckBox* m_clock_override_checkbox; wxCheckBox* m_clock_override_checkbox;
DolphinSlider* m_clock_override_slider; DolphinSlider* m_clock_override_slider;