SDL: Allow runtime switching of rendering backend

This commit is contained in:
Jeffrey Pfau 2015-03-31 21:41:53 -07:00
parent 2eb765eacc
commit bed6a0c130
5 changed files with 64 additions and 35 deletions

View File

@ -55,13 +55,14 @@ endif()
if(BUILD_PANDORA)
list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/pandora-sdl.c)
elseif(BUILD_BBB OR BUILD_RASPI OR NOT BUILD_GL)
list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/sw-sdl.c)
else()
list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/gl-sdl.c)
add_definitions(-DBUILD_GL)
find_package(OpenGL REQUIRED)
include_directories(${OPENGL_INCLUDE_DIR})
list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/sw-sdl.c)
if(BUILD_GL)
list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/gl-sdl.c)
add_definitions(-DBUILD_GL)
find_package(OpenGL REQUIRED)
include_directories(${OPENGL_INCLUDE_DIR})
endif()
endif()
add_executable(${BINARY_NAME}-sdl WIN32 ${PLATFORM_SRC} ${MAIN_SRC})

View File

@ -49,7 +49,17 @@ static void _doViewport(int w, int h, struct SDLSoftwareRenderer* renderer) {
glClear(GL_COLOR_BUFFER_BIT);
}
bool GBASDLInit(struct SDLSoftwareRenderer* renderer) {
static bool GBASDLGLInit(struct SDLSoftwareRenderer* renderer);
static void GBASDLGLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer);
static void GBASDLGLDeinit(struct SDLSoftwareRenderer* renderer);
void GBASDLGLCreate(struct SDLSoftwareRenderer* renderer) {
renderer->init = GBASDLGLInit;
renderer->deinit = GBASDLGLDeinit;
renderer->runloop = GBASDLGLRunloop;
}
bool GBASDLGLInit(struct SDLSoftwareRenderer* renderer) {
#ifndef COLOR_16_BIT
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
@ -110,7 +120,7 @@ bool GBASDLInit(struct SDLSoftwareRenderer* renderer) {
return true;
}
void GBASDLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer) {
void GBASDLGLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer) {
SDL_Event event;
glEnable(GL_TEXTURE_2D);
@ -159,6 +169,6 @@ void GBASDLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* render
}
}
void GBASDLDeinit(struct SDLSoftwareRenderer* renderer) {
void GBASDLGLDeinit(struct SDLSoftwareRenderer* renderer) {
free(renderer->d.outputBuffer);
}

View File

@ -28,8 +28,8 @@
#define PORT "sdl"
static bool _GBASDLInit(struct SDLSoftwareRenderer* renderer);
static void _GBASDLDeinit(struct SDLSoftwareRenderer* renderer);
static bool GBASDLInit(struct SDLSoftwareRenderer* renderer);
static void GBASDLDeinit(struct SDLSoftwareRenderer* renderer);
int main(int argc, char** argv) {
struct SDLSoftwareRenderer renderer;
@ -83,7 +83,13 @@ int main(int argc, char** argv) {
renderer.lockAspectRatio = opts.lockAspectRatio;
renderer.filter = opts.resampleVideo;
if (!_GBASDLInit(&renderer)) {
#ifdef BUILD_GL
GBASDLGLCreate(&renderer);
#else
GBASDLSWCreate(&renderer);
#endif
if (!GBASDLInit(&renderer)) {
freeArguments(&args);
GBAConfigFreeOpts(&opts);
GBAConfigDeinit(&config);
@ -113,7 +119,7 @@ int main(int argc, char** argv) {
int didFail = 0;
if (GBAThreadStart(&context)) {
GBASDLRunloop(&context, &renderer);
renderer.runloop(&context, &renderer);
GBAThreadJoin(&context);
} else {
didFail = 1;
@ -130,28 +136,28 @@ int main(int argc, char** argv) {
free(context.debugger);
GBAInputMapDeinit(&inputMap);
_GBASDLDeinit(&renderer);
GBASDLDeinit(&renderer);
return didFail;
}
static bool _GBASDLInit(struct SDLSoftwareRenderer* renderer) {
static bool GBASDLInit(struct SDLSoftwareRenderer* renderer) {
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
printf("Could not initialize video: %s\n", SDL_GetError());
return false;
}
return GBASDLInit(renderer);
return renderer->init(renderer);
}
static void _GBASDLDeinit(struct SDLSoftwareRenderer* renderer) {
static void GBASDLDeinit(struct SDLSoftwareRenderer* renderer) {
GBASDLDeinitEvents(&renderer->events);
GBASDLDeinitAudio(&renderer->audio);
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_DestroyWindow(renderer->window);
#endif
GBASDLDeinit(renderer);
renderer->deinit(renderer);
SDL_Quit();

View File

@ -41,12 +41,14 @@ struct SDLSoftwareRenderer {
struct GBASDLEvents events;
struct GBASDLPlayer player;
bool (*init)(struct SDLSoftwareRenderer* renderer);
void (*runloop)(struct GBAThread* context, struct SDLSoftwareRenderer* renderer);
void (*deinit)(struct SDLSoftwareRenderer* renderer);
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_Window* window;
#ifndef BUILD_GL
SDL_Texture* tex;
SDL_Texture* sdlTex;
SDL_Renderer* sdlRenderer;
#endif
#endif
int viewportWidth;
@ -86,9 +88,9 @@ struct SDLSoftwareRenderer {
#endif
};
bool GBASDLInit(struct SDLSoftwareRenderer* renderer);
void GBASDLDeinit(struct SDLSoftwareRenderer* renderer);
void GBASDLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer);
void GBASDLSWCreate(struct SDLSoftwareRenderer* renderer);
#ifdef BUILD_GL
void GBASDLGLCreate(struct SDLSoftwareRenderer* renderer);
#endif
#endif

View File

@ -8,7 +8,17 @@
#include "gba/supervisor/thread.h"
#include "util/arm-algo.h"
bool GBASDLInit(struct SDLSoftwareRenderer* renderer) {
static bool GBASDLSWInit(struct SDLSoftwareRenderer* renderer);
static void GBASDLSWRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer);
static void GBASDLSWDeinit(struct SDLSoftwareRenderer* renderer);
void GBASDLSWCreate(struct SDLSoftwareRenderer* renderer) {
renderer->init = GBASDLSWInit;
renderer->deinit = GBASDLSWDeinit;
renderer->runloop = GBASDLSWRunloop;
}
bool GBASDLSWInit(struct SDLSoftwareRenderer* renderer) {
#if !SDL_VERSION_ATLEAST(2, 0, 0)
#ifdef COLOR_16_BIT
SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 16, SDL_DOUBLEBUF | SDL_HWSURFACE);
@ -24,15 +34,15 @@ bool GBASDLInit(struct SDLSoftwareRenderer* renderer) {
renderer->sdlRenderer = SDL_CreateRenderer(renderer->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
#ifdef COLOR_16_BIT
#ifdef COLOR_5_6_5
renderer->tex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS);
renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS);
#else
renderer->tex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_ABGR1555, SDL_TEXTUREACCESS_STREAMING, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS);
renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_ABGR1555, SDL_TEXTUREACCESS_STREAMING, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS);
#endif
#else
renderer->tex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS);
renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS);
#endif
SDL_LockTexture(renderer->tex, 0, (void**) &renderer->d.outputBuffer, &renderer->d.outputBufferStride);
SDL_LockTexture(renderer->sdlTex, 0, (void**) &renderer->d.outputBuffer, &renderer->d.outputBufferStride);
renderer->d.outputBufferStride /= BYTES_PER_PIXEL;
#else
SDL_Surface* surface = SDL_GetVideoSurface();
@ -72,7 +82,7 @@ bool GBASDLInit(struct SDLSoftwareRenderer* renderer) {
return true;
}
void GBASDLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer) {
void GBASDLSWRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer) {
SDL_Event event;
#if !SDL_VERSION_ATLEAST(2, 0, 0)
SDL_Surface* surface = SDL_GetVideoSurface();
@ -85,10 +95,10 @@ void GBASDLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* render
if (GBASyncWaitFrameStart(&context->sync, context->frameskip)) {
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_UnlockTexture(renderer->tex);
SDL_RenderCopy(renderer->sdlRenderer, renderer->tex, 0, 0);
SDL_UnlockTexture(renderer->sdlTex);
SDL_RenderCopy(renderer->sdlRenderer, renderer->sdlTex, 0, 0);
SDL_RenderPresent(renderer->sdlRenderer);
SDL_LockTexture(renderer->tex, 0, (void**) &renderer->d.outputBuffer, &renderer->d.outputBufferStride);
SDL_LockTexture(renderer->sdlTex, 0, (void**) &renderer->d.outputBuffer, &renderer->d.outputBufferStride);
renderer->d.outputBufferStride /= BYTES_PER_PIXEL;
#else
#ifdef USE_PIXMAN
@ -122,7 +132,7 @@ void GBASDLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* render
}
}
void GBASDLDeinit(struct SDLSoftwareRenderer* renderer) {
void GBASDLSWDeinit(struct SDLSoftwareRenderer* renderer) {
if (renderer->ratio > 1) {
free(renderer->d.outputBuffer);
}