mirror of https://github.com/mgba-emu/mgba.git
GBA Thread: Add functionality for running callbacks on the GBA thread
This commit is contained in:
parent
9c07698068
commit
91ee44c458
1
CHANGES
1
CHANGES
|
@ -46,6 +46,7 @@ Misc:
|
|||
- Debugger: Free watchpoints in addition to breakpoints
|
||||
- Qt: Move GL frame drawing back onto its own thread
|
||||
- GBA: Add status log level
|
||||
- GBA Thread: Add functionality for running callbacks on the GBA thread
|
||||
|
||||
0.2.0: (2015-04-03)
|
||||
Features:
|
||||
|
|
|
@ -274,6 +274,13 @@ static THREAD_ENTRY _GBAThreadRun(void* context) {
|
|||
threadContext->state = THREAD_INTERRUPTED;
|
||||
ConditionWake(&threadContext->stateCond);
|
||||
}
|
||||
if (threadContext->state == THREAD_RUN_ON) {
|
||||
if (threadContext->run) {
|
||||
threadContext->run(threadContext);
|
||||
}
|
||||
threadContext->state = THREAD_RUNNING;
|
||||
ConditionWake(&threadContext->stateCond);
|
||||
}
|
||||
if (threadContext->state == THREAD_RESETING) {
|
||||
threadContext->state = THREAD_RUNNING;
|
||||
resetScheduled = 1;
|
||||
|
@ -598,6 +605,17 @@ void GBAThreadContinue(struct GBAThread* threadContext) {
|
|||
MutexUnlock(&threadContext->stateMutex);
|
||||
}
|
||||
|
||||
void GBARunOnThread(struct GBAThread* threadContext, void (*run)(struct GBAThread*)) {
|
||||
MutexLock(&threadContext->stateMutex);
|
||||
threadContext->run = run;
|
||||
_waitOnInterrupt(threadContext);
|
||||
threadContext->state = THREAD_RUN_ON;
|
||||
threadContext->gba->cpu->nextEvent = 0;
|
||||
ConditionWake(&threadContext->stateCond);
|
||||
_waitUntilNotState(threadContext, THREAD_RUN_ON);
|
||||
MutexUnlock(&threadContext->stateMutex);
|
||||
}
|
||||
|
||||
void GBAThreadPause(struct GBAThread* threadContext) {
|
||||
bool frameOn = true;
|
||||
MutexLock(&threadContext->stateMutex);
|
||||
|
|
|
@ -28,6 +28,7 @@ enum ThreadState {
|
|||
THREAD_INTERRUPTING,
|
||||
THREAD_PAUSED,
|
||||
THREAD_PAUSING,
|
||||
THREAD_RUN_ON,
|
||||
THREAD_RESETING,
|
||||
THREAD_EXITING,
|
||||
THREAD_SHUTDOWN,
|
||||
|
@ -97,6 +98,7 @@ struct GBAThread {
|
|||
ThreadCallback cleanCallback;
|
||||
ThreadCallback frameCallback;
|
||||
void* userData;
|
||||
void (*run)(struct GBAThread*);
|
||||
|
||||
struct GBASync sync;
|
||||
|
||||
|
@ -126,6 +128,8 @@ bool GBAThreadIsActive(struct GBAThread* threadContext);
|
|||
void GBAThreadInterrupt(struct GBAThread* threadContext);
|
||||
void GBAThreadContinue(struct GBAThread* threadContext);
|
||||
|
||||
void GBARunOnThread(struct GBAThread* threadContext, void (*run)(struct GBAThread*));
|
||||
|
||||
void GBAThreadPause(struct GBAThread* threadContext);
|
||||
void GBAThreadUnpause(struct GBAThread* threadContext);
|
||||
bool GBAThreadIsPaused(struct GBAThread* threadContext);
|
||||
|
|
|
@ -506,17 +506,21 @@ void GameController::setUseBIOS(bool use) {
|
|||
}
|
||||
|
||||
void GameController::loadState(int slot) {
|
||||
threadInterrupt();
|
||||
GBALoadState(&m_threadContext, m_threadContext.stateDir, slot);
|
||||
threadContinue();
|
||||
emit stateLoaded(&m_threadContext);
|
||||
emit frameAvailable(m_drawContext);
|
||||
m_stateSlot = slot;
|
||||
GBARunOnThread(&m_threadContext, [](GBAThread* context) {
|
||||
GameController* controller = static_cast<GameController*>(context->userData);
|
||||
GBALoadState(context, context->stateDir, controller->m_stateSlot);
|
||||
controller->stateLoaded(context);
|
||||
controller->frameAvailable(controller->m_drawContext);
|
||||
});
|
||||
}
|
||||
|
||||
void GameController::saveState(int slot) {
|
||||
threadInterrupt();
|
||||
GBASaveState(&m_threadContext, m_threadContext.stateDir, slot, true);
|
||||
threadContinue();
|
||||
m_stateSlot = slot;
|
||||
GBARunOnThread(&m_threadContext, [](GBAThread* context) {
|
||||
GameController* controller = static_cast<GameController*>(context->userData);
|
||||
GBASaveState(context, context->stateDir, controller->m_stateSlot, true);
|
||||
});
|
||||
}
|
||||
|
||||
void GameController::setVideoSync(bool set) {
|
||||
|
@ -595,9 +599,7 @@ void GameController::clearAVStream() {
|
|||
|
||||
#ifdef USE_PNG
|
||||
void GameController::screenshot() {
|
||||
GBAThreadInterrupt(&m_threadContext);
|
||||
GBAThreadTakeScreenshot(&m_threadContext);
|
||||
GBAThreadContinue(&m_threadContext);
|
||||
GBARunOnThread(&m_threadContext, GBAThreadTakeScreenshot);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -184,6 +184,8 @@ private:
|
|||
bool m_turbo;
|
||||
bool m_turboForced;
|
||||
|
||||
int m_stateSlot;
|
||||
|
||||
InputController* m_inputController;
|
||||
std::shared_ptr<MultiplayerController> m_multiplayer;
|
||||
|
||||
|
|
Loading…
Reference in New Issue