diff --git a/CHANGES b/CHANGES index 891e2ca6f..aed3e0c11 100644 --- a/CHANGES +++ b/CHANGES @@ -64,6 +64,7 @@ Other fixes: - VFS: Failed file mapping should return NULL on POSIX Misc: - Core: Suspend runloop when a core crashes + - Core: Add wallclock offset RTC type - Debugger: Save and restore CLI history - Debugger: GDB now works while the game is paused - Debugger: Add command to load external symbol file (fixes mgba.io/i/2480) diff --git a/include/mgba/core/interface.h b/include/mgba/core/interface.h index fadaaa29d..e2625045f 100644 --- a/include/mgba/core/interface.h +++ b/include/mgba/core/interface.h @@ -239,6 +239,7 @@ enum mRTCGenericType { RTC_NO_OVERRIDE, RTC_FIXED, RTC_FAKE_EPOCH, + RTC_WALLCLOCK_OFFSET, RTC_CUSTOM_START = 0x1000 }; diff --git a/src/core/interface.c b/src/core/interface.c index 961b83619..d63754895 100644 --- a/src/core/interface.c +++ b/src/core/interface.c @@ -21,6 +21,7 @@ static void _rtcGenericSample(struct mRTCSource* source) { case RTC_NO_OVERRIDE: case RTC_FIXED: case RTC_FAKE_EPOCH: + case RTC_WALLCLOCK_OFFSET: break; } } @@ -39,6 +40,8 @@ static time_t _rtcGenericCallback(struct mRTCSource* source) { return rtc->value / 1000LL; case RTC_FAKE_EPOCH: return (rtc->value + rtc->p->frameCounter(rtc->p) * (rtc->p->frameCycles(rtc->p) * 1000LL) / rtc->p->frequency(rtc->p)) / 1000LL; + case RTC_WALLCLOCK_OFFSET: + return time(0) + rtc->value / 1000LL; } } diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index ec0edea11..8814f4443 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -898,6 +898,11 @@ void CoreController::setFakeEpoch(const QDateTime& time) { m_threadContext.core->rtc.value = time.toMSecsSinceEpoch(); } +void CoreController::setTimeOffset(qint64 offset) { + m_threadContext.core->rtc.override = RTC_WALLCLOCK_OFFSET; + m_threadContext.core->rtc.value = offset * 1000LL; +} + void CoreController::scanCard(const QString& path) { #ifdef M_CORE_GBA QImage image(path); diff --git a/src/platform/qt/CoreController.h b/src/platform/qt/CoreController.h index 663d0ed96..3e5ca6b4d 100644 --- a/src/platform/qt/CoreController.h +++ b/src/platform/qt/CoreController.h @@ -174,6 +174,7 @@ public slots: void setRealTime(); void setFixedTime(const QDateTime& time); void setFakeEpoch(const QDateTime& time); + void setTimeOffset(qint64 offset); void importSharkport(const QString& path); void exportSharkport(const QString& path); diff --git a/src/platform/qt/SensorView.cpp b/src/platform/qt/SensorView.cpp index 1742a26ee..22c2f5f3f 100644 --- a/src/platform/qt/SensorView.cpp +++ b/src/platform/qt/SensorView.cpp @@ -69,6 +69,14 @@ void SensorView::setController(std::shared_ptr controller) { connect(m_ui.timeFakeEpoch, &QRadioButton::clicked, [controller, this] () { controller->setFakeEpoch(m_ui.time->dateTime().toUTC()); }); + connect(m_ui.timeOffset, &QRadioButton::clicked, [controller, this] () { + controller->setTimeOffset(m_ui.offsetSeconds->value()); + }); + connect(m_ui.offsetSeconds, qOverload(&QSpinBox::valueChanged), [controller, this] (int value) { + if (m_ui.timeOffset->isChecked()) { + controller->setTimeOffset(value); + } + }); m_ui.timeButtons->checkedButton()->clicked(); connect(controller.get(), &CoreController::stopping, [this]() { diff --git a/src/platform/qt/SensorView.ui b/src/platform/qt/SensorView.ui index 7d65ba52c..ac7032e4d 100644 --- a/src/platform/qt/SensorView.ui +++ b/src/platform/qt/SensorView.ui @@ -6,8 +6,8 @@ 0 0 - 434 - 319 + 448 + 332 @@ -19,28 +19,18 @@ Sensors - + QLayout::SetFixedSize - + Realtime clock - - - - Fixed time - - - timeButtons - - - @@ -54,7 +44,53 @@ + + + + Fixed time + + + timeButtons + + + + + + + Now + + + + + + Offset time + + + timeButtons + + + + + + + sec + + + -99999999 + + + 99999999 + + + 1 + + + QAbstractSpinBox::AdaptiveDecimalStepType + + + + Start time at @@ -64,14 +100,7 @@ - - - - Now - - - - + true @@ -143,7 +172,7 @@ - +