diff --git a/CHANGES b/CHANGES index 3d102d1ef..490b28b42 100644 --- a/CHANGES +++ b/CHANGES @@ -90,6 +90,7 @@ Misc: - GBA: Don't include GBACLIDebugger struct unless needed - SDL: Clean up GL context - GBA Audio: Implement audio reset for channels A/B + - GBA Hardware: Backport generic RTC source into core 0.2.1: (2015-05-13) Bugfixes: diff --git a/src/gba/hardware.c b/src/gba/hardware.c index b11204e66..e0c341e26 100644 --- a/src/gba/hardware.c +++ b/src/gba/hardware.c @@ -17,6 +17,8 @@ static void _rtcProcessByte(struct GBACartridgeHardware* hw); static void _rtcUpdateClock(struct GBACartridgeHardware* hw); static unsigned _rtcBCD(unsigned value); +static time_t _rtcGenericCallback(struct GBARTCSource* source); + static void _gyroReadPins(struct GBACartridgeHardware* hw); static void _rumbleReadPins(struct GBACartridgeHardware* hw); @@ -246,7 +248,9 @@ void _rtcUpdateClock(struct GBACartridgeHardware* hw) { time_t t; struct GBARTCSource* rtc = hw->p->rtcSource; if (rtc) { - rtc->sample(rtc); + if (rtc->sample) { + rtc->sample(rtc); + } t = rtc->unixTime(rtc); } else { t = time(0); @@ -277,6 +281,27 @@ unsigned _rtcBCD(unsigned value) { return counter; } +time_t _rtcGenericCallback(struct GBARTCSource* source) { + struct GBARTCGenericSource* rtc = (struct GBARTCGenericSource*) source; + switch (rtc->override) { + case RTC_NO_OVERRIDE: + default: + return time(0); + case RTC_FIXED: + return rtc->value; + case RTC_FAKE_EPOCH: + return rtc->value + rtc->p->video.frameCounter * (int64_t) VIDEO_TOTAL_LENGTH / GBA_ARM7TDMI_FREQUENCY; + } +} + +void GBARTCGenericSourceInit(struct GBARTCGenericSource* rtc, struct GBA* gba) { + rtc->p = gba; + rtc->override = RTC_NO_OVERRIDE; + rtc->value = 0; + rtc->d.sample = 0; + rtc->d.unixTime = _rtcGenericCallback; +} + // == Gyro void GBAHardwareInitGyro(struct GBACartridgeHardware* hw) { @@ -466,7 +491,6 @@ void GBAHardwareDeserialize(struct GBACartridgeHardware* hw, const struct GBASer hw->readWrite = state->hw.readWrite; hw->pinState = state->hw.pinState; hw->direction = state->hw.pinDirection; - // TODO: Deterministic RTC hw->rtc = state->hw.rtc; hw->gyroSample = state->hw.gyroSample; hw->gyroEdge = state->hw.gyroEdge; diff --git a/src/gba/hardware.h b/src/gba/hardware.h index 11a91f55b..5ba17c221 100644 --- a/src/gba/hardware.h +++ b/src/gba/hardware.h @@ -35,6 +35,17 @@ struct GBARTCSource { time_t (*unixTime)(struct GBARTCSource*); }; +struct GBARTCGenericSource { + struct GBARTCSource d; + struct GBA* p; + enum { + RTC_NO_OVERRIDE, + RTC_FIXED, + RTC_FAKE_EPOCH + } override; + int64_t value; +}; + enum GBAHardwareDevice { HW_NO_OVERRIDE = 0x8000, HW_NONE = 0, @@ -132,6 +143,8 @@ uint8_t GBAHardwareTiltRead(struct GBACartridgeHardware* gpio, uint32_t address) struct GBAVideo; bool GBAHardwarePlayerCheckScreen(const struct GBAVideo* video); +void GBARTCGenericSourceInit(struct GBARTCGenericSource* rtc, struct GBA* gba); + struct GBASerializedState; void GBAHardwareSerialize(const struct GBACartridgeHardware* gpio, struct GBASerializedState* state); void GBAHardwareDeserialize(struct GBACartridgeHardware* gpio, const struct GBASerializedState* state); diff --git a/src/platform/qt/GameController.cpp b/src/platform/qt/GameController.cpp index e0c59deb8..c7fa7c57c 100644 --- a/src/platform/qt/GameController.cpp +++ b/src/platform/qt/GameController.cpp @@ -81,27 +81,12 @@ GameController::GameController(QObject* parent) }; setLuminanceLevel(0); - m_rtc.p = this; - m_rtc.override = GameControllerRTC::NO_OVERRIDE; - m_rtc.sample = [](GBARTCSource* context) {}; - m_rtc.unixTime = [](GBARTCSource* context) -> time_t { - GameControllerRTC* rtc = static_cast(context); - switch (rtc->override) { - case GameControllerRTC::NO_OVERRIDE: - default: - return time(nullptr); - case GameControllerRTC::FIXED: - return rtc->value; - case GameControllerRTC::FAKE_EPOCH: - return rtc->value + rtc->p->m_threadContext.gba->video.frameCounter * (int64_t) VIDEO_TOTAL_LENGTH / GBA_ARM7TDMI_FREQUENCY; - } - }; - m_threadContext.startCallback = [](GBAThread* context) { GameController* controller = static_cast(context->userData); controller->m_audioProcessor->setInput(context); context->gba->luminanceSource = &controller->m_lux; - context->gba->rtcSource = &controller->m_rtc; + GBARTCGenericSourceInit(&controller->m_rtc, context->gba); + context->gba->rtcSource = &controller->m_rtc.d; context->gba->rumble = controller->m_inputController->rumble(); context->gba->rotationSource = controller->m_inputController->rotationSource(); controller->m_fpsTarget = context->fpsTarget; @@ -730,16 +715,16 @@ void GameController::setLuminanceLevel(int level) { } void GameController::setRealTime() { - m_rtc.override = GameControllerRTC::NO_OVERRIDE; + m_rtc.override = GBARTCGenericSource::RTC_NO_OVERRIDE; } void GameController::setFixedTime(const QDateTime& time) { - m_rtc.override = GameControllerRTC::FIXED; + m_rtc.override = GBARTCGenericSource::RTC_FIXED; m_rtc.value = time.toMSecsSinceEpoch() / 1000; } void GameController::setFakeEpoch(const QDateTime& time) { - m_rtc.override = GameControllerRTC::FAKE_EPOCH; + m_rtc.override = GBARTCGenericSource::RTC_FAKE_EPOCH; m_rtc.value = time.toMSecsSinceEpoch() / 1000; } diff --git a/src/platform/qt/GameController.h b/src/platform/qt/GameController.h index e80769dca..349a39ce6 100644 --- a/src/platform/qt/GameController.h +++ b/src/platform/qt/GameController.h @@ -205,15 +205,7 @@ private: static const int LUX_LEVELS[10]; - struct GameControllerRTC : GBARTCSource { - GameController* p; - enum { - NO_OVERRIDE, - FIXED, - FAKE_EPOCH - } override; - int64_t value; - } m_rtc; + GBARTCGenericSource m_rtc; }; }