Bring SDL main to parity with GL main

This commit is contained in:
Jeffrey Pfau 2013-10-12 02:13:26 -07:00
parent cf298474bc
commit 51ec1c1099
1 changed files with 67 additions and 36 deletions

View File

@ -2,6 +2,7 @@
#include "gba-thread.h" #include "gba-thread.h"
#include "gba.h" #include "gba.h"
#include "renderers/video-software.h" #include "renderers/video-software.h"
#include "sdl-audio.h"
#include "sdl-events.h" #include "sdl-events.h"
#include <SDL.h> #include <SDL.h>
@ -12,9 +13,17 @@
#include <sys/time.h> #include <sys/time.h>
#include <unistd.h> #include <unistd.h>
static int _GBASDLInit(void); struct SoftwareRenderer {
static void _GBASDLDeinit(void); struct GBAVideoSoftwareRenderer d;
static void _GBASDLRunloop(struct GBAThread* context, struct GBAVideoSoftwareRenderer* renderer); 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) { int main(int argc, char** argv) {
const char* fname = "test.rom"; const char* fname = "test.rom";
@ -27,54 +36,69 @@ int main(int argc, char** argv) {
} }
struct GBAThread context; struct GBAThread context;
struct GBAVideoSoftwareRenderer renderer; struct SoftwareRenderer renderer;
GBAVideoSoftwareRendererCreate(&renderer.d);
if (!_GBASDLInit()) { if (!_GBASDLInit(&renderer)) {
return 1; 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.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); GBAThreadStart(&context);
_GBASDLRunloop(&context, &renderer); _GBASDLRunloop(&context);
SDL_UnlockSurface(surface); SDL_UnlockSurface(surface);
GBAThreadJoin(&context); GBAThreadJoin(&context);
close(fd); close(fd);
_GBASDLDeinit(); _GBASDLDeinit(&renderer);
return 0; return 0;
} }
static int _GBASDLInit() { static int _GBASDLInit(struct SoftwareRenderer* renderer) {
if (SDL_Init(SDL_INIT_VIDEO) < 0) { if (SDL_Init(SDL_INIT_VIDEO) < 0) {
return 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); SDL_SetVideoMode(240, 160, 32, SDL_DOUBLEBUF | SDL_HWSURFACE);
#endif
return 1; return 1;
} }
static void _GBASDLRunloop(struct GBAThread* context, struct GBAVideoSoftwareRenderer* renderer) { static void _GBASDLRunloop(struct GBAThread* context) {
SDL_Event event; SDL_Event event;
SDL_Surface* surface = SDL_GetVideoSurface(); SDL_Surface* surface = SDL_GetVideoSurface();
while (context->started && context->debugger->state != DEBUGGER_EXITING) { while (context->started && (!context->debugger || context->debugger->state != DEBUGGER_EXITING)) {
pthread_mutex_lock(&renderer->mutex); GBASyncWaitFrameStart(&context->sync, context->frameskip);
if (renderer->d.framesPending) {
renderer->d.framesPending = 0;
pthread_mutex_unlock(&renderer->mutex);
SDL_UnlockSurface(surface); SDL_UnlockSurface(surface);
SDL_Flip(surface); SDL_Flip(surface);
SDL_LockSurface(surface); SDL_LockSurface(surface);
@ -82,17 +106,24 @@ static void _GBASDLRunloop(struct GBAThread* context, struct GBAVideoSoftwareRen
while (SDL_PollEvent(&event)) { while (SDL_PollEvent(&event)) {
GBASDLHandleEvent(context, &event); GBASDLHandleEvent(context, &event);
} }
pthread_mutex_lock(&renderer->mutex); GBASyncWaitFrameEnd(&context->sync);
pthread_cond_broadcast(&renderer->downCond);
} else {
pthread_cond_broadcast(&renderer->downCond);
pthread_cond_wait(&renderer->upCond, &renderer->mutex);
}
pthread_mutex_unlock(&renderer->mutex);
} }
} }
static void _GBASDLDeinit() { static void _GBASDLDeinit(struct SoftwareRenderer* renderer) {
GBASDLDeinitEvents(); free(renderer->d.outputBuffer);
GBASDLDeinitEvents(&renderer->events);
GBASDLDeinitAudio(&renderer->audio);
SDL_Quit(); 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;
}