diff --git a/src/sdl-main.c b/src/sdl-main.c index 323337196..9bb140190 100644 --- a/src/sdl-main.c +++ b/src/sdl-main.c @@ -2,6 +2,7 @@ #include "gba-thread.h" #include "gba.h" #include "renderers/video-software.h" +#include "sdl-audio.h" #include "sdl-events.h" #include @@ -12,9 +13,17 @@ #include #include -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 @@ int main(int argc, char** argv) { } struct GBAThread context; - struct GBAVideoSoftwareRenderer renderer; + struct SoftwareRenderer renderer; + GBAVideoSoftwareRendererCreate(&renderer.d); - if (!_GBASDLInit()) { + if (!_GBASDLInit(&renderer)) { return 1; } - GBAVideoSoftwareRendererCreate(&renderer); - SDL_Surface* surface = SDL_GetVideoSurface(); - SDL_LockSurface(surface); - renderer.outputBuffer = surface->pixels; - renderer.outputBufferStride = surface->pitch / 4; context.fd = fd; - context.renderer = &renderer.d; + 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.d.outputBuffer = surface->pixels; +#ifdef COLOR_16_BIT + renderer.d.outputBufferStride = surface->pitch / 2; +#else + renderer.d.outputBufferStride = surface->pitch / 4; +#endif + 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; +}