mirror of https://github.com/mgba-emu/mgba.git
SDL: Allow runtime switching of rendering backend
This commit is contained in:
parent
2eb765eacc
commit
bed6a0c130
|
@ -55,13 +55,14 @@ endif()
|
||||||
|
|
||||||
if(BUILD_PANDORA)
|
if(BUILD_PANDORA)
|
||||||
list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/pandora-sdl.c)
|
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()
|
else()
|
||||||
list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/gl-sdl.c)
|
list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/sw-sdl.c)
|
||||||
add_definitions(-DBUILD_GL)
|
if(BUILD_GL)
|
||||||
find_package(OpenGL REQUIRED)
|
list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/gl-sdl.c)
|
||||||
include_directories(${OPENGL_INCLUDE_DIR})
|
add_definitions(-DBUILD_GL)
|
||||||
|
find_package(OpenGL REQUIRED)
|
||||||
|
include_directories(${OPENGL_INCLUDE_DIR})
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_executable(${BINARY_NAME}-sdl WIN32 ${PLATFORM_SRC} ${MAIN_SRC})
|
add_executable(${BINARY_NAME}-sdl WIN32 ${PLATFORM_SRC} ${MAIN_SRC})
|
||||||
|
|
|
@ -49,7 +49,17 @@ static void _doViewport(int w, int h, struct SDLSoftwareRenderer* renderer) {
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
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
|
#ifndef COLOR_16_BIT
|
||||||
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
||||||
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
|
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
|
||||||
|
@ -110,7 +120,7 @@ bool GBASDLInit(struct SDLSoftwareRenderer* renderer) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GBASDLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer) {
|
void GBASDLGLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer) {
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
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);
|
free(renderer->d.outputBuffer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,8 +28,8 @@
|
||||||
|
|
||||||
#define PORT "sdl"
|
#define PORT "sdl"
|
||||||
|
|
||||||
static bool _GBASDLInit(struct SDLSoftwareRenderer* renderer);
|
static bool GBASDLInit(struct SDLSoftwareRenderer* renderer);
|
||||||
static void _GBASDLDeinit(struct SDLSoftwareRenderer* renderer);
|
static void GBASDLDeinit(struct SDLSoftwareRenderer* renderer);
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
struct SDLSoftwareRenderer renderer;
|
struct SDLSoftwareRenderer renderer;
|
||||||
|
@ -83,7 +83,13 @@ int main(int argc, char** argv) {
|
||||||
renderer.lockAspectRatio = opts.lockAspectRatio;
|
renderer.lockAspectRatio = opts.lockAspectRatio;
|
||||||
renderer.filter = opts.resampleVideo;
|
renderer.filter = opts.resampleVideo;
|
||||||
|
|
||||||
if (!_GBASDLInit(&renderer)) {
|
#ifdef BUILD_GL
|
||||||
|
GBASDLGLCreate(&renderer);
|
||||||
|
#else
|
||||||
|
GBASDLSWCreate(&renderer);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!GBASDLInit(&renderer)) {
|
||||||
freeArguments(&args);
|
freeArguments(&args);
|
||||||
GBAConfigFreeOpts(&opts);
|
GBAConfigFreeOpts(&opts);
|
||||||
GBAConfigDeinit(&config);
|
GBAConfigDeinit(&config);
|
||||||
|
@ -113,7 +119,7 @@ int main(int argc, char** argv) {
|
||||||
|
|
||||||
int didFail = 0;
|
int didFail = 0;
|
||||||
if (GBAThreadStart(&context)) {
|
if (GBAThreadStart(&context)) {
|
||||||
GBASDLRunloop(&context, &renderer);
|
renderer.runloop(&context, &renderer);
|
||||||
GBAThreadJoin(&context);
|
GBAThreadJoin(&context);
|
||||||
} else {
|
} else {
|
||||||
didFail = 1;
|
didFail = 1;
|
||||||
|
@ -130,28 +136,28 @@ int main(int argc, char** argv) {
|
||||||
free(context.debugger);
|
free(context.debugger);
|
||||||
GBAInputMapDeinit(&inputMap);
|
GBAInputMapDeinit(&inputMap);
|
||||||
|
|
||||||
_GBASDLDeinit(&renderer);
|
GBASDLDeinit(&renderer);
|
||||||
|
|
||||||
return didFail;
|
return didFail;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool _GBASDLInit(struct SDLSoftwareRenderer* renderer) {
|
static bool GBASDLInit(struct SDLSoftwareRenderer* renderer) {
|
||||||
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||||||
printf("Could not initialize video: %s\n", SDL_GetError());
|
printf("Could not initialize video: %s\n", SDL_GetError());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GBASDLInit(renderer);
|
return renderer->init(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _GBASDLDeinit(struct SDLSoftwareRenderer* renderer) {
|
static void GBASDLDeinit(struct SDLSoftwareRenderer* renderer) {
|
||||||
GBASDLDeinitEvents(&renderer->events);
|
GBASDLDeinitEvents(&renderer->events);
|
||||||
GBASDLDeinitAudio(&renderer->audio);
|
GBASDLDeinitAudio(&renderer->audio);
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||||
SDL_DestroyWindow(renderer->window);
|
SDL_DestroyWindow(renderer->window);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GBASDLDeinit(renderer);
|
renderer->deinit(renderer);
|
||||||
|
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
|
||||||
|
|
|
@ -41,12 +41,14 @@ struct SDLSoftwareRenderer {
|
||||||
struct GBASDLEvents events;
|
struct GBASDLEvents events;
|
||||||
struct GBASDLPlayer player;
|
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)
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||||
SDL_Window* window;
|
SDL_Window* window;
|
||||||
#ifndef BUILD_GL
|
SDL_Texture* sdlTex;
|
||||||
SDL_Texture* tex;
|
|
||||||
SDL_Renderer* sdlRenderer;
|
SDL_Renderer* sdlRenderer;
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int viewportWidth;
|
int viewportWidth;
|
||||||
|
@ -86,9 +88,9 @@ struct SDLSoftwareRenderer {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
bool GBASDLInit(struct SDLSoftwareRenderer* renderer);
|
void GBASDLSWCreate(struct SDLSoftwareRenderer* renderer);
|
||||||
void GBASDLDeinit(struct SDLSoftwareRenderer* renderer);
|
|
||||||
void GBASDLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer);
|
|
||||||
|
|
||||||
|
#ifdef BUILD_GL
|
||||||
|
void GBASDLGLCreate(struct SDLSoftwareRenderer* renderer);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,17 @@
|
||||||
#include "gba/supervisor/thread.h"
|
#include "gba/supervisor/thread.h"
|
||||||
#include "util/arm-algo.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)
|
#if !SDL_VERSION_ATLEAST(2, 0, 0)
|
||||||
#ifdef COLOR_16_BIT
|
#ifdef COLOR_16_BIT
|
||||||
SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 16, SDL_DOUBLEBUF | SDL_HWSURFACE);
|
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);
|
renderer->sdlRenderer = SDL_CreateRenderer(renderer->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
|
||||||
#ifdef COLOR_16_BIT
|
#ifdef COLOR_16_BIT
|
||||||
#ifdef COLOR_5_6_5
|
#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
|
#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
|
#endif
|
||||||
#else
|
#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
|
#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;
|
renderer->d.outputBufferStride /= BYTES_PER_PIXEL;
|
||||||
#else
|
#else
|
||||||
SDL_Surface* surface = SDL_GetVideoSurface();
|
SDL_Surface* surface = SDL_GetVideoSurface();
|
||||||
|
@ -72,7 +82,7 @@ bool GBASDLInit(struct SDLSoftwareRenderer* renderer) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GBASDLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer) {
|
void GBASDLSWRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer) {
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
#if !SDL_VERSION_ATLEAST(2, 0, 0)
|
#if !SDL_VERSION_ATLEAST(2, 0, 0)
|
||||||
SDL_Surface* surface = SDL_GetVideoSurface();
|
SDL_Surface* surface = SDL_GetVideoSurface();
|
||||||
|
@ -85,10 +95,10 @@ void GBASDLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* render
|
||||||
|
|
||||||
if (GBASyncWaitFrameStart(&context->sync, context->frameskip)) {
|
if (GBASyncWaitFrameStart(&context->sync, context->frameskip)) {
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||||
SDL_UnlockTexture(renderer->tex);
|
SDL_UnlockTexture(renderer->sdlTex);
|
||||||
SDL_RenderCopy(renderer->sdlRenderer, renderer->tex, 0, 0);
|
SDL_RenderCopy(renderer->sdlRenderer, renderer->sdlTex, 0, 0);
|
||||||
SDL_RenderPresent(renderer->sdlRenderer);
|
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;
|
renderer->d.outputBufferStride /= BYTES_PER_PIXEL;
|
||||||
#else
|
#else
|
||||||
#ifdef USE_PIXMAN
|
#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) {
|
if (renderer->ratio > 1) {
|
||||||
free(renderer->d.outputBuffer);
|
free(renderer->d.outputBuffer);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue