1
0
mirror of https://github.com/luanti-org/luanti.git synced 2025-11-19 16:15:19 +01:00

IrrlichtMt: Initial SDL3 support (#16583)

This commit implements support for SDL3, more specifically, >= 3.2.0 (the first released version).
Almost all changes were made according to https://github.com/libsdl-org/SDL/blob/release-3.2.10/docs/README-migration.md?plain=1 and the suggestions provided by `SDL3/SDL_oldnames.h`.
This commit is contained in:
SmallJoker
2025-11-17 20:55:52 +01:00
committed by GitHub
parent fcd96e9244
commit 36c261c1f0
12 changed files with 465 additions and 187 deletions

View File

@@ -23,6 +23,8 @@ General options and their default values:
PRECOMPILE_HEADERS=FALSE - Precompile some headers (experimental; requires CMake 3.16 or later) PRECOMPILE_HEADERS=FALSE - Precompile some headers (experimental; requires CMake 3.16 or later)
PRECOMPILED_HEADERS_PATH= - Path to a file listing all headers to precompile (default points to src/precompiled_headers.txt) PRECOMPILED_HEADERS_PATH= - Path to a file listing all headers to precompile (default points to src/precompiled_headers.txt)
USE_SDL2_STATIC=TRUE - Links with SDL2::SDL2-static instead of SDL2::SDL2 USE_SDL2_STATIC=TRUE - Links with SDL2::SDL2-static instead of SDL2::SDL2
USE_SDL3=FALSE - Build with SDL3; Enables IrrlichtMt device SDL3 (experimental)
USE_SDL3_STATIC=TRUE - Links with SDL3::SDL3-static instead of SDL3::SDL3-shared
ENABLE_CURL=ON - Build with cURL; Enables use of online mod repo, public serverlist and remote media fetching via http ENABLE_CURL=ON - Build with cURL; Enables use of online mod repo, public serverlist and remote media fetching via http
ENABLE_CURSES=ON - Build with (n)curses; Enables a server side terminal (command line option: --terminal) ENABLE_CURSES=ON - Build with (n)curses; Enables a server side terminal (command line option: --terminal)
ENABLE_GETTEXT=ON - Build with Gettext; Allows using translations ENABLE_GETTEXT=ON - Build with Gettext; Allows using translations

View File

@@ -11,15 +11,16 @@ Build
The build system is CMake. The build system is CMake.
The following libraries are required to be installed: The following libraries are required to be installed:
* zlib, libPNG, libJPEG * zlib, libPNG, libJPEG
* OpenGL * OpenGL
* or on mobile: OpenGL ES (can be optionally enabled on desktop too) * or on mobile: OpenGL ES (can be optionally enabled on desktop too)
* SDL2 * SDL2 or SDL3 (see below)
Aside from standard search options (`ZLIB_INCLUDE_DIR`, `ZLIB_LIBRARY`, ...) the following options are available: Aside from standard search options (`ZLIB_INCLUDE_DIR`, `ZLIB_LIBRARY`, ...) the following options are available:
* `ENABLE_OPENGL` - Enable OpenGL driver * `ENABLE_OPENGL` - Enable OpenGL driver
* `ENABLE_OPENGL3` - Enable OpenGL 3+ driver * `ENABLE_OPENGL3` - Enable OpenGL 3+ driver
* `ENABLE_GLES2` - Enable OpenGL ES 2+ driver * `ENABLE_GLES2` - Enable OpenGL ES 2+ driver
* `USE_SDL3` (default: `OFF`) - Use the SDL3 device instead of SDL2 (**experimental**)
**However, IrrlichtMt cannot be built or installed separately.** **However, IrrlichtMt cannot be built or installed separately.**
@@ -34,6 +35,25 @@ We aim to support these platforms:
This doesn't mean other platforms don't work or won't be supported, if you find something that doesn't work contributions are welcome. This doesn't mean other platforms don't work or won't be supported, if you find something that doesn't work contributions are welcome.
Compatibility matrix
--------------------
Driver (rows) vs Device (columns)
| | SDL2 [1] | SDL3 [2] |
|---------------------------|----------|----------|
| OpenGL 1.2 (to 2.1) | Works | Testing |
| OpenGL 3.2+ | Works | Works |
| OpenGL ES 2.x | Works | Testing |
| WebGL 1 | ? | ? |
| Null (no graphics output) | Works | Works |
Notes:
* [1] `CIrrDeviceSDL` with `USE_SDL3=0`: supports [many platforms](https://wiki.libsdl.org/SDL3/README-platforms)
* [2] `CIrrDeviceSDL` with `USE_SDL3=1`
License License
------- -------

View File

@@ -14,7 +14,8 @@ enum E_DEVICE_TYPE
EIDT_OSX, EIDT_OSX,
//! A device which uses Simple DirectMedia Layer //! A device which uses Simple DirectMedia Layer
/** The SDL device works under all platforms supported by SDL. */ /** The SDL device works under all platforms supported by SDL2 or SDL3.
See also: CMake option 'USE_SDL3' */
EIDT_SDL, EIDT_SDL,
//! This selection allows Irrlicht to choose the best device from the ones available. //! This selection allows Irrlicht to choose the best device from the ones available.

View File

@@ -361,6 +361,7 @@ public:
\return The corresponding keycode. \return The corresponding keycode.
*/ */
virtual Keycode getKeyFromScancode(const u32 scancode) const { virtual Keycode getKeyFromScancode(const u32 scancode) const {
return Keycode(KEY_UNKNOWN, (wchar_t)scancode); (void)scancode;
return Keycode(KEY_UNKNOWN, (wchar_t)0xFFFF);
} }
}; };

View File

