mirror of https://github.com/mgba-emu/mgba.git
Qt: RTC overrides
This commit is contained in:
parent
f534638342
commit
8c0f082a83
|
@ -53,6 +53,8 @@ void GBAVideoReset(struct GBAVideo* video) {
|
||||||
video->nextVblankIRQ = 0;
|
video->nextVblankIRQ = 0;
|
||||||
video->nextVcounterIRQ = 0;
|
video->nextVcounterIRQ = 0;
|
||||||
|
|
||||||
|
video->frameCounter = 0;
|
||||||
|
|
||||||
if (video->vram) {
|
if (video->vram) {
|
||||||
mappedMemoryFree(video->vram, SIZE_VRAM);
|
mappedMemoryFree(video->vram, SIZE_VRAM);
|
||||||
}
|
}
|
||||||
|
@ -115,6 +117,7 @@ int32_t GBAVideoProcessEvents(struct GBAVideo* video, int32_t cycles) {
|
||||||
GBARaiseIRQ(video->p, IRQ_VBLANK);
|
GBARaiseIRQ(video->p, IRQ_VBLANK);
|
||||||
}
|
}
|
||||||
GBASyncPostFrame(video->p->sync);
|
GBASyncPostFrame(video->p->sync);
|
||||||
|
++video->frameCounter;
|
||||||
break;
|
break;
|
||||||
case VIDEO_VERTICAL_TOTAL_PIXELS - 1:
|
case VIDEO_VERTICAL_TOTAL_PIXELS - 1:
|
||||||
if (video->p->rr) {
|
if (video->p->rr) {
|
||||||
|
|
|
@ -190,6 +190,8 @@ struct GBAVideo {
|
||||||
uint16_t palette[SIZE_PALETTE_RAM >> 1];
|
uint16_t palette[SIZE_PALETTE_RAM >> 1];
|
||||||
uint16_t* vram;
|
uint16_t* vram;
|
||||||
union GBAOAM oam;
|
union GBAOAM oam;
|
||||||
|
|
||||||
|
int32_t frameCounter;
|
||||||
};
|
};
|
||||||
|
|
||||||
void GBAVideoInit(struct GBAVideo* video);
|
void GBAVideoInit(struct GBAVideo* video);
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "AudioProcessor.h"
|
#include "AudioProcessor.h"
|
||||||
#include "InputController.h"
|
#include "InputController.h"
|
||||||
|
|
||||||
|
#include <QDateTime>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -59,10 +60,27 @@ GameController::GameController(QObject* parent)
|
||||||
return lux->value;
|
return lux->value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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 * VIDEO_TOTAL_LENGTH / GBA_ARM7TDMI_FREQUENCY;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
m_threadContext.startCallback = [] (GBAThread* context) {
|
m_threadContext.startCallback = [] (GBAThread* context) {
|
||||||
GameController* controller = static_cast<GameController*>(context->userData);
|
GameController* controller = static_cast<GameController*>(context->userData);
|
||||||
controller->m_audioProcessor->setInput(context);
|
controller->m_audioProcessor->setInput(context);
|
||||||
context->gba->luminanceSource = &controller->m_lux;
|
context->gba->luminanceSource = &controller->m_lux;
|
||||||
|
context->gba->rtcSource = &controller->m_rtc;
|
||||||
controller->gameStarted(context);
|
controller->gameStarted(context);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -372,6 +390,20 @@ void GameController::clearAVStream() {
|
||||||
threadContinue();
|
threadContinue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GameController::setRealTime() {
|
||||||
|
m_rtc.override = GameControllerRTC::NO_OVERRIDE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameController::setFixedTime(const QDateTime& time) {
|
||||||
|
m_rtc.override = GameControllerRTC::FIXED;
|
||||||
|
m_rtc.value = time.toMSecsSinceEpoch() / 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameController::setFakeEpoch(const QDateTime& time) {
|
||||||
|
m_rtc.override = GameControllerRTC::FAKE_EPOCH;
|
||||||
|
m_rtc.value = time.toMSecsSinceEpoch() / 1000;
|
||||||
|
}
|
||||||
|
|
||||||
void GameController::updateKeys() {
|
void GameController::updateKeys() {
|
||||||
int activeKeys = m_activeKeys;
|
int activeKeys = m_activeKeys;
|
||||||
#ifdef BUILD_SDL
|
#ifdef BUILD_SDL
|
||||||
|
|
|
@ -94,6 +94,10 @@ public slots:
|
||||||
void clearAVStream();
|
void clearAVStream();
|
||||||
void setLuminanceValue(uint8_t value) { m_luxValue = value; }
|
void setLuminanceValue(uint8_t value) { m_luxValue = value; }
|
||||||
|
|
||||||
|
void setRealTime();
|
||||||
|
void setFixedTime(const QDateTime& time);
|
||||||
|
void setFakeEpoch(const QDateTime& time);
|
||||||
|
|
||||||
void setLogLevel(int);
|
void setLogLevel(int);
|
||||||
void enableLogLevel(int);
|
void enableLogLevel(int);
|
||||||
void disableLogLevel(int);
|
void disableLogLevel(int);
|
||||||
|
@ -144,6 +148,16 @@ private:
|
||||||
uint8_t value;
|
uint8_t value;
|
||||||
} m_lux;
|
} m_lux;
|
||||||
uint8_t m_luxValue;
|
uint8_t m_luxValue;
|
||||||
|
|
||||||
|
struct GameControllerRTC : GBARTCSource {
|
||||||
|
GameController* p;
|
||||||
|
enum {
|
||||||
|
NO_OVERRIDE,
|
||||||
|
FIXED,
|
||||||
|
FAKE_EPOCH
|
||||||
|
} override;
|
||||||
|
int64_t value;
|
||||||
|
} m_rtc;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,17 @@ GamePakView::GamePakView(GameController* controller, QWidget* parent)
|
||||||
connect(m_ui.lightSpin, SIGNAL(valueChanged(int)), this, SLOT(setLuminanceValue(int)));
|
connect(m_ui.lightSpin, SIGNAL(valueChanged(int)), this, SLOT(setLuminanceValue(int)));
|
||||||
connect(m_ui.lightSlide, SIGNAL(valueChanged(int)), this, SLOT(setLuminanceValue(int)));
|
connect(m_ui.lightSlide, SIGNAL(valueChanged(int)), this, SLOT(setLuminanceValue(int)));
|
||||||
|
|
||||||
|
connect(m_ui.timeNoOverride, SIGNAL(clicked()), controller, SLOT(setRealTime()));
|
||||||
|
connect(m_ui.timeFixed, &QRadioButton::clicked, [controller, this] () {
|
||||||
|
controller->setFixedTime(m_ui.time->dateTime());
|
||||||
|
});
|
||||||
|
connect(m_ui.timeFakeEpoch, &QRadioButton::clicked, [controller, this] () {
|
||||||
|
controller->setFakeEpoch(m_ui.time->dateTime());
|
||||||
|
});
|
||||||
|
connect(m_ui.time, &QDateTimeEdit::dateTimeChanged, [controller, this] (const QDateTime&) {
|
||||||
|
m_ui.timeButtons->checkedButton()->clicked();
|
||||||
|
});
|
||||||
|
|
||||||
if (controller->isLoaded()) {
|
if (controller->isLoaded()) {
|
||||||
gameStarted(controller->thread());
|
gameStarted(controller->thread());
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,38 +151,65 @@
|
||||||
</attribute>
|
</attribute>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QRadioButton" name="radioButton">
|
<widget class="QRadioButton" name="timeNoOverride">
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>System time</string>
|
<string>System time</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="checked">
|
<property name="checked">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">timeButtons</string>
|
||||||
|
</attribute>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QRadioButton" name="radioButton_2">
|
<widget class="QRadioButton" name="timeFixed">
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Manual time</string>
|
<string>Fixed time</string>
|
||||||
</property>
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">timeButtons</string>
|
||||||
|
</attribute>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QDateTimeEdit" name="dateTimeEdit">
|
<widget class="QRadioButton" name="timeFakeEpoch">
|
||||||
<property name="enabled">
|
<property name="text">
|
||||||
<bool>false</bool>
|
<string>Start time at</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">timeButtons</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDateTimeEdit" name="time">
|
||||||
|
<property name="wrapping">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="maximumDate">
|
||||||
|
<date>
|
||||||
|
<year>2099</year>
|
||||||
|
<month>12</month>
|
||||||
|
<day>31</day>
|
||||||
|
</date>
|
||||||
|
</property>
|
||||||
|
<property name="minimumDate">
|
||||||
|
<date>
|
||||||
|
<year>2000</year>
|
||||||
|
<month>1</month>
|
||||||
|
<day>1</day>
|
||||||
|
</date>
|
||||||
|
</property>
|
||||||
|
<property name="currentSection">
|
||||||
|
<enum>QDateTimeEdit::MonthSection</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="displayFormat">
|
<property name="displayFormat">
|
||||||
<string>M/d/yyyy h:mm AP</string>
|
<string>MM/dd/yy hh:mm:ss AP</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="calendarPopup">
|
<property name="timeSpec">
|
||||||
<bool>false</bool>
|
<enum>Qt::UTC</enum>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -231,4 +258,7 @@
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
<buttongroups>
|
||||||
|
<buttongroup name="timeButtons"/>
|
||||||
|
</buttongroups>
|
||||||
</ui>
|
</ui>
|
||||||
|
|
Loading…
Reference in New Issue