Clean up thread starting, stopping and sound
Jeffrey Pfau jeffrey@endrift.com
Wed, 09 Oct 2013 00:44:31 -0700
5 files changed,
36 insertions(+),
1 deletions(-)
M
src/gba/gba-thread.c
→
src/gba/gba-thread.c
@@ -65,6 +65,10 @@ threadContext->debugger = 0;
} gba.keySource = &threadContext->activeKeys; + if (threadContext->startCallback) { + threadContext->startCallback(threadContext); + } + threadContext->started = 1; pthread_mutex_lock(&threadContext->startMutex); pthread_cond_broadcast(&threadContext->startCond);@@ -78,7 +82,15 @@ while (threadContext->started) {
ARMRun(&gba.cpu); } } + + if (threadContext->cleanCallback) { + threadContext->cleanCallback(threadContext); + } + GBADeinit(&gba); + + pthread_cond_broadcast(&threadContext->sync.videoFrameAvailableCond); + pthread_cond_broadcast(&threadContext->sync.audioRequiredCond); free(savedata); return 0;
M
src/gba/gba-thread.h
→
src/gba/gba-thread.h
@@ -3,6 +3,9 @@ #define GBA_THREAD_H
#include <pthread.h> +struct GBAThread; +typedef void (*ThreadCallback)(struct GBAThread* threadContext); + struct GBAThread { // Output int started;@@ -22,6 +25,10 @@ pthread_t thread;
pthread_mutex_t startMutex; pthread_cond_t startCond; + + ThreadCallback startCallback; + ThreadCallback cleanCallback; + void* userData; struct GBASync { int videoFramePending;
M
src/gba/gba.c
→
src/gba/gba.c
@@ -61,6 +61,7 @@
void GBADeinit(struct GBA* gba) { GBAMemoryDeinit(&gba->memory); GBAVideoDeinit(&gba->video); + GBAAudioDeinit(&gba->audio); } void GBABoardInit(struct GBABoard* board) {
M
src/gl-main.c
→
src/gl-main.c
@@ -29,6 +29,8 @@
static int _GBASDLInit(struct GLSoftwareRenderer* renderer); static void _GBASDLDeinit(struct GLSoftwareRenderer* renderer); static void _GBASDLRunloop(struct GBAThread* context, struct GLSoftwareRenderer* renderer); +static void _GBASDLStart(struct GBAThread* context); +static void _GBASDLClean(struct GBAThread* context); static const GLint _glVertices[] = { 0, 0,@@ -74,8 +76,10 @@ context.renderer = &renderer.d.d;
context.frameskip = 0; context.sync.videoFrameWait = 0; context.sync.audioWait = 1; + context.startCallback = _GBASDLStart; + context.cleanCallback = _GBASDLClean; + context.userData = &renderer; GBAThreadStart(&context); - renderer.audio.audio = &context.gba->audio; _GBASDLRunloop(&context, &renderer);@@ -158,3 +162,13 @@ GBASDLDeinitEvents(&renderer->events);
GBASDLDeinitAudio(&renderer->audio); SDL_Quit(); } + +static void _GBASDLStart(struct GBAThread* threadContext) { + struct GLSoftwareRenderer* renderer = threadContext->userData; + renderer->audio.audio = &threadContext->gba->audio; +} + +static void _GBASDLClean(struct GBAThread* threadContext) { + struct GLSoftwareRenderer* renderer = threadContext->userData; + renderer->audio.audio = 0; +}
M
src/sdl/sdl-audio.c
→
src/sdl/sdl-audio.c
@@ -29,6 +29,7 @@ }
void GBASDLDeinitAudio(struct GBASDLAudio* context) { (void)(context); + SDL_PauseAudio(1); SDL_CloseAudio(); SDL_QuitSubSystem(SDL_INIT_AUDIO); }