diff --git a/CMake/Dependencies.cmake b/CMake/Dependencies.cmake index 02c56eef0..9a85ac773 100644 --- a/CMake/Dependencies.cmake +++ b/CMake/Dependencies.cmake @@ -66,7 +66,7 @@ elseif(USE_SDL1) elseif(USE_SDL3) dependency_options("SDL3" DEVILUTIONX_SYSTEM_SDL3 ON DEVILUTIONX_STATIC_SDL3) if(DEVILUTIONX_SYSTEM_SDL3) - find_package(SDL3 3.2.24 REQUIRED CONFIG REQUIRED COMPONENTS SDL3) + find_package(SDL3 3.2.0 REQUIRED CONFIG REQUIRED COMPONENTS SDL3) else() add_subdirectory(3rdParty/SDL3) endif() diff --git a/Source/controls/touch/gamepad.cpp b/Source/controls/touch/gamepad.cpp index 6b576845d..257e6b4da 100644 --- a/Source/controls/touch/gamepad.cpp +++ b/Source/controls/touch/gamepad.cpp @@ -1,6 +1,10 @@ #include +#ifdef USE_SDL3 +#include +#else #include +#endif #include "control.h" #include "controls/touch/event_handlers.h" @@ -56,15 +60,19 @@ constexpr bool PointsRight(float angle) void InitializeVirtualGamepad() { - const float sqrt2 = sqrtf(2); + const float sqrt2 = sqrtf(2.0F); const int screenPixels = std::min(gnScreenWidth, gnScreenHeight); int inputMargin = screenPixels / 10; int menuButtonWidth = screenPixels / 10; int directionPadSize = screenPixels / 4; - int padButtonSize = roundToInt(1.1f * screenPixels / 10); + int padButtonSize = roundToInt(1.1F * screenPixels / 10); int padButtonSpacing = inputMargin / 3; +#ifdef USE_SDL3 + const float dpi = SDL_GetWindowDisplayScale(ghMainWnd); +#else + float dpi = 0.0F; float hdpi; float vdpi; const int displayIndex = SDL_GetWindowDisplayIndex(ghMainWnd); @@ -79,12 +87,16 @@ void InitializeVirtualGamepad() hdpi *= static_cast(gnScreenWidth) / clientWidth; vdpi *= static_cast(gnScreenHeight) / clientHeight; - const float dpi = std::min(hdpi, vdpi); - inputMargin = roundToInt(0.25f * dpi); - menuButtonWidth = roundToInt(0.2f * dpi); + dpi = std::min(hdpi, vdpi); + } +#endif + + if (dpi != 0.0F) { + inputMargin = roundToInt(0.25F * dpi); + menuButtonWidth = roundToInt(0.2F * dpi); directionPadSize = roundToInt(dpi); - padButtonSize = roundToInt(0.3f * dpi); - padButtonSpacing = roundToInt(0.1f * dpi); + padButtonSize = roundToInt(0.3F * dpi); + padButtonSpacing = roundToInt(0.1F * dpi); } const int menuPanelTopMargin = 30; diff --git a/Source/controls/touch/renderers.cpp b/Source/controls/touch/renderers.cpp index 3c766068e..56384c017 100644 --- a/Source/controls/touch/renderers.cpp +++ b/Source/controls/touch/renderers.cpp @@ -1,6 +1,6 @@ #include "controls/touch/renderers.h" -#ifdef USE_SDL +#ifdef USE_SDL3 #include #else #include @@ -136,11 +136,12 @@ void LoadPotionArt(ButtonTexture *potionArt) if (!SDLC_SetSurfaceAndPaletteColors(surface.get(), palette.get(), logical_palette.data(), 0, 256)) ErrSdl(); - const Uint32 bgColor = SDL_MapRGB(surface->format, logical_palette[1].r, logical_palette[1].g, logical_palette[1].b); #ifdef USE_SDL3 + const Uint32 bgColor = SDL_MapRGB(SDL_GetPixelFormatDetails(surface->format), SDL_GetSurfacePalette(&*surface), logical_palette[1].r, logical_palette[1].g, logical_palette[1].b); if (!SDL_FillSurfaceRect(surface.get(), nullptr, bgColor)) ErrSdl(); if (!SDL_SetSurfaceColorKey(surface.get(), true, bgColor)) ErrSdl(); #else + const Uint32 bgColor = SDL_MapRGB(surface->format, logical_palette[1].r, logical_palette[1].g, logical_palette[1].b); if (SDL_FillRect(surface.get(), nullptr, bgColor) < 0) ErrSdl(); if (SDL_SetColorKey(surface.get(), SDL_TRUE, bgColor) < 0) @@ -192,7 +193,14 @@ Size ButtonTexture::size() const w = surface->w; h = surface->h; } else { +#ifdef USE_SDL3 + float fw, fh; + SDL_GetTextureSize(texture.get(), &fw, &fh); + w = fw; + h = fh; +#else SDL_QueryTexture(texture.get(), /*format=*/nullptr, /*access=*/nullptr, &w, &h); +#endif } w /= numSprites; h /= numFrames; @@ -209,7 +217,10 @@ void RenderVirtualGamepad(SDL_Renderer *renderer) return; #ifdef USE_SDL3 - if (!SDL_RenderTexture(renderer, art.texture.get(), src, dst)) ErrSdl(); + SDL_FRect fsrc, fdst; + SDL_RectToFRect(src, &fsrc); + SDL_RectToFRect(dst, &fdst); + if (!SDL_RenderTexture(renderer, art.texture.get(), &fsrc, &fdst)) ErrSdl(); #else if (SDL_RenderCopy(renderer, art.texture.get(), src, dst) <= -1) ErrSdl(); #endif @@ -227,7 +238,11 @@ void RenderVirtualGamepad(SDL_Surface *surface) if (art.surface == nullptr) return; +#ifdef USE_SDL3 + if (!SDL_BlitSurfaceScaled(art.surface.get(), src, surface, dst, SDL_SCALEMODE_LINEAR)) +#else if (SDL_BlitScaled(art.surface.get(), src, surface, dst) <= -1) +#endif ErrSdl(); }; diff --git a/Source/engine/demomode.cpp b/Source/engine/demomode.cpp index ad4abedc7..d284d6a31 100644 --- a/Source/engine/demomode.cpp +++ b/Source/engine/demomode.cpp @@ -286,8 +286,13 @@ bool CreateSdlEvent(const DemoMsg &dmsg, SDL_Event &event, uint16_t &modState) case DemoMsg::MouseWheelEvent: #ifdef USE_SDL3 event.type = SDL_EVENT_MOUSE_WHEEL; +#if SDL_VERSION_ATLEAST(3, 2, 12) event.wheel.integer_x = dmsg.wheel.x; event.wheel.integer_y = dmsg.wheel.y; +#else + event.wheel.x = dmsg.wheel.x; + event.wheel.y = dmsg.wheel.y; +#endif event.wheel.mouse_x = 0; event.wheel.mouse_y = 0; #else @@ -853,15 +858,23 @@ void RecordMessage(const SDL_Event &event, uint16_t modState) WriteDemoMsgHeader(DemoMsg::MouseWheelEvent); #ifdef USE_SDL3 - if (event.wheel.integer_x < std::numeric_limits::min() - || event.wheel.integer_x > std::numeric_limits::max() - || event.wheel.integer_y < std::numeric_limits::min() - || event.wheel.integer_y > std::numeric_limits::max()) { + int wheelX, wheelY; +#if SDL_VERSION_ATLEAST(3, 2, 12) + wheelX = event.wheel.integer_x; + wheelY = event.wheel.integer_y; +#else + wheelX = event.wheel.x; + wheelY = event.wheel.y; +#endif + if (wheelX < std::numeric_limits::min() + || wheelX > std::numeric_limits::max() + || wheelY < std::numeric_limits::min() + || wheelY > std::numeric_limits::max()) { app_fatal(StrCat("Mouse wheel event integer_x/y out of int16_t range. x=", - event.wheel.integer_x, " y=", event.wheel.integer_y)); + wheelX, " y=", wheelY)); } - WriteLE16(DemoRecording, event.wheel.integer_x); - WriteLE16(DemoRecording, event.wheel.integer_y); + WriteLE16(DemoRecording, wheelX); + WriteLE16(DemoRecording, wheelY); #else if (event.wheel.x < std::numeric_limits::min() || event.wheel.x > std::numeric_limits::max() diff --git a/Source/utils/display.cpp b/Source/utils/display.cpp index c65e64818..6b4499712 100644 --- a/Source/utils/display.cpp +++ b/Source/utils/display.cpp @@ -101,7 +101,10 @@ void CalculatePreferredWindowSize(int &width, int &height) { SDL_DisplayMode mode; #ifdef USE_SDL3 - const SDL_DisplayMode *modePtr = SDL_GetDesktopDisplayMode(0); + int numDisplays = 0; + SDL_DisplayID *displays = SDL_GetDisplays(&numDisplays); + if (numDisplays <= 0 || displays == nullptr) ErrSdl(); + const SDL_DisplayMode *modePtr = SDL_GetDesktopDisplayMode(displays[0]); if (modePtr == nullptr) ErrSdl(); mode = *modePtr; #else @@ -181,10 +184,8 @@ void UpdateAvailableResolutions() // Add resolutions bool supportsAnyResolution = false; #ifdef USE_SDL3 - const SDL_DisplayMode *fullscreenMode = SDL_GetWindowFullscreenMode(ghMainWnd); - if (fullscreenMode == nullptr) return; const SDL_DisplayID displayId = SDL_GetDisplayForWindow(ghMainWnd); - if (displayId == 0) return; + if (displayId == 0) ErrSdl(); int modeCount; SDLUniquePtr modes { SDL_GetFullscreenDisplayModes(displayId, &modeCount) }; if (modes == nullptr) return; @@ -257,7 +258,9 @@ void UpdateAvailableResolutions() #ifndef USE_SDL1 if (*graphicsOptions.fitToScreen) { #ifdef USE_SDL3 - const SDL_DisplayMode *modePtr = SDL_GetDesktopDisplayMode(0); + const SDL_DisplayID displayId = SDL_GetDisplayForWindow(ghMainWnd); + if (displayId == 0) ErrSdl(); + const SDL_DisplayMode *modePtr = SDL_GetDesktopDisplayMode(displayId); if (modePtr == nullptr) ErrSdl(); const SDL_DisplayMode &mode = *modePtr; #else @@ -372,8 +375,6 @@ SDL_DisplayMode GetNearestDisplayMode(Size preferredSize, { SDL_DisplayMode *nearestDisplayMode = nullptr; #ifdef USE_SDL3 - const SDL_DisplayMode *fullscreenMode = SDL_GetWindowFullscreenMode(ghMainWnd); - if (fullscreenMode == nullptr) ErrSdl(); const SDL_DisplayID displayId = SDL_GetDisplayForWindow(ghMainWnd); if (displayId == 0) ErrSdl(); int modeCount; @@ -810,9 +811,11 @@ void SetFullscreenMode() flags = *GetOptions().Graphics.upscale ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_FULLSCREEN; #endif } - if (SDL_SetWindowFullscreen(ghMainWnd, flags) != 0) { - ErrSdl(); - } +#if USE_SDL3 + if (!SDL_SetWindowFullscreen(ghMainWnd, flags)) ErrSdl(); +#else + if (SDL_SetWindowFullscreen(ghMainWnd, flags) != 0) ErrSdl(); +#endif if (!*GetOptions().Graphics.fullscreen) { SDL_RestoreWindow(ghMainWnd); // Avoid window being maximized before resizing diff --git a/Source/utils/sdl_compat.h b/Source/utils/sdl_compat.h index 6c7f1a010..76cbf7b3c 100644 --- a/Source/utils/sdl_compat.h +++ b/Source/utils/sdl_compat.h @@ -8,6 +8,7 @@ #include #include #include +#include #else #include #ifndef USE_SDL1 @@ -31,8 +32,23 @@ inline int SDLC_EventMotionIntX(const SDL_Event &event) { return static_cast(event.motion.y); } inline int SDLC_EventButtonIntX(const SDL_Event &event) { return static_cast(event.button.x); } inline int SDLC_EventButtonIntY(const SDL_Event &event) { return static_cast(event.button.y); } -inline int SDLC_EventWheelIntX(const SDL_Event &event) { return event.wheel.integer_x; } -inline int SDLC_EventWheelIntY(const SDL_Event &event) { return event.wheel.integer_y; } +inline int SDLC_EventWheelIntX(const SDL_Event &event) +{ +#if SDL_VERSION_ATLEAST(3, 2, 12) + return event.wheel.integer_x; +#else + return static_cast(event.wheel.x); +#endif +} + +inline int SDLC_EventWheelIntY(const SDL_Event &event) +{ +#if SDL_VERSION_ATLEAST(3, 2, 12) + return event.wheel.integer_y; +#else + return static_cast(event.wheel.y); +#endif +} inline const SDL_GamepadAxisEvent &SDLC_EventGamepadAxis(const SDL_Event &event) { return event.gaxis; } inline const SDL_GamepadButtonEvent &SDLC_EventGamepadButton(const SDL_Event &event) { return event.gbutton; }