Skip to content

Commit

Permalink
BACKENDS: Add SDL3 backend + imgui
Browse files Browse the repository at this point in the history
  • Loading branch information
scemino committed Dec 17, 2024
1 parent e0de34e commit d0f76eb
Show file tree
Hide file tree
Showing 24 changed files with 2,539 additions and 121 deletions.
484 changes: 451 additions & 33 deletions backends/events/sdl/sdl-events.cpp

Large diffs are not rendered by default.

11 changes: 8 additions & 3 deletions backends/events/sdl/sdl-events.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,10 @@ class SdlEventSource : public Common::EventSource {
/** Joystick */
SDL_Joystick *_joystick;

#if SDL_VERSION_ATLEAST(2, 0, 0)
#if SDL_VERSION_ATLEAST(3, 0, 0)
/** Game controller */
SDL_Gamepad *_controller;
#elif SDL_VERSION_ATLEAST(2, 0, 0)
/** Game controller */
SDL_GameController *_controller;
#endif
Expand Down Expand Up @@ -186,15 +189,17 @@ class SdlEventSource : public Common::EventSource {
bool handleResizeEvent(Common::Event &event, int w, int h);

/**
* Extracts unicode information for the specific key sym.
* Extracts unicode information for the specific key.
* May only be used for key down events.
*/
uint32 obtainUnicode(const SDL_Keysym keySym);
uint32 obtainUnicode(const SDL_KeyboardEvent &key);

#if !SDL_VERSION_ATLEAST(3, 0, 0)
/**
* Extracts the keycode for the specified key sym.
*/
SDL_Keycode obtainKeycode(const SDL_Keysym keySym);
#endif

/**
* Whether _fakeMouseMove contains an event we need to send.
Expand Down
37 changes: 32 additions & 5 deletions backends/graphics/openglsdl/openglsdl-graphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@
#include "common/translation.h"
#endif

#if SDL_VERSION_ATLEAST(3, 0, 0)
void sdlGLDestroyContext(SDL_GLContext context) {
SDL_GL_DestroyContext(context);
}
#elif SDL_VERSION_ATLEAST(2, 0, 0)
void sdlGLDestroyContext(SDL_GLContext context) {
SDL_GL_DeleteContext(context);
}
#endif

OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(SdlEventSource *eventSource, SdlWindow *window)
: SdlGraphicsManager(eventSource, window), _lastRequestedHeight(0),
#if SDL_VERSION_ATLEAST(2, 0, 0)
Expand Down Expand Up @@ -201,7 +211,7 @@ OpenGLSdlGraphicsManager::~OpenGLSdlGraphicsManager() {
#endif

notifyContextDestroy();
SDL_GL_DeleteContext(_glContext);
sdlGLDestroyContext(_glContext);
#else
if (_hwScreen) {
notifyContextDestroy();
Expand Down Expand Up @@ -255,7 +265,14 @@ void OpenGLSdlGraphicsManager::setFeatureState(OSystem::Feature f, bool enable)
bool OpenGLSdlGraphicsManager::getFeatureState(OSystem::Feature f) const {
switch (f) {
case OSystem::kFeatureFullscreenMode:
#if SDL_VERSION_ATLEAST(2, 0, 0)
#if SDL_VERSION_ATLEAST(3, 0, 0)
if (_window && _window->getSDLWindow()) {
// SDL_GetWindowFullscreenMode returns a pointer to the exclusive fullscreen mode to use or NULL for borderless
return ((SDL_GetWindowFlags(_window->getSDLWindow()) & SDL_WINDOW_FULLSCREEN) != 0) && (SDL_GetWindowFullscreenMode(_window->getSDLWindow()) == NULL);
} else {
return _wantsFullScreen;
}
#elif SDL_VERSION_ATLEAST(2, 0, 0)
if (_window && _window->getSDLWindow()) {
return (SDL_GetWindowFlags(_window->getSDLWindow()) & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0;
} else {
Expand Down Expand Up @@ -574,11 +591,15 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
destroyImGui();
#endif

SDL_GL_DeleteContext(_glContext);
sdlGLDestroyContext(_glContext);
_glContext = nullptr;
}

#if SDL_VERSION_ATLEAST(3, 0, 0)
uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY;
#else
uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI;
#endif

if (_wantsFullScreen) {
// On Linux/X11, when toggling to fullscreen, the window manager saves
Expand All @@ -596,7 +617,13 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
width = _desiredFullscreenWidth;
height = _desiredFullscreenHeight;

#if SDL_VERSION_ATLEAST(3, 0, 0)
flags |= SDL_WINDOW_FULLSCREEN;
SDL_SetWindowFullscreenMode(_window->getSDLWindow(), NULL);
SDL_SyncWindow(_window->getSDLWindow());
#else
flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
#endif
}

if (!_wantsFullScreen && ConfMan.getBool("window_maximized", Common::ConfigManager::kApplicationDomain)) {
Expand All @@ -608,7 +635,7 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, _glContextMajor);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, _glContextMinor);

#ifdef NINTENDO_SWITCH
#if defined(NINTENDO_SWITCH) && !SDL_VERSION_ATLEAST(3, 0, 0)
// Switch quirk: Switch seems to need this flag, otherwise the screen
// is zoomed when switching from Normal graphics mode to OpenGL
flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
Expand All @@ -627,7 +654,7 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
initImGui(nullptr, _glContext);
#endif

if (SDL_GL_SetSwapInterval(_vsync ? 1 : 0)) {
if (!SDL_GL_SetSwapInterval(_vsync ? 1 : 0)) {
warning("Unable to %s VSync: %s", _vsync ? "enable" : "disable", SDL_GetError());
}

Expand Down
104 changes: 94 additions & 10 deletions backends/graphics/sdl/sdl-graphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,15 @@
#include "backends/platform/sdl/emscripten/emscripten.h"
#endif

#if defined(USE_IMGUI) && SDL_VERSION_ATLEAST(2, 0, 0)
#if defined(USE_IMGUI) && SDL_VERSION_ATLEAST(3, 0, 0)
#include "backends/imgui/backends/imgui_impl_sdl3.h"
#ifdef USE_OPENGL
#include "backends/imgui/backends/imgui_impl_opengl3.h"
#endif
#ifdef USE_IMGUI_SDLRENDERER3
#include "backends/imgui/backends/imgui_impl_sdlrenderer3.h"
#endif
#elif defined(USE_IMGUI) && SDL_VERSION_ATLEAST(2, 0, 0)
#include "backends/imgui/backends/imgui_impl_sdl2.h"
#ifdef USE_OPENGL
#include "backends/imgui/backends/imgui_impl_opengl3.h"
Expand All @@ -48,6 +56,18 @@
#endif
#endif


void getMouseState(int *x, int *y) {
#if SDL_VERSION_ATLEAST(3, 0, 0)
float fx, fy;
SDL_GetMouseState(&fx, &fy);
*x = static_cast<int>(fx);
*y = static_cast<int>(fy);
#else
SDL_GetMouseState(x, y);
#endif
}

SdlGraphicsManager::SdlGraphicsManager(SdlEventSource *source, SdlWindow *window)
: _eventSource(source), _window(window), _hwScreen(nullptr)
#if SDL_VERSION_ATLEAST(2, 0, 0)
Expand All @@ -56,7 +76,7 @@ SdlGraphicsManager::SdlGraphicsManager(SdlEventSource *source, SdlWindow *window
{
ConfMan.registerDefault("fullscreen_res", "desktop");

SDL_GetMouseState(&_cursorX, &_cursorY);
getMouseState(&_cursorX, &_cursorY);
}

void SdlGraphicsManager::activateManager() {
Expand Down Expand Up @@ -220,7 +240,7 @@ bool SdlGraphicsManager::showMouse(bool visible) {
// area, so we need to ask SDL where the system's mouse cursor is
// instead
int x, y;
SDL_GetMouseState(&x, &y);
getMouseState(&x, &y);
if (!_activeArea.drawRect.contains(Common::Point(x, y))) {
showCursor = true;
}
Expand Down Expand Up @@ -312,7 +332,15 @@ bool SdlGraphicsManager::notifyMousePosition(Common::Point &mouse) {
}

void SdlGraphicsManager::showSystemMouseCursor(bool visible) {
#if SDL_VERSION_ATLEAST(3, 0, 0)
if(visible) {
SDL_ShowCursor();
} else {
SDL_HideCursor();
}
#else
SDL_ShowCursor(visible ? SDL_ENABLE : SDL_DISABLE);
#endif
}

void SdlGraphicsManager::setSystemMousePosition(const int x, const int y) {
Expand Down Expand Up @@ -354,7 +382,11 @@ bool SdlGraphicsManager::createOrUpdateWindow(int width, int height, const Uint3
// resized the game window), or when the launcher is visible (since a user
// may change the scaler, which should reset the window size)
if (!_window->getSDLWindow() || _lastFlags != flags || _overlayVisible || _allowWindowSizeReset) {
#if SDL_VERSION_ATLEAST(3, 0, 0)
const bool fullscreen = (flags & (SDL_WINDOW_FULLSCREEN)) != 0;
#else
const bool fullscreen = (flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_FULLSCREEN_DESKTOP)) != 0;
#endif
const bool maximized = (flags & SDL_WINDOW_MAXIMIZED);
if (!fullscreen && !maximized) {
if (_hintedWidth > width) {
Expand All @@ -368,6 +400,14 @@ bool SdlGraphicsManager::createOrUpdateWindow(int width, int height, const Uint3
if (!_window->createOrUpdateWindow(width, height, flags)) {
return false;
}
#if SDL_VERSION_ATLEAST(3, 0, 0)
if(fullscreen) {
if(!SDL_SetWindowFullscreenMode(_window->getSDLWindow(), NULL))
return false;
if(!SDL_SyncWindow(_window->getSDLWindow()))
return false;
}
#endif

_lastFlags = flags;
_allowWindowSizeReset = false;
Expand Down Expand Up @@ -594,21 +634,45 @@ void SdlGraphicsManager::initImGui(SDL_Renderer *renderer, void *glContext) {
if (!_imGuiReady && glContext) {
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows

#if SDL_VERSION_ATLEAST(3, 0, 0)
if (!ImGui_ImplSDL3_InitForOpenGL(_window->getSDLWindow(), glContext)) {
#else
if (!ImGui_ImplSDL2_InitForOpenGL(_window->getSDLWindow(), glContext)) {
#endif
ImGui::DestroyContext();
return;
}

if (!ImGui_ImplOpenGL3_Init("#version 110")) {
#if SDL_VERSION_ATLEAST(3, 0, 0)
ImGui_ImplSDL3_Shutdown();
#else
ImGui_ImplSDL2_Shutdown();
#endif
ImGui::DestroyContext();
return;
}

_imGuiReady = true;
}
#endif
#ifdef USE_IMGUI_SDLRENDERER2
#ifdef USE_IMGUI_SDLRENDERER3
if (!_imGuiReady && renderer) {
if (!ImGui_ImplSDL3_InitForSDLRenderer(_window->getSDLWindow(), renderer)) {
ImGui::DestroyContext();
return;
}

if (!ImGui_ImplSDLRenderer3_Init(renderer)) {
ImGui_ImplSDL3_Shutdown();
ImGui::DestroyContext();
return;
}

_imGuiReady = true;
_imGuiSDLRenderer = renderer;
}
#elif defined(USE_IMGUI_SDLRENDERER2)
if (!_imGuiReady && renderer) {
if (!ImGui_ImplSDL2_InitForSDLRenderer(_window->getSDLWindow(), renderer)) {
ImGui::DestroyContext();
Expand Down Expand Up @@ -649,23 +713,35 @@ void SdlGraphicsManager::renderImGui() {
_imGuiInited = true;
}

#ifdef USE_IMGUI_SDLRENDERER2
#ifdef USE_IMGUI_SDLRENDERER3
if (_imGuiSDLRenderer) {
ImGui_ImplSDLRenderer3_NewFrame();
} else {
#elif defined(USE_IMGUI_SDLRENDERER2)
if (_imGuiSDLRenderer) {
ImGui_ImplSDLRenderer2_NewFrame();
} else {
#endif
#ifdef USE_OPENGL
ImGui_ImplOpenGL3_NewFrame();
#endif
#ifdef USE_IMGUI_SDLRENDERER2
#if defined(USE_IMGUI_SDLRENDERER2) || defined(USE_IMGUI_SDLRENDERER3)
}
#endif
#if SDL_VERSION_ATLEAST(3, 0, 0)
ImGui_ImplSDL3_NewFrame();
#else
ImGui_ImplSDL2_NewFrame();
#endif

ImGui::NewFrame();
_imGuiCallbacks.render();
ImGui::Render();
#ifdef USE_IMGUI_SDLRENDERER2
#ifdef USE_IMGUI_SDLRENDERER3
if (_imGuiSDLRenderer) {
ImGui_ImplSDLRenderer3_RenderDrawData(ImGui::GetDrawData(), _imGuiSDLRenderer);
} else {
#elif defined(USE_IMGUI_SDLRENDERER2)
if (_imGuiSDLRenderer) {
ImGui_ImplSDLRenderer2_RenderDrawData(ImGui::GetDrawData(), _imGuiSDLRenderer);
} else {
Expand All @@ -679,7 +755,7 @@ void SdlGraphicsManager::renderImGui() {
ImGui::RenderPlatformWindowsDefault();
SDL_GL_MakeCurrent(backup_current_window, backup_current_context);
#endif
#ifdef USE_IMGUI_SDLRENDERER2
#if defined(USE_IMGUI_SDLRENDERER2) || defined(USE_IMGUI_SDLRENDERER3)
}
#endif
}
Expand All @@ -696,18 +772,26 @@ void SdlGraphicsManager::destroyImGui() {
_imGuiInited = false;
_imGuiReady = false;

#ifdef USE_IMGUI_SDLRENDERER2
#ifdef USE_IMGUI_SDLRENDERER3
if (_imGuiSDLRenderer) {
ImGui_ImplSDLRenderer3_Shutdown();
} else {
#elif defined(USE_IMGUI_SDLRENDERER2)
if (_imGuiSDLRenderer) {
ImGui_ImplSDLRenderer2_Shutdown();
} else {
#endif
#ifdef USE_OPENGL
ImGui_ImplOpenGL3_Shutdown();
#endif
#ifdef USE_IMGUI_SDLRENDERER2
#if defined(USE_IMGUI_SDLRENDERER2) || defined(USE_IMGUI_SDLRENDERER3)
}
#endif
#if SDL_VERSION_ATLEAST(3, 0, 0)
ImGui_ImplSDL3_Shutdown();
#else
ImGui_ImplSDL2_Shutdown();
#endif
ImGui::DestroyContext();
}
#endif
5 changes: 4 additions & 1 deletion backends/graphics/sdl/sdl-graphics.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,10 @@ class SdlGraphicsManager : virtual public WindowedGraphicsManager, public Common
* values stored by the graphics manager.
*/
void getWindowSizeFromSdl(int *width, int *height) const {
#if SDL_VERSION_ATLEAST(2, 0, 0)
#if SDL_VERSION_ATLEAST(3, 0, 0)
assert(_window);
SDL_GetWindowSizeInPixels(_window->getSDLWindow(), width, height);
#elif SDL_VERSION_ATLEAST(2, 0, 0)
assert(_window);
SDL_GL_GetDrawableSize(_window->getSDLWindow(), width, height);
#else
Expand Down
Loading

0 comments on commit d0f76eb

Please sign in to comment.