changeset 613:f76cada0bbb2

misc: switch to SDL3
author David Demelier <markand@malikania.fr>
date Sun, 20 Aug 2023 11:14:58 +0200
parents 297fa28cac90
children 281608524dd1
files CMakeLists.txt INSTALL.md cmake/FindSDL2.cmake libmlk-core/CMakeLists.txt libmlk-core/mlk/core/event.c libmlk-core/mlk/core/gamepad.c libmlk-core/mlk/core/gamepad.h libmlk-core/mlk/core/painter.c libmlk-core/mlk/core/sys.c libmlk-core/mlk/core/texture.c libmlk-core/mlk/core/window.c libmlk-util/CMakeLists.txt libmlk-util/libmlk-util-config.cmake
diffstat 13 files changed, 95 insertions(+), 188 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Sun Aug 20 10:48:57 2023 +0200
+++ b/CMakeLists.txt	Sun Aug 20 11:14:58 2023 +0200
@@ -70,10 +70,12 @@
 include(cmake/MlkNls.cmake)
 include(cmake/MlkTileset.cmake)
 
-find_package(SDL2 MODULE REQUIRED COMPONENTS image ttf)
+find_package(Jansson REQUIRED)
 find_package(OpenAL REQUIRED)
+find_package(SDL3 REQUIRED)
+find_package(SDL3_image REQUIRED)
+find_package(SDL3_ttf REQUIRED)
 find_package(SndFile REQUIRED)
-find_package(Jansson REQUIRED)
 
 # POSIX math library isn't available everywhere.
 find_library(M_LIBRARY m)
@@ -110,10 +112,6 @@
 	add_subdirectory(examples)
 endif ()
 
