diff --git a/CHANGES b/CHANGES index 5d2105968..730cc6804 100644 --- a/CHANGES +++ b/CHANGES @@ -113,6 +113,7 @@ Misc: - Qt: Window title updates can be disabled (closes mgba.io/i/1912) - Qt: Redo OpenGL context thread handling (fixes mgba.io/i/1724) - Qt: Discard additional frame draws if waiting fails + - SDL: Fall back to sw blit if OpenGL init fails - Util: Reset vector size on deinit - VFS: Change semantics of VFile.sync on mapped files (fixes mgba.io/i/1730) diff --git a/src/platform/sdl/CMakeLists.txt b/src/platform/sdl/CMakeLists.txt index b79e91142..9dcf74704 100644 --- a/src/platform/sdl/CMakeLists.txt +++ b/src/platform/sdl/CMakeLists.txt @@ -94,12 +94,10 @@ else() list(APPEND PLATFORM_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/gl-common.c) include_directories(${OPENGLES2_INCLUDE_DIR}) endif() - if(NOT BUILD_GL AND NOT BUILD_GLES2) - if(SDL_VERSION EQUAL "2") - list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/sw-sdl2.c) - else() - list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/sw-sdl1.c) - endif() + if(SDL_VERSION EQUAL "2") + list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/sw-sdl2.c) + else() + list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/sw-sdl1.c) endif() endif() diff --git a/src/platform/sdl/gl-common.c b/src/platform/sdl/gl-common.c index d9c62c9a5..37a041828 100644 --- a/src/platform/sdl/gl-common.c +++ b/src/platform/sdl/gl-common.c @@ -24,7 +24,7 @@ void mSDLGLCommonSwap(struct VideoBackend* context) { #endif } -void mSDLGLCommonInit(struct mSDLRenderer* renderer) { +bool mSDLGLCommonInit(struct mSDLRenderer* renderer) { #ifndef COLOR_16_BIT SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); @@ -41,7 +41,11 @@ void mSDLGLCommonInit(struct mSDLRenderer* renderer) { #if SDL_VERSION_ATLEAST(2, 0, 0) renderer->window = SDL_CreateWindow(projectName, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, renderer->viewportWidth, renderer->viewportHeight, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | (SDL_WINDOW_FULLSCREEN_DESKTOP * renderer->player.fullscreen)); - renderer->glCtx = SDL_GL_CreateContext(renderer->window); + renderer->glCtx = NULL;//SDL_GL_CreateContext(renderer->window); + if (!renderer->glCtx) { + SDL_DestroyWindow(renderer->window); + return false; + } SDL_GL_SetSwapInterval(1); SDL_GetWindowSize(renderer->window, &renderer->viewportWidth, &renderer->viewportHeight); renderer->player.window = renderer->window; @@ -51,10 +55,14 @@ void mSDLGLCommonInit(struct mSDLRenderer* renderer) { #else SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1); #ifdef COLOR_16_BIT - SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 16, SDL_OPENGL | SDL_RESIZABLE | (SDL_FULLSCREEN * renderer->player.fullscreen)); + SDL_Surface* surface = SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 16, SDL_OPENGL | SDL_RESIZABLE | (SDL_FULLSCREEN * renderer->player.fullscreen)); #else - SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 32, SDL_OPENGL | SDL_RESIZABLE | (SDL_FULLSCREEN * renderer->player.fullscreen)); + SDL_Surface* surface = SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 32, SDL_OPENGL | SDL_RESIZABLE | (SDL_FULLSCREEN * renderer->player.fullscreen)); #endif + if (!surface) { + return false; + } SDL_WM_SetCaption(projectName, ""); #endif + return true; } diff --git a/src/platform/sdl/gl-common.h b/src/platform/sdl/gl-common.h index 307da756f..be98d7964 100644 --- a/src/platform/sdl/gl-common.h +++ b/src/platform/sdl/gl-common.h @@ -10,11 +10,11 @@ CXX_GUARD_START -#include "main.h" - +struct VideoBackend; +struct mSDLRenderer; void mSDLGLDoViewport(int w, int h, struct VideoBackend* v); void mSDLGLCommonSwap(struct VideoBackend* context); -void mSDLGLCommonInit(struct mSDLRenderer* renderer); +bool mSDLGLCommonInit(struct mSDLRenderer* renderer); CXX_GUARD_END diff --git a/src/platform/sdl/gl-sdl.c b/src/platform/sdl/gl-sdl.c index 539ef88d0..6c1508d33 100644 --- a/src/platform/sdl/gl-sdl.c +++ b/src/platform/sdl/gl-sdl.c @@ -24,8 +24,6 @@ void mSDLGLCreate(struct mSDLRenderer* renderer) { } bool mSDLGLInit(struct mSDLRenderer* renderer) { - mSDLGLCommonInit(renderer); - size_t size = renderer->width * renderer->height * BYTES_PER_PIXEL; renderer->outputBuffer = malloc(size); memset(renderer->outputBuffer, 0, size); diff --git a/src/platform/sdl/gles2-sdl.c b/src/platform/sdl/gles2-sdl.c index 1cedc5ad5..7237b6273 100644 --- a/src/platform/sdl/gles2-sdl.c +++ b/src/platform/sdl/gles2-sdl.c @@ -28,12 +28,6 @@ void mSDLGLES2Create(struct mSDLRenderer* renderer) { } bool mSDLGLES2Init(struct mSDLRenderer* renderer) { -#ifdef BUILD_RASPI - mRPIGLCommonInit(renderer); -#else - mSDLGLCommonInit(renderer); -#endif - size_t size = renderer->width * renderer->height * BYTES_PER_PIXEL; #ifdef _WIN32 renderer->outputBuffer = _aligned_malloc(size, 16); diff --git a/src/platform/sdl/main.c b/src/platform/sdl/main.c index 2b2704a9c..fdf88703e 100644 --- a/src/platform/sdl/main.c +++ b/src/platform/sdl/main.c @@ -39,7 +39,6 @@ #define PORT "sdl" -static bool mSDLInit(struct mSDLRenderer* renderer); static void mSDLDeinit(struct mSDLRenderer* renderer); static int mSDLRun(struct mSDLRenderer* renderer, struct mArguments* args); @@ -84,6 +83,12 @@ int main(int argc, char** argv) { return 0; } + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + printf("Could not initialize video: %s\n", SDL_GetError()); + freeArguments(&args); + return 1; + } + renderer.core = mCoreFind(args.fname); if (!renderer.core) { printf("Could not run game. Are you sure the file exists and is a compatible game?\n"); @@ -97,14 +102,6 @@ int main(int argc, char** argv) { } renderer.core->desiredVideoDimensions(renderer.core, &renderer.width, &renderer.height); -#ifdef BUILD_GL - mSDLGLCreate(&renderer); -#elif defined(BUILD_GLES2) || defined(USE_EPOXY) - mSDLGLES2Create(&renderer); -#else - mSDLSWCreate(&renderer); -#endif - renderer.ratio = graphicsOpts.multiplier; if (renderer.ratio == 0) { renderer.ratio = 1; @@ -139,7 +136,25 @@ int main(int argc, char** argv) { renderer.interframeBlending = renderer.core->opts.interframeBlending; renderer.filter = renderer.core->opts.resampleVideo; - if (!mSDLInit(&renderer)) { +#ifdef BUILD_GL + if (mSDLGLCommonInit(&renderer)) { + mSDLGLCreate(&renderer); + } else +#elif defined(BUILD_GLES2) || defined(USE_EPOXY) +#ifdef BUILD_RASPI + mRPIGLCommonInit(&renderer); +#else + if (mSDLGLCommonInit(&renderer)) +#endif + { + mSDLGLES2Create(&renderer); + } else +#endif + { + mSDLSWCreate(&renderer); + } + + if (!renderer.init(&renderer)) { freeArguments(&args); mCoreConfigDeinit(&renderer.core->config); renderer.core->deinit(renderer.core); @@ -295,15 +310,6 @@ int mSDLRun(struct mSDLRenderer* renderer, struct mArguments* args) { return didFail; } -static bool mSDLInit(struct mSDLRenderer* renderer) { - if (SDL_Init(SDL_INIT_VIDEO) < 0) { - printf("Could not initialize video: %s\n", SDL_GetError()); - return false; - } - - return renderer->init(renderer); -} - static void mSDLDeinit(struct mSDLRenderer* renderer) { mSDLDeinitEvents(&renderer->events); mSDLDeinitAudio(&renderer->audio); diff --git a/src/platform/sdl/main.h b/src/platform/sdl/main.h index d6148babf..5f52f5e19 100644 --- a/src/platform/sdl/main.h +++ b/src/platform/sdl/main.h @@ -14,6 +14,7 @@ CXX_GUARD_START #include "sdl-events.h" #ifdef BUILD_GL +#include "gl-common.h" #include "platform/opengl/gl.h" #endif @@ -29,6 +30,7 @@ CXX_GUARD_START #endif #if defined(BUILD_GLES2) || defined(USE_EPOXY) +#include "gl-common.h" #include "platform/opengl/gles2.h" #endif