diff --git a/src/openrct2/drawing/NewDrawing.cpp b/src/openrct2/drawing/NewDrawing.cpp index 93422d74e5..1b91c5dcca 100644 --- a/src/openrct2/drawing/NewDrawing.cpp +++ b/src/openrct2/drawing/NewDrawing.cpp @@ -49,24 +49,41 @@ extern "C" return _drawingEngineType; } + bool drawing_engine_requires_restart(sint32 srcEngine, sint32 dstEngine) + { + // Linux requires a restart. This could be improved in the future by recreating the window, + // https://github.com/OpenRCT2/OpenRCT2/issues/2015 + bool requiresRestart = true; +#ifdef __WINDOWS__ + if (dstEngine != DRAWING_ENGINE_OPENGL) + { + // Windows is apparently able to switch to hardware rendering on the fly although + // using the same window in an unaccelerated and accelerated context is unsupported by SDL2 + requiresRestart = false; + } +#endif + return requiresRestart; + } + void drawing_engine_init() { assert(_drawingEngine == nullptr); + IDrawingEngine * drawingEngine = nullptr; _drawingEngineType = gConfigGeneral.drawing_engine; switch (_drawingEngineType) { case DRAWING_ENGINE_SOFTWARE: - _drawingEngine = DrawingEngineFactory::CreateSoftware(); + drawingEngine = DrawingEngineFactory::CreateSoftware(); break; case DRAWING_ENGINE_SOFTWARE_WITH_HARDWARE_DISPLAY: - _drawingEngine = DrawingEngineFactory::CreateSoftwareWithHardwareDisplay(); + drawingEngine = DrawingEngineFactory::CreateSoftwareWithHardwareDisplay(); break; case DRAWING_ENGINE_OPENGL: - _drawingEngine = DrawingEngineFactory::CreateOpenGL(); + drawingEngine = DrawingEngineFactory::CreateOpenGL(); break; } - if (_drawingEngine == nullptr) + if (drawingEngine == nullptr) { if (_drawingEngineType == DRAWING_ENGINE_SOFTWARE) { @@ -88,13 +105,14 @@ extern "C" { try { - _drawingEngine->Initialise(gWindow); - _drawingEngine->SetUncappedFrameRate(gConfigGeneral.uncap_fps == 1); + drawingEngine->Initialise(gWindow); + drawingEngine->SetUncappedFrameRate(gConfigGeneral.uncap_fps == 1); + _drawingEngine = drawingEngine; } catch (const Exception &ex) { - delete _drawingEngine; - _drawingEngine = nullptr; + delete drawingEngine; + drawingEngine = nullptr; if (_drawingEngineType == DRAWING_ENGINE_SOFTWARE) { _drawingEngineType = DRAWING_ENGINE_NONE; @@ -127,12 +145,18 @@ extern "C" void drawing_engine_set_palette(SDL_Color * colours) { - _drawingEngine->SetPalette(colours); + if (_drawingEngine != nullptr) + { + _drawingEngine->SetPalette(colours); + } } void drawing_engine_draw() { - _drawingEngine->Draw(); + if (_drawingEngine != nullptr) + { + _drawingEngine->Draw(); + } } void drawing_engine_copy_rect(sint32 x, sint32 y, sint32 width, sint32 height, sint32 dx, sint32 dy) diff --git a/src/openrct2/drawing/NewDrawing.h b/src/openrct2/drawing/NewDrawing.h index 3ddc1bc335..9470026a1d 100644 --- a/src/openrct2/drawing/NewDrawing.h +++ b/src/openrct2/drawing/NewDrawing.h @@ -29,6 +29,7 @@ extern "C" extern rct_string_id DrawingEngineStringIds[3]; sint32 drawing_engine_get_type(); +bool drawing_engine_requires_restart(sint32 srcEngine, sint32 dstEngine); void drawing_engine_init(); void drawing_engine_resize(); void drawing_engine_set_palette(SDL_Color * colours); diff --git a/src/openrct2/platform/shared.c b/src/openrct2/platform/shared.c index 62c6fd1f88..3de9cc0ba0 100644 --- a/src/openrct2/platform/shared.c +++ b/src/openrct2/platform/shared.c @@ -581,8 +581,6 @@ void platform_init() static void platform_create_window() { - sint32 width, height; - if (SDL_Init(SDL_INIT_VIDEO) < 0) { log_fatal("SDL_Init %s", SDL_GetError()); exit(-1); @@ -597,16 +595,18 @@ static void platform_create_window() sub_68371D(); // Get window size - width = gConfigGeneral.window_width; - height = gConfigGeneral.window_height; + sint32 width = gConfigGeneral.window_width; + sint32 height = gConfigGeneral.window_height; if (width == -1) width = 640; if (height == -1) height = 480; // Create window in window first rather than fullscreen so we have the display the window is on first - gWindow = SDL_CreateWindow( - "OpenRCT2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL - ); + uint32 flags = SDL_WINDOW_RESIZABLE; + if (gConfigGeneral.drawing_engine == DRAWING_ENGINE_OPENGL) { + flags |= SDL_WINDOW_OPENGL; + } + gWindow = SDL_CreateWindow(OPENRCT2_NAME, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, flags); if (!gWindow) { log_fatal("SDL_CreateWindow failed %s", SDL_GetError()); exit(-1); diff --git a/src/openrct2/windows/options.c b/src/openrct2/windows/options.c index 61fa92989a..2aa8569374 100644 --- a/src/openrct2/windows/options.c +++ b/src/openrct2/windows/options.c @@ -1222,16 +1222,15 @@ static void window_options_dropdown(rct_window *w, sint32 widgetIndex, sint32 dr break; case WIDX_DRAWING_ENGINE_DROPDOWN: if (dropdownIndex != gConfigGeneral.drawing_engine) { - gConfigGeneral.drawing_engine = (uint8)dropdownIndex; -#ifdef __WINDOWS__ - // Windows is apparently able to switch to hardware rendering on the fly although - // using the same window in an unaccelerated and accelerated context is unsupported by SDL2 - platform_refresh_video(); -#else - // Linux requires a restart. This could be improved in the future by recreating the window, - // https://github.com/OpenRCT2/OpenRCT2/issues/2015 - window_error_open(STR_RESTART_REQUIRED, STR_NONE); -#endif + sint32 srcEngine = drawing_engine_get_type(); + sint32 dstEngine = dropdownIndex; + + gConfigGeneral.drawing_engine = (uint8)dstEngine; + if (drawing_engine_requires_restart(srcEngine, dstEngine)) { + window_error_open(STR_RESTART_REQUIRED, STR_NONE); + } else { + platform_refresh_video(); + } config_save_default(); window_invalidate(w); }