GBA Hardware: Backport generic RTC source into core

This commit is contained in:
Jeffrey Pfau 2015-06-29 21:09:36 -07:00
parent 908e61f415
commit 99878b32ca
5 changed files with 46 additions and 31 deletions

View File

@ -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:

View File

@ -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;

View File

@ -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);

View File

@ -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<GameControllerRTC*>(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<GameController*>(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;
}

View File

@ -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;
};
}