@@ -17,7 +17,12 @@
#include "Keycodes.h" #include "Keycodes.h"
#include "COSOperator.h" #include "COSOperator.h"
#include "SIrrCreationParameters.h" #include "SIrrCreationParameters.h"
#ifdef _IRR_USE_SDL3_
#include <SDL3/SDL_version.h>
#else
#include <SDL_video.h> #include <SDL_video.h>
#endif
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
@@ -29,6 +34,72 @@
#include "CSDLManager.h" #include "CSDLManager.h"
#ifndef _IRR_USE_SDL3_
// SDL2 backwards compatibility for things that were renamed in SDL3.
#define SDL_KMOD_SHIFT KMOD_SHIFT
#define SDL_KMOD_CTRL KMOD_CTRL
#define SDL_KMOD_NUM KMOD_NUM
#define SDL_TextInputActive(unused) SDL_IsTextInputActive()
#define SDL_CloseJoystick SDL_JoystickClose
#define SDL_GL_DestroyContext SDL_GL_DeleteContext
#define SDL_WINDOW_HIGH_PIXEL_DENSITY SDL_WINDOW_ALLOW_HIGHDPI
#define SDL_StartTextInput(unused) SDL_StartTextInput()
#define SDL_StopTextInput(unused) SDL_StopTextInput()
#define SDL_EVENT_MOUSE_MOTION SDL_MOUSEMOTION
#define SDL_EVENT_MOUSE_WHEEL SDL_MOUSEWHEEL
#define SDL_EVENT_MOUSE_BUTTON_DOWN SDL_MOUSEBUTTONDOWN
#define SDL_EVENT_MOUSE_BUTTON_UP SDL_MOUSEBUTTONUP
#define SDL_EVENT_TEXT_INPUT SDL_TEXTINPUT
#define SDL_EVENT_KEY_DOWN SDL_KEYDOWN
#define SDL_EVENT_KEY_UP SDL_KEYUP
#define SDL_EVENT_QUIT SDL_QUIT
#define SDL_EVENT_USER SDL_USEREVENT
#define SDL_EVENT_FINGER_DOWN SDL_FINGERDOWN
#define SDL_EVENT_FINGER_MOTION SDL_FINGERMOTION
#define SDL_EVENT_FINGER_UP SDL_FINGERUP
#define SDL_EVENT_WILL_ENTER_BACKGROUND SDL_APP_WILLENTERBACKGROUND
#define SDL_EVENT_WILL_ENTER_FOREGROUND SDL_APP_WILLENTERFOREGROUND
#define SDL_EVENT_RENDER_TARGETS_RESET SDL_RENDER_TARGETS_RESET
#define SDL_EVENT_RENDER_DEVICE_LOST SDL_RENDER_DEVICE_RESET
#define SDL_UpdateJoysticks SDL_JoystickUpdate
#define SDL_GetNumJoystickButtons SDL_JoystickNumButtons
#define SDL_GetNumJoystickAxes SDL_JoystickNumAxes
#define SDL_GetJoystickButton SDL_JoystickGetButton
#define SDL_GetJoystickAxis SDL_JoystickGetAxis
#define SDL_GetNumJoystickHats SDL_JoystickNumHats
#define SDL_GetJoystickHat SDL_JoystickGetHat
#define SDL_OpenJoystick SDL_JoystickOpen
#define SDL_GetJoystickName SDL_JoystickName
#define SDL_GetWindowSizeInPixels SDL_GL_GetDrawableSize
#define SDL_DestroySurface SDL_FreeSurface
#define SDL_SYSTEM_CURSOR_DEFAULT SDL_SYSTEM_CURSOR_ARROW
#define SDL_SYSTEM_CURSOR_POINTER SDL_SYSTEM_CURSOR_HAND
#define SDL_SYSTEM_CURSOR_TEXT SDL_SYSTEM_CURSOR_IBEAM
#define SDL_SYSTEM_CURSOR_NOT_ALLOWED SDL_SYSTEM_CURSOR_NO
#define SDL_SYSTEM_CURSOR_MOVE SDL_SYSTEM_CURSOR_SIZEALL
#define SDL_SYSTEM_CURSOR_NESW_RESIZE SDL_SYSTEM_CURSOR_SIZENESW
#define SDL_SYSTEM_CURSOR_NWSE_RESIZE SDL_SYSTEM_CURSOR_SIZENWSE
#define SDL_SYSTEM_CURSOR_NS_RESIZE SDL_SYSTEM_CURSOR_SIZENS
#define SDL_SYSTEM_CURSOR_EW_RESIZE SDL_SYSTEM_CURSOR_SIZEWE
#endif
#ifdef _IRR_USE_SDL3_
#define SDL_FINGER_ID(ev) ((ev).tfinger.fingerID)
#else
#define SDL_FINGER_ID(ev) ((ev).tfinger.fingerId)
#endif
// Since SDL doesn't have mouse keys as keycodes we need to fall back to EKEY_CODE in some cases. // Since SDL doesn't have mouse keys as keycodes we need to fall back to EKEY_CODE in some cases.
static inline bool is_fake_key(EKEY_CODE key) { static inline bool is_fake_key(EKEY_CODE key) {
switch (key) { switch (key) {
@@ -158,7 +229,7 @@ bool CIrrDeviceSDL::keyIsKnownSpecial(EKEY_CODE irrlichtKey)
} }
} }
int CIrrDeviceSDL::findCharToPassToIrrlicht(uint32_t sdlKey, EKEY_CODE irrlichtKey, bool numlock) wchar_t CIrrDeviceSDL::findCharToPassToIrrlicht(uint32_t sdlKey, EKEY_CODE irrlichtKey, u16 keymod)
{ {
switch (irrlichtKey) { switch (irrlichtKey) {
// special cases that always return a char regardless of how the SDL keycode // special cases that always return a char regardless of how the SDL keycode
@@ -184,7 +255,7 @@ int CIrrDeviceSDL::findCharToPassToIrrlicht(uint32_t sdlKey, EKEY_CODE irrlichtK
break; break;
} }
if (numlock) { if (keymod & SDL_KMOD_NUM) {
// Number keys on the numpad are also affected, but we only want them // Number keys on the numpad are also affected, but we only want them
// to produce number chars when numlock is enabled. // to produce number chars when numlock is enabled.
switch (irrlichtKey) { switch (irrlichtKey) {
@@ -252,15 +323,32 @@ std::variant<u32, EKEY_CODE> CIrrDeviceSDL::getScancodeFromKey(const Keycode &ke
} else { } else {
keynum = std::get<wchar_t>(key); keynum = std::get<wchar_t>(key);
} }
// SDL3 returns a valid scancode for keycode 0. This is undesired.
if (keynum == 0)
return (u32) 0;
#ifdef _IRR_USE_SDL3_
SDL_Keymod kmod = SDL_KMOD_NONE; // TODO: respect modifiers
return (u32)SDL_GetScancodeFromKey(keynum, &kmod);
#else
// Modifiers not supported
return (u32)SDL_GetScancodeFromKey(keynum); return (u32)SDL_GetScancodeFromKey(keynum);
#endif
} }
Keycode CIrrDeviceSDL::getKeyFromScancode(const u32 scancode) const Keycode CIrrDeviceSDL::getKeyFromScancode(const u32 scancode) const
{ {
#ifdef _IRR_USE_SDL3_
// TODO: SDL_HINT_KEYCODE_OPTIONS ?
auto keycode = SDL_GetKeyFromScancode((SDL_Scancode)scancode, SDL_KMOD_NONE, true);
#else
// Modifiers not supported
auto keycode = SDL_GetKeyFromScancode((SDL_Scancode)scancode); auto keycode = SDL_GetKeyFromScancode((SDL_Scancode)scancode);
#endif
const auto &keyentry = KeyMap.find(keycode); const auto &keyentry = KeyMap.find(keycode);
auto irrcode = keyentry != KeyMap.end() ? keyentry->second : KEY_UNKNOWN; auto irrcode = keyentry != KeyMap.end() ? keyentry->second : KEY_UNKNOWN;
auto keychar = findCharToPassToIrrlicht(keycode, irrcode, false); wchar_t keychar = findCharToPassToIrrlicht(keycode, irrcode, false);
return Keycode(irrcode, keychar); return Keycode(irrcode, keychar);
} }
@@ -273,18 +361,22 @@ void CIrrDeviceSDL::resetReceiveTextInputEvents()
// sent as text input events instead of the result) when // sent as text input events instead of the result) when
// SDL_StartTextInput() is called on the same input box. // SDL_StartTextInput() is called on the same input box.
core::rect<s32> pos = elem->getAbsolutePosition(); core::rect<s32> pos = elem->getAbsolutePosition();
if (!SDL_IsTextInputActive() || lastElemPos != pos) { if (!SDL_TextInputActive(Window) || lastElemPos != pos) {
lastElemPos = pos; lastElemPos = pos;
SDL_Rect rect; SDL_Rect rect;
rect.x = pos.UpperLeftCorner.X; rect.x = pos.UpperLeftCorner.X;
rect.y = pos.UpperLeftCorner.Y; rect.y = pos.UpperLeftCorner.Y;
rect.w = pos.getWidth(); rect.w = pos.getWidth();
rect.h = pos.getHeight(); rect.h = pos.getHeight();
#ifdef _IRR_USE_SDL3_
SDL_SetTextInputArea(Window, &rect, 10);
#else
SDL_SetTextInputRect(&rect); SDL_SetTextInputRect(&rect);
SDL_StartTextInput(); #endif
SDL_StartTextInput(Window);
} }
} else { } else {
SDL_StopTextInput(); SDL_StopTextInput(Window);
} }
} }
@@ -302,7 +394,9 @@ CIrrDeviceSDL::CIrrDeviceSDL(const SIrrlichtCreationParameters &param) :
// Blocking on pause causes problems with multiplayer. // Blocking on pause causes problems with multiplayer.
// see <https://github.com/luanti-org/luanti/issues/10842> // see <https://github.com/luanti-org/luanti/issues/10842>
SDL_SetHint(SDL_HINT_ANDROID_BLOCK_ON_PAUSE, "0"); SDL_SetHint(SDL_HINT_ANDROID_BLOCK_ON_PAUSE, "0");
#ifndef _IRR_USE_SDL3_
SDL_SetHint(SDL_HINT_ANDROID_BLOCK_ON_PAUSE_PAUSEAUDIO, "0"); SDL_SetHint(SDL_HINT_ANDROID_BLOCK_ON_PAUSE_PAUSEAUDIO, "0");
#endif // SDL3: Handled automatically
SDL_SetHint(SDL_HINT_ANDROID_TRAP_BACK_BUTTON, "1"); SDL_SetHint(SDL_HINT_ANDROID_TRAP_BACK_BUTTON, "1");
@@ -319,14 +413,16 @@ CIrrDeviceSDL::CIrrDeviceSDL(const SIrrlichtCreationParameters &param) :
#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) #if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_)
// These are not interesting for our use // These are not interesting for our use
#ifndef _IRR_USE_SDL3_
SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, "0"); SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, "0");
#endif // SDL3: Removed hint
SDL_SetHint(SDL_HINT_TV_REMOTE_AS_JOYSTICK, "0"); SDL_SetHint(SDL_HINT_TV_REMOTE_AS_JOYSTICK, "0");
#endif #endif
#if SDL_VERSION_ATLEAST(2, 24, 0) #if SDL_VERSION_ATLEAST(2, 24, 0) && !SDL_VERSION_ATLEAST(3, 0, 0)
// highdpi support on Windows // highdpi support on Windows
SDL_SetHint(SDL_HINT_WINDOWS_DPI_SCALING, "1"); SDL_SetHint(SDL_HINT_WINDOWS_DPI_SCALING, "1");
#endif #endif // SDL3: Removed hint
// Minetest has its own code to synthesize mouse events from touch events, // Minetest has its own code to synthesize mouse events from touch events,
// so we prevent SDL from doing it. // so we prevent SDL from doing it.
@@ -338,18 +434,33 @@ CIrrDeviceSDL::CIrrDeviceSDL(const SIrrlichtCreationParameters &param) :
#endif #endif
// Set IME hints // Set IME hints
#ifdef _IRR_USE_SDL3_
SDL_SetHint(SDL_HINT_IME_IMPLEMENTED_UI, "0");
#else
SDL_SetHint(SDL_HINT_IME_INTERNAL_EDITING, "1"); SDL_SetHint(SDL_HINT_IME_INTERNAL_EDITING, "1");
#endif
#if defined(SDL_HINT_IME_SHOW_UI) #if defined(SDL_HINT_IME_SHOW_UI)
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1"); SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
#endif #endif
u32 flags = SDL_INIT_TIMER | SDL_INIT_EVENTS; // Initialize SDL
u32 flags = SDL_INIT_EVENTS;
#ifndef _IRR_USE_SDL3_
flags |= SDL_INIT_TIMER;
#endif
if (CreationParams.DriverType != video::EDT_NULL) if (CreationParams.DriverType != video::EDT_NULL)
flags |= SDL_INIT_VIDEO; flags |= SDL_INIT_VIDEO;
#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) #if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_)
flags |= SDL_INIT_JOYSTICK; flags |= SDL_INIT_JOYSTICK;
#endif #endif
if (SDL_Init(flags) < 0) {
#ifdef _IRR_USE_SDL3_
if (!SDL_Init(flags))
#else
if (SDL_Init(flags) < 0)
#endif
{
os::Printer::log("Unable to initialize SDL", SDL_GetError(), ELL_ERROR); os::Printer::log("Unable to initialize SDL", SDL_GetError(), ELL_ERROR);
Close = true; Close = true;
} }
@@ -368,18 +479,7 @@ CIrrDeviceSDL::CIrrDeviceSDL(const SIrrlichtCreationParameters &param) :
core::stringc sdlver = "SDL "; core::stringc sdlver = "SDL ";
{ {
SDL_version v{}; sdlver += getVersionString();
SDL_GetVersion(&v);
sdlver += v.major;
sdlver += ".";
sdlver += v.minor;
sdlver += ".";
sdlver += v.patch;
// the SDL team seems to intentionally number sdl2-compat this way:
// <https://github.com/libsdl-org/sdl2-compat/tags>
if (v.patch >= 50)
sdlver += " (compat)";
sdlver += " on "; sdlver += " on ";
sdlver += SDL_GetPlatform(); sdlver += SDL_GetPlatform();
} }
@@ -407,11 +507,11 @@ CIrrDeviceSDL::~CIrrDeviceSDL()
#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) #if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_)
const u32 numJoysticks = Joysticks.size(); const u32 numJoysticks = Joysticks.size();
for (u32 i = 0; i < numJoysticks; ++i) for (u32 i = 0; i < numJoysticks; ++i)
SDL_JoystickClose(Joysticks[i]); SDL_CloseJoystick(Joysticks[i]);
#endif #endif
if (Window && Context) { if (Window && Context) {
SDL_GL_MakeCurrent(Window, NULL); SDL_GL_MakeCurrent(Window, NULL);
SDL_GL_DeleteContext(Context); SDL_GL_DestroyContext(Context);
} }
if (Window) { if (Window) {
SDL_DestroyWindow(Window); SDL_DestroyWindow(Window);
@@ -532,9 +632,11 @@ bool CIrrDeviceSDL::createWindow()
bool CIrrDeviceSDL::createWindowWithContext() bool CIrrDeviceSDL::createWindowWithContext()
{ {
u32 SDL_Flags = 0; u32 SDL_Flags = 0;
SDL_Flags |= SDL_WINDOW_ALLOW_HIGHDPI; SDL_Flags |= SDL_WINDOW_HIGH_PIXEL_DENSITY;
#ifndef _IRR_USE_SDL3_
SDL_Flags |= getFullscreenFlag(CreationParams.Fullscreen); SDL_Flags |= getFullscreenFlag(CreationParams.Fullscreen);
#endif
if (Resizable) if (Resizable)
SDL_Flags |= SDL_WINDOW_RESIZABLE; SDL_Flags |= SDL_WINDOW_RESIZABLE;
if (CreationParams.WindowMaximized) if (CreationParams.WindowMaximized)
@@ -629,7 +731,11 @@ bool CIrrDeviceSDL::createWindowWithContext()
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
} }
#ifdef _IRR_USE_SDL3_
Window = SDL_CreateWindow("", Width, Height, SDL_Flags);
#else
Window = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, Width, Height, SDL_Flags); Window = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, Width, Height, SDL_Flags);
#endif
if (!Window) { if (!Window) {
os::Printer::log("Could not create window", SDL_GetError(), ELL_WARNING); os::Printer::log("Could not create window", SDL_GetError(), ELL_WARNING);
return false; return false;
@@ -643,6 +749,11 @@ bool CIrrDeviceSDL::createWindowWithContext()
return false; return false;
} }
#ifdef _IRR_USE_SDL3_
if (CreationParams.Fullscreen)
SDL_SetWindowFullscreen(Window, true);
#endif
updateSizeAndScale(); updateSizeAndScale();
if (ScaleX != 1.0f || ScaleY != 1.0f) { if (ScaleX != 1.0f || ScaleY != 1.0f) {
// The given window size is in pixels, not in screen coordinates. // The given window size is in pixels, not in screen coordinates.
@@ -708,12 +819,33 @@ bool CIrrDeviceSDL::run()
SEvent irrevent; SEvent irrevent;
SDL_Event SDL_event; SDL_Event SDL_event;
auto get_touch_id_x_y = [this, &irrevent, &SDL_event]() {
irrevent.TouchInput.ID = SDL_FINGER_ID(SDL_event);
irrevent.TouchInput.X = static_cast<s32>(SDL_event.tfinger.x * Width);
irrevent.TouchInput.Y = static_cast<s32>(SDL_event.tfinger.y * Height);
};
auto handle_window_resize_event = [this, &irrevent]() {
u32 old_w = Width, old_h = Height;
f32 old_scale_x = ScaleX, old_scale_y = ScaleY;
updateSizeAndScale();
if (old_w != Width || old_h != Height) {
if (VideoDriver)
VideoDriver->OnResize(core::dimension2d<u32>(Width, Height));
}
if (old_scale_x != ScaleX || old_scale_y != ScaleY) {
irrevent.EventType = EET_APPLICATION_EVENT;
irrevent.ApplicationEvent.EventType = EAET_DPI_CHANGED;
postEventFromUser(irrevent);
}
};
while (!Close && wrap_PollEvent(&SDL_event)) { while (!Close && wrap_PollEvent(&SDL_event)) {
// os::Printer::log("event: ", core::stringc((int)SDL_event.type).c_str(), ELL_INFORMATION); // just for debugging // os::Printer::log("event: ", core::stringc((int)SDL_event.type).c_str(), ELL_INFORMATION); // just for debugging
irrevent = {}; irrevent = {};
switch (SDL_event.type) { switch (SDL_event.type) {
case SDL_MOUSEMOTION: { case SDL_EVENT_MOUSE_MOTION: {
SDL_Keymod keymod = SDL_GetModState(); SDL_Keymod keymod = SDL_GetModState();
irrevent.EventType = EET_MOUSE_INPUT_EVENT; irrevent.EventType = EET_MOUSE_INPUT_EVENT;
@@ -721,7 +853,12 @@ bool CIrrDeviceSDL::run()
MouseXRel = static_cast<s32>(SDL_event.motion.xrel * ScaleX); MouseXRel = static_cast<s32>(SDL_event.motion.xrel * ScaleX);
MouseYRel = static_cast<s32>(SDL_event.motion.yrel * ScaleY); MouseYRel = static_cast<s32>(SDL_event.motion.yrel * ScaleY);
if (!SDL_GetRelativeMouseMode()) { #ifdef _IRR_USE_SDL3_
if (!SDL_GetWindowRelativeMouseMode(Window))
#else
if (!SDL_GetRelativeMouseMode())
#endif
{
MouseX = static_cast<s32>(SDL_event.motion.x * ScaleX); MouseX = static_cast<s32>(SDL_event.motion.x * ScaleX);
MouseY = static_cast<s32>(SDL_event.motion.y * ScaleY); MouseY = static_cast<s32>(SDL_event.motion.y * ScaleY);
} else { } else {
@@ -732,25 +869,27 @@ bool CIrrDeviceSDL::run()
irrevent.MouseInput.Y = MouseY; irrevent.MouseInput.Y = MouseY;
irrevent.MouseInput.ButtonStates = MouseButtonStates; irrevent.MouseInput.ButtonStates = MouseButtonStates;
irrevent.MouseInput.Shift = (keymod & KMOD_SHIFT) != 0; irrevent.MouseInput.Shift = (keymod & SDL_KMOD_SHIFT) != 0;
irrevent.MouseInput.Control = (keymod & KMOD_CTRL) != 0; irrevent.MouseInput.Control = (keymod & SDL_KMOD_CTRL) != 0;
postEventFromUser(irrevent); postEventFromUser(irrevent);
break; break;
} }
case SDL_MOUSEWHEEL: { case SDL_EVENT_MOUSE_WHEEL: {
SDL_Keymod keymod = SDL_GetModState(); SDL_Keymod keymod = SDL_GetModState();
irrevent.EventType = EET_MOUSE_INPUT_EVENT; irrevent.EventType = EET_MOUSE_INPUT_EVENT;
irrevent.MouseInput.Event = EMIE_MOUSE_WHEEL; irrevent.MouseInput.Event = EMIE_MOUSE_WHEEL;
#if SDL_VERSION_ATLEAST(2, 0, 18) #ifdef _IRR_USE_SDL3_
irrevent.MouseInput.Wheel = SDL_event.wheel.y;
#elif SDL_VERSION_ATLEAST(2, 0, 18)
irrevent.MouseInput.Wheel = SDL_event.wheel.preciseY; irrevent.MouseInput.Wheel = SDL_event.wheel.preciseY;
#else #else
irrevent.MouseInput.Wheel = SDL_event.wheel.y; irrevent.MouseInput.Wheel = SDL_event.wheel.y;
#endif #endif
irrevent.MouseInput.ButtonStates = MouseButtonStates; irrevent.MouseInput.ButtonStates = MouseButtonStates;
irrevent.MouseInput.Shift = (keymod & KMOD_SHIFT) != 0; irrevent.MouseInput.Shift = (keymod & SDL_KMOD_SHIFT) != 0;
irrevent.MouseInput.Control = (keymod & KMOD_CTRL) != 0; irrevent.MouseInput.Control = (keymod & SDL_KMOD_CTRL) != 0;
irrevent.MouseInput.X = MouseX; irrevent.MouseInput.X = MouseX;
irrevent.MouseInput.Y = MouseY; irrevent.MouseInput.Y = MouseY;
@@ -761,8 +900,8 @@ bool CIrrDeviceSDL::run()
postEventFromUser(irrevent); postEventFromUser(irrevent);
break; break;
} }
case SDL_MOUSEBUTTONDOWN: case SDL_EVENT_MOUSE_BUTTON_DOWN:
case SDL_MOUSEBUTTONUP: { case SDL_EVENT_MOUSE_BUTTON_UP: {
SDL_Keymod keymod = SDL_GetModState(); SDL_Keymod keymod = SDL_GetModState();
irrevent.EventType = EET_MOUSE_INPUT_EVENT; irrevent.EventType = EET_MOUSE_INPUT_EVENT;
@@ -801,7 +940,7 @@ bool CIrrDeviceSDL::run()
#endif #endif
switch (button) { switch (button) {
case SDL_BUTTON_LEFT: case SDL_BUTTON_LEFT:
if (SDL_event.type == SDL_MOUSEBUTTONDOWN) { if (SDL_event.type == SDL_EVENT_MOUSE_BUTTON_DOWN) {
irrevent.MouseInput.Event = EMIE_LMOUSE_PRESSED_DOWN; irrevent.MouseInput.Event = EMIE_LMOUSE_PRESSED_DOWN;
MouseButtonStates |= EMBSM_LEFT; MouseButtonStates |= EMBSM_LEFT;
} else { } else {
@@ -811,7 +950,7 @@ bool CIrrDeviceSDL::run()
break; break;
case SDL_BUTTON_RIGHT: case SDL_BUTTON_RIGHT:
if (SDL_event.type == SDL_MOUSEBUTTONDOWN) { if (SDL_event.type == SDL_EVENT_MOUSE_BUTTON_DOWN) {
irrevent.MouseInput.Event = EMIE_RMOUSE_PRESSED_DOWN; irrevent.MouseInput.Event = EMIE_RMOUSE_PRESSED_DOWN;
MouseButtonStates |= EMBSM_RIGHT; MouseButtonStates |= EMBSM_RIGHT;
} else { } else {
@@ -821,7 +960,7 @@ bool CIrrDeviceSDL::run()
break; break;
case SDL_BUTTON_MIDDLE: case SDL_BUTTON_MIDDLE:
if (SDL_event.type == SDL_MOUSEBUTTONDOWN) { if (SDL_event.type == SDL_EVENT_MOUSE_BUTTON_DOWN) {
irrevent.MouseInput.Event = EMIE_MMOUSE_PRESSED_DOWN; irrevent.MouseInput.Event = EMIE_MMOUSE_PRESSED_DOWN;
MouseButtonStates |= EMBSM_MIDDLE; MouseButtonStates |= EMBSM_MIDDLE;
} else { } else {
@@ -844,8 +983,8 @@ bool CIrrDeviceSDL::run()
break; break;
} }
bool shift = (keymod & KMOD_SHIFT) != 0; bool shift = (keymod & SDL_KMOD_SHIFT) != 0;
bool control = (keymod & KMOD_CTRL) != 0; bool control = (keymod & SDL_KMOD_CTRL) != 0;
if (irrevent.EventType == EET_MOUSE_INPUT_EVENT && irrevent.MouseInput.Event != EMIE_MOUSE_MOVED) { if (irrevent.EventType == EET_MOUSE_INPUT_EVENT && irrevent.MouseInput.Event != EMIE_MOUSE_MOVED) {
irrevent.MouseInput.ButtonStates = MouseButtonStates; irrevent.MouseInput.ButtonStates = MouseButtonStates;
irrevent.MouseInput.X = static_cast<s32>(SDL_event.button.x * ScaleX); irrevent.MouseInput.X = static_cast<s32>(SDL_event.button.x * ScaleX);
@@ -866,7 +1005,7 @@ bool CIrrDeviceSDL::run()
} }
} else if (irrevent.EventType == EET_KEY_INPUT_EVENT) { } else if (irrevent.EventType == EET_KEY_INPUT_EVENT) {
irrevent.KeyInput.Char = 0; irrevent.KeyInput.Char = 0;
irrevent.KeyInput.PressedDown = SDL_event.type == SDL_MOUSEBUTTONDOWN; irrevent.KeyInput.PressedDown = SDL_event.type == SDL_EVENT_MOUSE_BUTTON_DOWN;
irrevent.KeyInput.Shift = shift; irrevent.KeyInput.Shift = shift;
irrevent.KeyInput.Control = control; irrevent.KeyInput.Control = control;
postEventFromUser(irrevent); postEventFromUser(irrevent);
@@ -874,7 +1013,7 @@ bool CIrrDeviceSDL::run()
break; break;
} }
case SDL_TEXTINPUT: { case SDL_EVENT_TEXT_INPUT: {
irrevent.EventType = EET_STRING_INPUT_EVENT; irrevent.EventType = EET_STRING_INPUT_EVENT;
irrevent.StringInput.Str = new core::stringw(); irrevent.StringInput.Str = new core::stringw();
core::utf8ToWString(*irrevent.StringInput.Str, SDL_event.text.text); core::utf8ToWString(*irrevent.StringInput.Str, SDL_event.text.text);
@@ -883,10 +1022,17 @@ bool CIrrDeviceSDL::run()
irrevent.StringInput.Str = NULL; irrevent.StringInput.Str = NULL;
} break; } break;
case SDL_KEYDOWN: case SDL_EVENT_KEY_DOWN:
case SDL_KEYUP: { case SDL_EVENT_KEY_UP: {
#ifdef _IRR_USE_SDL3_
SDL_Keycode keysym = SDL_event.key.key;
SDL_Scancode scancode = SDL_event.key.scancode;
SDL_Keymod keymod = SDL_event.key.mod;
#else
auto keysym = SDL_event.key.keysym.sym; auto keysym = SDL_event.key.keysym.sym;
auto scancode = SDL_event.key.keysym.scancode; auto scancode = SDL_event.key.keysym.scancode;
auto keymod = SDL_event.key.keysym.mod;
#endif
// Treat AC_BACK as the Escape key // Treat AC_BACK as the Escape key
if (scancode == SDL_SCANCODE_AC_BACK) { if (scancode == SDL_SCANCODE_AC_BACK) {
@@ -900,26 +1046,41 @@ bool CIrrDeviceSDL::run()
if (!Keycode::isValid(key)) if (!Keycode::isValid(key))
os::Printer::log("keycode not mapped", core::stringc(keysym), ELL_DEBUG); os::Printer::log("keycode not mapped", core::stringc(keysym), ELL_DEBUG);
// Make sure to only input special characters if something is in focus, as SDL_TEXTINPUT handles normal unicode already // Make sure to only input special characters if something is in focus,
if (SDL_IsTextInputActive() && !keyIsKnownSpecial(key) && (SDL_event.key.keysym.mod & KMOD_CTRL) == 0) // as SDL_EVENT_TEXT_INPUT handles normal unicode already
if (SDL_TextInputActive(Window) && !keyIsKnownSpecial(key) && (keymod & SDL_KMOD_CTRL) == 0)
break; break;
irrevent.EventType = EET_KEY_INPUT_EVENT; irrevent.EventType = EET_KEY_INPUT_EVENT;
irrevent.KeyInput.Key = key; irrevent.KeyInput.Key = key;
irrevent.KeyInput.PressedDown = (SDL_event.type == SDL_KEYDOWN); irrevent.KeyInput.PressedDown = (SDL_event.type == SDL_EVENT_KEY_DOWN);
irrevent.KeyInput.Shift = (SDL_event.key.keysym.mod & KMOD_SHIFT) != 0; irrevent.KeyInput.Shift = (keymod & SDL_KMOD_SHIFT) != 0;
irrevent.KeyInput.Control = (SDL_event.key.keysym.mod & KMOD_CTRL) != 0; irrevent.KeyInput.Control = (keymod & SDL_KMOD_CTRL) != 0;
irrevent.KeyInput.Char = findCharToPassToIrrlicht(keysym, key, #ifdef _IRR_USE_SDL3_
(SDL_event.key.keysym.mod & KMOD_NUM) != 0); {
// Look up the printable character (like in an input box)
SDL_Keycode keycode_Aa = SDL_GetKeyFromScancode(scancode, keymod, false);
// Discard non-printable, such as CTRL, HOME, F3, ...
irrevent.KeyInput.Char = keycode_Aa < SDLK_EXTENDED_MASK ? keycode_Aa : 0;
}
#else
irrevent.KeyInput.Char = findCharToPassToIrrlicht(keysym, key, keymod);
#endif
irrevent.KeyInput.SystemKeyCode = scancode; irrevent.KeyInput.SystemKeyCode = scancode;
postEventFromUser(irrevent); postEventFromUser(irrevent);
} break; } break;
case SDL_QUIT: case SDL_EVENT_QUIT:
Close = true; Close = true;
break; break;
#ifdef _IRR_USE_SDL3_
case SDL_EVENT_WINDOW_RESIZED:
case SDL_EVENT_WINDOW_DISPLAY_CHANGED:
handle_window_resize_event();
break;
#else
case SDL_WINDOWEVENT: case SDL_WINDOWEVENT:
switch (SDL_event.window.event) { switch (SDL_event.window.event) {
case SDL_WINDOWEVENT_RESIZED: case SDL_WINDOWEVENT_RESIZED:
@@ -927,23 +1088,13 @@ bool CIrrDeviceSDL::run()
#if SDL_VERSION_ATLEAST(2, 0, 18) #if SDL_VERSION_ATLEAST(2, 0, 18)
case SDL_WINDOWEVENT_DISPLAY_CHANGED: case SDL_WINDOWEVENT_DISPLAY_CHANGED:
#endif #endif
u32 old_w = Width, old_h = Height; handle_window_resize_event();
f32 old_scale_x = ScaleX, old_scale_y = ScaleY;
updateSizeAndScale();
if (old_w != Width || old_h != Height) {
if (VideoDriver)
VideoDriver->OnResize(core::dimension2d<u32>(Width, Height));
}
if (old_scale_x != ScaleX || old_scale_y != ScaleY) {
irrevent.EventType = EET_APPLICATION_EVENT;
irrevent.ApplicationEvent.EventType = EAET_DPI_CHANGED;
postEventFromUser(irrevent);
}
break; break;
} }
break; break;
#endif
case SDL_USEREVENT: case SDL_EVENT_USER:
irrevent.EventType = EET_USER_EVENT; irrevent.EventType = EET_USER_EVENT;
irrevent.UserEvent.UserData1 = reinterpret_cast<uintptr_t>(SDL_event.user.data1); irrevent.UserEvent.UserData1 = reinterpret_cast<uintptr_t>(SDL_event.user.data1);
irrevent.UserEvent.UserData2 = reinterpret_cast<uintptr_t>(SDL_event.user.data2); irrevent.UserEvent.UserData2 = reinterpret_cast<uintptr_t>(SDL_event.user.data2);
@@ -951,35 +1102,29 @@ bool CIrrDeviceSDL::run()
postEventFromUser(irrevent); postEventFromUser(irrevent);
break; break;
case SDL_FINGERDOWN: case SDL_EVENT_FINGER_DOWN:
irrevent.EventType = EET_TOUCH_INPUT_EVENT; irrevent.EventType = EET_TOUCH_INPUT_EVENT;
irrevent.TouchInput.Event = ETIE_PRESSED_DOWN; irrevent.TouchInput.Event = ETIE_PRESSED_DOWN;
irrevent.TouchInput.ID = SDL_event.tfinger.fingerId; get_touch_id_x_y();
irrevent.TouchInput.X = static_cast<s32>(SDL_event.tfinger.x * Width);
irrevent.TouchInput.Y = static_cast<s32>(SDL_event.tfinger.y * Height);
CurrentTouchCount++; CurrentTouchCount++;
irrevent.TouchInput.touchedCount = CurrentTouchCount; irrevent.TouchInput.touchedCount = CurrentTouchCount;
postEventFromUser(irrevent); postEventFromUser(irrevent);
break; break;
case SDL_FINGERMOTION: case SDL_EVENT_FINGER_MOTION:
irrevent.EventType = EET_TOUCH_INPUT_EVENT; irrevent.EventType = EET_TOUCH_INPUT_EVENT;
irrevent.TouchInput.Event = ETIE_MOVED; irrevent.TouchInput.Event = ETIE_MOVED;
irrevent.TouchInput.ID = SDL_event.tfinger.fingerId; get_touch_id_x_y();
irrevent.TouchInput.X = static_cast<s32>(SDL_event.tfinger.x * Width);
irrevent.TouchInput.Y = static_cast<s32>(SDL_event.tfinger.y * Height);
irrevent.TouchInput.touchedCount = CurrentTouchCount; irrevent.TouchInput.touchedCount = CurrentTouchCount;
postEventFromUser(irrevent); postEventFromUser(irrevent);
break; break;
case SDL_FINGERUP: case SDL_EVENT_FINGER_UP:
irrevent.EventType = EET_TOUCH_INPUT_EVENT; irrevent.EventType = EET_TOUCH_INPUT_EVENT;
irrevent.TouchInput.Event = ETIE_LEFT_UP; irrevent.TouchInput.Event = ETIE_LEFT_UP;
irrevent.TouchInput.ID = SDL_event.tfinger.fingerId; get_touch_id_x_y();
irrevent.TouchInput.X = static_cast<s32>(SDL_event.tfinger.x * Width);
irrevent.TouchInput.Y = static_cast<s32>(SDL_event.tfinger.y * Height);
// To match Android behavior, still count the pointer that was // To match Android behavior, still count the pointer that was
// just released. // just released.
irrevent.TouchInput.touchedCount = CurrentTouchCount; irrevent.TouchInput.touchedCount = CurrentTouchCount;
@@ -990,25 +1135,25 @@ bool CIrrDeviceSDL::run()
postEventFromUser(irrevent); postEventFromUser(irrevent);
break; break;
// Contrary to what the SDL documentation says, SDL_APP_WILLENTERBACKGROUND // SDL2: Contrary to what the SDL documentation says, SDL_APP_WILLENTERBACKGROUND
// and SDL_APP_WILLENTERFOREGROUND are actually sent in onStop/onStart, // and SDL_APP_WILLENTERFOREGROUND are actually sent in onStop/onStart,
// not onPause/onResume, on recent Android versions. This can be verified // not onPause/onResume, on recent Android versions. This can be verified
// by testing or by looking at the org.libsdl.app.SDLActivity Java code. // by testing or by looking at the org.libsdl.app.SDLActivity Java code.
// -> This means we can use them to implement isWindowVisible(). // -> This means we can use them to implement isWindowVisible().
case SDL_APP_WILLENTERBACKGROUND: case SDL_EVENT_WILL_ENTER_BACKGROUND:
IsInBackground = true; IsInBackground = true;
break; break;
case SDL_APP_WILLENTERFOREGROUND: case SDL_EVENT_WILL_ENTER_FOREGROUND:
IsInBackground = false; IsInBackground = false;
break; break;
case SDL_RENDER_TARGETS_RESET: case SDL_EVENT_RENDER_TARGETS_RESET:
os::Printer::log("Received SDL_RENDER_TARGETS_RESET. Rendering is probably broken.", ELL_ERROR); os::Printer::log("Received SDL_RENDER_TARGETS_RESET. Rendering is probably broken.", ELL_ERROR);
break; break;
case SDL_RENDER_DEVICE_RESET: case SDL_EVENT_RENDER_DEVICE_LOST:
os::Printer::log("Received SDL_RENDER_DEVICE_RESET. Rendering is probably broken.", ELL_ERROR); os::Printer::log("Received SDL_RENDER_DEVICE_RESET. Rendering is probably broken.", ELL_ERROR);
break; break;
@@ -1023,7 +1168,7 @@ bool CIrrDeviceSDL::run()
// open/close in the constructor/destructor instead // open/close in the constructor/destructor instead
// update joystick states manually // update joystick states manually
SDL_JoystickUpdate(); SDL_UpdateJoysticks();
// we'll always send joystick input events... // we'll always send joystick input events...
SEvent joyevent; SEvent joyevent;
joyevent.EventType = EET_JOYSTICK_INPUT_EVENT; joyevent.EventType = EET_JOYSTICK_INPUT_EVENT;
@@ -1032,13 +1177,14 @@ bool CIrrDeviceSDL::run()
if (joystick) { if (joystick) {
int j; int j;
// query all buttons // query all buttons
const int numButtons = core::min_(SDL_JoystickNumButtons(joystick), 32); const int numButtons = core::min_(SDL_GetNumJoystickButtons(joystick), 32);
joyevent.JoystickEvent.ButtonStates = 0; joyevent.JoystickEvent.ButtonStates = 0;
for (j = 0; j < numButtons; ++j) for (j = 0; j < numButtons; ++j)
joyevent.JoystickEvent.ButtonStates |= (SDL_JoystickGetButton(joystick, j) << j); joyevent.JoystickEvent.ButtonStates |= (SDL_GetJoystickButton(joystick, j) << j);
// query all axes, already in correct range // query all axes, already in correct range
const int numAxes = core::min_(SDL_JoystickNumAxes(joystick), (int)SEvent::SJoystickEvent::NUMBER_OF_AXES); const int numAxes = core::min_(SDL_GetNumJoystickAxes(joystick),
(int)SEvent::SJoystickEvent::NUMBER_OF_AXES);
joyevent.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_X] = 0; joyevent.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_X] = 0;
joyevent.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_Y] = 0; joyevent.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_Y] = 0;
joyevent.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_Z] = 0; joyevent.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_Z] = 0;
@@ -1046,11 +1192,11 @@ bool CIrrDeviceSDL::run()
joyevent.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_U] = 0; joyevent.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_U] = 0;
joyevent.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_V] = 0; joyevent.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_V] = 0;
for (j = 0; j < numAxes; ++j) for (j = 0; j < numAxes; ++j)
joyevent.JoystickEvent.Axis[j] = SDL_JoystickGetAxis(joystick, j); joyevent.JoystickEvent.Axis[j] = SDL_GetJoystickAxis(joystick, j);
// we can only query one hat, SDL only supports 8 directions // we can only query one hat, SDL only supports 8 directions
if (SDL_JoystickNumHats(joystick) > 0) { if (SDL_GetNumJoystickHats(joystick) > 0) {
switch (SDL_JoystickGetHat(joystick, 0)) { switch (SDL_GetJoystickHat(joystick, 0)) {
case SDL_HAT_UP: case SDL_HAT_UP:
joyevent.JoystickEvent.POV = 0; joyevent.JoystickEvent.POV = 0;
break; break;
@@ -1101,21 +1247,28 @@ bool CIrrDeviceSDL::activateJoysticks(core::array<SJoystickInfo> &joystickInfo)
#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) #if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_)
joystickInfo.clear(); joystickInfo.clear();
int numJoysticks = 0;
#ifdef _IRR_USE_SDL3_
(void)SDL_GetJoysticks(&numJoysticks);
#else
numJoysticks = SDL_NumJoysticks();
#endif
// we can name up to 256 different joysticks // we can name up to 256 different joysticks
const int numJoysticks = core::min_(SDL_NumJoysticks(), 256); numJoysticks = core::min_(numJoysticks, 256);
Joysticks.reallocate(numJoysticks); Joysticks.reallocate(numJoysticks);
joystickInfo.reallocate(numJoysticks); joystickInfo.reallocate(numJoysticks);
int joystick = 0; int joystick = 0;
for (; joystick < numJoysticks; ++joystick) { for (; joystick < numJoysticks; ++joystick) {
Joysticks.push_back(SDL_JoystickOpen(joystick)); Joysticks.push_back(SDL_OpenJoystick(joystick));
SJoystickInfo info; SJoystickInfo info;
info.Joystick = joystick; info.Joystick = joystick;
info.Axes = SDL_JoystickNumAxes(Joysticks[joystick]); info.Axes = SDL_GetNumJoystickAxes(Joysticks[joystick]);
info.Buttons = SDL_JoystickNumButtons(Joysticks[joystick]); info.Buttons = SDL_GetNumJoystickButtons(Joysticks[joystick]);
info.Name = SDL_JoystickName(Joysticks[joystick]); info.Name = SDL_GetJoystickName(Joysticks[joystick]);
info.PovHat = (SDL_JoystickNumHats(Joysticks[joystick]) > 0) info.PovHat = (SDL_GetNumJoystickHats(Joysticks[joystick]) > 0)
? SJoystickInfo::POV_HAT_PRESENT ? SJoystickInfo::POV_HAT_PRESENT
: SJoystickInfo::POV_HAT_ABSENT; : SJoystickInfo::POV_HAT_ABSENT;
@@ -1143,7 +1296,7 @@ void CIrrDeviceSDL::updateSizeAndScale()
SDL_GetWindowSize(Window, &window_w, &window_h); SDL_GetWindowSize(Window, &window_w, &window_h);
int drawable_w, drawable_h; int drawable_w, drawable_h;
SDL_GL_GetDrawableSize(Window, &drawable_w, &drawable_h); SDL_GetWindowSizeInPixels(Window, &drawable_w, &drawable_h);
ScaleX = (float)drawable_w / (float)window_w; ScaleX = (float)drawable_w / (float)window_w;
ScaleY = (float)drawable_h / (float)window_h; ScaleY = (float)drawable_h / (float)window_h;
@@ -1152,6 +1305,35 @@ void CIrrDeviceSDL::updateSizeAndScale()
Height = drawable_h; Height = drawable_h;
} }
std::string CIrrDeviceSDL::getVersionString() const
{
char buf[32];
#ifdef _IRR_USE_SDL3_
int ver = SDL_GetVersion();
snprintf_irr(buf, sizeof(buf), "%d.%d.%d (%d.%d.%d)",
// Version of the dynamic library
SDL_VERSIONNUM_MAJOR(ver),
SDL_VERSIONNUM_MINOR(ver),
SDL_VERSIONNUM_MICRO(ver),
// Version of the headers
SDL_MAJOR_VERSION,
SDL_MINOR_VERSION,
SDL_MICRO_VERSION
);
return std::string(buf);
#else
SDL_version ver{};
SDL_GetVersion(&ver);
snprintf_irr(buf, sizeof(buf), "%d.%d.%d%s",
ver.major, ver.minor, ver.patch,
// the SDL team seems to intentionally number sdl2-compat this way:
// <https://github.com/libsdl-org/sdl2-compat/tags>
ver.patch >= 50 ? " (compat)" : ""
);
return std::string(buf);
#endif
}
//! Get the display density in dots per inch. //! Get the display density in dots per inch.
float CIrrDeviceSDL::getDisplayDensity() const float CIrrDeviceSDL::getDisplayDensity() const
{ {
@@ -1200,8 +1382,14 @@ bool CIrrDeviceSDL::setWindowIcon(const video::IImage *img)
u32 height = img->getDimension().Height; u32 height = img->getDimension().Height;
u32 width = img->getDimension().Width; u32 width = img->getDimension().Width;
SDL_Surface *surface = SDL_CreateRGBSurface(0, width, height, 32, SDL_Surface *surface =
0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000); #ifdef _IRR_USE_SDL3_
SDL_CreateSurface(width, height, SDL_GetPixelFormatForMasks(
32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000));
#else
SDL_CreateRGBSurface(0, width, height,
32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
#endif
if (!surface) { if (!surface) {
os::Printer::log("Failed to create SDL suface", ELL_ERROR); os::Printer::log("Failed to create SDL suface", ELL_ERROR);
@@ -1214,13 +1402,13 @@ bool CIrrDeviceSDL::setWindowIcon(const video::IImage *img)
if (!succ) { if (!succ) {
os::Printer::log("Could not copy icon image. Is the format not ECF_A8R8G8B8?", ELL_ERROR); os::Printer::log("Could not copy icon image. Is the format not ECF_A8R8G8B8?", ELL_ERROR);
SDL_FreeSurface(surface); SDL_DestroySurface(surface);
return false; return false;
} }
SDL_SetWindowIcon(Window, surface); SDL_SetWindowIcon(Window, surface);
SDL_FreeSurface(surface); SDL_DestroySurface(surface);
return true; return true;
} }
@@ -1240,7 +1428,11 @@ void CIrrDeviceSDL::setResizable(bool resize)
#else // !_IRR_EMSCRIPTEN_PLATFORM_ #else // !_IRR_EMSCRIPTEN_PLATFORM_
if (resize != Resizable) { if (resize != Resizable) {
if (Window) { if (Window) {
#ifdef _IRR_USE_SDL3_
SDL_SetWindowResizable(Window, resize);
#else
SDL_SetWindowResizable(Window, (SDL_bool)resize); SDL_SetWindowResizable(Window, (SDL_bool)resize);
#endif
} }
Resizable = resize; Resizable = resize;
} }
@@ -1283,11 +1475,17 @@ bool CIrrDeviceSDL::isFullscreen() const
{ {
if (!Window) if (!Window)
return false; return false;
u32 flags = SDL_GetWindowFlags(Window); u32 flags = SDL_GetWindowFlags(Window);
return (flags & SDL_WINDOW_FULLSCREEN) != 0 || return (flags & SDL_WINDOW_FULLSCREEN) != 0 ||
#ifdef _IRR_USE_SDL3_
!SDL_GetWindowFullscreenMode(Window); // borderless fullscreen
#else
(flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0; (flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0;
#endif
} }
#ifndef _IRR_USE_SDL3_
u32 CIrrDeviceSDL::getFullscreenFlag(bool fullscreen) u32 CIrrDeviceSDL::getFullscreenFlag(bool fullscreen)
{ {
if (!fullscreen) if (!fullscreen)
@@ -1298,15 +1496,20 @@ u32 CIrrDeviceSDL::getFullscreenFlag(bool fullscreen)
return SDL_WINDOW_FULLSCREEN_DESKTOP; return SDL_WINDOW_FULLSCREEN_DESKTOP;
#endif #endif
} }
#endif
bool CIrrDeviceSDL::setFullscreen(bool fullscreen) bool CIrrDeviceSDL::setFullscreen(bool fullscreen)
{ {
if (!Window) if (!Window)
return false; return false;
#ifdef _IRR_USE_SDL3_
bool success = SDL_SetWindowFullscreen(Window, fullscreen);
#else
// The SDL wiki says that this may trigger SDL_RENDER_TARGETS_RESET, but // The SDL wiki says that this may trigger SDL_RENDER_TARGETS_RESET, but
// looking at the SDL source, this only happens with D3D, so it's not // looking at the SDL source, this only happens with D3D, so it's not
// relevant to us. // relevant to us.
bool success = SDL_SetWindowFullscreen(Window, getFullscreenFlag(fullscreen)) == 0; bool success = SDL_SetWindowFullscreen(Window, getFullscreenFlag(fullscreen)) == 0;
#endif
if (!success) if (!success)
os::Printer::log("SDL_SetWindowFullscreen failed", SDL_GetError(), ELL_ERROR); os::Printer::log("SDL_SetWindowFullscreen failed", SDL_GetError(), ELL_ERROR);
return success; return success;
@@ -1335,8 +1538,12 @@ bool CIrrDeviceSDL::isWindowActive() const
return false; return false;
} }
#endif #endif
const u32 windowFlags = SDL_GetWindowFlags(Window); const u64 windowFlags = SDL_GetWindowFlags(Window);
return windowFlags & SDL_WINDOW_SHOWN && windowFlags & SDL_WINDOW_INPUT_FOCUS; #ifdef _IRR_USE_SDL3_
return !(windowFlags & SDL_WINDOW_HIDDEN) && (windowFlags & SDL_WINDOW_INPUT_FOCUS);
#else
return (windowFlags & SDL_WINDOW_SHOWN) && (windowFlags & SDL_WINDOW_INPUT_FOCUS);
#endif
} }
//! returns if window has focus. //! returns if window has focus.
@@ -1351,6 +1558,7 @@ bool CIrrDeviceSDL::isWindowMinimized() const
return Window && (SDL_GetWindowFlags(Window) & SDL_WINDOW_MINIMIZED) != 0; return Window && (SDL_GetWindowFlags(Window) & SDL_WINDOW_MINIMIZED) != 0;
} }
void CIrrDeviceSDL::createKeyMap() void CIrrDeviceSDL::createKeyMap()
{ {
// I don't know if this is the best method to create // I don't know if this is the best method to create
@@ -1405,32 +1613,13 @@ void CIrrDeviceSDL::createKeyMap()
KeyMap.emplace(SDLK_8, KEY_KEY_8); KeyMap.emplace(SDLK_8, KEY_KEY_8);
KeyMap.emplace(SDLK_9, KEY_KEY_9); KeyMap.emplace(SDLK_9, KEY_KEY_9);
KeyMap.emplace(SDLK_a, KEY_KEY_A); #ifdef _IRR_USE_SDL3_
KeyMap.emplace(SDLK_b, KEY_KEY_B); const u32 sdl_key_A = SDLK_A;
KeyMap.emplace(SDLK_c, KEY_KEY_C); #else
KeyMap.emplace(SDLK_d, KEY_KEY_D); const u32 sdl_key_A = SDLK_a;
KeyMap.emplace(SDLK_e, KEY_KEY_E); #endif
KeyMap.emplace(SDLK_f, KEY_KEY_F); for (u32 i = 0; i <= ('Z' - 'A'); ++i)
KeyMap.emplace(SDLK_g, KEY_KEY_G); KeyMap.emplace(sdl_key_A + i, (EKEY_CODE)(KEY_KEY_A + i));
KeyMap.emplace(SDLK_h, KEY_KEY_H);
KeyMap.emplace(SDLK_i, KEY_KEY_I);
KeyMap.emplace(SDLK_j, KEY_KEY_J);
KeyMap.emplace(SDLK_k, KEY_KEY_K);
KeyMap.emplace(SDLK_l, KEY_KEY_L);
KeyMap.emplace(SDLK_m, KEY_KEY_M);
KeyMap.emplace(SDLK_n, KEY_KEY_N);
KeyMap.emplace(SDLK_o, KEY_KEY_O);
KeyMap.emplace(SDLK_p, KEY_KEY_P);
KeyMap.emplace(SDLK_q, KEY_KEY_Q);
KeyMap.emplace(SDLK_r, KEY_KEY_R);
KeyMap.emplace(SDLK_s, KEY_KEY_S);
KeyMap.emplace(SDLK_t, KEY_KEY_T);
KeyMap.emplace(SDLK_u, KEY_KEY_U);
KeyMap.emplace(SDLK_v, KEY_KEY_V);
KeyMap.emplace(SDLK_w, KEY_KEY_W);
KeyMap.emplace(SDLK_x, KEY_KEY_X);
KeyMap.emplace(SDLK_y, KEY_KEY_Y);
KeyMap.emplace(SDLK_z, KEY_KEY_Z);
KeyMap.emplace(SDLK_LGUI, KEY_LWIN); KeyMap.emplace(SDLK_LGUI, KEY_LWIN);
KeyMap.emplace(SDLK_RGUI, KEY_RWIN); KeyMap.emplace(SDLK_RGUI, KEY_RWIN);
@@ -1492,19 +1681,19 @@ void CIrrDeviceSDL::CCursorControl::initCursors()
{ {
Cursors.reserve(gui::ECI_COUNT); Cursors.reserve(gui::ECI_COUNT);
Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW)); // ECI_NORMAL Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_DEFAULT)); // ECI_NORMAL
Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_CROSSHAIR)); // ECI_CROSS Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_CROSSHAIR)); // ECI_CROSS
Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND)); // ECI_HAND Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_POINTER)); // ECI_HAND
Cursors.emplace_back(nullptr); // ECI_HELP Cursors.emplace_back(nullptr); // ECI_HELP
Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM)); // ECI_IBEAM Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_TEXT)); // ECI_IBEAM
Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO)); // ECI_NO Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NOT_ALLOWED)); // ECI_NO
Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_WAIT)); // ECI_WAIT Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_WAIT)); // ECI_WAIT
Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL)); // ECI_SIZEALL Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_MOVE)); // ECI_SIZEALL
Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW)); // ECI_SIZENESW Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NESW_RESIZE)); // ECI_SIZENESW
Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE)); // ECI_SIZENWSE Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NWSE_RESIZE)); // ECI_SIZENWSE
Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS)); // ECI_SIZENS Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NS_RESIZE)); // ECI_SIZENS
Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE)); // ECI_SIZEWE Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_EW_RESIZE)); // ECI_SIZEWE
Cursors.emplace_back(nullptr); // ECI_UP Cursors.emplace_back(nullptr); // ECI_UP
} }
#endif // _IRR_COMPILE_WITH_SDL_DEVICE_ #endif // _IRR_COMPILE_WITH_SDL_DEVICE_

