all repos — mgba @ 51ec1c1099dbcd374bd577933ba30f55adb05603

mGBA Game Boy Advance Emulator

Bring SDL main to parity with GL main
Jeffrey Pfau jeffrey@endrift.com
Sat, 12 Oct 2013 02:13:26 -0700
commit

51ec1c1099dbcd374bd577933ba30f55adb05603

parent

cf298474bcaf57a6c10cfcbe050eb61e630c269f

1 files changed, 66 insertions(+), 35 deletions(-)

jump to
M src/sdl-main.csrc/sdl-main.c

@@ -2,6 +2,7 @@ #include "debugger.h"

#include "gba-thread.h" #include "gba.h" #include "renderers/video-software.h" +#include "sdl-audio.h" #include "sdl-events.h" #include <SDL.h>

@@ -12,9 +13,17 @@ #include <signal.h>

#include <sys/time.h> #include <unistd.h> -static int _GBASDLInit(void); -static void _GBASDLDeinit(void); -static void _GBASDLRunloop(struct GBAThread* context, struct GBAVideoSoftwareRenderer* renderer); +struct SoftwareRenderer { + struct GBAVideoSoftwareRenderer d; + struct GBASDLAudio audio; + struct GBASDLEvents events; +}; + +static int _GBASDLInit(struct SoftwareRenderer* renderer); +static void _GBASDLDeinit(struct SoftwareRenderer* renderer); +static void _GBASDLRunloop(struct GBAThread* context); +static void _GBASDLStart(struct GBAThread* context); +static void _GBASDLClean(struct GBAThread* context); int main(int argc, char** argv) { const char* fname = "test.rom";

@@ -27,72 +36,94 @@ return 1;

} struct GBAThread context; - struct GBAVideoSoftwareRenderer renderer; + struct SoftwareRenderer renderer; + GBAVideoSoftwareRendererCreate(&renderer.d); - if (!_GBASDLInit()) { + if (!_GBASDLInit(&renderer)) { return 1; } - GBAVideoSoftwareRendererCreate(&renderer); + + context.fd = fd; + context.fname = fname; + context.useDebugger = 1; + 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; + SDL_Surface* surface = SDL_GetVideoSurface(); SDL_LockSurface(surface); - renderer.outputBuffer = surface->pixels; - renderer.outputBufferStride = surface->pitch / 4; + renderer.d.outputBuffer = surface->pixels; +#ifdef COLOR_16_BIT + renderer.d.outputBufferStride = surface->pitch / 2; +#else + renderer.d.outputBufferStride = surface->pitch / 4; +#endif - context.fd = fd; - context.renderer = &renderer.d; GBAThreadStart(&context); - _GBASDLRunloop(&context, &renderer); + _GBASDLRunloop(&context); SDL_UnlockSurface(surface); GBAThreadJoin(&context); close(fd); - _GBASDLDeinit(); + _GBASDLDeinit(&renderer); return 0; } -static int _GBASDLInit() { +static int _GBASDLInit(struct SoftwareRenderer* renderer) { if (SDL_Init(SDL_INIT_VIDEO) < 0) { return 0; } - GBASDLInitEvents(); + GBASDLInitEvents(&renderer->events); +// GBASDLInitAudio(&renderer->audio); +#ifdef COLOR_16_BIT + SDL_SetVideoMode(240, 160, 16, SDL_DOUBLEBUF | SDL_HWSURFACE); +#else SDL_SetVideoMode(240, 160, 32, SDL_DOUBLEBUF | SDL_HWSURFACE); +#endif return 1; } -static void _GBASDLRunloop(struct GBAThread* context, struct GBAVideoSoftwareRenderer* renderer) { +static void _GBASDLRunloop(struct GBAThread* context) { SDL_Event event; SDL_Surface* surface = SDL_GetVideoSurface(); - while (context->started && context->debugger->state != DEBUGGER_EXITING) { - pthread_mutex_lock(&renderer->mutex); - if (renderer->d.framesPending) { - renderer->d.framesPending = 0; - pthread_mutex_unlock(&renderer->mutex); + while (context->started && (!context->debugger || context->debugger->state != DEBUGGER_EXITING)) { + GBASyncWaitFrameStart(&context->sync, context->frameskip); + SDL_UnlockSurface(surface); + SDL_Flip(surface); + SDL_LockSurface(surface); - SDL_UnlockSurface(surface); - SDL_Flip(surface); - SDL_LockSurface(surface); - - while (SDL_PollEvent(&event)) { - GBASDLHandleEvent(context, &event); - } - pthread_mutex_lock(&renderer->mutex); - pthread_cond_broadcast(&renderer->downCond); - } else { - pthread_cond_broadcast(&renderer->downCond); - pthread_cond_wait(&renderer->upCond, &renderer->mutex); + while (SDL_PollEvent(&event)) { + GBASDLHandleEvent(context, &event); } - pthread_mutex_unlock(&renderer->mutex); + GBASyncWaitFrameEnd(&context->sync); } } -static void _GBASDLDeinit() { - GBASDLDeinitEvents(); +static void _GBASDLDeinit(struct SoftwareRenderer* renderer) { + free(renderer->d.outputBuffer); + + GBASDLDeinitEvents(&renderer->events); + GBASDLDeinitAudio(&renderer->audio); SDL_Quit(); } + +static void _GBASDLStart(struct GBAThread* threadContext) { + struct SoftwareRenderer* renderer = threadContext->userData; + renderer->audio.audio = &threadContext->gba->audio; +} + +static void _GBASDLClean(struct GBAThread* threadContext) { + struct SoftwareRenderer* renderer = threadContext->userData; + renderer->audio.audio = 0; +}