-#
-# SDL2 is not always configured using CMake on some systems which means the
-# CMake configuration file isn't provided, so use our own...
-#
 configure_file(
 	${molko_SOURCE_DIR}/cmake/MlkOptions.install.cmake
 	${molko_BINARY_DIR}/cmake/MlkOptions.cmake
@@ -121,7 +119,6 @@
 install(
 	FILES
 		${molko_BINARY_DIR}/cmake/MlkOptions.cmake
-		${molko_SOURCE_DIR}/cmake/FindSDL2.cmake
 		${molko_SOURCE_DIR}/cmake/FindSndFile.cmake
 		${molko_SOURCE_DIR}/cmake/MlkBcc.cmake
 		${molko_SOURCE_DIR}/cmake/MlkMap.cmake
--- a/INSTALL.md	Sun Aug 20 10:48:57 2023 +0200
+++ b/INSTALL.md	Sun Aug 20 11:14:58 2023 +0200
@@ -9,10 +9,10 @@
 - C23 compliant compiler.
 - [CMake][], Make build system.
 - [Jansson][], JSON parsing library.
-- [SDL2][], Multimedia library.
-- [SDL2_image][], Image loading addon for SDL2.
-- [SDL2_mixer][], Audio addon for SDL2.
-- [SDL2_ttf][], Fonts addon for SDL2.
+- [SDL3][], Multimedia library.
+- [SDL3_image][], Image loading addon for SDL3.
+- [SDL3_mixer][], Audio addon for SDL3.
+- [SDL3_ttf][], Fonts addon for SDL3.
 
 Molko's Engine is mostly written in C23 with a very limited POSIX extensions
 (including `stat`, `strlcpy`, `fmemopen`) but where support is missing fallback
@@ -65,10 +65,10 @@
 You will need the following packages:
 
 - *jansson*
-- *sdl2*
-- *sdl2_image*
-- *sdl2_mixer*
-- *sdl2_ttf*
+- *sdl3*
+- *sdl3_image*
+- *sdl3_mixer*
+- *sdl3_ttf*
 
 Platform: Windows
 -----------------
@@ -80,10 +80,10 @@
 Once you have MSYS2 installed, simply install the following packages from the
 appropriate MinGW shell prior to the chapter above.
 
-- *mingw-w64-clang-x86_64-SDL2*
-- *mingw-w64-clang-x86_64-SDL2_image*
-- *mingw-w64-clang-x86_64-SDL2_mixer*
-- *mingw-w64-clang-x86_64-SDL2_ttf*
+- *mingw-w64-clang-x86_64-SDL3*
+- *mingw-w64-clang-x86_64-SDL3_image*
+- *mingw-w64-clang-x86_64-SDL3_mixer*
+- *mingw-w64-clang-x86_64-SDL3_ttf*
 - *mingw-w64-clang-x86_64-jansson*
 
 Note: replace `x86_64` with `i686` if you have a deprecated system or if you
@@ -109,8 +109,8 @@
 [CMake]: http://cmake.org
 [Jansson]: http://www.digip.org/jansson
 [MSYS2]: http://www.msys2.org
-[SDL2]: http://libsdl.org
-[SDL2_image]: https://www.libsdl.org/projects/SDL_image
-[SDL2_mixer]: https://www.libsdl.org/projects/SDL_mixer
-[SDL2_ttf]: https://www.libsdl.org/projects/SDL_ttf
+[SDL3]: http://libsdl.org
+[SDL3_image]: https://www.libsdl.org/projects/SDL_image
+[SDL3_mixer]: https://www.libsdl.org/projects/SDL_mixer
+[SDL3_ttf]: https://www.libsdl.org/projects/SDL_ttf
 [gettext]: https://www.gnu.org/software/gettext
--- a/cmake/FindSDL2.cmake	Sun Aug 20 10:48:57 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-# FindSDL2
-# --------
-#
-# Find SDL2 library and components, this modules defines:
-#
-#  SDL2_LIBRARY, the name of the library to link against.
-#  SDL2_MAIN_LIBRARY, for SDL2main (if present).
-#  SDL2_LIBRARIES, alias to SDL2_LIBRARY.
-#  SDL2_FOUND, true if found.
-#  SDL2_INCLUDE_DIR, where to find SDL.h.
-#
-# The following imported targets will be defined:
-#
-# SDL2::SDL2
-# SDL2::SDL2main (if present)
-#
-# This module also handle the following official SDL addons:
-#
-# - image
-# - mixer
-# - net
-# - ttf
-#
-# And thus, variables SDL2_<C>_LIBRARY, SDL2_<C>_INCLUDE_DIRS and SDL2::<C>
-# imported targets will be defined if they are found.
-#
-
-include(FindPackageHandleStandardArgs)
-
-# The official include convention is <SDL.h> not <SDL/SDL.h>.
-find_path(
-	SDL2_INCLUDE_DIR
-	NAMES SDL.h
-	PATH_SUFFIXES include/SDL2 include
-)
-
-find_library(SDL2_LIBRARY NAMES SDL2 libSDL2 SDL2d libSDL2d)
-find_library(SDL2_MAIN_LIBRARY NAMES SDL2main libSDL2main SDL2maind libSDL2maind)
-
-# Standard components.
-foreach (c ${SDL2_FIND_COMPONENTS})
-	find_path(
-		SDL2_${c}_INCLUDE_DIR
-		NAMES SDL.h
-		PATH_SUFFIXES include/SDL2 include
-	)
-
-	find_library(
-		SDL2_${c}_LIBRARY
-		NAMES SDL2_${c} libSDL2_${c} SDL2_${c}d SDL2_${c}_d
-	)
-
-	if (NOT TARGET SDL2::${c} AND SDL2_${c}_LIBRARY)
-		set(SDL2_${c}_FOUND TRUE)
-		add_library(SDL2::${c} UNKNOWN IMPORTED)
-		set_target_properties(
-			SDL2::${c}
-			PROPERTIES
-				IMPORTED_LINK_INTERFACE_LANGUAGES "C"
-				IMPORTED_LOCATION "${SDL2_${c}_LIBRARY}"
-				INTERFACE_INCLUDE_DIRECTORIES "${SDL2_${c}_INCLUDE_DIRS}"
-		)
-	endif ()
-
-	mark_as_advanced(SDL2_${c}_INCLUDE_DIR SDL2_${c}_LIBRARY)
-endforeach ()
-
-find_package_handle_standard_args(
-	SDL2
-	REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR
-	HANDLE_COMPONENTS
-)
-
-if (SDL2_FOUND)
-	set(SDL2_LIBRARIES ${SDL2_LIBRARY})
-	set(SDL2_INCLUDE_DIRS ${SDL2_INCLUDE_DIR})
-
-	if (NOT TARGET SDL2::SDL2)
-		add_library(SDL2::SDL2 UNKNOWN IMPORTED)
-		set_target_properties(
-			SDL2::SDL2
-			PROPERTIES
-				IMPORTED_LINK_INTERFACE_LANGUAGES "C"
-				IMPORTED_LOCATION "${SDL2_LIBRARY}"
-				INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIRS}"
-		)
-	endif ()
-
-	if (NOT TARGET SDL2::main AND SDL2_MAIN_LIBRARY)
-		add_library(SDL2::main UNKNOWN IMPORTED)
-		set_target_properties(
-			SDL2::main
-			PROPERTIES
-				IMPORTED_LINK_INTERFACE_LANGUAGES "C"
-				IMPORTED_LOCATION "${SDL2_MAIN_LIBRARY}"
-				INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIRS}"
-		)
-	endif ()
-endif ()
-
-mark_as_advanced(SDL2_INCLUDE_DIR SDL2_LIBRARY)
--- a/libmlk-core/CMakeLists.txt	Sun Aug 20 10:48:57 2023 +0200
+++ b/libmlk-core/CMakeLists.txt	Sun Aug 20 11:14:58 2023 +0200
@@ -121,9 +121,9 @@
 			${LIBRARIES}
 			${OPENAL_LIBRARY}
 			SndFile::SndFile