View File

@@ -16,7 +16,13 @@
#include <emscripten/html5.h> #include <emscripten/html5.h>
#endif #endif
#ifdef _IRR_USE_SDL3_
#define SDL_DISABLE_OLD_NAMES
#include <SDL3/SDL.h>
#include <SDL3/SDL_mouse.h>
#else
#include <SDL.h> #include <SDL.h>
#endif
#include <memory> #include <memory>
#include <unordered_map> #include <unordered_map>
@@ -99,12 +105,7 @@ public:
} }
//! Get the SDL version //! Get the SDL version
std::string getVersionString() const override std::string getVersionString() const override;
{
SDL_version ver;
SDL_GetVersion(&ver);
return std::to_string(ver.major) + "." + std::to_string(ver.minor) + "." + std::to_string(ver.patch);
}
//! Get the display density in dots per inch. //! Get the display density in dots per inch.
float getDisplayDensity() const override; float getDisplayDensity() const override;
@@ -125,11 +126,14 @@ public:
void setVisible(bool visible) override void setVisible(bool visible) override
{ {
IsVisible = visible; IsVisible = visible;
#ifdef _IRR_USE_SDL3_
if (visible) if (visible)
SDL_ShowCursor(SDL_ENABLE); SDL_ShowCursor();
else { else
SDL_ShowCursor(SDL_DISABLE); SDL_HideCursor();
} #else
SDL_ShowCursor(visible ? SDL_ENABLE : SDL_DISABLE);
#endif
} }
//! Returns if the cursor is currently visible. //! Returns if the cursor is currently visible.
@@ -166,8 +170,11 @@ public:
static_cast<int>(x / Device->ScaleX), static_cast<int>(x / Device->ScaleX),
static_cast<int>(y / Device->ScaleY)); static_cast<int>(y / Device->ScaleY));
#endif #endif
#ifdef _IRR_USE_SDL3_
if (SDL_GetWindowRelativeMouseMode(Device->Window)) {
#else
if (SDL_GetRelativeMouseMode()) { if (SDL_GetRelativeMouseMode()) {
#endif
// There won't be an event for this warp (details on libsdl-org/SDL/issues/6034) // There won't be an event for this warp (details on libsdl-org/SDL/issues/6034)
Device->MouseX = x; Device->MouseX = x;
Device->MouseY = y; Device->MouseY = y;
@@ -197,13 +204,16 @@ public:
virtual void setRelativeMode(bool relative) override virtual void setRelativeMode(bool relative) override
{ {
#ifdef _IRR_USE_SDL3_
if (relative != (bool)SDL_GetWindowRelativeMouseMode(Device->Window)) {
SDL_SetWindowRelativeMouseMode(Device->Window, relative);
}
#else
// Only change it when necessary, as it flushes mouse motion when enabled // Only change it when necessary, as it flushes mouse motion when enabled
if (relative != static_cast<bool>(SDL_GetRelativeMouseMode())) { if (relative != static_cast<bool>(SDL_GetRelativeMouseMode())) {
if (relative) SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE);
SDL_SetRelativeMouseMode(SDL_TRUE);
else
SDL_SetRelativeMouseMode(SDL_FALSE);
} }
#endif
} }
void setActiveIcon(gui::ECURSOR_ICON iconId) override void setActiveIcon(gui::ECURSOR_ICON iconId) override
@@ -263,8 +273,13 @@ public:
{ {
void operator()(SDL_Cursor *ptr) void operator()(SDL_Cursor *ptr)
{ {
#ifdef _IRR_USE_SDL3_
if (ptr)
SDL_DestroyCursor(ptr);
#else
if (ptr) if (ptr)
SDL_FreeCursor(ptr); SDL_FreeCursor(ptr);
#endif
} }
}; };
std::vector<std::unique_ptr<SDL_Cursor, CursorDeleter>> Cursors; std::vector<std::unique_ptr<SDL_Cursor, CursorDeleter>> Cursors;
@@ -282,7 +297,7 @@ private:
static bool keyIsKnownSpecial(EKEY_CODE irrlichtKey); static bool keyIsKnownSpecial(EKEY_CODE irrlichtKey);
// Return the Char that should be sent to Irrlicht for the given key (either the one passed in or 0). // Return the Char that should be sent to Irrlicht for the given key (either the one passed in or 0).
static int findCharToPassToIrrlicht(uint32_t sdlKey, EKEY_CODE irrlichtKey, bool numlock); static wchar_t findCharToPassToIrrlicht(uint32_t sdlKey, EKEY_CODE irrlichtKey, u16 keymod);
std::variant<u32, EKEY_CODE> getScancodeFromKey(const Keycode &key) const override; std::variant<u32, EKEY_CODE> getScancodeFromKey(const Keycode &key) const override;
Keycode getKeyFromScancode(const u32 scancode) const override; Keycode getKeyFromScancode(const u32 scancode) const override;
@@ -316,7 +331,9 @@ private:
bool Resizable; bool Resizable;
#ifndef _IRR_USE_SDL3_
static u32 getFullscreenFlag(bool fullscreen); static u32 getFullscreenFlag(bool fullscreen);
#endif // SDL3: Replaced by boolean
core::rect<s32> lastElemPos; core::rect<s32> lastElemPos;

View File

@@ -1,5 +1,11 @@
set(DEFAULT_SDL3 OFF)
option(USE_SDL2_STATIC "Link with SDL2 static libraries" FALSE) option(USE_SDL2_STATIC "Link with SDL2 static libraries" FALSE)
option(USE_SDL3 "Use the SDL3 backend instead of SDL3" ${DEFAULT_SDL3})
option(USE_SDL3_STATIC "Link with SDL3 static libraries" FALSE)
# Compiler flags # Compiler flags
if(CMAKE_BUILD_TYPE STREQUAL "Debug") if(CMAKE_BUILD_TYPE STREQUAL "Debug")
@@ -165,8 +171,25 @@ endif()
if(ENABLE_OPENGL) if(ENABLE_OPENGL)
find_package(OpenGL REQUIRED) find_package(OpenGL REQUIRED)
endif() endif()
set(USE_SDL2_SHARED FALSE) set(USE_SDL2_SHARED FALSE)
if(TRUE) if(USE_SDL3)
set(USE_SDL2_STATIC FALSE) # do not attempt to link against SDL2
# https://wiki.libsdl.org/SDL3/README-cmake#a-system-sdl-library
if(USE_SDL3_STATIC)
set(SDL3_SUFFIX "static")
else()
set(SDL3_SUFFIX "shared")
endif()
find_package(SDL3 REQUIRED CONFIG REQUIRED COMPONENTS SDL3-${SDL3_SUFFIX})
message(STATUS "Found SDL3: ${SDL3_VERSION} (${SDL3_SUFFIX} library)")
# https://github.com/libsdl-org/SDL/blob/release-3.2.x/include/SDL3/SDL_opengl_glext.h#L2859
set(USE_SDL_OPENGL_4_5_HEADER TRUE)
else()
# Fall back to SDL2
if(NOT USE_SDL2_STATIC) if(NOT USE_SDL2_STATIC)
set(USE_SDL2_SHARED TRUE) set(USE_SDL2_SHARED TRUE)
endif() endif()
@@ -199,20 +222,22 @@ endif()
# More special config # More special config
if(ENABLE_OPENGL) if(USE_SDL2 AND ENABLE_OPENGL)
# The legacy GL driver requires some symbols from GL 4.5 to compile,
# which SDL only provides since 2.26.0 (Nov 2022).
# We have a fallback in case this isn't satisfied so test for it.
set(CMAKE_REQUIRED_INCLUDES ${SDL2_INCLUDE_DIRS}) set(CMAKE_REQUIRED_INCLUDES ${SDL2_INCLUDE_DIRS})
unset(CHECK_GL_VERSION_4_5 CACHE) unset(USE_SDL_OPENGL_4_5_HEADER CACHE) # Why?
check_cxx_source_compiles("#include <SDL_opengl.h>\n\ check_cxx_source_compiles("#include <SDL_opengl.h>\n\
#ifndef GL_VERSION_4_5\n\ #ifndef GL_VERSION_4_5\n\
#error\n\ #error\n\
#endif\n\ #endif\n\
int main() {}" CHECK_GL_VERSION_4_5) int main() {}" USE_SDL_OPENGL_4_5_HEADER)
if(CHECK_GL_VERSION_4_5) endif()
add_compile_definitions(IRR_PREFER_SDL_GL_HEADER)
endif() if(USE_SDL_OPENGL_4_5_HEADER)
# The legacy GL driver requires some symbols from GL 4.5 to compile,
# which SDL only provides since 2.26.0 (Nov 2022).
# We have a fallback in case this isn't satisfied so test for it.
add_compile_definitions(IRR_PREFER_SDL_GL_HEADER)
message(STATUS "Using SDL OpenGL header")
endif() endif()
# Platform-specific libs # Platform-specific libs
@@ -228,7 +253,7 @@ set(link_includes
"${ZLIB_INCLUDE_DIR}" "${ZLIB_INCLUDE_DIR}"
"${JPEG_INCLUDE_DIR}" "${JPEG_INCLUDE_DIR}"
"${PNG_INCLUDE_DIR}" "${PNG_INCLUDE_DIR}"
"${SDL2_INCLUDE_DIRS}" "$<$<NOT:$<BOOL:${USE_SDL3}>>:${SDL2_INCLUDE_DIRS}>"
${OPENGL_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR}
${OPENGLES2_INCLUDE_DIR} ${OPENGLES2_INCLUDE_DIR}
@@ -387,6 +412,12 @@ if(APPLE)
set_target_properties(IRROTHEROBJ PROPERTIES COMPILE_OPTIONS "-xobjective-c++") set_target_properties(IRROTHEROBJ PROPERTIES COMPILE_OPTIONS "-xobjective-c++")
endif() endif()
if(USE_SDL3)
include_directories(IRROTHEROBJ $<TARGET_PROPERTY:SDL3::Headers,INTERFACE_INCLUDE_DIRECTORIES>)
target_compile_definitions(IRROTHEROBJ PRIVATE _IRR_USE_SDL3_)
target_compile_definitions(IRRVIDEOOBJ PRIVATE _IRR_USE_SDL3_) # OpenGL/Common.h
endif()
add_library(IRRGUIOBJ OBJECT add_library(IRRGUIOBJ OBJECT
CGUIButton.h CGUIButton.h
CGUICheckBox.h CGUICheckBox.h
@@ -485,6 +516,8 @@ target_link_libraries(IrrlichtMt PRIVATE
"$<$<BOOL:${USE_SDL2_SHARED}>:SDL2::SDL2>" "$<$<BOOL:${USE_SDL2_SHARED}>:SDL2::SDL2>"
"$<$<BOOL:${USE_SDL2_STATIC}>:SDL2::SDL2-static>" "$<$<BOOL:${USE_SDL2_STATIC}>:SDL2::SDL2-static>"
"$<$<BOOL:${USE_SDL3}>:SDL3::SDL3-${SDL3_SUFFIX}>"
"$<$<BOOL:${OPENGL_DIRECT_LINK}>:${OPENGL_LIBRARIES}>" "$<$<BOOL:${OPENGL_DIRECT_LINK}>:${OPENGL_LIBRARIES}>"
${EGL_LIBRARY} ${EGL_LIBRARY}

View File

@@ -17,9 +17,13 @@
#endif #endif
#endif #endif
#if defined(_IRR_COMPILE_WITH_SDL_DEVICE_) // "SDL_version.h" for SDL_VERSION_ATLEAST
#include <SDL_clipboard.h> #ifdef _IRR_USE_SDL3_
#include <SDL_version.h> #include <SDL3/SDL_clipboard.h>
#include <SDL3/SDL_version.h>
#else
#include <SDL_clipboard.h>
#include <SDL_version.h>
#endif #endif
#include "fast_atof.h" #include "fast_atof.h"
@@ -89,4 +93,3 @@ const c8 *COSOperator::getTextFromPrimarySelection() const
return 0; return 0;
#endif #endif
} }

View File

@@ -7,8 +7,12 @@
#ifdef _IRR_COMPILE_WITH_OPENGL_ #ifdef _IRR_COMPILE_WITH_OPENGL_
#if defined(_IRR_COMPILE_WITH_SDL_DEVICE_) && defined(IRR_PREFER_SDL_GL_HEADER) #if defined(_IRR_COMPILE_WITH_SDL_DEVICE_) && defined(IRR_PREFER_SDL_GL_HEADER)
#include <SDL_video.h> #ifdef _IRR_USE_SDL3_
#include <SDL_opengl.h> #include <SDL3/SDL_opengl.h>
#else
#include <SDL_video.h>
#include <SDL_opengl.h>
#endif
#else #else
#include "vendor/gl.h" #include "vendor/gl.h"
#endif #endif

View File

@@ -33,7 +33,7 @@ bool CSDLManager::activateContext(const SExposedVideoData &videoData, bool resto
void *CSDLManager::getProcAddress(const std::string &procName) void *CSDLManager::getProcAddress(const std::string &procName)
{ {
return SDL_GL_GetProcAddress(procName.c_str()); return (void *)SDL_GL_GetProcAddress(procName.c_str());
} }
bool CSDLManager::swapBuffers() bool CSDLManager::swapBuffers()

View File

@@ -8,8 +8,12 @@
#include "irrTypes.h" #include "irrTypes.h"
// even though we have mt_opengl.h our driver code still uses GL_* constants // even though we have mt_opengl.h our driver code still uses GL_* constants
#if defined(_IRR_COMPILE_WITH_SDL_DEVICE_) #if defined(_IRR_COMPILE_WITH_SDL_DEVICE_)
#include <SDL_video.h> #ifdef _IRR_USE_SDL3_
#include <SDL_opengl.h> #include <SDL3/SDL_opengl.h>
#else
#include <SDL_video.h>
#include <SDL_opengl.h>
#endif
#else #else
#include "vendor/gl.h" #include "vendor/gl.h"
#endif #endif

View File

@@ -7,7 +7,11 @@
#include "irrMath.h" #include "irrMath.h"
#if defined(_IRR_COMPILE_WITH_SDL_DEVICE_) #if defined(_IRR_COMPILE_WITH_SDL_DEVICE_)
#include <SDL_endian.h> #ifdef _IRR_USE_SDL3_
#include <SDL3/SDL_endian.h>
#else
#include <SDL_endian.h>
#endif
#define bswap_16(X) SDL_Swap16(X) #define bswap_16(X) SDL_Swap16(X)
#define bswap_32(X) SDL_Swap32(X) #define bswap_32(X) SDL_Swap32(X)
#define bswap_64(X) SDL_Swap64(X) #define bswap_64(X) SDL_Swap64(X)