GBA Thread: Kill GBAThread
jump to
@@ -5,7 +5,6 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "config.h" -#include "gba/gba.h" #include "util/formatting.h" #include "util/string.h" #include "util/vfs.h"
@@ -5,10 +5,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "audio.h" +#include "core/sync.h" #include "gba/gba.h" #include "gba/io.h" #include "gba/serialize.h" -#include "gba/supervisor/thread.h" #include "gba/video.h" const unsigned GBA_AUDIO_SAMPLES = 2048;
@@ -5,14 +5,16 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "gba.h" +#include "core/thread.h" + #include "arm/decoder.h" #include "arm/isa-inlines.h" #include "gba/bios.h" #include "gba/cheats.h" +#include "gba/context/overrides.h" #include "gba/io.h" #include "gba/rr/rr.h" -#include "gba/supervisor/thread.h" #include "gba/serialize.h" #include "gba/sio.h"@@ -90,8 +92,6 @@
gba->romVf = 0; gba->biosVf = 0; - gba->logHandler = 0; - gba->logLevel = GBA_LOG_WARN | GBA_LOG_ERROR | GBA_LOG_FATAL; gba->stream = 0; gba->keyCallback = 0; gba->stopCallback = 0;@@ -650,80 +650,12 @@ gba->cpu->nextEvent = gba->cpu->cycles;
gba->stopCallback->stop(gba->stopCallback); } -static void _GBAVLog(struct GBA* gba, enum GBALogLevel level, const char* format, va_list args) { - struct GBAThread* threadContext = GBAThreadGetContext(); - enum GBALogLevel logLevel = GBA_LOG_ALL; - - if (gba) { - logLevel = gba->logLevel; - } - - if (threadContext) { - logLevel = threadContext->logLevel; - gba = threadContext->gba; - } - - if (!(level & logLevel) && level != GBA_LOG_FATAL) { - return; - } - - if (level == GBA_LOG_FATAL && gba) { - gba->cpu->nextEvent = 0; - } - - if (threadContext) { - if (level == GBA_LOG_FATAL) { - MutexLock(&threadContext->stateMutex); - threadContext->state = THREAD_CRASHED; - MutexUnlock(&threadContext->stateMutex); - } - } - if (gba && gba->logHandler) { - gba->logHandler(threadContext, level, format, args); - return; - } - - vprintf(format, args); - printf("\n"); - - if (level == GBA_LOG_FATAL && !threadContext) { - abort(); - } -} - void GBALog(struct GBA* gba, enum GBALogLevel level, const char* format, ...) { - va_list args; - va_start(args, format); - _GBAVLog(gba, level, format, args); - va_end(args); + // TODO: Kill GBALog } void GBADebuggerLogShim(struct Debugger* debugger, enum DebuggerLogLevel level, const char* format, ...) { - struct GBA* gba = 0; - if (debugger->cpu) { - gba = (struct GBA*) debugger->cpu->master; - } - - enum GBALogLevel gbaLevel; - switch (level) { - default: // Avoids compiler warning - case DEBUGGER_LOG_DEBUG: - gbaLevel = GBA_LOG_DEBUG; - break; - case DEBUGGER_LOG_INFO: - gbaLevel = GBA_LOG_INFO; - break; - case DEBUGGER_LOG_WARN: - gbaLevel = GBA_LOG_WARN; - break; - case DEBUGGER_LOG_ERROR: - gbaLevel = GBA_LOG_ERROR; - break; - } - va_list args; - va_start(args, format); - _GBAVLog(gba, gbaLevel, format, args); - va_end(args); + // TODO: Kill GBADebuggerLogShim } bool GBAIsROM(struct VFile* vf) {@@ -879,18 +811,7 @@
void GBAFrameStarted(struct GBA* gba) { UNUSED(gba); - struct GBAThread* thread = GBAThreadGetContext(); - if (!thread) { - return; - } - - if (thread->rewindBuffer) { - --thread->rewindBufferNext; - if (thread->rewindBufferNext <= 0) { - thread->rewindBufferNext = thread->rewindBufferInterval; - GBARecordFrame(thread); - } - } + // TODO: Put back rewind } void GBAFrameEnded(struct GBA* gba) {@@ -969,12 +890,6 @@ } else {
GBAPatch16(gba->cpu, address, opcode, 0); } } - -#if (!defined(USE_PTHREADS) && !defined(_WIN32)) || defined(DISABLE_THREADING) -struct GBAThread* GBAThreadGetContext(void) { - return 0; -} -#endif static bool _setSoftwareBreakpoint(struct Debugger* debugger, uint32_t address, enum ExecutionMode mode, uint32_t* opcode) { GBASetBreakpoint((struct GBA*) debugger->cpu->master, &debugger->d, address, mode, opcode);
@@ -56,7 +56,6 @@ SP_BASE_SUPERVISOR = 0x03007FE0
}; struct GBA; -struct GBAThread; struct Patch; struct VFile;@@ -114,8 +113,6 @@ struct VFile* biosVf;
const char* activeFile; - GBALogHandler logHandler; - enum GBALogLevel logLevel; struct mAVStream* stream; struct mKeyCallback* keyCallback; struct mStopCallback* stopCallback;
@@ -37,10 +37,7 @@
struct GBA; struct GBAAudio; struct GBASIO; -struct GBAThread; struct GBAVideoRenderer; - -typedef void (*GBALogHandler)(struct GBAThread*, enum GBALogLevel, const char* format, va_list args); extern const int GBA_LUX_LEVELS[10];
@@ -5,11 +5,11 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "serialize.h" +#include "core/sync.h" #include "gba/audio.h" #include "gba/cheats.h" #include "gba/io.h" #include "gba/rr/rr.h" -#include "gba/supervisor/thread.h" #include "gba/video.h" #include "util/memory.h"@@ -356,66 +356,6 @@ return state;
} #endif -bool GBASaveState(struct GBAThread* threadContext, struct VDir* dir, int slot, int flags) { - struct VFile* vf = GBAGetState(threadContext->gba, dir, slot, true); - if (!vf) { - return false; - } - bool success = GBASaveStateNamed(threadContext->gba, vf, flags); - vf->close(vf); - if (success) { -#if SAVESTATE_DEBUG - vf = GBAGetState(threadContext->gba, dir, slot, false); - if (vf) { - struct GBA* backup = anonymousMemoryMap(sizeof(*backup)); - memcpy(backup, threadContext->gba, sizeof(*backup)); - memset(threadContext->gba->memory.io, 0, sizeof(threadContext->gba->memory.io)); - memset(threadContext->gba->timers, 0, sizeof(threadContext->gba->timers)); - GBALoadStateNamed(threadContext->gba, vf, flags); - if (memcmp(backup, threadContext->gba, sizeof(*backup))) { - char suffix[16] = { '\0' }; - struct VFile* vf2; - snprintf(suffix, sizeof(suffix), ".dump.0.%d", slot); - vf2 = VDirOptionalOpenFile(dir, threadContext->gba->activeFile, "savestate", suffix, write ? (O_CREAT | O_TRUNC | O_RDWR) : O_RDONLY); - if (vf2) { - vf2->write(vf2, backup, sizeof(*backup)); - vf2->close(vf2); - } - snprintf(suffix, sizeof(suffix), ".dump.1.%d", slot); - vf2 = VDirOptionalOpenFile(dir, threadContext->gba->activeFile, "savestate", suffix, write ? (O_CREAT | O_TRUNC | O_RDWR) : O_RDONLY); - if (vf2) { - vf2->write(vf2, threadContext->gba, sizeof(*threadContext->gba)); - vf2->close(vf2); - } - } - mappedMemoryFree(backup, sizeof(*backup)); - vf->close(vf); - } -#endif - GBALog(threadContext->gba, GBA_LOG_STATUS, "State %i saved", slot); - } else { - GBALog(threadContext->gba, GBA_LOG_STATUS, "State %i failed to save", slot); - } - - return success; -} - -bool GBALoadState(struct GBAThread* threadContext, struct VDir* dir, int slot, int flags) { - struct VFile* vf = GBAGetState(threadContext->gba, dir, slot, false); - if (!vf) { - return false; - } - threadContext->rewindBufferSize = 0; - bool success = GBALoadStateNamed(threadContext->gba, vf, flags); - vf->close(vf); - if (success) { - GBALog(threadContext->gba, GBA_LOG_STATUS, "State %i loaded", slot); - } else { - GBALog(threadContext->gba, GBA_LOG_STATUS, "State %i failed to load", slot); - } - return success; -} - bool GBASaveStateNamed(struct GBA* gba, struct VFile* vf, int flags) { struct GBAExtdata extdata; GBAExtdataInit(&extdata);@@ -671,82 +611,7 @@ void GBADeallocateState(struct GBASerializedState* state) {
mappedMemoryFree(state, sizeof(struct GBASerializedState)); } -void GBARecordFrame(struct GBAThread* thread) { - int offset = thread->rewindBufferWriteOffset; - struct GBASerializedState* state = thread->rewindBuffer[offset]; - if (!state) { - state = GBAAllocateState(); - thread->rewindBuffer[offset] = state; - } - GBASerialize(thread->gba, state); - - if (thread->rewindScreenBuffer) { - unsigned stride; - const uint8_t* pixels = 0; - thread->gba->video.renderer->getPixels(thread->gba->video.renderer, &stride, (const void**) &pixels); - if (pixels) { - size_t y; - for (y = 0; y < VIDEO_VERTICAL_PIXELS; ++y) { - memcpy(&thread->rewindScreenBuffer[(offset * VIDEO_VERTICAL_PIXELS + y) * VIDEO_HORIZONTAL_PIXELS * BYTES_PER_PIXEL], &pixels[y * stride * BYTES_PER_PIXEL], VIDEO_HORIZONTAL_PIXELS * BYTES_PER_PIXEL); - } - } - } - thread->rewindBufferSize = thread->rewindBufferSize == thread->rewindBufferCapacity ? thread->rewindBufferCapacity : thread->rewindBufferSize + 1; - thread->rewindBufferWriteOffset = (offset + 1) % thread->rewindBufferCapacity; -} - -void GBARewindSettingsChanged(struct GBAThread* threadContext, int newCapacity, int newInterval) { - if (newCapacity == threadContext->rewindBufferCapacity && newInterval == threadContext->rewindBufferInterval) { - return; - } - threadContext->rewindBufferInterval = newInterval; - threadContext->rewindBufferNext = threadContext->rewindBufferInterval; - threadContext->rewindBufferSize = 0; - if (threadContext->rewindBuffer) { - int i; - for (i = 0; i < threadContext->rewindBufferCapacity; ++i) { - GBADeallocateState(threadContext->rewindBuffer[i]); - } - free(threadContext->rewindBuffer); - free(threadContext->rewindScreenBuffer); - } - threadContext->rewindBufferCapacity = newCapacity; - if (threadContext->rewindBufferCapacity > 0) { - threadContext->rewindBuffer = calloc(threadContext->rewindBufferCapacity, sizeof(struct GBASerializedState*)); - threadContext->rewindScreenBuffer = calloc(threadContext->rewindBufferCapacity, VIDEO_VERTICAL_PIXELS * VIDEO_HORIZONTAL_PIXELS * BYTES_PER_PIXEL); - } else { - threadContext->rewindBuffer = 0; - threadContext->rewindScreenBuffer = 0; - } -} - -int GBARewind(struct GBAThread* thread, int nStates) { - if (nStates > thread->rewindBufferSize || nStates < 0) { - nStates = thread->rewindBufferSize; - } - if (nStates == 0) { - return 0; - } - int offset = thread->rewindBufferWriteOffset - nStates; - if (offset < 0) { - offset += thread->rewindBufferCapacity; - } - struct GBASerializedState* state = thread->rewindBuffer[offset]; - if (!state) { - return 0; - } - thread->rewindBufferSize -= nStates; - thread->rewindBufferWriteOffset = offset; - GBADeserialize(thread->gba, state); - if (thread->rewindScreenBuffer) { - thread->gba->video.renderer->putPixels(thread->gba->video.renderer, VIDEO_HORIZONTAL_PIXELS, &thread->rewindScreenBuffer[offset * VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS * BYTES_PER_PIXEL]); - } - return nStates; -} - -void GBARewindAll(struct GBAThread* thread) { - GBARewind(thread, thread->rewindBufferSize); -} +// TODO: Put back rewind void GBATakeScreenshot(struct GBA* gba, struct VDir* dir) { #ifdef USE_PNG
@@ -358,13 +358,10 @@ struct GBAExtdataItem data[EXTDATA_MAX];
}; struct VDir; -struct GBAThread; void GBASerialize(struct GBA* gba, struct GBASerializedState* state); bool GBADeserialize(struct GBA* gba, const struct GBASerializedState* state); -bool GBASaveState(struct GBAThread* thread, struct VDir* dir, int slot, int flags); -bool GBALoadState(struct GBAThread* thread, struct VDir* dir, int slot, int flags); struct VFile* GBAGetState(struct GBA* gba, struct VDir* dir, int slot, bool write); void GBADeleteState(struct GBA* thread, struct VDir* dir, int slot);@@ -381,11 +378,6 @@
struct GBASerializedState* GBAExtractState(struct VFile* vf, struct GBAExtdata* extdata); struct GBASerializedState* GBAAllocateState(void); void GBADeallocateState(struct GBASerializedState* state); - -void GBARecordFrame(struct GBAThread* thread); -void GBARewindSettingsChanged(struct GBAThread* thread, int newCapacity, int newInterval); -int GBARewind(struct GBAThread* thread, int nStates); -void GBARewindAll(struct GBAThread* thread); void GBATakeScreenshot(struct GBA* gba, struct VDir* dir);
@@ -7,7 +7,6 @@ #include "cli.h"
#include "gba/io.h" #include "gba/serialize.h" -#include "gba/supervisor/thread.h" #ifdef USE_CLI_DEBUGGER
@@ -1,736 +0,0 @@
-/* Copyright (c) 2013-2015 Jeffrey Pfau - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "thread.h" - -#include "arm.h" -#include "core/config.h" -#include "gba/gba.h" -#include "gba/cheats.h" -#include "gba/serialize.h" -#include "gba/rr/mgm.h" -#include "gba/rr/vbm.h" - -#include "debugger/debugger.h" - -#include "util/patch.h" -#include "util/vfs.h" - -#include "platform/commandline.h" - -#include <signal.h> - -static const float _defaultFPSTarget = 60.f; - -#ifndef DISABLE_THREADING - -static bool _reloadDirectories(struct GBAThread* threadContext) { - mDirectorySetDetachBase(&threadContext->dirs); - - char basename[PATH_MAX]; - if (threadContext->fname) { - char dirname[PATH_MAX]; - separatePath(threadContext->fname, dirname, basename, 0); - mDirectorySetAttachBase(&threadContext->dirs, VDirOpen(dirname)); - } else { - return false; - } - - char path[PATH_MAX]; - snprintf(path, sizeof(path), "%s.sav", basename); - threadContext->save = threadContext->dirs.save->openFile(threadContext->dirs.save, path, O_CREAT | O_RDWR); - - if (!threadContext->patch) { - snprintf(path, sizeof(path), "%s.ups", basename); - threadContext->patch = threadContext->dirs.patch->openFile(threadContext->dirs.patch, path, O_RDONLY); - } - if (!threadContext->patch) { - snprintf(path, sizeof(path), "%s.ips", basename); - threadContext->patch = threadContext->dirs.patch->openFile(threadContext->dirs.patch, path, O_RDONLY); - } - if (!threadContext->patch) { - snprintf(path, sizeof(path), "%s.bps", basename); - threadContext->patch = threadContext->dirs.patch->openFile(threadContext->dirs.patch, path, O_RDONLY); - } - return true; -} - -#ifdef USE_PTHREADS -static pthread_key_t _contextKey; -static pthread_once_t _contextOnce = PTHREAD_ONCE_INIT; - -static void _createTLS(void) { - pthread_key_create(&_contextKey, 0); -} -#elif _WIN32 -static DWORD _contextKey; -static INIT_ONCE _contextOnce = INIT_ONCE_STATIC_INIT; - -static BOOL CALLBACK _createTLS(PINIT_ONCE once, PVOID param, PVOID* context) { - UNUSED(once); - UNUSED(param); - UNUSED(context); - _contextKey = TlsAlloc(); - return TRUE; -} -#endif - -static void _changeState(struct GBAThread* threadContext, enum mCoreThreadState newState, bool broadcast) { - MutexLock(&threadContext->stateMutex); - threadContext->state = newState; - if (broadcast) { - ConditionWake(&threadContext->stateCond); - } - MutexUnlock(&threadContext->stateMutex); -} - -static void _waitOnInterrupt(struct GBAThread* threadContext) { - while (threadContext->state == THREAD_INTERRUPTED) { - ConditionWait(&threadContext->stateCond, &threadContext->stateMutex); - } -} - -static void _waitUntilNotState(struct GBAThread* threadContext, enum mCoreThreadState oldState) { - MutexLock(&threadContext->sync.videoFrameMutex); - bool videoFrameWait = threadContext->sync.videoFrameWait; - threadContext->sync.videoFrameWait = false; - MutexUnlock(&threadContext->sync.videoFrameMutex); - - while (threadContext->state == oldState) { - MutexUnlock(&threadContext->stateMutex); - - if (!MutexTryLock(&threadContext->sync.videoFrameMutex)) { - ConditionWake(&threadContext->sync.videoFrameRequiredCond); - MutexUnlock(&threadContext->sync.videoFrameMutex); - } - - if (!MutexTryLock(&threadContext->sync.audioBufferMutex)) { - ConditionWake(&threadContext->sync.audioRequiredCond); - MutexUnlock(&threadContext->sync.audioBufferMutex); - } - - MutexLock(&threadContext->stateMutex); - ConditionWake(&threadContext->stateCond); - } - - MutexLock(&threadContext->sync.videoFrameMutex); - threadContext->sync.videoFrameWait = videoFrameWait; - MutexUnlock(&threadContext->sync.videoFrameMutex); -} - -static void _pauseThread(struct GBAThread* threadContext, bool onThread) { - threadContext->state = THREAD_PAUSING; - if (!onThread) { - _waitUntilNotState(threadContext, THREAD_PAUSING); - } -} - -struct GBAThreadStop { - struct mStopCallback d; - struct GBAThread* p; -}; - -static void _stopCallback(struct mStopCallback* stop) { - struct GBAThreadStop* callback = (struct GBAThreadStop*) stop; - if (callback->p->stopCallback(callback->p)) { - _changeState(callback->p, THREAD_EXITING, false); - } -} - -static THREAD_ENTRY _GBAThreadRun(void* context) { -#ifdef USE_PTHREADS - pthread_once(&_contextOnce, _createTLS); -#elif _WIN32 - InitOnceExecuteOnce(&_contextOnce, _createTLS, NULL, 0); -#endif - - struct GBA gba; - struct ARMCore cpu; - struct Patch patch; - struct GBACheatDevice cheatDevice; - struct GBAThread* threadContext = context; - struct mCPUComponent* components[GBA_COMPONENT_MAX] = { 0 }; - struct GBARRContext* movie = 0; - int numComponents = GBA_COMPONENT_MAX; - - ThreadSetName("CPU Thread"); - -#if !defined(_WIN32) && defined(USE_PTHREADS) - sigset_t signals; - sigemptyset(&signals); - pthread_sigmask(SIG_SETMASK, &signals, 0); -#endif - - GBACreate(&gba); - ARMSetComponents(&cpu, &gba.d, numComponents, components); - ARMInit(&cpu); - gba.sync = &threadContext->sync; - threadContext->gba = &gba; - threadContext->cpu = &cpu; - gba.logLevel = threadContext->logLevel; - gba.logHandler = threadContext->logHandler; - gba.stream = threadContext->stream; - gba.video.frameskip = threadContext->frameskip; - - struct GBAThreadStop stop; - if (threadContext->stopCallback) { - stop.d.stop = _stopCallback; - stop.p = threadContext; - gba.stopCallback = &stop.d; - } - - gba.idleOptimization = threadContext->idleOptimization; -#ifdef USE_PTHREADS - pthread_setspecific(_contextKey, threadContext); -#elif _WIN32 - TlsSetValue(_contextKey, threadContext); -#endif - - if (threadContext->audioBuffers) { - GBAAudioResizeBuffer(&gba.audio, threadContext->audioBuffers); - } else { - threadContext->audioBuffers = GBA_AUDIO_SAMPLES; - } - - if (threadContext->renderer) { - GBAVideoAssociateRenderer(&gba.video, threadContext->renderer); - } - - if (threadContext->rom) { - if (GBAIsMB(threadContext->rom)) { - GBALoadMB(&gba, threadContext->rom, threadContext->fname); - } else { - GBALoadROM(&gba, threadContext->rom, threadContext->save, threadContext->fname); - } - - struct GBACartridgeOverride override; - const struct GBACartridge* cart = (const struct GBACartridge*) gba.pristineRom; - memcpy(override.id, &cart->id, sizeof(override.id)); - if (GBAOverrideFind(threadContext->overrides, &override)) { - GBAOverrideApply(&gba, &override); - } - if (threadContext->hasOverride) { - GBAOverrideApply(&gba, &threadContext->override); - } - - if (threadContext->patch && loadPatch(threadContext->patch, &patch)) { - GBAApplyPatch(&gba, &patch); - } - } - - if (threadContext->bios && GBAIsBIOS(threadContext->bios)) { - GBALoadBIOS(&gba, threadContext->bios); - } - - if (threadContext->movie) { - struct VDir* movieDir = VDirOpen(threadContext->movie); - if (!movieDir) { - movieDir = VDirOpenArchive(threadContext->movie); - } - if (movieDir) { - struct GBAMGMContext* mgm = malloc(sizeof(*mgm)); - GBAMGMContextCreate(mgm); - if (!GBAMGMSetStream(mgm, movieDir)) { - mgm->d.destroy(&mgm->d); - } else { - movie = &mgm->d; - } - } else { - struct VFile* movieFile = VFileOpen(threadContext->movie, O_RDONLY); - if (movieFile) { - struct GBAVBMContext* vbm = malloc(sizeof(*vbm)); - GBAVBMContextCreate(vbm); - if (!GBAVBMSetStream(vbm, movieFile)) { - vbm->d.destroy(&vbm->d); - } else { - movie = &vbm->d; - } - } - } - } - - ARMReset(&cpu); - - if (movie) { - gba.rr = movie; - movie->startPlaying(movie, false); - GBARRInitPlay(&gba); - } - - if (threadContext->skipBios && gba.pristineRom) { - GBASkipBIOS(&gba); - } - - if (!threadContext->cheats) { - GBACheatDeviceCreate(&cheatDevice); - threadContext->cheats = &cheatDevice; - } - if (threadContext->cheatsFile) { - GBACheatParseFile(threadContext->cheats, threadContext->cheatsFile); - } - GBACheatAttachDevice(&gba, threadContext->cheats); - - if (threadContext->debugger) { - threadContext->debugger->log = GBADebuggerLogShim; - GBAAttachDebugger(&gba, threadContext->debugger); - DebuggerEnter(threadContext->debugger, DEBUGGER_ENTER_ATTACHED, 0); - } - - GBASIOSetDriverSet(&gba.sio, &threadContext->sioDrivers); - - if (threadContext->volume == 0) { - threadContext->volume = GBA_AUDIO_VOLUME_MAX; - } - if (threadContext->mute) { - gba.audio.masterVolume = 0; - } else { - gba.audio.masterVolume = threadContext->volume; - } - - gba.keySource = &threadContext->activeKeys; - - if (threadContext->startCallback) { - threadContext->startCallback(threadContext); - } - - _changeState(threadContext, THREAD_RUNNING, true); - - while (threadContext->state < THREAD_EXITING) { - if (threadContext->debugger) { - struct Debugger* debugger = threadContext->debugger; - DebuggerRun(debugger); - if (debugger->state == DEBUGGER_SHUTDOWN) { - _changeState(threadContext, THREAD_EXITING, false); - } - } else { - while (threadContext->state == THREAD_RUNNING) { - ARMRunLoop(&cpu); - } - } - - int resetScheduled = 0; - MutexLock(&threadContext->stateMutex); - while (threadContext->state > THREAD_RUNNING && threadContext->state < THREAD_EXITING) { - if (threadContext->state == THREAD_PAUSING) { - threadContext->state = THREAD_PAUSED; - ConditionWake(&threadContext->stateCond); - } - if (threadContext->state == THREAD_INTERRUPTING) { - threadContext->state = THREAD_INTERRUPTED; - ConditionWake(&threadContext->stateCond); - } - if (threadContext->state == THREAD_RUN_ON) { - if (threadContext->run) { - threadContext->run(threadContext); - } - threadContext->state = threadContext->savedState; - ConditionWake(&threadContext->stateCond); - } - if (threadContext->state == THREAD_RESETING) { - threadContext->state = THREAD_RUNNING; - resetScheduled = 1; - } - while (threadContext->state == THREAD_PAUSED || threadContext->state == THREAD_INTERRUPTED) { - ConditionWait(&threadContext->stateCond, &threadContext->stateMutex); - } - } - MutexUnlock(&threadContext->stateMutex); - if (resetScheduled) { - ARMReset(&cpu); - if (threadContext->skipBios && gba.pristineRom) { - GBASkipBIOS(&gba); - } - } - } - - while (threadContext->state < THREAD_SHUTDOWN) { - _changeState(threadContext, THREAD_SHUTDOWN, false); - } - - if (threadContext->cleanCallback) { - threadContext->cleanCallback(threadContext); - } - - threadContext->gba = 0; - ARMDeinit(&cpu); - GBADestroy(&gba); - if (&cheatDevice == threadContext->cheats) { - GBACheatDeviceDestroy(&cheatDevice); - } - - if (movie) { - movie->destroy(movie); - free(movie); - } - - threadContext->sync.videoFrameOn = false; - ConditionWake(&threadContext->sync.videoFrameAvailableCond); - ConditionWake(&threadContext->sync.audioRequiredCond); - - return 0; -} - -void GBAMapOptionsToContext(const struct mCoreOptions* opts, struct GBAThread* threadContext) { - if (opts->useBios) { - threadContext->bios = VFileOpen(opts->bios, O_RDONLY); - } else { - threadContext->bios = 0; - } - threadContext->frameskip = opts->frameskip; - threadContext->volume = opts->volume; - threadContext->mute = opts->mute; - threadContext->logLevel = opts->logLevel; - if (opts->rewindEnable) { - threadContext->rewindBufferCapacity = opts->rewindBufferCapacity; - threadContext->rewindBufferInterval = opts->rewindBufferInterval; - } else { - threadContext->rewindBufferCapacity = 0; - } - threadContext->skipBios = opts->skipBios; - threadContext->sync.audioWait = opts->audioSync; - threadContext->sync.videoFrameWait = opts->videoSync; - - if (opts->fpsTarget) { - threadContext->fpsTarget = opts->fpsTarget; - } - - if (opts->audioBuffers) { - threadContext->audioBuffers = opts->audioBuffers; - } - - mDirectorySetMapOptions(&threadContext->dirs, opts); -} - -void GBAMapArgumentsToContext(const struct mArguments* args, struct GBAThread* threadContext) { - GBAThreadLoadROM(threadContext, args->fname); - threadContext->fname = args->fname; - threadContext->patch = VFileOpen(args->patch, O_RDONLY); - threadContext->cheatsFile = VFileOpen(args->cheatsFile, O_RDONLY); - threadContext->movie = args->movie; -} - -bool GBAThreadStart(struct GBAThread* threadContext) { - // TODO: error check - threadContext->activeKeys = 0; - threadContext->state = THREAD_INITIALIZED; - threadContext->sync.videoFrameOn = true; - - threadContext->rewindBuffer = 0; - threadContext->rewindScreenBuffer = 0; - int newCapacity = threadContext->rewindBufferCapacity; - int newInterval = threadContext->rewindBufferInterval; - threadContext->rewindBufferCapacity = 0; - threadContext->rewindBufferInterval = 0; - GBARewindSettingsChanged(threadContext, newCapacity, newInterval); - - if (!threadContext->fpsTarget) { - threadContext->fpsTarget = _defaultFPSTarget; - } - - bool bootBios = threadContext->bootBios && threadContext->bios; - - if (threadContext->rom && (!GBAIsROM(threadContext->rom) || bootBios)) { - threadContext->rom->close(threadContext->rom); - threadContext->rom = 0; - } - - if (!threadContext->rom && !bootBios) { - threadContext->state = THREAD_SHUTDOWN; - return false; - } - - _reloadDirectories(threadContext); - - MutexInit(&threadContext->stateMutex); - ConditionInit(&threadContext->stateCond); - - MutexInit(&threadContext->sync.videoFrameMutex); - ConditionInit(&threadContext->sync.videoFrameAvailableCond); - ConditionInit(&threadContext->sync.videoFrameRequiredCond); - MutexInit(&threadContext->sync.audioBufferMutex); - ConditionInit(&threadContext->sync.audioRequiredCond); - - threadContext->interruptDepth = 0; - -#ifdef USE_PTHREADS - sigset_t signals; - sigemptyset(&signals); - sigaddset(&signals, SIGINT); - sigaddset(&signals, SIGTRAP); - pthread_sigmask(SIG_BLOCK, &signals, 0); -#endif - - MutexLock(&threadContext->stateMutex); - ThreadCreate(&threadContext->thread, _GBAThreadRun, threadContext); - while (threadContext->state < THREAD_RUNNING) { - ConditionWait(&threadContext->stateCond, &threadContext->stateMutex); - } - MutexUnlock(&threadContext->stateMutex); - - return true; -} - -bool GBAThreadHasStarted(struct GBAThread* threadContext) { - bool hasStarted; - MutexLock(&threadContext->stateMutex); - hasStarted = threadContext->state > THREAD_INITIALIZED; - MutexUnlock(&threadContext->stateMutex); - return hasStarted; -} - -bool GBAThreadHasExited(struct GBAThread* threadContext) { - bool hasExited; - MutexLock(&threadContext->stateMutex); - hasExited = threadContext->state > THREAD_EXITING; - MutexUnlock(&threadContext->stateMutex); - return hasExited; -} - -bool GBAThreadHasCrashed(struct GBAThread* threadContext) { - bool hasExited; - MutexLock(&threadContext->stateMutex); - hasExited = threadContext->state == THREAD_CRASHED; - MutexUnlock(&threadContext->stateMutex); - return hasExited; -} - -void GBAThreadEnd(struct GBAThread* threadContext) { - MutexLock(&threadContext->stateMutex); - _waitOnInterrupt(threadContext); - threadContext->state = THREAD_EXITING; - if (threadContext->gba) { - threadContext->gba->cpu->halted = false; - } - ConditionWake(&threadContext->stateCond); - MutexUnlock(&threadContext->stateMutex); - MutexLock(&threadContext->sync.audioBufferMutex); - threadContext->sync.audioWait = 0; - ConditionWake(&threadContext->sync.audioRequiredCond); - MutexUnlock(&threadContext->sync.audioBufferMutex); - - MutexLock(&threadContext->sync.videoFrameMutex); - threadContext->sync.videoFrameWait = false; - threadContext->sync.videoFrameOn = false; - ConditionWake(&threadContext->sync.videoFrameRequiredCond); - ConditionWake(&threadContext->sync.videoFrameAvailableCond); - MutexUnlock(&threadContext->sync.videoFrameMutex); -} - -void GBAThreadReset(struct GBAThread* threadContext) { - MutexLock(&threadContext->stateMutex); - _waitOnInterrupt(threadContext); - threadContext->state = THREAD_RESETING; - ConditionWake(&threadContext->stateCond); - MutexUnlock(&threadContext->stateMutex); -} - -void GBAThreadJoin(struct GBAThread* threadContext) { - ThreadJoin(threadContext->thread); - - MutexDeinit(&threadContext->stateMutex); - ConditionDeinit(&threadContext->stateCond); - - MutexDeinit(&threadContext->sync.videoFrameMutex); - ConditionWake(&threadContext->sync.videoFrameAvailableCond); - ConditionDeinit(&threadContext->sync.videoFrameAvailableCond); - ConditionWake(&threadContext->sync.videoFrameRequiredCond); - ConditionDeinit(&threadContext->sync.videoFrameRequiredCond); - - ConditionWake(&threadContext->sync.audioRequiredCond); - ConditionDeinit(&threadContext->sync.audioRequiredCond); - MutexDeinit(&threadContext->sync.audioBufferMutex); - - int i; - for (i = 0; i < threadContext->rewindBufferCapacity; ++i) { - if (threadContext->rewindBuffer[i]) { - GBADeallocateState(threadContext->rewindBuffer[i]); - } - } - free(threadContext->rewindBuffer); - free(threadContext->rewindScreenBuffer); - - if (threadContext->rom) { - threadContext->rom->close(threadContext->rom); - threadContext->rom = 0; - } - - if (threadContext->save) { - threadContext->save->close(threadContext->save); - threadContext->save = 0; - } - - if (threadContext->bios) { - threadContext->bios->close(threadContext->bios); - threadContext->bios = 0; - } - - if (threadContext->patch) { - threadContext->patch->close(threadContext->patch); - threadContext->patch = 0; - } -} - -bool GBAThreadIsActive(struct GBAThread* threadContext) { - return threadContext->state >= THREAD_RUNNING && threadContext->state < THREAD_EXITING; -} - -void GBAThreadInterrupt(struct GBAThread* threadContext) { - MutexLock(&threadContext->stateMutex); - ++threadContext->interruptDepth; - if (threadContext->interruptDepth > 1 || !GBAThreadIsActive(threadContext)) { - MutexUnlock(&threadContext->stateMutex); - return; - } - threadContext->savedState = threadContext->state; - _waitOnInterrupt(threadContext); - threadContext->state = THREAD_INTERRUPTING; - threadContext->gba->cpu->nextEvent = 0; - ConditionWake(&threadContext->stateCond); - _waitUntilNotState(threadContext, THREAD_INTERRUPTING); - MutexUnlock(&threadContext->stateMutex); -} - -void GBAThreadContinue(struct GBAThread* threadContext) { - MutexLock(&threadContext->stateMutex); - --threadContext->interruptDepth; - if (threadContext->interruptDepth < 1 && GBAThreadIsActive(threadContext)) { - threadContext->state = threadContext->savedState; - ConditionWake(&threadContext->stateCond); - } - MutexUnlock(&threadContext->stateMutex); -} - -void GBARunOnThread(struct GBAThread* threadContext, void (*run)(struct GBAThread*)) { - MutexLock(&threadContext->stateMutex); - threadContext->run = run; - _waitOnInterrupt(threadContext); - threadContext->savedState = threadContext->state; - 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 = threadContext->sync.videoFrameOn; - MutexLock(&threadContext->stateMutex); - _waitOnInterrupt(threadContext); - if (threadContext->state == THREAD_RUNNING) { - _pauseThread(threadContext, false); - threadContext->frameWasOn = frameOn; - frameOn = false; - } - MutexUnlock(&threadContext->stateMutex); - - mCoreSyncSetVideoSync(&threadContext->sync, frameOn); -} - -void GBAThreadUnpause(struct GBAThread* threadContext) { - bool frameOn = threadContext->sync.videoFrameOn; - MutexLock(&threadContext->stateMutex); - _waitOnInterrupt(threadContext); - if (threadContext->state == THREAD_PAUSED || threadContext->state == THREAD_PAUSING) { - threadContext->state = THREAD_RUNNING; - ConditionWake(&threadContext->stateCond); - frameOn = threadContext->frameWasOn; - } - MutexUnlock(&threadContext->stateMutex); - - mCoreSyncSetVideoSync(&threadContext->sync, frameOn); -} - -bool GBAThreadIsPaused(struct GBAThread* threadContext) { - bool isPaused; - MutexLock(&threadContext->stateMutex); - _waitOnInterrupt(threadContext); - isPaused = threadContext->state == THREAD_PAUSED; - MutexUnlock(&threadContext->stateMutex); - return isPaused; -} - -void GBAThreadTogglePause(struct GBAThread* threadContext) { - bool frameOn = threadContext->sync.videoFrameOn; - MutexLock(&threadContext->stateMutex); - _waitOnInterrupt(threadContext); - if (threadContext->state == THREAD_PAUSED || threadContext->state == THREAD_PAUSING) { - threadContext->state = THREAD_RUNNING; - ConditionWake(&threadContext->stateCond); - frameOn = threadContext->frameWasOn; - } else if (threadContext->state == THREAD_RUNNING) { - _pauseThread(threadContext, false); - threadContext->frameWasOn = frameOn; - frameOn = false; - } - MutexUnlock(&threadContext->stateMutex); - - mCoreSyncSetVideoSync(&threadContext->sync, frameOn); -} - -void GBAThreadPauseFromThread(struct GBAThread* threadContext) { - bool frameOn = true; - MutexLock(&threadContext->stateMutex); - _waitOnInterrupt(threadContext); - if (threadContext->state == THREAD_RUNNING) { - _pauseThread(threadContext, true); - frameOn = false; - } - MutexUnlock(&threadContext->stateMutex); - - mCoreSyncSetVideoSync(&threadContext->sync, frameOn); -} - -void GBAThreadLoadROM(struct GBAThread* threadContext, const char* fname) { - threadContext->rom = mDirectorySetOpenPath(&threadContext->dirs, fname, GBAIsROM); -} - -void GBAThreadReplaceROM(struct GBAThread* threadContext, const char* fname) { - GBAUnloadROM(threadContext->gba); - - if (threadContext->rom) { - threadContext->rom->close(threadContext->rom); - threadContext->rom = 0; - } - - if (threadContext->save) { - threadContext->save->close(threadContext->save); - threadContext->save = 0; - } - - if (threadContext->dirs.archive) { - threadContext->dirs.archive->close(threadContext->dirs.archive); - threadContext->dirs.archive = 0; - } - - GBAThreadLoadROM(threadContext, fname); - - threadContext->fname = fname; - _reloadDirectories(threadContext); - - GBARaiseIRQ(threadContext->gba, IRQ_GAMEPAK); - GBALoadROM(threadContext->gba, threadContext->rom, threadContext->save, threadContext->fname); -} - -#ifdef USE_PTHREADS -struct GBAThread* GBAThreadGetContext(void) { - pthread_once(&_contextOnce, _createTLS); - return pthread_getspecific(_contextKey); -} -#elif _WIN32 -struct GBAThread* GBAThreadGetContext(void) { - InitOnceExecuteOnce(&_contextOnce, _createTLS, NULL, 0); - return TlsGetValue(_contextKey); -} -#endif - -void GBAThreadTakeScreenshot(struct GBAThread* threadContext) { - GBATakeScreenshot(threadContext->gba, threadContext->dirs.screenshot); -} - -#else -struct GBAThread* GBAThreadGetContext(void) { - return 0; -} -#endif
@@ -1,127 +0,0 @@
-/* Copyright (c) 2013-2015 Jeffrey Pfau - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef GBA_THREAD_H -#define GBA_THREAD_H - -#include "util/common.h" - -#include "core/directories.h" -#include "core/sync.h" -#include "core/thread.h" -#include "gba/gba.h" -#include "gba/input.h" -#include "gba/context/overrides.h" - -#include "util/threading.h" - -struct GBAThread; -struct mArguments; -struct GBACheatSet; -struct mCoreOptions; - -typedef void (*GBAThreadCallback)(struct GBAThread* threadContext); -typedef bool (*ThreadStopCallback)(struct GBAThread* threadContext); - -struct GBAThread { - // Output - enum mCoreThreadState state; - struct GBA* gba; - struct ARMCore* cpu; - - // Input - struct GBAVideoRenderer* renderer; - struct GBASIODriverSet sioDrivers; - struct Debugger* debugger; -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 - struct mDirectorySet dirs; -#endif - struct VFile* rom; - struct VFile* save; - struct VFile* bios; - struct VFile* patch; - struct VFile* cheatsFile; - const char* fname; - const char* movie; - int activeKeys; - struct mAVStream* stream; - struct Configuration* overrides; - enum GBAIdleLoopOptimization idleOptimization; - bool bootBios; - - bool hasOverride; - struct GBACartridgeOverride override; - - // Run-time options - int frameskip; - float fpsTarget; - size_t audioBuffers; - bool skipBios; - int volume; - bool mute; - - // Threading state - Thread thread; - - Mutex stateMutex; - Condition stateCond; - enum mCoreThreadState savedState; - int interruptDepth; - bool frameWasOn; - - GBALogHandler logHandler; - int logLevel; - GBAThreadCallback startCallback; - GBAThreadCallback cleanCallback; - GBAThreadCallback frameCallback; - ThreadStopCallback stopCallback; - void* userData; - void (*run)(struct GBAThread*); - - struct mCoreSync sync; - - int rewindBufferSize; - int rewindBufferCapacity; - int rewindBufferInterval; - int rewindBufferNext; - struct GBASerializedState** rewindBuffer; - int rewindBufferWriteOffset; - uint8_t* rewindScreenBuffer; - - struct GBACheatDevice* cheats; -}; - -void GBAMapOptionsToContext(const struct mCoreOptions*, struct GBAThread*); -void GBAMapArgumentsToContext(const struct mArguments*, struct GBAThread*); - -bool GBAThreadStart(struct GBAThread* threadContext); -bool GBAThreadHasStarted(struct GBAThread* threadContext); -bool GBAThreadHasExited(struct GBAThread* threadContext); -bool GBAThreadHasCrashed(struct GBAThread* threadContext); -void GBAThreadEnd(struct GBAThread* threadContext); -void GBAThreadReset(struct GBAThread* threadContext); -void GBAThreadJoin(struct GBAThread* threadContext); - -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); -void GBAThreadTogglePause(struct GBAThread* threadContext); -void GBAThreadPauseFromThread(struct GBAThread* threadContext); -struct GBAThread* GBAThreadGetContext(void); - -void GBAThreadLoadROM(struct GBAThread* threadContext, const char* fname); -void GBAThreadReplaceROM(struct GBAThread* threadContext, const char* fname); - -#ifdef USE_PNG -void GBAThreadTakeScreenshot(struct GBAThread* threadContext); -#endif - -#endif
@@ -9,8 +9,8 @@ #include <QApplication>
#include <QResizeEvent> extern "C" { -#include "gba/supervisor/thread.h" - +#include "core/core.h" +#include "core/thread.h" #ifdef BUILD_GL #include "platform/opengl/gl.h" #endif
@@ -16,7 +16,6 @@ #include <QFileOpenEvent>
#include <QIcon> extern "C" { -#include "gba/supervisor/thread.h" #include "platform/commandline.h" #include "util/nointro.h" #include "util/socket.h"
@@ -11,10 +11,6 @@ #include <QWidget>
#include "ui_LogView.h" -extern "C" { -#include "gba/supervisor/thread.h" -} - namespace QGBA { class LogController;
@@ -9,7 +9,7 @@ #include "ConfigController.h"
#include "GameController.h" extern "C" { -#include "gba/supervisor/thread.h" +#include "gba/gba.h" } using namespace QGBA;
@@ -13,6 +13,7 @@ #include <QFileDialog>
#include <QFontDatabase> extern "C" { +#include "core/core.h" #include "gba/supervisor/export.h" #include "util/vfs.h" }
@@ -9,6 +9,8 @@ #include "GBAApp.h"
#include "GameController.h" extern "C" { +#include "core/core.h" +#include "gba/gba.h" #include "util/nointro.h" }
@@ -10,10 +10,6 @@ #include <QWidget>
#include "ui_ROMInfo.h" -extern "C" { -#include "gba/supervisor/thread.h" -} - namespace QGBA { class GameController;
@@ -21,7 +21,6 @@ #include "gba/input.h"
#ifdef M_CORE_GBA #include "gba/core.h" #include "gba/gba.h" -#include "gba/supervisor/thread.h" #include "gba/video.h" #endif #ifdef M_CORE_GB
@@ -5,8 +5,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "sdl-audio.h" +#include "core/thread.h" #include "gba/gba.h" -#include "gba/supervisor/thread.h" #include "third-party/blip_buf/blip_buf.h"
@@ -12,7 +12,6 @@ #include "gba/input.h"
#include "gba/io.h" #include "gba/rr/rr.h" #include "gba/serialize.h" -#include "gba/supervisor/thread.h" #include "gba/video.h" #include "gba/renderers/video-software.h" #include "util/configuration.h"@@ -380,159 +379,6 @@ context->frameCallback = 0;
mCoreThreadPauseFromThread(context); } -static void _mSDLHandleKeypressGBA(struct GBAThread* context, struct mSDLPlayer* sdlContext, const struct SDL_KeyboardEvent* event) { - enum GBAKey key = GBA_KEY_NONE; - if (!event->keysym.mod) { -#if !defined(BUILD_PANDORA) && SDL_VERSION_ATLEAST(2, 0, 0) - key = mInputMapKey(sdlContext->bindings, SDL_BINDING_KEY, event->keysym.scancode); -#else - key = mInputMapKey(sdlContext->bindings, SDL_BINDING_KEY, event->keysym.sym); -#endif - } - if (key != GBA_KEY_NONE) { - if (event->type == SDL_KEYDOWN) { - context->activeKeys |= 1 << key; - } else { - context->activeKeys &= ~(1 << key); - } - return; - } - if (event->keysym.sym == SDLK_TAB) { - context->sync.audioWait = event->type != SDL_KEYDOWN; - return; - } - if (event->type == SDL_KEYDOWN) { - switch (event->keysym.sym) { - case SDLK_F11: - if (context->debugger) { - DebuggerEnter(context->debugger, DEBUGGER_ENTER_MANUAL, 0); - } - return; -#ifdef USE_PNG - case SDLK_F12: - GBAThreadInterrupt(context); - GBAThreadTakeScreenshot(context); - GBAThreadContinue(context); - return; -#endif - case SDLK_BACKQUOTE: - GBAThreadInterrupt(context); - GBARewind(context, 10); - GBAThreadContinue(context); - return; -#ifdef BUILD_PANDORA - case SDLK_ESCAPE: - GBAThreadEnd(context); - return; -#endif - default: - if ((event->keysym.mod & GUI_MOD) && (event->keysym.mod & GUI_MOD) == event->keysym.mod) { - switch (event->keysym.sym) { -#if SDL_VERSION_ATLEAST(2, 0, 0) - case SDLK_f: - SDL_SetWindowFullscreen(sdlContext->window, sdlContext->fullscreen ? 0 : SDL_WINDOW_FULLSCREEN_DESKTOP); - sdlContext->fullscreen = !sdlContext->fullscreen; - sdlContext->windowUpdated = 1; - break; -#endif - case SDLK_p: - GBAThreadTogglePause(context); - break; - case SDLK_r: - GBAThreadReset(context); - break; - default: - break; - } - } - if (event->keysym.mod & KMOD_SHIFT) { - switch (event->keysym.sym) { - case SDLK_F1: - case SDLK_F2: - case SDLK_F3: - case SDLK_F4: - case SDLK_F5: - case SDLK_F6: - case SDLK_F7: - case SDLK_F8: - case SDLK_F9: - GBAThreadInterrupt(context); - GBASaveState(context, context->dirs.state, event->keysym.sym - SDLK_F1 + 1, SAVESTATE_SCREENSHOT); - GBAThreadContinue(context); - break; - default: - break; - } - } else { - switch (event->keysym.sym) { - case SDLK_F1: - case SDLK_F2: - case SDLK_F3: - case SDLK_F4: - case SDLK_F5: - case SDLK_F6: - case SDLK_F7: - case SDLK_F8: - case SDLK_F9: - GBAThreadInterrupt(context); - GBALoadState(context, context->dirs.state, event->keysym.sym - SDLK_F1 + 1, SAVESTATE_SCREENSHOT); - GBAThreadContinue(context); - break; - default: - break; - } - } - return; - } - } -} - -static void _mSDLHandleJoyButtonGBA(struct GBAThread* context, struct mSDLPlayer* sdlContext, const struct SDL_JoyButtonEvent* event) { - enum GBAKey key = 0; - key = mInputMapKey(sdlContext->bindings, SDL_BINDING_BUTTON, event->button); - if (key == GBA_KEY_NONE) { - return; - } - - if (event->type == SDL_JOYBUTTONDOWN) { - context->activeKeys |= 1 << key; - } else { - context->activeKeys &= ~(1 << key); - } -} - -static void _mSDLHandleJoyHatGBA(struct GBAThread* context, const struct SDL_JoyHatEvent* event) { - enum GBAKey key = 0; - - if (event->value & SDL_HAT_UP) { - key |= 1 << GBA_KEY_UP; - } - if (event->value & SDL_HAT_LEFT) { - key |= 1 << GBA_KEY_LEFT; - } - if (event->value & SDL_HAT_DOWN) { - key |= 1 << GBA_KEY_DOWN; - } - if (event->value & SDL_HAT_RIGHT) { - key |= 1 << GBA_KEY_RIGHT; - } - - context->activeKeys &= ~((1 << GBA_KEY_UP) | (1 << GBA_KEY_LEFT) | (1 << GBA_KEY_DOWN) | (1 << GBA_KEY_RIGHT)); - context->activeKeys |= key; -} - -static void _mSDLHandleJoyAxisGBA(struct GBAThread* context, struct mSDLPlayer* sdlContext, const struct SDL_JoyAxisEvent* event) { - int keys = context->activeKeys; - - keys = mInputClearAxis(sdlContext->bindings, SDL_BINDING_BUTTON, event->axis, keys); - enum GBAKey key = mInputMapAxis(sdlContext->bindings, SDL_BINDING_BUTTON, event->axis, event->value); - if (key != -1) { - keys |= 1 << key; - } - - context->activeKeys = keys; -} - static void _mSDLHandleKeypress(struct mCoreThread* context, struct mSDLPlayer* sdlContext, const struct SDL_KeyboardEvent* event) { int key = -1; if (!event->keysym.mod) {@@ -680,33 +526,6 @@ break;
} } #endif - -void mSDLHandleEventGBA(struct GBAThread* context, struct mSDLPlayer* sdlContext, const union SDL_Event* event) { - switch (event->type) { - case SDL_QUIT: - GBAThreadEnd(context); - break; -#if SDL_VERSION_ATLEAST(2, 0, 0) - case SDL_WINDOWEVENT: - _mSDLHandleWindowEvent(sdlContext, &event->window); - break; -#endif - case SDL_KEYDOWN: - case SDL_KEYUP: - _mSDLHandleKeypressGBA(context, sdlContext, &event->key); - break; - case SDL_JOYBUTTONDOWN: - case SDL_JOYBUTTONUP: - _mSDLHandleJoyButtonGBA(context, sdlContext, &event->jbutton); - break; - case SDL_JOYHATMOTION: - _mSDLHandleJoyHatGBA(context, &event->jhat); - break; - case SDL_JOYAXISMOTION: - _mSDLHandleJoyAxisGBA(context, sdlContext, &event->jaxis); - break; - } -} void mSDLHandleEvent(struct mCoreThread* context, struct mSDLPlayer* sdlContext, const union SDL_Event* event) { switch (event->type) {
@@ -93,9 +93,7 @@
void mSDLPlayerLoadConfig(struct mSDLPlayer*, const struct Configuration*); void mSDLPlayerSaveConfig(const struct mSDLPlayer*, struct Configuration*); -struct GBAThread; void mSDLInitBindingsGBA(struct mInputMap* inputMap); -void mSDLHandleEventGBA(struct GBAThread* context, struct mSDLPlayer* sdlContext, const union SDL_Event* event); struct mCoreThread; void mSDLHandleEvent(struct mCoreThread* context, struct mSDLPlayer* sdlContext, const union SDL_Event* event);