-			SDL2::SDL2
-			SDL2::image
-			SDL2::ttf
+			SDL3::SDL3
+			SDL3_image::SDL3_image-shared
+			SDL3_ttf::SDL3_ttf-shared
 			libmlk-util
 	INCLUDES
 		PUBLIC
--- a/libmlk-core/mlk/core/event.c	Sun Aug 20 10:48:57 2023 +0200
+++ b/libmlk-core/mlk/core/event.c	Sun Aug 20 11:14:58 2023 +0200
@@ -16,6 +16,8 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <string.h>
+
 #include <SDL.h>
 
 #include "event.h"
@@ -180,28 +182,28 @@
 	int button;
 	enum mlk_gamepad_button value;
 } pads[] = {
-	{ SDL_CONTROLLER_BUTTON_A,              MLK_GAMEPAD_BUTTON_A            },
-	{ SDL_CONTROLLER_BUTTON_B,              MLK_GAMEPAD_BUTTON_B            },
-	{ SDL_CONTROLLER_BUTTON_X,              MLK_GAMEPAD_BUTTON_X            },
-	{ SDL_CONTROLLER_BUTTON_Y,              MLK_GAMEPAD_BUTTON_Y            },
-	{ SDL_CONTROLLER_BUTTON_BACK,           MLK_GAMEPAD_BUTTON_BACK         },
-	{ SDL_CONTROLLER_BUTTON_GUIDE,          MLK_GAMEPAD_BUTTON_LOGO         },
-	{ SDL_CONTROLLER_BUTTON_START,          MLK_GAMEPAD_BUTTON_START        },
-	{ SDL_CONTROLLER_BUTTON_LEFTSTICK,      MLK_GAMEPAD_BUTTON_LTHUMB       },
-	{ SDL_CONTROLLER_BUTTON_RIGHTSTICK,     MLK_GAMEPAD_BUTTON_RTHUMB       },
-	{ SDL_CONTROLLER_BUTTON_LEFTSHOULDER,   MLK_GAMEPAD_BUTTON_LSHOULDER    },
-	{ SDL_CONTROLLER_BUTTON_RIGHTSHOULDER,  MLK_GAMEPAD_BUTTON_RSHOULDER    },
-	{ SDL_CONTROLLER_BUTTON_DPAD_UP,        MLK_GAMEPAD_BUTTON_UP           },
-	{ SDL_CONTROLLER_BUTTON_DPAD_DOWN,      MLK_GAMEPAD_BUTTON_DOWN         },
-	{ SDL_CONTROLLER_BUTTON_DPAD_LEFT,      MLK_GAMEPAD_BUTTON_LEFT         },
-	{ SDL_CONTROLLER_BUTTON_DPAD_RIGHT,     MLK_GAMEPAD_BUTTON_RIGHT        },
+	{ SDL_GAMEPAD_BUTTON_A,                 MLK_GAMEPAD_BUTTON_A            },
+	{ SDL_GAMEPAD_BUTTON_B,                 MLK_GAMEPAD_BUTTON_B            },
+	{ SDL_GAMEPAD_BUTTON_X,                 MLK_GAMEPAD_BUTTON_X            },
+	{ SDL_GAMEPAD_BUTTON_Y,                 MLK_GAMEPAD_BUTTON_Y            },
+	{ SDL_GAMEPAD_BUTTON_BACK,              MLK_GAMEPAD_BUTTON_BACK         },
+	{ SDL_GAMEPAD_BUTTON_GUIDE,             MLK_GAMEPAD_BUTTON_LOGO         },
+	{ SDL_GAMEPAD_BUTTON_START,             MLK_GAMEPAD_BUTTON_START        },
+	{ SDL_GAMEPAD_BUTTON_LEFT_STICK,        MLK_GAMEPAD_BUTTON_LTHUMB       },
+	{ SDL_GAMEPAD_BUTTON_RIGHT_STICK,       MLK_GAMEPAD_BUTTON_RTHUMB       },
+	{ SDL_GAMEPAD_BUTTON_LEFT_SHOULDER,     MLK_GAMEPAD_BUTTON_LSHOULDER    },
+	{ SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER,    MLK_GAMEPAD_BUTTON_RSHOULDER    },
+	{ SDL_GAMEPAD_BUTTON_DPAD_UP,           MLK_GAMEPAD_BUTTON_UP           },
+	{ SDL_GAMEPAD_BUTTON_DPAD_DOWN,         MLK_GAMEPAD_BUTTON_DOWN         },
+	{ SDL_GAMEPAD_BUTTON_DPAD_LEFT,         MLK_GAMEPAD_BUTTON_LEFT         },
+	{ SDL_GAMEPAD_BUTTON_DPAD_RIGHT,        MLK_GAMEPAD_BUTTON_RIGHT        },
 	{ -1,                                   MLK_GAMEPAD_BUTTON_UNKNOWN      }
 };
 
 static void
 convert_key(const SDL_Event *event, union mlk_event *ev)
 {
-	ev->type = event->type == SDL_KEYDOWN ? MLK_EVENT_KEYDOWN : MLK_EVENT_KEYUP;
+	ev->type = event->type == SDL_EVENT_KEY_DOWN ? MLK_EVENT_KEYDOWN : MLK_EVENT_KEYUP;
 	ev->key.key = MLK_KEY_UNKNOWN;
 
 	for (size_t i = 0; keymap[i].key != 0; ++i) {
@@ -231,7 +233,7 @@
 static void
 convert_click(const SDL_Event *event, union mlk_event *ev)
 {
-	ev->type = event->type == SDL_MOUSEBUTTONDOWN ? MLK_EVENT_CLICKDOWN : MLK_EVENT_CLICKUP;
+	ev->type = event->type == SDL_EVENT_MOUSE_BUTTON_DOWN ? MLK_EVENT_CLICKDOWN : MLK_EVENT_CLICKUP;
 	ev->click.button = MLK_MOUSE_BUTTON_NONE;
 	ev->click.x = event->button.x;
 	ev->click.y = event->button.y;
@@ -248,10 +250,10 @@
 static void
 convert_pad(const SDL_Event *event, union mlk_event *ev)
 {
-	ev->type = event->type == SDL_CONTROLLERBUTTONDOWN ? MLK_EVENT_PADDOWN : MLK_EVENT_PADUP;
+	ev->type = event->type == SDL_EVENT_GAMEPAD_BUTTON_DOWN ? MLK_EVENT_PADDOWN : MLK_EVENT_PADUP;
 
 	for (size_t i = 0; pads[i].value != MLK_GAMEPAD_BUTTON_UNKNOWN; ++i) {
-		if (pads[i].button == event->cbutton.button) {
+		if (pads[i].button == event->gbutton.button) {
 			ev->pad.button = pads[i].value;
 			break;
 		}
@@ -262,12 +264,12 @@
 	int axis;
 	enum mlk_gamepad_axis value;
 } axises[] = {
-	{ SDL_CONTROLLER_AXIS_LEFTX,            MLK_GAMEPAD_AXIS_LX             },
-	{ SDL_CONTROLLER_AXIS_LEFTY,            MLK_GAMEPAD_AXIS_LY             },
-	{ SDL_CONTROLLER_AXIS_RIGHTX,           MLK_GAMEPAD_AXIS_RX             },
-	{ SDL_CONTROLLER_AXIS_RIGHTY,           MLK_GAMEPAD_AXIS_RY             },
-	{ SDL_CONTROLLER_AXIS_TRIGGERLEFT,      MLK_GAMEPAD_AXIS_LTRIGGER       },
-	{ SDL_CONTROLLER_AXIS_TRIGGERRIGHT,     MLK_GAMEPAD_AXIS_RTRIGGER       },
+	{ SDL_GAMEPAD_AXIS_LEFTX,               MLK_GAMEPAD_AXIS_LX             },
+	{ SDL_GAMEPAD_AXIS_LEFTY,               MLK_GAMEPAD_AXIS_LY             },
+	{ SDL_GAMEPAD_AXIS_RIGHTX,              MLK_GAMEPAD_AXIS_RX             },
+	{ SDL_GAMEPAD_AXIS_RIGHTY,              MLK_GAMEPAD_AXIS_RY             },
+	{ SDL_GAMEPAD_AXIS_LEFT_TRIGGER,        MLK_GAMEPAD_AXIS_LTRIGGER       },
+	{ SDL_GAMEPAD_AXIS_RIGHT_TRIGGER,       MLK_GAMEPAD_AXIS_RTRIGGER       },
 	{ -1,                                   MLK_GAMEPAD_AXIS_UNKNOWN        }
 };
 
@@ -275,10 +277,10 @@
 convert_axis(const SDL_Event *event, union mlk_event *ev)
 {
 	ev->type = MLK_EVENT_AXIS;
-	ev->axis.value = event->caxis.value;
+	ev->axis.value = event->gaxis.value;
 
 	for (size_t i = 0; axises[i].value != MLK_GAMEPAD_AXIS_UNKNOWN; ++i) {
-		if (axises[i].axis == event->caxis.axis) {
+		if (axises[i].axis == event->gaxis.axis) {
 			ev->axis.axis = axises[i].value;
 			break;
 		}
@@ -298,25 +300,25 @@
 	 */
 	while (SDL_PollEvent(&event)) {
 		switch (event.type) {
-		case SDL_QUIT:
+		case SDL_EVENT_QUIT:
 			ev->type = MLK_EVENT_QUIT;
 			return 1;
-		case SDL_KEYDOWN:
-		case SDL_KEYUP:
+		case SDL_EVENT_KEY_DOWN:
+		case SDL_EVENT_KEY_UP:
 			convert_key(&event, ev);
 			return 1;
-		case SDL_MOUSEMOTION:
+		case SDL_EVENT_MOUSE_MOTION:
 			convert_mouse(&event, ev);
 			return 1;
-		case SDL_MOUSEBUTTONDOWN:
-		case SDL_MOUSEBUTTONUP:
+		case SDL_EVENT_MOUSE_BUTTON_DOWN:
+		case SDL_EVENT_MOUSE_BUTTON_UP:
 			convert_click(&event, ev);
 			return 1;
-		case SDL_CONTROLLERBUTTONDOWN:
-		case SDL_CONTROLLERBUTTONUP:
+		case SDL_EVENT_GAMEPAD_BUTTON_DOWN:
+		case SDL_EVENT_GAMEPAD_BUTTON_UP:
 			convert_pad(&event, ev);
 			return 1;
-		case SDL_CONTROLLERAXISMOTION:
+		case SDL_EVENT_GAMEPAD_AXIS_MOTION:
 			convert_axis(&event, ev);
 			return 1;
 		default:
--- a/libmlk-core/mlk/core/gamepad.c	Sun Aug 20 10:48:57 2023 +0200
+++ b/libmlk-core/mlk/core/gamepad.c	Sun Aug 20 11:14:58 2023 +0200
@@ -31,7 +31,7 @@
 
 	memset(pad, 0, sizeof (*pad));
 
-	if (!(pad->handle = SDL_GameControllerOpen(idx)))
+	if (!(pad->handle = SDL_OpenGamepad(idx)))
 		return mlk_errf("%s", SDL_GetError());
 
 	return 0;
@@ -43,11 +43,13 @@
 	assert(pad);
 
 	if (pad->handle)
-		SDL_GameControllerClose(pad->handle);
+		SDL_CloseGamepad(pad->handle);
 
 	memset(pad, 0, sizeof (*pad));
 }
 
+#if 0
+
 int
 mlk_gamepad_iter_begin(struct mlk_gamepad_iter *it)
 {
@@ -84,3 +86,5 @@
 
 	return 1;
 }
+
+#endif
--- a/libmlk-core/mlk/core/gamepad.h	Sun Aug 20 10:48:57 2023 +0200
+++ b/libmlk-core/mlk/core/gamepad.h	Sun Aug 20 11:14:58 2023 +0200
@@ -174,6 +174,8 @@
 	/** \endcond MLK_PRIVATE_DECLS */
 };
 
+#if 0
+
 /**
  * \struct mlk_gamepad_iter
  * \brief Iterate over all plugged gamepads.
@@ -247,6 +249,8 @@
 int
 mlk_gamepad_iter_next(struct mlk_gamepad_iter *iter);
 
+#endif
+
 #if defined(__cplusplus)
 }
 #endif
--- a/libmlk-core/mlk/core/painter.c	Sun Aug 20 10:48:57 2023 +0200
+++ b/libmlk-core/mlk/core/painter.c	Sun Aug 20 11:14:58 2023 +0200
@@ -65,19 +65,19 @@
 void
 mlk_painter_draw_line(int x1, int y1, int x2, int y2)
 {
-	SDL_RenderDrawLine(MLK__RENDERER(), x1, y1, x2, y2);
+	SDL_RenderLine(MLK__RENDERER(), x1, y1, x2, y2);
 }
 
 void
 mlk_painter_draw_point(int x1, int y1)
 {
-	SDL_RenderDrawPoint(MLK__RENDERER(), x1, y1);
+	SDL_RenderPoint(MLK__RENDERER(), x1, y1);
 }
 
 void
 mlk_painter_draw_rectangle(int x, int y, unsigned int width, unsigned int height)
 {
-	const SDL_Rect rect = {
+	const SDL_FRect rect = {
 		.w = width,
 		.h = height,
 		.x = x,
@@ -95,8 +95,8 @@
 	for (double dy = 1; dy <= radius; dy += 1.0) {
 		dx = floor(sqrt((2.0 * radius * dy) - (dy * dy)));
 
-		SDL_RenderDrawLine(MLK__RENDERER(), x - dx, y + dy - radius, x + dx, y + dy - radius);
-		SDL_RenderDrawLine(MLK__RENDERER(), x - dx, y - dy + radius, x + dx, y - dy + radius);
+		SDL_RenderLine(MLK__RENDERER(), x - dx, y + dy - radius, x + dx, y + dy - radius);
+		SDL_RenderLine(MLK__RENDERER(), x - dx, y - dy + radius, x + dx, y - dy + radius);
 	}
 }
 
--- a/libmlk-core/mlk/core/sys.c	Sun Aug 20 10:48:57 2023 +0200
+++ b/libmlk-core/mlk/core/sys.c	Sun Aug 20 11:14:58 2023 +0200
@@ -260,8 +260,8 @@
 	(void)organization;
 	(void)name;
 
-	/* SDL2. */
-	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) < 0)
+	/* SDL. */
+	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD) < 0)
 		return mlk_errf("%s", SDL_GetError());
 	if (IMG_Init(IMG_INIT_PNG) != IMG_INIT_PNG)
 		return mlk_errf("%s", SDL_GetError());
--- a/libmlk-core/mlk/core/texture.c	Sun Aug 20 10:48:57 2023 +0200
+++ b/libmlk-core/mlk/core/texture.c	Sun Aug 20 11:14:58 2023 +0200
@@ -101,14 +101,14 @@
 {
 	assert(tex);
 
-	SDL_Rect dst = {
+	SDL_FRect dst = {
 		.x = x,
 		.y = y,
 		.w = tex->w,
 		.h = tex->h
 	};
 
-	if (SDL_RenderCopy(MLK__RENDERER(), tex->handle, NULL, &dst) < 0)
+	if (SDL_RenderTexture(MLK__RENDERER(), tex->handle, NULL, &dst) < 0)
 		return mlk_errf("%s", SDL_GetError());
 
 	return 0;
@@ -126,20 +126,20 @@
                   unsigned dst_h,
                   double angle)
 {
-	const SDL_Rect src = {
+	const SDL_FRect src = {
 		.x = src_x,
 		.y = src_y,
 		.w = src_w,
 		.h = src_h
 	};
-	const SDL_Rect dst = {
+	const SDL_FRect dst = {
 		.x = dst_x,
 		.y = dst_y,
 		.w = dst_w,
 		.h = dst_h
 	};
 
-	if (SDL_RenderCopyEx(MLK__RENDERER(), tex->handle, &src, &dst, angle, NULL, SDL_FLIP_NONE) < 0)
+	if (SDL_RenderTextureRotated(MLK__RENDERER(), tex->handle, &src, &dst, angle, NULL, SDL_FLIP_NONE) < 0)
 		return mlk_errf("%s", SDL_GetError());
 
 	return 0;
@@ -172,7 +172,7 @@
 	tex->w = surface->w;
 	tex->h = surface->h;
 
-	SDL_FreeSurface(surface);
+	SDL_DestroySurface(surface);
 
 	return 0;
 }
--- a/libmlk-core/mlk/core/window.c	Sun Aug 20 10:48:57 2023 +0200
+++ b/libmlk-core/mlk/core/window.c	Sun Aug 20 11:14:58 2023 +0200
@@ -52,10 +52,10 @@
 static void
 load_framerate(void)
 {
-	SDL_DisplayMode mode;
+	const SDL_DisplayMode *mode;
 
-	if (SDL_GetWindowDisplayMode(handle.win, &mode) == 0)
-		mlk_window.framerate = mode.refresh_rate;
+	if ((mode = SDL_GetCurrentDisplayMode(SDL_GetDisplayForWindow(handle.win))))
+		mlk_window.framerate = mode->refresh_rate;
 }
 
 static void
@@ -63,19 +63,19 @@
 {
 	for (size_t i = 0; i < MLK_UTIL_SIZE(cursors); ++i)
 		if (cursors[i])
-			SDL_FreeCursor(cursors[i]);
+			SDL_DestroyCursor(cursors[i]);
 }
 
 static int
 load_window(const char *title, unsigned int w, unsigned int h)
 {
-	return (handle.win = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, 0)) != NULL;
+	return (handle.win = SDL_CreateWindow(title, w, h, 0)) != NULL;
 }
 
 static int
 load_renderer(void)
 {
-	return (handle.renderer = SDL_CreateRenderer(handle.win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC)) != NULL;
+	return (handle.renderer = SDL_CreateRenderer(handle.win, NULL, 0));
 }
 
 int
@@ -103,9 +103,9 @@
 	assert(cursor < MLK_WINDOW_CURSOR_LAST);
 
 	if (cursor == MLK_WINDOW_CURSOR_OFF)
-		SDL_ShowCursor(0);
+		SDL_ShowCursor();
 	else {
-		SDL_ShowCursor(1);
+		SDL_HideCursor();
 		SDL_SetCursor(cursors[cursor]);
 	}
 }
--- a/libmlk-util/CMakeLists.txt	Sun Aug 20 10:48:57 2023 +0200
+++ b/libmlk-util/CMakeLists.txt	Sun Aug 20 11:14:58 2023 +0200
@@ -65,7 +65,6 @@
 		${HEADERS}
 		${libmlk-util_BINARY_DIR}/mlk/util/sysconfig.h
 	HEADERS_DIRECTORY mlk/util
-	LIBRARIES ${LIBRARIES}
 	INCLUDES
 		PUBLIC
 			$<BUILD_INTERFACE:${libmlk-util_SOURCE_DIR}>
--- a/libmlk-util/libmlk-util-config.cmake	Sun Aug 20 10:48:57 2023 +0200
+++ b/libmlk-util/libmlk-util-config.cmake	Sun Aug 20 11:14:58 2023 +0200
@@ -21,10 +21,12 @@
 set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../mlk;${CMAKE_MODULE_PATH}")
 
 # Local modules.
-find_dependency(SDL2 COMPONENTS ttf image)
 find_dependency(SndFile)
 
 # External modules.
 find_dependency(OpenAL)
+find_dependency(SDL3)
+find_dependency(SDL3_image)
+find_dependency(SDL3_ttf)
 
 include("${CMAKE_CURRENT_LIST_DIR}/libmlk-util-targets.cmake")