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.h"
#include "renderers/video-software.h"
#include "sdl-audio.h"
#include "sdl-events.h"
#include <SDL.h>
@ -12,9 +13,17 @@
#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 @@ 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;
}