diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 3685a3fe316..cb8dc351ef7 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -27,7 +27,7 @@ on: jobs: build-android: env: - # Revision of https://github.com/pelya/commandergenius.git - SDL2 repo is a submodule + # Revision of https://github.com/pelya/commandergenius.git - SDL3 repo is a submodule # We check out a specific stable revision, so the build won't break if I modify my SDL repo SDL_ANDROID_REV: 798fd0f5e167aa6ecce33623dbf88ebc6cd647ea # It takes 35 minutes per one architecture to build SuperTux, of which 20 minutes are for building Boost and ICU libraries @@ -53,8 +53,8 @@ jobs: run: > git submodule update --init --recursive --depth=1 project/jni/boost/src project/jni/iconv/src - project/jni/sdl2 project/jni/sdl2_image - project/jni/sdl2_mixer project/jni/sdl2_ttf + project/jni/sdl3 project/jni/sdl3_image + project/jni/sdl3_mixer project/jni/sdl3_ttf - name: Symlink the application dir run: | diff --git a/.github/workflows/bsd.yml b/.github/workflows/bsd.yml index 4449a879c3c..4e529ee0303 100644 --- a/.github/workflows/bsd.yml +++ b/.github/workflows/bsd.yml @@ -60,8 +60,8 @@ jobs: pkg install -y git pkg install -y cmake pkg install -y googletest - pkg install -y sdl2 - pkg install -y sdl2_image + pkg install -y sdl3 + pkg install -y sdl3_image pkg install -y openal-soft pkg install -y glew # pkg install -y glbinding # TODO: Uncomment whenever possible diff --git a/.github/workflows/gnulinux.yml b/.github/workflows/gnulinux.yml index 2fbbc269569..70120a054d1 100644 --- a/.github/workflows/gnulinux.yml +++ b/.github/workflows/gnulinux.yml @@ -54,6 +54,18 @@ jobs: fetch-depth: 0 submodules: recursive + - name: Patch vcpkg dbus portfile on 32-bit + if: ${{ matrix.arch == 32 }} + shell: pwsh + run: | + # Patch dbus port file to work around dbus issue on 32-bit + # See https://github.com/microsoft/vcpkg/issues/40031 + git config core.filemode false + cp mk/vcpkg/dbus.patch $Env:VCPKG_INSTALLATION_ROOT + pushd $Env:VCPKG_INSTALLATION_ROOT + git apply dbus.patch + popd + - name: Install 64-bit dependencies if: ${{ matrix.arch == 64 }} run: | @@ -76,8 +88,6 @@ jobs: libogg-dev \ libvorbis-dev \ libopenal-dev \ - libsdl2-dev \ - libsdl2-image-dev \ libglib2.0-dev \ libfreetype6-dev \ libraqm-dev \ @@ -89,7 +99,16 @@ jobs: libphysfs-dev \ zlib1g-dev \ lcov \ - doxygen + doxygen \ + libltdl-dev + + # Let's get out of this directory to disable vcpkg manifest mode. + # Manifest mode is not adequate here because most dependencies can + # be used via the system package manager. + pushd / + + vcpkg update + vcpkg install --triplet x64-linux sdl3 sdl3-image sdl3-ttf - name: Install 32-bit dependencies if: ${{ matrix.arch == 32 }} @@ -114,21 +133,21 @@ jobs: libogg-dev:i386 \ libvorbis-dev:i386 \ libopenal-dev:i386 \ - libsdl2-dev:i386 \ - libsdl2-image-dev:i386 \ libfreetype6-dev:i386 \ libcurl4-openssl-dev:i386 \ zlib1g-dev:i386 \ libfmt-dev:i386 \ - libglm-dev - + libglm-dev \ + libltdl-dev + # Let's get out of this directory to disable vcpkg manifest mode. # Manifest mode is not adequate here because most dependencies can # be used via the system package manager. pushd / # These libraries don't exist for 32-bit in Ubuntu repositories. - vcpkg install --triplet x86-linux physfs glew libraqm + vcpkg update + vcpkg install --triplet x86-linux physfs glew libraqm sdl3 sdl3-image sdl3-ttf popd @@ -181,12 +200,10 @@ jobs: -DCMAKE_POLICY_VERSION_MINIMUM="3.5" ` -DSUPERTUX_PACKAGE_VERSION="$Env:GIT_TAG dev - $Env:GIT_HASH ($Env:GIT_BRANCH) (CI ARTIFACT)" ` -DSUPERTUX_VERSION_STRING="$Env:GIT_BRANCH-$Env:GIT_HASH" ` - $(if ($Env:32BIT -eq "true") { - "-DCMAKE_TOOLCHAIN_FILE=$Env:VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake " - "-DVCPKG_TARGET_TRIPLET=x86-linux " - "-DVCPKG_MANIFEST_MODE=OFF " - "-DPhysFS_PREFER_FIND_PACKAGE=ON" - }) ` + -DCMAKE_TOOLCHAIN_FILE="$Env:VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake" ` + -DVCPKG_MANIFEST_MODE=OFF ` + -DPhysFS_PREFER_FIND_PACKAGE=ON ` + -DVCPKG_TARGET_TRIPLET="$(if ($Env:32BIT -eq "true") {"x86"} else {"x64"})-linux" ` -DBUILD_DOCUMENTATION="$(if ($Env:MAKE_DOCS -eq "true") {"ON"} else {"OFF"})" ` -DCMAKE_CXX_FLAGS="$(if ($Env:32BIT -eq "true") {"-m32"})" ` -DCMAKE_C_FLAGS="$(if ($Env:32BIT -eq "true") {"-m32"})" ` diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 8be604cc864..6dc3b1cfc8b 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -53,7 +53,7 @@ jobs: cp -rf ./mk/brew/glm.rb $(brew --repository homebrew/core)/Formula/ HOMEBREW_NO_AUTO_UPDATE=1 brew install glm --build-from-source brew install cmake bash rename libogg libvorbis glew \ - openal-soft sdl2 sdl2_image libraqm freetype \ + openal-soft sdl3 sdl3_image sdl3_ttf libraqm freetype \ glib gtk-doc zlib physfs fmt install_name_tool -change \ diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 5e7693fc97d..984dfb541cf 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -64,13 +64,15 @@ jobs: run: | cd C:/ vcpkg integrate install + vcpkg update vcpkg install curl:$Env:ARCH-windows vcpkg install glew:$Env:ARCH-windows vcpkg install libogg:$Env:ARCH-windows vcpkg install libvorbis:$Env:ARCH-windows vcpkg install openal-soft:$Env:ARCH-windows - vcpkg install sdl2:$Env:ARCH-windows - vcpkg install sdl2-image[libjpeg-turbo]:$Env:ARCH-windows + vcpkg install sdl3:$Env:ARCH-windows + vcpkg install sdl3-image[jpeg]:$Env:ARCH-windows + vcpkg install sdl3-ttf[harfbuzz]:$Env:ARCH-windows vcpkg install glm:$Env:ARCH-windows vcpkg install zlib:$Env:ARCH-windows vcpkg install fmt:$Env:ARCH-windows diff --git a/CMakeLists.txt b/CMakeLists.txt index 64336d4f29e..294f7b7f6d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -167,12 +167,14 @@ add_package(TARGET Freetype PKG Freetype PKG_USE Freetype::Freetype CONFIG REQUIRED PKG_CONFIG freetype2) add_package(TARGET RAQM PKG RAQM PKG_USE RAQM CONFIG PKG_CONFIG libraqm raqm) +add_package(TARGET SDL3 + PKG SDL3 PKG_USE SDL3::SDL3 CONFIG REQUIRED PKG_CONFIG sdl3 SDL3) +add_package(TARGET SDL3_image + PKG SDL3_image PKG_USE SDL3_image::SDL3_image CONFIG REQUIRED PKG_CONFIG SDL3_image sdl3_image) +add_package(TARGET SDL3_ttf + PKG SDL3_ttf PKG_USE SDL3_ttf::SDL3_ttf CONFIG REQUIRED PKG_CONFIG SDL3_ttf sdl3_ttf) if(NOT EMSCRIPTEN) - add_package(TARGET SDL2 - PKG SDL2 PKG_USE SDL2::SDL2 CONFIG REQUIRED PKG_CONFIG sdl2 SDL2) - add_package(TARGET SDL2_image - PKG SDL2_image PKG_USE SDL2_image::SDL2_image CONFIG REQUIRED PKG_CONFIG SDL2_image sdl2_image) add_package(TARGET libcurl PKG CURL PKG_USE CURL::libcurl PKG_CONFIG libcurl) add_package(TARGET OpenAL @@ -189,11 +191,11 @@ endif() if(TARGET RAQM) message(STATUS "Compiling SDL_ttf with RAQM") - set(SDL2TTF_RAQM ON) + set(SDL3TTF_RAQM ON) endif() add_subdirectory(external/sexp-cpp EXCLUDE_FROM_ALL) -add_subdirectory(external/SDL_ttf EXCLUDE_FROM_ALL) +#add_subdirectory(external/SDL_ttf EXCLUDE_FROM_ALL) add_subdirectory(external/SDL_SavePNG EXCLUDE_FROM_ALL) add_subdirectory(external/simplesquirrel EXCLUDE_FROM_ALL) add_subdirectory(external/partio_zip EXCLUDE_FROM_ALL) @@ -299,18 +301,18 @@ else() target_link_libraries(supertux2 PUBLIC simplesquirrel) endif() target_link_libraries(supertux2 PUBLIC - tinygettext sexp SDL_SavePNG SDL2_ttf + tinygettext sexp SDL_SavePNG SDL3_ttf PartioZip OpenAL FindLocale obstack glm fmt PhysFS) target_compile_definitions(supertux2 PUBLIC GLM_ENABLE_EXPERIMENTAL) if(NOT EMSCRIPTEN) target_link_libraries(supertux2 PUBLIC - # SDL2_image - SDL2_image - # SDL2 main (windows?) - $ - # SDL2 - SDL2 + # SDL3_image + SDL3_image + # SDL3 main (windows?) + $ + # SDL3 + SDL3 ) target_link_libraries(supertux2 PUBLIC Ogg diff --git a/INSTALL.md b/INSTALL.md index 2b100708ce8..4dba795b99a 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -62,12 +62,12 @@ For ease of use, here are some installation lines for some Linux distributions: - Ubuntu 22.xx or later: ``` - sudo apt-get update && sudo apt-get install -y cmake build-essential libogg-dev libvorbis-dev libopenal-dev libsdl2-dev libsdl2-image-dev libfreetype6-dev libraqm-dev libcurl4-openssl-dev libglew-dev libharfbuzz-dev libfribidi-dev libglm-dev zlib1g-dev libfmt-dev libsdl2-ttf-dev libphysfs-dev + sudo apt-get update && sudo apt-get install -y cmake build-essential libogg-dev libvorbis-dev libopenal-dev libsdl3-dev libsdl3-image-dev libfreetype6-dev libraqm-dev libcurl4-openssl-dev libglew-dev libharfbuzz-dev libfribidi-dev libglm-dev zlib1g-dev libfmt-dev libsdl3-ttf-dev libphysfs-dev ``` - ArchLinux (using sudo, as of August 28th 2024) ``` - sudo pacman -S cmake base-devel libogg libvorbis openal sdl2 sdl2_image sdl2_ttf freetype2 libraqm curl openssl glew harfbuzz fribidi glm zlib fmt physfs + sudo pacman -S cmake base-devel libogg libvorbis openal sdl3 sdl3_image sdl3_ttf freetype2 libraqm curl openssl glew harfbuzz fribidi glm zlib fmt physfs ``` ### Linux/UNIX using CMake diff --git a/NEWS.md b/NEWS.md index 3457bae6c39..4ab59e12d25 100644 --- a/NEWS.md +++ b/NEWS.md @@ -182,7 +182,7 @@ SuperTux 0.4.0 (2015-12-20) Compared to 0.1.3, this release features: -* a nearly completely rewritten game engine based on OpenGL, OpenAL, SDL2, ... +* a nearly completely rewritten game engine based on OpenGL, OpenAL, SDL3, ... * support for translations * in-game manager for downloadable add-ons and translations * Bonus Island III, a for now unfinished Forest Island and the development levels in Incubator Island @@ -231,7 +231,7 @@ SuperTux 0.3.5 (2015-04-11) In celebration of SuperTux's 15 year anniversary, we are releasing SuperTux 0.3.5. -This release includes the switch to SDL2 for graphics rendering, a few performance +This release includes the switch to SDL3 for graphics rendering, a few performance improvements, tons of bugfixes, new tiles and badguys amongst other things. NOTE: Due to the planned shutdown of Google Code, the SuperTux source code has @@ -243,7 +243,7 @@ http://supertux.lethargik.org/wiki/Changelog_0.3.5 Major changes in this release: -* move to SDL2 for graphics rendering +* move to SDL3 for graphics rendering * glow effects * new badguys: iceflame, ghostflame, livefire, goldbomb, smartblock * new bonuses: coinrain, coinexplode diff --git a/clickable.yaml b/clickable.yaml index b0d398a6ae8..4878b8886e5 100644 --- a/clickable.yaml +++ b/clickable.yaml @@ -1,5 +1,5 @@ clickable_minimum_required: 7 -framework: "ubuntu-sdk-20.04" +framework: "ubuntu-sdk-24.04" builder: "cmake" build_dir: "build.clickable" image_setup: @@ -12,8 +12,8 @@ dependencies_target: - "libogg-dev" - "libvorbis-dev" - "libopenal-dev" - - "libsdl2-dev" - - "libsdl2-image-dev" + - "libsdl3" + - "libsdl3-image" - "libphysfs-dev" - "libcurl4-openssl-dev" - "libfreetype6-dev" @@ -25,10 +25,10 @@ install_lib: - "/usr/lib/${ARCH_TRIPLET}/libvorbis.so*" - "/usr/lib/${ARCH_TRIPLET}/libvorbisfile.so*" - "/usr/lib/${ARCH_TRIPLET}/libopenal.so*" - - "/usr/lib/${ARCH_TRIPLET}/libSDL2.so*" - - "/usr/lib/${ARCH_TRIPLET}/libSDL2-2.0.so*" - - "/usr/lib/${ARCH_TRIPLET}/libSDL2_image.so*" - - "/usr/lib/${ARCH_TRIPLET}/libSDL2_image-2.0.so*" + - "/usr/lib/${ARCH_TRIPLET}/libSDL3.so*" + - "/usr/lib/${ARCH_TRIPLET}/libSDL3-2.0.so*" + - "/usr/lib/${ARCH_TRIPLET}/libSDL3_image.so*" + - "/usr/lib/${ARCH_TRIPLET}/libSDL3_image-2.0.so*" - "/usr/lib/${ARCH_TRIPLET}/libfreetype.so*" - "/usr/lib/${ARCH_TRIPLET}/libraqm.so*" - "/usr/lib/${ARCH_TRIPLET}/libcurl.so*" @@ -41,4 +41,4 @@ build_args: - "-DWARNINGS=ON" - "-DWERROR=ON" - "-DCLICK_ARCH=${ARCH}" - - "-DCLICK_FRAMEWORK=ubuntu-sdk-20.04" + - "-DCLICK_FRAMEWORK=ubuntu-sdk-24.04" diff --git a/external/SDL_SavePNG/CMakeLists.txt b/external/SDL_SavePNG/CMakeLists.txt index 57edaeef367..8fea2173312 100644 --- a/external/SDL_SavePNG/CMakeLists.txt +++ b/external/SDL_SavePNG/CMakeLists.txt @@ -2,5 +2,5 @@ project(SDL_SavePNG) add_library(SDL_SavePNG OBJECT ${PROJECT_SOURCE_DIR}/savepng.c) set_target_properties(SDL_SavePNG PROPERTIES POSITION_INDEPENDENT_CODE ON) -target_link_libraries(SDL_SavePNG PUBLIC PNG SDL2) +target_link_libraries(SDL_SavePNG PUBLIC PNG SDL3) target_include_directories(SDL_SavePNG PUBLIC ${PROJECT_SOURCE_DIR}) diff --git a/external/SDL_SavePNG/main.c b/external/SDL_SavePNG/main.c index c03eac67775..c2431217b6b 100644 --- a/external/SDL_SavePNG/main.c +++ b/external/SDL_SavePNG/main.c @@ -1,4 +1,4 @@ -#include +#include #include "savepng.h" // includes , you must link with -lpng diff --git a/external/SDL_SavePNG/savepng.c b/external/SDL_SavePNG/savepng.c index 4ac44a9d4e0..83895fb3598 100644 --- a/external/SDL_SavePNG/savepng.c +++ b/external/SDL_SavePNG/savepng.c @@ -4,7 +4,8 @@ * This code is free software, available under zlib/libpng license. * http://www.libpng.org/pub/png/src/libpng-LICENSE.txt */ -#include +#include +#include #include #define SUCCESS 0 @@ -31,17 +32,18 @@ static void png_error_SDL(png_structp ctx, png_const_charp str) } static void png_write_SDL(png_structp png_ptr, png_bytep data, png_size_t length) { - SDL_RWops *rw = (SDL_RWops*)png_get_io_ptr(png_ptr); - SDL_RWwrite(rw, data, sizeof(png_byte), length); + SDL_IOStream *rw = (SDL_IOStream*)png_get_io_ptr(png_ptr); + SDL_WriteIO(rw, data, length); } SDL_Surface *SDL_PNGFormatAlpha(SDL_Surface *src) { SDL_Surface *surf; SDL_Rect rect = { 0 }; + const SDL_PixelFormatDetails* format = SDL_GetPixelFormatDetails(src->format); /* NO-OP for images < 32bpp and 32bpp images that already have Alpha channel */ - if (src->format->BitsPerPixel <= 24 || src->format->Amask) { + if (format->bits_per_pixel <= 24 || format->Amask) { src->refcount++; return src; } @@ -49,14 +51,14 @@ SDL_Surface *SDL_PNGFormatAlpha(SDL_Surface *src) /* Convert 32bpp alpha-less image to 24bpp alpha-less image */ rect.w = src->w; rect.h = src->h; - surf = SDL_CreateRGBSurface(src->flags, src->w, src->h, 24, - src->format->Rmask, src->format->Gmask, src->format->Bmask, 0); - SDL_LowerBlit(src, &rect, surf, &rect); + surf = SDL_CreateSurface(src->w, src->h, + SDL_GetPixelFormatForMasks(24, format->Rmask, format->Gmask, format->Bmask, 0)); + SDL_BlitSurfaceUnchecked(src, &rect, surf, &rect); return surf; } -int SDL_SavePNG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst) +int SDL_SavePNG_RW(SDL_Surface *surface, SDL_IOStream *dst, int freedst) { png_structp png_ptr; png_infop info_ptr; @@ -75,14 +77,14 @@ int SDL_SavePNG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst) if (!surface) { SDL_SetError("Argument 1 to SDL_SavePNG_RW can't be NULL, expecting SDL_Surface*\n"); - if (freedst) SDL_RWclose(dst); + if (freedst) SDL_CloseIO(dst); return (ERROR); } png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, png_error_SDL, NULL); /* err_ptr, err_fn, warn_fn */ if (!png_ptr) { SDL_SetError("Unable to png_create_write_struct on %s\n", PNG_LIBPNG_VER_STRING); - if (freedst) SDL_RWclose(dst); + if (freedst) SDL_CloseIO(dst); return (ERROR); } info_ptr = png_create_info_struct(png_ptr); @@ -90,13 +92,13 @@ int SDL_SavePNG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst) { SDL_SetError("Unable to png_create_info_struct\n"); png_destroy_write_struct(&png_ptr, NULL); - if (freedst) SDL_RWclose(dst); + if (freedst) SDL_CloseIO(dst); return (ERROR); } if (setjmp(png_jmpbuf(png_ptr))) /* All other errors, see also "png_error_SDL" */ { png_destroy_write_struct(&png_ptr, &info_ptr); - if (freedst) SDL_RWclose(dst); + if (freedst) SDL_CloseIO(dst); return (ERROR); } @@ -104,10 +106,13 @@ int SDL_SavePNG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst) png_set_write_fn(png_ptr, dst, png_write_SDL, NULL); /* w_ptr, write_fn, flush_fn */ /* Prepare chunks */ + const SDL_PixelFormatDetails* format = SDL_GetPixelFormatDetails(surface->format); + SDL_Palette* palette = SDL_GetSurfacePalette(surface); + colortype = PNG_COLOR_MASK_COLOR; - if (surface->format->BytesPerPixel > 0 - && surface->format->BytesPerPixel <= 8 - && (pal = surface->format->palette)) + if (format->bytes_per_pixel > 0 + && format->bytes_per_pixel <= 8 + && (pal = palette)) { colortype |= PNG_COLOR_MASK_PALETTE; pal_ptr = (png_colorp)malloc(pal->ncolors * sizeof(png_color)); @@ -119,7 +124,7 @@ int SDL_SavePNG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst) png_set_PLTE(png_ptr, info_ptr, pal_ptr, pal->ncolors); free(pal_ptr); } - else if (surface->format->BytesPerPixel > 3 || surface->format->Amask) + else if (format->bytes_per_pixel > 3 || format->Amask) colortype |= PNG_COLOR_MASK_ALPHA; png_set_IHDR(png_ptr, info_ptr, surface->w, surface->h, 8, colortype, @@ -128,9 +133,9 @@ int SDL_SavePNG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst) // png_set_packing(png_ptr); /* Allow BGR surfaces */ - if (surface->format->Rmask == bmask - && surface->format->Gmask == gmask - && surface->format->Bmask == rmask) + if (format->Rmask == bmask + && format->Gmask == gmask + && format->Bmask == rmask) png_set_bgr(png_ptr); /* Write everything */ @@ -149,6 +154,6 @@ int SDL_SavePNG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst) /* Done */ png_destroy_write_struct(&png_ptr, &info_ptr); - if (freedst) SDL_RWclose(dst); + if (freedst) SDL_CloseIO(dst); return (SUCCESS); } diff --git a/external/SDL_SavePNG/savepng.h b/external/SDL_SavePNG/savepng.h index 59424660456..7339e95973a 100644 --- a/external/SDL_SavePNG/savepng.h +++ b/external/SDL_SavePNG/savepng.h @@ -6,7 +6,7 @@ * This code is free software, available under zlib/libpng license. * http://www.libpng.org/pub/png/src/libpng-LICENSE.txt */ -#include +#include #ifdef __cplusplus extern "C" { /* This helps CPP projects that include this header */ @@ -31,7 +31,7 @@ extern "C" { /* This helps CPP projects that include this header */ * Returns 0 success or -1 on failure, the error message is then retrievable * via SDL_GetError(). */ -extern int SDL_SavePNG_RW(SDL_Surface *surface, SDL_RWops *rw, int freedst); +extern int SDL_SavePNG_RW(SDL_Surface *surface, SDL_IOStream *rw, int freedst); /* * Return new SDL_Surface with a format suitable for PNG output. diff --git a/external/tinygettext b/external/tinygettext index 6ac1c347602..02fa963dd95 160000 --- a/external/tinygettext +++ b/external/tinygettext @@ -1 +1 @@ -Subproject commit 6ac1c34760216c5fce74c5e4c3b0fa9b6d9e05e5 +Subproject commit 02fa963dd95eadd01af015e553610e496b63ebb5 diff --git a/flake.lock b/flake.lock index b5f1f220e9e..fbf5703b967 100644 --- a/flake.lock +++ b/flake.lock @@ -1,6 +1,6 @@ { "nodes": { - "SDL2_ttf": { + "SDL3_ttf": { "inputs": { "flake-utils": [ "flake-utils" @@ -74,7 +74,7 @@ }, "root": { "inputs": { - "SDL2_ttf": "SDL2_ttf", + "SDL3_ttf": "SDL3_ttf", "flake-utils": "flake-utils", "nixpkgs": "nixpkgs", "sexpcpp": "sexpcpp", diff --git a/flake.nix b/flake.nix index e2c56bd45a8..c29d6765c63 100644 --- a/flake.nix +++ b/flake.nix @@ -41,16 +41,16 @@ tinygettext.inputs.flake-utils.follows = "flake-utils"; tinygettext.inputs.tinycmmc.follows = "tinycmmc"; - SDL2_ttf.url = "github:SuperTux/SDL_ttf"; - SDL2_ttf.inputs.nixpkgs.follows = "nixpkgs"; - SDL2_ttf.inputs.flake-utils.follows = "flake-utils"; + SDL3_ttf.url = "github:SuperTux/SDL_ttf"; + SDL3_ttf.inputs.nixpkgs.follows = "nixpkgs"; + SDL3_ttf.inputs.flake-utils.follows = "flake-utils"; squirrel_src.url = "github:albertodemichelis/squirrel"; squirrel_src.flake = false; }; outputs = { self, nixpkgs, flake-utils, - tinycmmc, sexpcpp, tinygettext, SDL2_ttf, + tinycmmc, sexpcpp, tinygettext, SDL3_ttf, squirrel_src }: flake-utils.lib.eachDefaultSystem (system: let @@ -90,7 +90,7 @@ EOF ''; cmakeFlags = [ "-DINSTALL_SUBDIR_BIN=bin" - "-DUSE_SYSTEM_SDL2_TTF=ON" + "-DUSE_SYSTEM_SDL3_TTF=ON" ]; enableParallelBuilding = true; nativeBuildInputs = [ @@ -108,7 +108,7 @@ EOF squirrel sexpcpp.packages.${system}.default tinygettext.packages.${system}.default - SDL2_ttf.packages.${system}.default + SDL3_ttf.packages.${system}.default pkgs.physfs pkgs.libpng @@ -120,8 +120,8 @@ EOF pkgs.gtest pkgs.glm - pkgs.SDL2 - pkgs.SDL2_image + pkgs.SDL3 + pkgs.SDL3_image pkgs.openal pkgs.libvorbis diff --git a/guix.scm b/guix.scm index 97f53975f40..450f214f2a0 100644 --- a/guix.scm +++ b/guix.scm @@ -68,8 +68,8 @@ ("python" ,python) ("gcc-10" ,gcc-10))) (inputs - `(("sdl2" ,sdl2) - ("sdl2-image" ,sdl2-image) + `(("sdl3" ,sdl3) + ("sdl3-image" ,sdl3-image) ("openal" ,openal) ("mesa" ,mesa) ("glew" ,glew) diff --git a/mk/clickable/clickable-glew.yaml b/mk/clickable/clickable-glew.yaml index 5f559d8ff8c..85718c3de4a 100644 --- a/mk/clickable/clickable-glew.yaml +++ b/mk/clickable/clickable-glew.yaml @@ -1,19 +1,20 @@ clickable_minimum_required: 7 -framework: "ubuntu-sdk-20.04" +framework: "ubuntu-sdk-24.04" builder: "cmake" build_dir: "build.clickable" image_setup: env: BUILD_ARCH: $ARCH run: + - ls -la /usr/lib/${ARCH_TRIPLET}/ # I don't know how to split this and honestly I don't care - wget -O fmtlib.zip https://github.com/fmtlib/fmt/releases/download/9.1.0/fmt-9.1.0.zip && unzip fmtlib.zip && cd fmt-9.1.0 && mkdir build && cd build && cmake .. -DFMT_TEST=OFF -DFMT_DOC=OFF -DCMAKE_BUILD_TYPE=Release && cmake --build . && cmake --install . dependencies_target: - "libogg-dev" - "libvorbis-dev" - "libopenal-dev" - - "libsdl2-dev" - - "libsdl2-image-dev" + - "libsdl3" + - "libsdl3-image" - "libphysfs-dev" - "libcurl4-openssl-dev" - "libfreetype6-dev" @@ -26,10 +27,10 @@ install_lib: - "/usr/lib/${ARCH_TRIPLET}/libvorbis.so*" - "/usr/lib/${ARCH_TRIPLET}/libvorbisfile.so*" - "/usr/lib/${ARCH_TRIPLET}/libopenal.so*" - - "/usr/lib/${ARCH_TRIPLET}/libSDL2.so*" - - "/usr/lib/${ARCH_TRIPLET}/libSDL2-2.0.so*" - - "/usr/lib/${ARCH_TRIPLET}/libSDL2_image.so*" - - "/usr/lib/${ARCH_TRIPLET}/libSDL2_image-2.0.so*" + - "/usr/lib/${ARCH_TRIPLET}/libSDL3.so*" + - "/usr/lib/${ARCH_TRIPLET}/libSDL3-2.0.so*" + - "/usr/lib/${ARCH_TRIPLET}/libSDL3_image.so*" + - "/usr/lib/${ARCH_TRIPLET}/libSDL3_image-2.0.so*" - "/usr/lib/${ARCH_TRIPLET}/libfreetype.so*" - "/usr/lib/${ARCH_TRIPLET}/libraqm.so*" - "/usr/lib/${ARCH_TRIPLET}/libcurl.so*" @@ -42,4 +43,4 @@ build_args: - "-DWARNINGS=ON" - "-DWERROR=ON" - "-DCLICK_ARCH=${ARCH}" - - "-DCLICK_FRAMEWORK=ubuntu-sdk-20.04" + - "-DCLICK_FRAMEWORK=ubuntu-sdk-24.04" diff --git a/mk/clickable/supertux2.apparmor b/mk/clickable/supertux2.apparmor index e34364a5d08..7f91f2f4efa 100644 --- a/mk/clickable/supertux2.apparmor +++ b/mk/clickable/supertux2.apparmor @@ -3,5 +3,5 @@ "audio", "networking" ], - "policy_version": 20.04 + "policy_version": 24.04 } diff --git a/mk/cmake/SuperTux/AddPackage.cmake b/mk/cmake/SuperTux/AddPackage.cmake index 921646f013c..64aaf4ba648 100644 --- a/mk/cmake/SuperTux/AddPackage.cmake +++ b/mk/cmake/SuperTux/AddPackage.cmake @@ -27,14 +27,14 @@ # Usage: # -# add_package(TARGET SDL2 <-- The output target, a "target alias" (sometimes). -# PKG SDL2 <-- The find_package package, in this case it gets SDL2 +# add_package(TARGET SDL3 <-- The output target, a "target alias" (sometimes). +# PKG SDL3 <-- The find_package package, in this case it gets SDL3 # (might look similar to the output target). -# PKG_USE SDL2::SDL2 <-- Specific target from the package we want to alias. +# PKG_USE SDL3::SDL3 <-- Specific target from the package we want to alias. # CONFIG <-- (optional) Passed to find_package if its a CONFIG. # REQUIRED <-- (optional) NOT passed to find_package, just a check to # throw an error if we've exhausted all options. -# PKG_CONFIG sdl2 sdl2_ttf <-- (optional, recommended) List of packages for pkg-config. +# PKG_CONFIG sdl3 sdl3_ttf <-- (optional, recommended) List of packages for pkg-config. # PREFER_PKGCONFIG <-- (optional) If the host machine is running a unix-like, # ) skip the find_package call and use pkg-config. diff --git a/mk/cmake/SuperTux/Emscripten.cmake b/mk/cmake/SuperTux/Emscripten.cmake index 58b9f6b4c27..6074900bb1f 100644 --- a/mk/cmake/SuperTux/Emscripten.cmake +++ b/mk/cmake/SuperTux/Emscripten.cmake @@ -3,7 +3,7 @@ set(IS_EMSCRIPTEN_BUILD ON) set(SQ_DISABLE_INSTALLER YES) set(SSQ_BUILD_INSTALL NO) -set(EM_USE_FLAGS "-sDISABLE_EXCEPTION_CATCHING=0 -sUSE_SDL=2 -sUSE_SDL_IMAGE=2 -sSDL2_IMAGE_FORMATS='[\"png\",\"jpg\"]' -sUSE_VORBIS=1") +set(EM_USE_FLAGS "-sDISABLE_EXCEPTION_CATCHING=0 -sUSE_SDL=3 -sUSE_VORBIS=1") set(EM_LINK_FLAGS " -sINITIAL_MEMORY=134217728 -sALLOW_MEMORY_GROWTH=1 -sMAXIMUM_MEMORY=536870912 -sERROR_ON_UNDEFINED_SYMBOLS=0 --preload-file ${BUILD_CONFIG_DATA_DIR} --use-preload-plugins -lidbfs.js") if(ENABLE_OPENGL) set(EM_LINK_FLAGS "${EM_LINK_FLAGS} -sFULL_ES2") @@ -25,9 +25,3 @@ set_target_properties(OpenAL PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${PROJECT_SOURCE_DIR}/mk/emscripten/AL" INTERFACE_LINK_LIBRARIES "-lopenal" ) - -add_library(SDL2 INTERFACE IMPORTED) -set_target_properties(SDL2 PROPERTIES - INTERFACE_COMPILE_OPTIONS "-sUSE_SDL=2" - INTERFACE_LINK_LIBRARIES "-sUSE_SDL=2" -) diff --git a/mk/vcpkg/dbus.patch b/mk/vcpkg/dbus.patch new file mode 100644 index 00000000000..e4accd8cb60 --- /dev/null +++ b/mk/vcpkg/dbus.patch @@ -0,0 +1,12 @@ +diff --git a/ports/dbus/portfile.cmake b/ports/dbus/portfile.cmake +index 3ddd2e455a..a985556391 100644 +--- a/ports/dbus/portfile.cmake ++++ b/ports/dbus/portfile.cmake +@@ -33,6 +33,7 @@ vcpkg_cmake_configure( + -DDBUS_ENABLE_XML_DOCS=OFF + -DDBUS_INSTALL_SYSTEM_LIBS=OFF + #-DDBUS_SERVICE=ON ++ -DDBUS_SESSION_SOCKET_DIR=/tmp + -DDBUS_WITH_GLIB=OFF + -DTHREADS_PREFER_PTHREAD_FLAG=ON + -DXSLTPROC_EXECUTABLE=FALSE diff --git a/src/audio/sound_manager.cpp b/src/audio/sound_manager.cpp index b7057f5953c..5b94cc8ff7f 100644 --- a/src/audio/sound_manager.cpp +++ b/src/audio/sound_manager.cpp @@ -16,7 +16,7 @@ #include "audio/sound_manager.hpp" -#include +#include #include #include #include diff --git a/src/control/game_controller_manager.cpp b/src/control/game_controller_manager.cpp index 57f1983e61e..a2931361267 100644 --- a/src/control/game_controller_manager.cpp +++ b/src/control/game_controller_manager.cpp @@ -39,17 +39,17 @@ GameControllerManager::~GameControllerManager() { for (const auto& con : m_game_controllers) { - SDL_GameControllerClose(con.first); + SDL_CloseGamepad(con.first); } } void -GameControllerManager::process_button_event(const SDL_ControllerButtonEvent& ev) +GameControllerManager::process_button_event(const SDL_GamepadButtonEvent& ev) { int player_id; { - auto it = m_game_controllers.find(SDL_GameControllerFromInstanceID(ev.which)); + auto it = m_game_controllers.find(SDL_GetGamepadFromID(ev.which)); if (it == m_game_controllers.end() || it->second < 0) return; @@ -57,71 +57,71 @@ GameControllerManager::process_button_event(const SDL_ControllerButtonEvent& ev) player_id = it->second; } - //log_info << "button event: " << static_cast(ev.button) << " " << static_cast(ev.state) << std::endl; + //log_info << "button event: " << static_cast(ev.button) << " " << static_cast(ev.down) << std::endl; Controller& controller = m_parent->get_controller(player_id); auto set_control = [this, &controller](Control control, Uint8 value) { m_button_state[static_cast(control)] = (value != 0); - controller.set_control(control, m_button_state[static_cast(control)] == SDL_PRESSED || m_stick_state[static_cast(control)] == SDL_PRESSED); + controller.set_control(control, m_button_state[static_cast(control)] == true || m_stick_state[static_cast(control)] == true); }; switch (ev.button) { - case SDL_CONTROLLER_BUTTON_A: - set_control(Control::JUMP, ev.state); - set_control(Control::MENU_SELECT, ev.state); + case SDL_GAMEPAD_BUTTON_SOUTH: + set_control(Control::JUMP, ev.down); + set_control(Control::MENU_SELECT, ev.down); break; - case SDL_CONTROLLER_BUTTON_B: - set_control(Control::MENU_BACK, ev.state); + case SDL_GAMEPAD_BUTTON_EAST: + set_control(Control::MENU_BACK, ev.down); break; - case SDL_CONTROLLER_BUTTON_X: - set_control(Control::ACTION, ev.state); + case SDL_GAMEPAD_BUTTON_WEST: + set_control(Control::ACTION, ev.down); break; - case SDL_CONTROLLER_BUTTON_Y: + case SDL_GAMEPAD_BUTTON_NORTH: break; - case SDL_CONTROLLER_BUTTON_BACK: - set_control(Control::ITEM, ev.state); + case SDL_GAMEPAD_BUTTON_BACK: + set_control(Control::ITEM, ev.down); break; - case SDL_CONTROLLER_BUTTON_GUIDE: - set_control(Control::CHEAT_MENU, ev.state); + case SDL_GAMEPAD_BUTTON_GUIDE: + set_control(Control::CHEAT_MENU, ev.down); break; - case SDL_CONTROLLER_BUTTON_START: - set_control(Control::START, ev.state); + case SDL_GAMEPAD_BUTTON_START: + set_control(Control::START, ev.down); break; - case SDL_CONTROLLER_BUTTON_LEFTSTICK: + case SDL_GAMEPAD_BUTTON_LEFT_STICK: break; - case SDL_CONTROLLER_BUTTON_RIGHTSTICK: + case SDL_GAMEPAD_BUTTON_RIGHT_STICK: break; - case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: - set_control(Control::PEEK_LEFT, ev.state); + case SDL_GAMEPAD_BUTTON_LEFT_SHOULDER: + set_control(Control::PEEK_LEFT, ev.down); break; - case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: - set_control(Control::PEEK_RIGHT, ev.state); + case SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER: + set_control(Control::PEEK_RIGHT, ev.down); break; - case SDL_CONTROLLER_BUTTON_DPAD_UP: - set_control(Control::UP, ev.state); + case SDL_GAMEPAD_BUTTON_DPAD_UP: + set_control(Control::UP, ev.down); break; - case SDL_CONTROLLER_BUTTON_DPAD_DOWN: - set_control(Control::DOWN, ev.state); + case SDL_GAMEPAD_BUTTON_DPAD_DOWN: + set_control(Control::DOWN, ev.down); break; - case SDL_CONTROLLER_BUTTON_DPAD_LEFT: - set_control(Control::LEFT, ev.state); + case SDL_GAMEPAD_BUTTON_DPAD_LEFT: + set_control(Control::LEFT, ev.down); break; - case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: - set_control(Control::RIGHT, ev.state); + case SDL_GAMEPAD_BUTTON_DPAD_RIGHT: + set_control(Control::RIGHT, ev.down); break; default: @@ -130,12 +130,12 @@ GameControllerManager::process_button_event(const SDL_ControllerButtonEvent& ev) } void -GameControllerManager::process_axis_event(const SDL_ControllerAxisEvent& ev) +GameControllerManager::process_axis_event(const SDL_GamepadAxisEvent& ev) { int player_id; { - auto it = m_game_controllers.find(SDL_GameControllerFromInstanceID(ev.which)); + auto it = m_game_controllers.find(SDL_GetGamepadFromID(ev.which)); if (it == m_game_controllers.end() || it->second < 0) return; @@ -180,26 +180,26 @@ GameControllerManager::process_axis_event(const SDL_ControllerAxisEvent& ev) switch (ev.axis) { - case SDL_CONTROLLER_AXIS_LEFTX: + case SDL_GAMEPAD_AXIS_LEFTX: axis2button(ev.value, Control::LEFT, Control::RIGHT); break; - case SDL_CONTROLLER_AXIS_LEFTY: + case SDL_GAMEPAD_AXIS_LEFTY: axis2button(ev.value, Control::UP, Control::DOWN); break; - case SDL_CONTROLLER_AXIS_RIGHTX: + case SDL_GAMEPAD_AXIS_RIGHTX: axis2button(ev.value, Control::PEEK_LEFT, Control::PEEK_RIGHT); break; - case SDL_CONTROLLER_AXIS_RIGHTY: + case SDL_GAMEPAD_AXIS_RIGHTY: axis2button(ev.value, Control::PEEK_UP, Control::PEEK_DOWN); break; - case SDL_CONTROLLER_AXIS_TRIGGERLEFT: + case SDL_GAMEPAD_AXIS_LEFT_TRIGGER: break; - case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: + case SDL_GAMEPAD_AXIS_RIGHT_TRIGGER: break; default: @@ -213,13 +213,13 @@ GameControllerManager::on_controller_added(int joystick_index) if (!m_parent->can_add_user()) return; - if (!SDL_IsGameController(joystick_index)) + if (!SDL_IsGamepad(joystick_index)) { log_warning << "joystick is not a game controller, ignoring: " << joystick_index << std::endl; } else { - SDL_GameController* game_controller = SDL_GameControllerOpen(joystick_index); + SDL_Gamepad* game_controller = SDL_OpenGamepad(joystick_index); if (!game_controller) { log_warning << "failed to open game_controller: " << joystick_index @@ -259,12 +259,12 @@ void GameControllerManager::on_controller_removed(int instance_id) { auto it = std::find_if(m_game_controllers.begin(), m_game_controllers.end(), [instance_id] (decltype(m_game_controllers)::const_reference pair) { - return SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(pair.first)) == instance_id; + return SDL_GetJoystickID(SDL_GetGamepadJoystick(pair.first)) == instance_id; }); if (it != m_game_controllers.end()) { - SDL_GameControllerClose(it->first); + SDL_CloseGamepad(it->first); auto deleted_player_id = it->second; @@ -280,7 +280,7 @@ GameControllerManager::on_controller_removed(int instance_id) else { log_debug << "Controller was unplugged but was not initially detected: " - << SDL_JoystickName(SDL_JoystickFromInstanceID(instance_id)) + << SDL_GetJoystickName(SDL_GetJoystickFromID(instance_id)) << std::endl; } } @@ -294,7 +294,7 @@ GameControllerManager::on_player_removed(int player_id) if (it2 != m_game_controllers.end()) { it2->second = -1; - // Try again, in case multiple controllers were bount to a player. + // Try again, in case multiple controllers were bound to a player. // Recursive call shouldn't go too deep except in hardcore scenarios. on_player_removed(player_id); } @@ -309,17 +309,18 @@ GameControllerManager::has_corresponding_game_controller(int player_id) const } int -GameControllerManager::rumble(SDL_GameController* controller) const +GameControllerManager::rumble(SDL_Gamepad* controller) const { #if SDL_VERSION_ATLEAST(2, 0, 9) if (g_config->multiplayer_buzz_controllers) { #if SDL_VERSION_ATLEAST(2, 0, 18) - if (SDL_GameControllerHasRumble(controller)) + auto controller_properties = SDL_GetGamepadProperties(controller); + if (controller_properties && SDL_GetBooleanProperty(controller_properties, SDL_PROP_GAMEPAD_CAP_RUMBLE_BOOLEAN, false)) { #endif // TODO: Rumble intensity setting (like volume). - SDL_GameControllerRumble(controller, 0xFFFF, 0xFFFF, 300); + SDL_RumbleGamepad(controller, 0xFFFF, 0xFFFF, 300); #if SDL_VERSION_ATLEAST(2, 0, 18) } else @@ -336,7 +337,7 @@ GameControllerManager::rumble(SDL_GameController* controller) const } void -GameControllerManager::bind_controller(SDL_GameController* controller, int player_id) +GameControllerManager::bind_controller(SDL_Gamepad* controller, int player_id) { m_game_controllers[controller] = player_id; diff --git a/src/control/game_controller_manager.hpp b/src/control/game_controller_manager.hpp index 93ee7d50ff4..96a6ed6223e 100644 --- a/src/control/game_controller_manager.hpp +++ b/src/control/game_controller_manager.hpp @@ -20,13 +20,11 @@ #include #include +#include + #include "control/controller.hpp" class InputManager; -struct SDL_ControllerAxisEvent; -struct SDL_ControllerButtonEvent; -struct _SDL_GameController; -typedef struct _SDL_GameController SDL_GameController; /** * Manages GameControllers. @@ -39,8 +37,8 @@ class GameControllerManager final GameControllerManager(InputManager* parent); ~GameControllerManager(); - void process_button_event(const SDL_ControllerButtonEvent& ev); - void process_axis_event(const SDL_ControllerAxisEvent& ev); + void process_button_event(const SDL_GamepadButtonEvent& ev); + void process_axis_event(const SDL_GamepadAxisEvent& ev); void on_controller_added(int joystick_index); void on_controller_removed(int instance_id); @@ -49,16 +47,16 @@ class GameControllerManager final bool has_corresponding_game_controller(int player_id) const; /** @returns 0 if success, 1 if controller doesn't support rumbling, 2 if game doesn't support rumbling */ - int rumble(SDL_GameController* controller) const; + int rumble(SDL_Gamepad* controller) const; - void bind_controller(SDL_GameController* controller, int player_id); + void bind_controller(SDL_Gamepad* controller, int player_id); - inline std::unordered_map& get_controller_mapping() { return m_game_controllers; } + inline std::unordered_map& get_controller_mapping() { return m_game_controllers; } private: InputManager* m_parent; int m_deadzone; - std::unordered_map m_game_controllers; + std::unordered_map m_game_controllers; std::array(Control::CONTROLCOUNT)> m_stick_state; std::array(Control::CONTROLCOUNT)> m_button_state; diff --git a/src/control/input_manager.cpp b/src/control/input_manager.cpp index e1c4f7aaedb..bfe93ef2aad 100644 --- a/src/control/input_manager.cpp +++ b/src/control/input_manager.cpp @@ -83,60 +83,60 @@ void InputManager::process_event(const SDL_Event& event) { switch (event.type) { - case SDL_TEXTINPUT: + case SDL_EVENT_TEXT_INPUT: keyboard_manager->process_text_input_event(event.text); break; - case SDL_KEYUP: - case SDL_KEYDOWN: + case SDL_EVENT_KEY_UP: + case SDL_EVENT_KEY_DOWN: keyboard_manager->process_key_event(event.key); break; - case SDL_JOYAXISMOTION: + case SDL_EVENT_JOYSTICK_AXIS_MOTION: if (!m_use_game_controller) joystick_manager->process_axis_event(event.jaxis); break; - case SDL_JOYHATMOTION: + case SDL_EVENT_JOYSTICK_HAT_MOTION: if (!m_use_game_controller) joystick_manager->process_hat_event(event.jhat); break; - case SDL_JOYBUTTONDOWN: - case SDL_JOYBUTTONUP: + case SDL_EVENT_JOYSTICK_BUTTON_DOWN: + case SDL_EVENT_JOYSTICK_BUTTON_UP: if (!m_use_game_controller) joystick_manager->process_button_event(event.jbutton); break; - case SDL_JOYDEVICEADDED: + case SDL_EVENT_JOYSTICK_ADDED: joystick_manager->on_joystick_added(event.jdevice.which); break; - case SDL_JOYDEVICEREMOVED: + case SDL_EVENT_JOYSTICK_REMOVED: joystick_manager->on_joystick_removed(event.jdevice.which); break; - case SDL_CONTROLLERAXISMOTION: - if (m_use_game_controller) game_controller_manager->process_axis_event(event.caxis); + case SDL_EVENT_GAMEPAD_AXIS_MOTION: + if (m_use_game_controller) game_controller_manager->process_axis_event(event.gaxis); break; - case SDL_CONTROLLERBUTTONDOWN: - if (m_use_game_controller) game_controller_manager->process_button_event(event.cbutton); + case SDL_EVENT_GAMEPAD_BUTTON_DOWN: + if (m_use_game_controller) game_controller_manager->process_button_event(event.gbutton); break; - case SDL_CONTROLLERBUTTONUP: - if (m_use_game_controller) game_controller_manager->process_button_event(event.cbutton); + case SDL_EVENT_GAMEPAD_BUTTON_UP: + if (m_use_game_controller) game_controller_manager->process_button_event(event.gbutton); break; - case SDL_CONTROLLERDEVICEADDED: - log_debug << "SDL_CONTROLLERDEVICEADDED" << std::endl; - game_controller_manager->on_controller_added(event.cdevice.which); + case SDL_EVENT_GAMEPAD_ADDED: + log_debug << "SDL_EVENT_GAMEPAD_ADDED" << std::endl; + game_controller_manager->on_controller_added(event.gdevice.which); break; - case SDL_CONTROLLERDEVICEREMOVED: - log_debug << "SDL_CONTROLLERDEVICEREMOVED" << std::endl; - game_controller_manager->on_controller_removed(event.cdevice.which); + case SDL_EVENT_GAMEPAD_REMOVED: + log_debug << "SDL_EVENT_GAMEPAD_REMOVED" << std::endl; + game_controller_manager->on_controller_removed(event.gdevice.which); break; - case SDL_CONTROLLERDEVICEREMAPPED: - log_debug << "SDL_CONTROLLERDEVICEREMAPPED" << std::endl; + case SDL_EVENT_GAMEPAD_REMAPPED: + log_debug << "SDL_EVENT_GAMEPAD_REMAPPED" << std::endl; break; default: diff --git a/src/control/input_manager.hpp b/src/control/input_manager.hpp index da8d6e58671..35079e6acd0 100644 --- a/src/control/input_manager.hpp +++ b/src/control/input_manager.hpp @@ -18,7 +18,7 @@ #include "control/controller.hpp" -#include +#include #include #include #include diff --git a/src/control/joystick_config.hpp b/src/control/joystick_config.hpp index fd732896c2c..3529d9ce1f5 100644 --- a/src/control/joystick_config.hpp +++ b/src/control/joystick_config.hpp @@ -17,7 +17,7 @@ #pragma once #include -#include +#include #include "control/controller.hpp" diff --git a/src/control/joystick_manager.cpp b/src/control/joystick_manager.cpp index 404ec6d78f7..47e8e526d15 100644 --- a/src/control/joystick_manager.cpp +++ b/src/control/joystick_manager.cpp @@ -46,7 +46,7 @@ JoystickManager::~JoystickManager() { for (auto& joy : joysticks) { - SDL_JoystickClose(joy.first); + SDL_CloseJoystick(joy.first); } } @@ -58,7 +58,7 @@ JoystickManager::on_joystick_added(int joystick_index) if (!parent->can_add_user()) return; - SDL_Joystick* joystick = SDL_JoystickOpen(joystick_index); + SDL_Joystick* joystick = SDL_OpenJoystick(joystick_index); if (!joystick) { log_warning << "failed to open joystick: " << joystick_index @@ -68,17 +68,17 @@ JoystickManager::on_joystick_added(int joystick_index) { joysticks[joystick] = -1; - if (min_joybuttons < 0 || SDL_JoystickNumButtons(joystick) < min_joybuttons) - min_joybuttons = SDL_JoystickNumButtons(joystick); + if (min_joybuttons < 0 || SDL_GetNumJoystickButtons(joystick) < min_joybuttons) + min_joybuttons = SDL_GetNumJoystickButtons(joystick); - if (SDL_JoystickNumButtons(joystick) > max_joybuttons) - max_joybuttons = SDL_JoystickNumButtons(joystick); + if (SDL_GetNumJoystickButtons(joystick) > max_joybuttons) + max_joybuttons = SDL_GetNumJoystickButtons(joystick); - if (SDL_JoystickNumAxes(joystick) > max_joyaxis) - max_joyaxis = SDL_JoystickNumAxes(joystick); + if (SDL_GetNumJoystickAxes(joystick) > max_joyaxis) + max_joyaxis = SDL_GetNumJoystickAxes(joystick); - if (SDL_JoystickNumHats(joystick) > max_joyhats) - max_joyhats = SDL_JoystickNumHats(joystick); + if (SDL_GetNumJoystickHats(joystick) > max_joyhats) + max_joyhats = SDL_GetNumJoystickHats(joystick); if (!parent->m_use_game_controller && g_config->multiplayer_auto_manage_players) { @@ -111,12 +111,12 @@ JoystickManager::on_joystick_removed(int instance_id) log_debug << "on_joystick_removed: " << static_cast(instance_id) << std::endl; auto it = std::find_if(joysticks.begin(), joysticks.end(), [instance_id] (decltype(joysticks)::const_reference pair) { - return SDL_JoystickInstanceID(pair.first) == instance_id; + return SDL_GetJoystickID(pair.first) == instance_id; }); if (it != joysticks.end()) { - SDL_JoystickClose(it->first); + SDL_CloseJoystick(it->first); auto deleted_player_id = it->second; @@ -132,7 +132,7 @@ JoystickManager::on_joystick_removed(int instance_id) else { log_debug << "Joystick was unplugged but was not initially detected: " - << SDL_JoystickName(SDL_JoystickFromInstanceID(instance_id)) + << SDL_GetJoystickName(SDL_GetJoystickFromID(instance_id)) << std::endl; } } @@ -242,7 +242,7 @@ JoystickManager::process_button_event(const SDL_JoyButtonEvent& jbutton) { if (wait_for_joystick >= 0) { - if (jbutton.state == SDL_PRESSED) + if (jbutton.down == true) { m_joystick_config.bind_joybutton(jbutton.which, jbutton.button, static_cast(wait_for_joystick)); MenuManager::instance().refresh(); @@ -256,7 +256,7 @@ JoystickManager::process_button_event(const SDL_JoyButtonEvent& jbutton) if (i == m_joystick_config.m_joy_button_map.end()) { log_debug << "Unmapped joybutton " << static_cast(jbutton.button) << " pressed" << std::endl; } else { - set_joy_controls(jbutton.which, i->second, (jbutton.state == SDL_PRESSED)); + set_joy_controls(jbutton.which, i->second, (jbutton.down == true)); } } } @@ -270,7 +270,7 @@ JoystickManager::bind_next_event_to(Control id) void JoystickManager::set_joy_controls(SDL_JoystickID joystick, Control id, bool value) { - auto it = joysticks.find(SDL_JoystickFromInstanceID(joystick)); + auto it = joysticks.find(SDL_GetJoystickFromID(joystick)); if (it == joysticks.end() || it->second < 0) return; @@ -313,11 +313,12 @@ JoystickManager::rumble(SDL_Joystick* controller) const if (g_config->multiplayer_buzz_controllers) { #if SDL_VERSION_ATLEAST(2, 0, 18) - if (SDL_JoystickHasRumble(controller)) + auto controller_properties = SDL_GetJoystickProperties(controller); + if (controller_properties && SDL_GetBooleanProperty(controller_properties, SDL_PROP_GAMEPAD_CAP_RUMBLE_BOOLEAN, false)) { #endif // TODO: Rumble intensity setting (like volume) - SDL_JoystickRumble(controller, 0xFFFF, 0xFFFF, 300); + SDL_RumbleJoystick(controller, 0xFFFF, 0xFFFF, 300); #if SDL_VERSION_ATLEAST(2, 0, 18) } else diff --git a/src/control/joystick_manager.hpp b/src/control/joystick_manager.hpp index 99d129efaef..055baf8be61 100644 --- a/src/control/joystick_manager.hpp +++ b/src/control/joystick_manager.hpp @@ -17,7 +17,7 @@ #pragma once -#include +#include #include #include diff --git a/src/control/keyboard_config.cpp b/src/control/keyboard_config.cpp index 11d295f1afa..b4eafb014bf 100644 --- a/src/control/keyboard_config.cpp +++ b/src/control/keyboard_config.cpp @@ -54,7 +54,7 @@ KeyboardConfig::KeyboardConfig() : m_keymap[SDLK_LCTRL] = {0, Control::ACTION}; m_keymap[SDLK_LSHIFT] = {0, Control::ITEM}; m_keymap[SDLK_ESCAPE] = {0, Control::ESCAPE}; - m_keymap[SDLK_p] = {0, Control::START}; + m_keymap[SDLK_P] = {0, Control::START}; m_keymap[SDLK_PAUSE] = {0, Control::START}; m_keymap[SDLK_RETURN] = {0, Control::MENU_SELECT}; m_keymap[SDLK_KP_ENTER] = {0, Control::MENU_SELECT}; @@ -72,12 +72,12 @@ void KeyboardConfig::read(const ReaderMapping& keymap_mapping) { // backwards compatibility: - // keycode values changed between SDL1 and SDL2, so we skip old SDL1 + // keycode values changed between SDL1 and SDL3, so we skip old SDL1 // based values and use the defaults instead on the first read of // the config file - bool config_is_sdl2 = false; - keymap_mapping.get("sdl2", config_is_sdl2); - if (!config_is_sdl2) + bool config_is_sdl3 = false; + keymap_mapping.get("sdl3", config_is_sdl3); + if (!config_is_sdl3) return; keymap_mapping.get("jump-with-up", m_jump_with_up_kbd); @@ -163,10 +163,10 @@ KeyboardConfig::reversemap_key(int player, Control c) const void KeyboardConfig::write(Writer& writer) { - // this flag handles the transition from SDL1 to SDL2, as keycodes + // this flag handles the transition from SDL1 to SDL3, as keycodes // are incompatible between the two, if it's not set an old SDL1 // config file is assumed and controls are reset to default - writer.write("sdl2", true); + writer.write("sdl3", true); writer.write("jump-with-up", m_jump_with_up_kbd); diff --git a/src/control/keyboard_config.hpp b/src/control/keyboard_config.hpp index c65e29f95bf..a4ce52a3645 100644 --- a/src/control/keyboard_config.hpp +++ b/src/control/keyboard_config.hpp @@ -16,7 +16,7 @@ #pragma once -#include +#include #include #include diff --git a/src/control/keyboard_manager.cpp b/src/control/keyboard_manager.cpp index 947b40dbe6d..ccbd724ee1d 100644 --- a/src/control/keyboard_manager.cpp +++ b/src/control/keyboard_manager.cpp @@ -34,13 +34,13 @@ KeyboardManager::KeyboardManager(InputManager* parent, void KeyboardManager::process_key_event(const SDL_KeyboardEvent& event) { - auto key_mapping = m_keyboard_config.m_keymap.find(event.keysym.sym); + auto key_mapping = m_keyboard_config.m_keymap.find(event.key); // if console key was pressed: toggle console if (key_mapping != m_keyboard_config.m_keymap.end() && key_mapping->second.control == Control::CONSOLE) { - if (event.type == SDL_KEYDOWN) + if (event.type == SDL_EVENT_KEY_DOWN) { // text input gets locked between the console-key being pressed // and released to avoid the console-key getting interpreted as @@ -49,7 +49,7 @@ KeyboardManager::process_key_event(const SDL_KeyboardEvent& event) Console::current()->toggle(); } - else if (event.type == SDL_KEYUP) + else if (event.type == SDL_EVENT_KEY_UP) { m_lock_text_input = false; } @@ -72,7 +72,7 @@ KeyboardManager::process_key_event(const SDL_KeyboardEvent& event) else { auto control = key_mapping->second; - bool value = (event.type == SDL_KEYDOWN); + bool value = (event.type == SDL_EVENT_KEY_DOWN); if (control.player >= m_parent->get_num_users()) return; @@ -99,10 +99,10 @@ KeyboardManager::process_text_input_event(const SDL_TextInputEvent& event) void KeyboardManager::process_console_key_event(const SDL_KeyboardEvent& event) { - if (event.type != SDL_KEYDOWN) return; + if (event.type != SDL_EVENT_KEY_DOWN) return; auto console = Console::current(); - switch (event.keysym.sym) { + switch (event.key) { case SDLK_RETURN: console->enter(); break; @@ -127,13 +127,13 @@ KeyboardManager::process_console_key_event(const SDL_KeyboardEvent& event) case SDLK_END: console->move_cursor(+65535); break; - case SDLK_a: - if (event.keysym.mod & KMOD_CTRL) { + case SDLK_A: + if (event.mod & SDL_KMOD_CTRL) { console->move_cursor(-65535); } break; - case SDLK_e: - if (event.keysym.mod & KMOD_CTRL) { + case SDLK_E: + if (event.mod & SDL_KMOD_CTRL) { console->move_cursor(+65535); } break; @@ -160,13 +160,13 @@ KeyboardManager::process_menu_key_event(const SDL_KeyboardEvent& event) // wait for key mode? if (m_wait_for_key) { - if (event.type == SDL_KEYUP) + if (event.type == SDL_EVENT_KEY_UP) return; - if (event.keysym.sym != SDLK_ESCAPE && - event.keysym.sym != SDLK_PAUSE) + if (event.key != SDLK_ESCAPE && + event.key != SDLK_PAUSE) { - m_keyboard_config.bind_key(event.keysym.sym, m_wait_for_key->player, m_wait_for_key->control); + m_keyboard_config.bind_key(event.key, m_wait_for_key->player, m_wait_for_key->control); } m_parent->reset(); MenuManager::instance().refresh(); @@ -176,7 +176,7 @@ KeyboardManager::process_menu_key_event(const SDL_KeyboardEvent& event) if (m_parent->joystick_manager->wait_for_joystick >= 0) { - if (event.keysym.sym == SDLK_ESCAPE) + if (event.key == SDLK_ESCAPE) { m_parent->reset(); MenuManager::instance().refresh(); @@ -189,7 +189,7 @@ KeyboardManager::process_menu_key_event(const SDL_KeyboardEvent& event) /* we use default keys when the menu is open (to avoid problems when * redefining keys to invalid settings */ - switch (event.keysym.sym) { + switch (event.key) { case SDLK_UP: control = Control::UP; break; @@ -223,7 +223,7 @@ KeyboardManager::process_menu_key_event(const SDL_KeyboardEvent& event) } // Keep empty because this is in the menu; only the first player may navigate - m_parent->get_controller().set_control(control, (event.type == SDL_KEYDOWN)); + m_parent->get_controller().set_control(control, (event.type == SDL_EVENT_KEY_DOWN)); } void diff --git a/src/control/mobile_controller.cpp b/src/control/mobile_controller.cpp index 376130206da..f0f3c3a0d2c 100644 --- a/src/control/mobile_controller.cpp +++ b/src/control/mobile_controller.cpp @@ -18,7 +18,7 @@ #include -#include "SDL.h" +#include #include "control/controller.hpp" #include "math/vector.hpp" @@ -177,11 +177,11 @@ MobileController::update() m_up = m_down = m_left = m_right = m_jump = m_action = m_cheats = m_debug = m_escape = false; // Allow using on-screen controls with the mouse - int x, y; + float x, y; auto buttons = SDL_GetMouseState(&x, &y); if ((buttons & SDL_BUTTON_LMASK) != 0) { - activate_widget_at_pos(static_cast(x), static_cast(y)); + activate_widget_at_pos(x, y); } for (auto& i : m_fingers) @@ -225,7 +225,7 @@ bool MobileController::process_finger_down_event(const SDL_TouchFingerEvent& event) { Vector pos(event.x * float(m_screen_width), event.y * float(m_screen_height)); - m_fingers[event.fingerId] = pos; + m_fingers[event.fingerID] = pos; return m_rect_jump.contains(pos) || m_rect_action.contains(pos) || m_rect_escape.contains(pos) || @@ -238,7 +238,7 @@ bool MobileController::process_finger_up_event(const SDL_TouchFingerEvent& event) { Vector pos(event.x * float(m_screen_width), event.y * float(m_screen_height)); - m_fingers.erase(event.fingerId); + m_fingers.erase(event.fingerID); return m_rect_jump.contains(pos) || m_rect_action.contains(pos) || m_rect_escape.contains(pos) || @@ -251,7 +251,7 @@ bool MobileController::process_finger_motion_event(const SDL_TouchFingerEvent& event) { Vector pos(event.x * float(m_screen_width), event.y * float(m_screen_height)); - m_fingers[event.fingerId] = pos; + m_fingers[event.fingerID] = pos; return m_rect_jump.contains(pos) || m_rect_action.contains(pos) || m_rect_escape.contains(pos) || diff --git a/src/control/mobile_controller.hpp b/src/control/mobile_controller.hpp index 82e8468e75e..c231167ade1 100644 --- a/src/control/mobile_controller.hpp +++ b/src/control/mobile_controller.hpp @@ -16,7 +16,7 @@ #pragma once -#include +#include #include #include "config.h" diff --git a/src/editor/editor.cpp b/src/editor/editor.cpp index 33cd5f86e4a..017aaa6262f 100644 --- a/src/editor/editor.cpp +++ b/src/editor/editor.cpp @@ -878,34 +878,34 @@ Editor::event(const SDL_Event& ev) try { - if (ev.type == SDL_KEYDOWN) + if (ev.type == SDL_EVENT_KEY_DOWN) { - m_ctrl_pressed = ev.key.keysym.mod & KMOD_CTRL; + m_ctrl_pressed = ev.key.mod & SDL_KMOD_CTRL; if (m_ctrl_pressed) m_scroll_speed = 16.0f; - else if (ev.key.keysym.mod & KMOD_RSHIFT) + else if (ev.key.mod & SDL_KMOD_RSHIFT) m_scroll_speed = 96.0f; - if (ev.key.keysym.sym == SDLK_F6) + if (ev.key.key == SDLK_F6) { Compositor::s_render_lighting = !Compositor::s_render_lighting; return; } else if (m_ctrl_pressed) { - switch (ev.key.keysym.sym) + switch (ev.key.key) { - case SDLK_t: + case SDLK_T: test_level(std::nullopt); break; - case SDLK_s: + case SDLK_S: save_level(); break; - case SDLK_z: + case SDLK_Z: undo(); break; - case SDLK_y: + case SDLK_Y: redo(); break; case SDLK_PLUS: // Zoom in @@ -916,24 +916,24 @@ Editor::event(const SDL_Event& ev) case SDLK_KP_MINUS: m_new_scale = m_sector->get_camera().get_current_scale() - CAMERA_ZOOM_SENSITIVITY; break; - case SDLK_d: // Reset zoom + case SDLK_D: // Reset zoom m_new_scale = 1.f; break; } } } - else if (ev.type == SDL_KEYUP) + else if (ev.type == SDL_EVENT_KEY_UP) { - m_ctrl_pressed = ev.key.keysym.mod & KMOD_CTRL; + m_ctrl_pressed = ev.key.mod & SDL_KMOD_CTRL; - if (!m_ctrl_pressed && !(ev.key.keysym.mod & KMOD_RSHIFT)) + if (!m_ctrl_pressed && !(ev.key.mod & SDL_KMOD_RSHIFT)) m_scroll_speed = 32.0f; } - else if (ev.type == SDL_MOUSEMOTION) + else if (ev.type == SDL_EVENT_MOUSE_MOTION) { m_mouse_pos = VideoSystem::current()->get_viewport().to_logical(ev.motion.x, ev.motion.y); } - else if (ev.type == SDL_MOUSEWHEEL && !m_toolbox_widget->has_mouse_focus() && !m_layers_widget->has_mouse_focus()) + else if (ev.type == SDL_EVENT_MOUSE_WHEEL && !m_toolbox_widget->has_mouse_focus() && !m_layers_widget->has_mouse_focus()) { // Scroll or zoom with mouse wheel, if the mouse is not over the toolbox. // The toolbox does scrolling independently from the main area. diff --git a/src/editor/overlay_widget.cpp b/src/editor/overlay_widget.cpp index a845833127d..85e6d7b71e4 100644 --- a/src/editor/overlay_widget.cpp +++ b/src/editor/overlay_widget.cpp @@ -1132,9 +1132,9 @@ EditorOverlayWidget::on_mouse_motion(const SDL_MouseMotionEvent& motion) bool EditorOverlayWidget::on_key_up(const SDL_KeyboardEvent& key) { - std::uint16_t mod = key.keysym.mod; + std::uint16_t mod = key.mod; - if (mod & KMOD_SHIFT) + if (mod & SDL_KMOD_SHIFT) { g_config->editor_snap_to_grid = !g_config->editor_snap_to_grid; } @@ -1145,7 +1145,7 @@ EditorOverlayWidget::on_key_up(const SDL_KeyboardEvent& key) // Hovered objects depend on if ctrl is pressed hover_object(); } - else if (mod & KMOD_ALT) + else if (mod & SDL_KMOD_ALT) { alt_pressed = false; } @@ -1155,14 +1155,14 @@ EditorOverlayWidget::on_key_up(const SDL_KeyboardEvent& key) bool EditorOverlayWidget::on_key_down(const SDL_KeyboardEvent& key) { - SDL_Keycode sym = key.keysym.sym; - std::uint16_t mod = key.keysym.mod; + SDL_Keycode sym = key.key; + std::uint16_t mod = key.mod; if (sym == SDLK_F8) { g_config->editor_render_grid = !g_config->editor_render_grid; } - else if (sym == SDLK_F7 || mod & KMOD_SHIFT) + else if (sym == SDLK_F7 || mod & SDL_KMOD_SHIFT) { g_config->editor_snap_to_grid = !g_config->editor_snap_to_grid; } @@ -1177,7 +1177,7 @@ EditorOverlayWidget::on_key_down(const SDL_KeyboardEvent& key) // Hovered objects depend on if ctrl is pressed. hover_object(); } - else if (mod & KMOD_ALT) + else if (mod & SDL_KMOD_ALT) { alt_pressed = true; } diff --git a/src/editor/overlay_widget.hpp b/src/editor/overlay_widget.hpp index 635565d262f..b73a822574f 100644 --- a/src/editor/overlay_widget.hpp +++ b/src/editor/overlay_widget.hpp @@ -16,7 +16,7 @@ #pragma once -#include +#include #include #include "control/input_manager.hpp" diff --git a/src/editor/particle_editor.cpp b/src/editor/particle_editor.cpp index 13460c43384..60d642c1b1c 100644 --- a/src/editor/particle_editor.cpp +++ b/src/editor/particle_editor.cpp @@ -821,27 +821,27 @@ ParticleEditor::event(const SDL_Event& ev) break; } - if (ev.type == SDL_KEYDOWN && - ev.key.keysym.sym == SDLK_z && - ev.key.keysym.mod & KMOD_CTRL) { + if (ev.type == SDL_EVENT_KEY_DOWN && + ev.key.key == SDLK_Z && + ev.key.mod & SDL_KMOD_CTRL) { undo(); } - if (ev.type == SDL_KEYDOWN && - ev.key.keysym.sym == SDLK_y && - ev.key.keysym.mod & KMOD_CTRL) { + if (ev.type == SDL_EVENT_KEY_DOWN && + ev.key.key == SDLK_Y && + ev.key.mod & SDL_KMOD_CTRL) { redo(); } - if (ev.type == SDL_KEYDOWN && - ev.key.keysym.sym == SDLK_s && - ev.key.keysym.mod & KMOD_CTRL) { - request_save(ev.key.keysym.mod & KMOD_SHIFT); + if (ev.type == SDL_EVENT_KEY_DOWN && + ev.key.key == SDLK_S && + ev.key.mod & SDL_KMOD_CTRL) { + request_save(ev.key.mod & SDL_KMOD_SHIFT); } - if (ev.type == SDL_KEYDOWN && - ev.key.keysym.sym == SDLK_o && - ev.key.keysym.mod & KMOD_CTRL) { + if (ev.type == SDL_EVENT_KEY_DOWN && + ev.key.key == SDLK_O && + ev.key.mod & SDL_KMOD_CTRL) { MenuManager::instance().set_menu(MenuStorage::PARTICLE_EDITOR_OPEN); } } diff --git a/src/editor/particle_editor.hpp b/src/editor/particle_editor.hpp index 7bce553fce7..c24238d7663 100644 --- a/src/editor/particle_editor.hpp +++ b/src/editor/particle_editor.hpp @@ -20,7 +20,7 @@ #include #include -#include +#include #include "interface/control.hpp" #include "interface/control_button.hpp" diff --git a/src/editor/scroller_widget.cpp b/src/editor/scroller_widget.cpp index 92529d5fe57..5a6fb85541a 100644 --- a/src/editor/scroller_widget.cpp +++ b/src/editor/scroller_widget.cpp @@ -135,7 +135,7 @@ EditorScrollerWidget::on_mouse_motion(const SDL_MouseMotionEvent& motion) bool EditorScrollerWidget::on_key_down(const SDL_KeyboardEvent& key) { - if (key.keysym.sym == SDLK_F9) { + if (key.key == SDLK_F9) { rendered = !rendered; } return false; diff --git a/src/editor/widget.cpp b/src/editor/widget.cpp index dafd8419335..46216076117 100644 --- a/src/editor/widget.cpp +++ b/src/editor/widget.cpp @@ -21,22 +21,22 @@ Widget::event(const SDL_Event& ev) { switch (ev.type) { - case SDL_MOUSEBUTTONDOWN: + case SDL_EVENT_MOUSE_BUTTON_DOWN: return on_mouse_button_down(ev.button); - case SDL_MOUSEBUTTONUP: + case SDL_EVENT_MOUSE_BUTTON_UP: return on_mouse_button_up(ev.button); - case SDL_MOUSEMOTION: + case SDL_EVENT_MOUSE_MOTION: return on_mouse_motion(ev.motion); - case SDL_MOUSEWHEEL: + case SDL_EVENT_MOUSE_WHEEL: return on_mouse_wheel(ev.wheel); - case SDL_KEYDOWN: + case SDL_EVENT_KEY_DOWN: return on_key_down(ev.key); - case SDL_KEYUP: + case SDL_EVENT_KEY_UP: return on_key_up(ev.key); default: diff --git a/src/editor/widget.hpp b/src/editor/widget.hpp index 5e2105863e5..3f6d1e3bc77 100644 --- a/src/editor/widget.hpp +++ b/src/editor/widget.hpp @@ -16,7 +16,7 @@ #pragma once -#include +#include class DrawingContext; diff --git a/src/gui/dialog.cpp b/src/gui/dialog.cpp index 9551ea541b9..7ca681104e4 100644 --- a/src/gui/dialog.cpp +++ b/src/gui/dialog.cpp @@ -116,7 +116,7 @@ Dialog::event(const SDL_Event& ev) return; switch (ev.type) { - case SDL_MOUSEBUTTONDOWN: + case SDL_EVENT_MOUSE_BUTTON_DOWN: if (ev.button.button == SDL_BUTTON_LEFT) { Vector mouse_pos = VideoSystem::current()->get_viewport().to_logical(ev.motion.x, ev.motion.y); @@ -129,7 +129,7 @@ Dialog::event(const SDL_Event& ev) } break; - case SDL_MOUSEMOTION: + case SDL_EVENT_MOUSE_MOTION: { Vector mouse_pos = VideoSystem::current()->get_viewport().to_logical(ev.motion.x, ev.motion.y); int new_button = get_button_at(mouse_pos); diff --git a/src/gui/dialog.hpp b/src/gui/dialog.hpp index 1de58f639ee..2bb259e9413 100644 --- a/src/gui/dialog.hpp +++ b/src/gui/dialog.hpp @@ -16,7 +16,7 @@ #pragma once -#include +#include #include #include #include diff --git a/src/gui/item_color_picker_2d.cpp b/src/gui/item_color_picker_2d.cpp index 1bd083948fe..45fc86ea285 100644 --- a/src/gui/item_color_picker_2d.cpp +++ b/src/gui/item_color_picker_2d.cpp @@ -29,7 +29,7 @@ namespace { /** Get the color of a pixel from an 8-bit RGB image * - * @param surface SDL2 surface containing the image + * @param surface SDL3 surface containing the image * @param pos Floating-point pixel coordinates in [0,1]^2 * * @return Color of the pixel at the integer position which corresponds to pos @@ -37,7 +37,8 @@ namespace { Color get_pixel(const SDLSurfacePtr& surface, const Vector& pos) { - assert(surface->format->BytesPerPixel == 3); + const SDL_PixelFormatDetails* format = SDL_GetPixelFormatDetails(surface->format); + assert(format->bytes_per_pixel == 3); int x = math::clamp( static_cast(pos.x * static_cast(surface->w - 1) + 0.5f), 0, @@ -104,9 +105,9 @@ ItemColorPicker2D::draw(DrawingContext& context, const Vector& pos, void ItemColorPicker2D::event(const SDL_Event& ev) { - bool is_mouseclick = ev.type == SDL_MOUSEBUTTONDOWN + bool is_mouseclick = ev.type == SDL_EVENT_MOUSE_BUTTON_DOWN && ev.button.button == SDL_BUTTON_LEFT; - bool is_hold_mousemove = ev.type == SDL_MOUSEMOTION + bool is_hold_mousemove = ev.type == SDL_EVENT_MOUSE_MOTION && (ev.motion.state & SDL_BUTTON_LMASK); if (is_mouseclick) { m_mousedown = true; diff --git a/src/gui/item_colorchannel_rgba.cpp b/src/gui/item_colorchannel_rgba.cpp index 26ff4c076fe..1813564c55f 100644 --- a/src/gui/item_colorchannel_rgba.cpp +++ b/src/gui/item_colorchannel_rgba.cpp @@ -94,7 +94,7 @@ ItemColorChannelRGBA::enable_edit_mode() void ItemColorChannelRGBA::event(const SDL_Event& ev) { - if (ev.type == SDL_TEXTINPUT) { + if (ev.type == SDL_EVENT_TEXT_INPUT) { std::string txt = ev.text.text; for (auto& c : txt) { add_char(c); diff --git a/src/gui/item_horizontalmenu.cpp b/src/gui/item_horizontalmenu.cpp index ff7bab32fab..a86b0e0aaa4 100644 --- a/src/gui/item_horizontalmenu.cpp +++ b/src/gui/item_horizontalmenu.cpp @@ -214,7 +214,7 @@ ItemHorizontalMenu::event(const SDL_Event& ev) { switch (ev.type) { - case SDL_MOUSEMOTION: + case SDL_EVENT_MOUSE_MOTION: { const Vector mouse_pos = VideoSystem::current()->get_viewport().to_logical(ev.motion.x, ev.motion.y); diff --git a/src/gui/item_script_line.cpp b/src/gui/item_script_line.cpp index bf4fdfece04..91e273518e0 100644 --- a/src/gui/item_script_line.cpp +++ b/src/gui/item_script_line.cpp @@ -67,11 +67,11 @@ ItemScriptLine::get_width() const void ItemScriptLine::event(const SDL_Event& ev) { - if (ev.type == SDL_KEYDOWN) + if (ev.type == SDL_EVENT_KEY_DOWN) { - if (SDL_GetModState() & KMOD_CTRL) // Commands which require CTRL + if (SDL_GetModState() & SDL_KMOD_CTRL) // Commands which require CTRL { - if (ev.key.keysym.sym == SDLK_d) // Duplicate line + if (ev.key.key == SDLK_D) // Duplicate line { duplicate_line(); } diff --git a/src/gui/item_textfield.cpp b/src/gui/item_textfield.cpp index 3978a56ffad..cace9c48381 100644 --- a/src/gui/item_textfield.cpp +++ b/src/gui/item_textfield.cpp @@ -74,43 +74,43 @@ ItemTextField::get_width() const void ItemTextField::event(const SDL_Event& ev) { - if (ev.type == SDL_TEXTINPUT) // Text input + if (ev.type == SDL_EVENT_TEXT_INPUT) // Text input { insert_text(ev.text.text, m_cursor_left_offset); } - else if (ev.type == SDL_KEYDOWN) + else if (ev.type == SDL_EVENT_KEY_DOWN) { - if (ev.key.keysym.sym == SDLK_DELETE) // Delete back + if (ev.key.key == SDLK_DELETE) // Delete back { delete_back(); } - else if (ev.key.keysym.sym == SDLK_HOME) // Home: go to beginning of text + else if (ev.key.key == SDLK_HOME) // Home: go to beginning of text { go_to_beginning(); } - else if (ev.key.keysym.sym == SDLK_END) // End: go to end of text + else if (ev.key.key == SDLK_END) // End: go to end of text { go_to_end(); } - else if (SDL_GetModState() & KMOD_CTRL) //Commands which require CTRL + else if (SDL_GetModState() & SDL_KMOD_CTRL) //Commands which require CTRL { - if (ev.key.keysym.sym == SDLK_x) // Cut (whole line) + if (ev.key.key == SDLK_X) // Cut (whole line) { cut(); } - else if (ev.key.keysym.sym == SDLK_c) // Copy (whole line) + else if (ev.key.key == SDLK_C) // Copy (whole line) { copy(); } - else if (ev.key.keysym.sym == SDLK_v) // Paste + else if (ev.key.key == SDLK_V) // Paste { paste(); } - else if (ev.key.keysym.sym == SDLK_z) // Undo + else if (ev.key.key == SDLK_Z) // Undo { undo(); } - else if (ev.key.keysym.sym == SDLK_y) // Redo + else if (ev.key.key == SDLK_Y) // Redo { redo(); } diff --git a/src/gui/menu.cpp b/src/gui/menu.cpp index cf14843af5c..3e82c639904 100644 --- a/src/gui/menu.cpp +++ b/src/gui/menu.cpp @@ -581,17 +581,17 @@ Menu::event(const SDL_Event& ev) m_items[m_active_item]->event(ev); switch (ev.type) { - case SDL_KEYDOWN: - case SDL_TEXTINPUT: - if (((ev.type == SDL_KEYDOWN && ev.key.keysym.sym == SDLK_BACKSPACE) || - ev.type == SDL_TEXTINPUT) && m_items[m_active_item]->changes_width()) + case SDL_EVENT_KEY_DOWN: + case SDL_EVENT_TEXT_INPUT: + if (((ev.type == SDL_EVENT_KEY_DOWN && ev.key.key == SDLK_BACKSPACE) || + ev.type == SDL_EVENT_TEXT_INPUT) && m_items[m_active_item]->changes_width()) { // Changed item value? Let's recalculate width: calculate_width(); } break; - case SDL_MOUSEBUTTONDOWN: + case SDL_EVENT_MOUSE_BUTTON_DOWN: if (ev.button.button == SDL_BUTTON_LEFT) { Vector mouse_pos = VideoSystem::current()->get_viewport().to_logical(ev.motion.x, ev.motion.y); @@ -606,7 +606,7 @@ Menu::event(const SDL_Event& ev) } break; - case SDL_MOUSEMOTION: + case SDL_EVENT_MOUSE_MOTION: { Vector mouse_pos = VideoSystem::current()->get_viewport().to_logical(ev.motion.x, ev.motion.y); float x = mouse_pos.x; diff --git a/src/gui/menu.hpp b/src/gui/menu.hpp index 4d7ff1e4a7b..155a1b5adeb 100644 --- a/src/gui/menu.hpp +++ b/src/gui/menu.hpp @@ -18,7 +18,7 @@ #include #include -#include +#include #include "gui/menu_action.hpp" #include "math/vector.hpp" diff --git a/src/gui/mousecursor.cpp b/src/gui/mousecursor.cpp index 6b1af146d63..05dfe648485 100644 --- a/src/gui/mousecursor.cpp +++ b/src/gui/mousecursor.cpp @@ -16,10 +16,10 @@ #include "gui/mousecursor.hpp" -#include -#include -#include -#include +#include +#include +#include +#include #include #include "supertux/gameconfig.hpp" @@ -65,7 +65,7 @@ MouseCursor::set_cursor_action(const std::string& action) std::string filename = (*surfaces)[0]->get_filename(); SDLSurfacePtr surface = SDLSurface::from_file(filename); m_cursors[action] = - std::move(std::shared_ptr(SDL_CreateColorCursor(surface.get(), 0, 0), &SDL_FreeCursor)); + std::move(std::shared_ptr(SDL_CreateColorCursor(surface.get(), 0, 0), &SDL_DestroyCursor)); if (m_cursors[action]) { SDL_SetCursor(m_cursors[action].get()); @@ -105,7 +105,7 @@ MouseCursor::apply_state(MouseCursorState state) case MouseCursorState::HIDE: if (g_config->custom_system_cursor) - SDL_ShowCursor(SDL_DISABLE); + SDL_HideCursor(); break; } } @@ -118,10 +118,10 @@ MouseCursor::draw(DrawingContext& context) { if (m_custom_cursor_last) { - SDL_Cursor* default_cursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); + SDL_Cursor* default_cursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_DEFAULT); if (default_cursor) SDL_SetCursor(default_cursor); - SDL_FreeCursor(default_cursor); + SDL_DestroyCursor(default_cursor); m_custom_cursor_last = false; } return; @@ -129,12 +129,12 @@ MouseCursor::draw(DrawingContext& context) if (m_state != MouseCursorState::HIDE) { - int x, y; + float x, y; Uint32 ispressed = SDL_GetMouseState(&x, &y); - if (g_config->custom_system_cursor && SDL_ShowCursor(SDL_QUERY) == SDL_DISABLE) + if (g_config->custom_system_cursor && !SDL_CursorVisible()) { - SDL_ShowCursor(SDL_ENABLE); + SDL_ShowCursor(); } if (m_mobile_mode) @@ -143,7 +143,7 @@ MouseCursor::draw(DrawingContext& context) y = m_y; } - if (ispressed & SDL_BUTTON(1) || ispressed & SDL_BUTTON(2)) + if (ispressed & SDL_BUTTON_MASK(1) || ispressed & SDL_BUTTON_MASK(2)) { apply_state(MouseCursorState::CLICK); } diff --git a/src/gui/mousecursor.hpp b/src/gui/mousecursor.hpp index 793409532af..4ef7e8e293a 100644 --- a/src/gui/mousecursor.hpp +++ b/src/gui/mousecursor.hpp @@ -16,7 +16,7 @@ #pragma once -#include +#include #include #include #include diff --git a/src/gui/notification.cpp b/src/gui/notification.cpp index e1377463218..fed60947b31 100644 --- a/src/gui/notification.cpp +++ b/src/gui/notification.cpp @@ -169,7 +169,7 @@ Notification::event(const SDL_Event& ev) switch (ev.type) { - case SDL_MOUSEBUTTONDOWN: + case SDL_EVENT_MOUSE_BUTTON_DOWN: if (ev.button.button == SDL_BUTTON_LEFT) { if (m_mouse_over) @@ -193,7 +193,7 @@ Notification::event(const SDL_Event& ev) } break; - case SDL_MOUSEMOTION: + case SDL_EVENT_MOUSE_MOTION: { m_mouse_pos = VideoSystem::current()->get_viewport().to_logical(ev.motion.x, ev.motion.y); m_mouse_over = bg_rect.contains(m_mouse_pos); diff --git a/src/gui/notification.hpp b/src/gui/notification.hpp index d40fe423569..ac895df8508 100644 --- a/src/gui/notification.hpp +++ b/src/gui/notification.hpp @@ -16,7 +16,7 @@ #pragma once -#include +#include #include #include diff --git a/src/interface/container.hpp b/src/interface/container.hpp index f7e54beeb5e..49bb0438024 100644 --- a/src/interface/container.hpp +++ b/src/interface/container.hpp @@ -16,7 +16,7 @@ #pragma once -#include +#include #include "interface/control.hpp" #include "math/rectf.hpp" diff --git a/src/interface/control.hpp b/src/interface/control.hpp index 9a79f034025..1630cb9f419 100644 --- a/src/interface/control.hpp +++ b/src/interface/control.hpp @@ -17,7 +17,7 @@ #pragma once #include -#include +#include #include "control/input_manager.hpp" #include "editor/widget.hpp" diff --git a/src/interface/control_button.cpp b/src/interface/control_button.cpp index 6acd889731a..3111f25dbbb 100644 --- a/src/interface/control_button.cpp +++ b/src/interface/control_button.cpp @@ -89,7 +89,7 @@ ControlButton::on_key_up(const SDL_KeyboardEvent& key) if (!m_has_focus) return false; - if (key.keysym.sym == SDLK_SPACE) { + if (key.key == SDLK_SPACE) { if (m_on_change) m_on_change(); m_mouse_down = false; @@ -105,7 +105,7 @@ ControlButton::on_key_down(const SDL_KeyboardEvent& key) if (!m_has_focus) return false; - if (key.keysym.sym == SDLK_SPACE) { + if (key.key == SDLK_SPACE) { m_mouse_down = true; return true; } diff --git a/src/interface/control_checkbox.cpp b/src/interface/control_checkbox.cpp index 518c4bfdd3b..48bade715e2 100644 --- a/src/interface/control_checkbox.cpp +++ b/src/interface/control_checkbox.cpp @@ -79,7 +79,7 @@ ControlCheckbox::on_mouse_button_down(const SDL_MouseButtonEvent& button) bool ControlCheckbox::on_key_up(const SDL_KeyboardEvent& key) { - if (key.keysym.sym != SDLK_SPACE || !m_has_focus) + if (key.key != SDLK_SPACE || !m_has_focus) return false; *m_value = !*m_value; diff --git a/src/interface/control_enum.hpp b/src/interface/control_enum.hpp index 97fca3a2239..b8443e090ba 100644 --- a/src/interface/control_enum.hpp +++ b/src/interface/control_enum.hpp @@ -219,9 +219,9 @@ template bool ControlEnum::on_key_up(const SDL_KeyboardEvent& key) { - if ((key.keysym.sym == SDLK_SPACE - || key.keysym.sym == SDLK_RETURN - || key.keysym.sym == SDLK_RETURN2) && m_has_focus) { + if ((key.key == SDLK_SPACE + || key.key == SDLK_RETURN + || key.key == SDLK_RETURN2) && m_has_focus) { m_open_list = !m_open_list; return true; } else { @@ -236,7 +236,7 @@ ControlEnum::on_key_down(const SDL_KeyboardEvent& key) if (!m_has_focus) return false; - if (key.keysym.sym == SDLK_DOWN) { + if (key.key == SDLK_DOWN) { bool is_next = false; // Hacky way to get the next one in the list for (const auto& option : m_options) { @@ -257,7 +257,7 @@ ControlEnum::on_key_down(const SDL_KeyboardEvent& key) m_on_change(); return true; - } else if (key.keysym.sym == SDLK_UP) { + } else if (key.key == SDLK_UP) { bool is_last = false; bool currently_on_first = true; diff --git a/src/interface/control_textbox.cpp b/src/interface/control_textbox.cpp index 89c94116f5f..d090c940a36 100644 --- a/src/interface/control_textbox.cpp +++ b/src/interface/control_textbox.cpp @@ -18,7 +18,7 @@ #include -#include +#include #include "math/vector.hpp" #include "math/rectf.hpp" @@ -174,12 +174,12 @@ ControlTextbox::on_key_up(const SDL_KeyboardEvent& key) if (m_has_focus) { - if (key.keysym.sym == SDLK_LSHIFT || key.keysym.sym == SDLK_RSHIFT) + if (key.key == SDLK_LSHIFT || key.key == SDLK_RSHIFT) { m_shift_pressed = false; return true; } - else if (key.keysym.sym == SDLK_LCTRL || key.keysym.sym == SDLK_RCTRL) + else if (key.key == SDLK_LCTRL || key.key == SDLK_RCTRL) { m_ctrl_pressed = false; return true; @@ -195,7 +195,7 @@ ControlTextbox::on_key_down(const SDL_KeyboardEvent& key) if (!m_has_focus) return false; - if (key.keysym.sym == SDLK_LEFT && m_caret_pos > 0) + if (key.key == SDLK_LEFT && m_caret_pos > 0) { if (!m_shift_pressed && m_secondary_caret_pos != m_caret_pos) { @@ -212,7 +212,7 @@ ControlTextbox::on_key_down(const SDL_KeyboardEvent& key) recenter_offset(); return true; } - else if (key.keysym.sym == SDLK_RIGHT && m_caret_pos < int(m_charlist.size())) + else if (key.key == SDLK_RIGHT && m_caret_pos < int(m_charlist.size())) { if (!m_shift_pressed && m_secondary_caret_pos != m_caret_pos) { @@ -229,7 +229,7 @@ ControlTextbox::on_key_down(const SDL_KeyboardEvent& key) recenter_offset(); return true; } - else if (key.keysym.sym == SDLK_BACKSPACE) + else if (key.key == SDLK_BACKSPACE) { if (!erase_selected_text() && m_caret_pos > 0) { @@ -237,7 +237,7 @@ ControlTextbox::on_key_down(const SDL_KeyboardEvent& key) } return true; } - else if (key.keysym.sym == SDLK_DELETE) + else if (key.key == SDLK_DELETE) { if (!erase_selected_text() && static_cast(m_charlist.size()) > m_caret_pos) { @@ -246,7 +246,7 @@ ControlTextbox::on_key_down(const SDL_KeyboardEvent& key) } return true; } - else if (key.keysym.sym == SDLK_HOME) + else if (key.key == SDLK_HOME) { m_caret_pos = 0; m_cursor_timer = CONTROL_CURSOR_TIMER; @@ -256,7 +256,7 @@ ControlTextbox::on_key_down(const SDL_KeyboardEvent& key) recenter_offset(); return true; } - else if (key.keysym.sym == SDLK_END) + else if (key.key == SDLK_END) { m_caret_pos = int(m_charlist.size()); m_cursor_timer = CONTROL_CURSOR_TIMER; @@ -266,34 +266,34 @@ ControlTextbox::on_key_down(const SDL_KeyboardEvent& key) recenter_offset(); return true; } - else if (key.keysym.sym == SDLK_LSHIFT || key.keysym.sym == SDLK_RSHIFT) + else if (key.key == SDLK_LSHIFT || key.key == SDLK_RSHIFT) { m_shift_pressed = true; return true; } - else if (key.keysym.sym == SDLK_LCTRL || key.keysym.sym == SDLK_RCTRL) + else if (key.key == SDLK_LCTRL || key.key == SDLK_RCTRL) { m_ctrl_pressed = true; return true; } - else if (key.keysym.sym == SDLK_c && m_ctrl_pressed) + else if (key.key == SDLK_C && m_ctrl_pressed) { copy(); return true; } - else if (key.keysym.sym == SDLK_v && m_ctrl_pressed) + else if (key.key == SDLK_V && m_ctrl_pressed) { paste(); return true; } - else if (key.keysym.sym == SDLK_a && m_ctrl_pressed) + else if (key.key == SDLK_A && m_ctrl_pressed) { m_caret_pos = 0; m_secondary_caret_pos = static_cast(m_charlist.size()); recenter_offset(); return true; } - else if (key.keysym.sym == SDLK_RETURN) + else if (key.key == SDLK_RETURN) { parse_value(); return true; @@ -306,7 +306,7 @@ bool ControlTextbox::event(const SDL_Event& ev) { Widget::event(ev); - if (ev.type == SDL_TEXTINPUT && m_has_focus) + if (ev.type == SDL_EVENT_TEXT_INPUT && m_has_focus) put_text(std::string(ev.text.text)); return false; diff --git a/src/interface/label.hpp b/src/interface/label.hpp index e8c5133a13f..90229ea5dec 100644 --- a/src/interface/label.hpp +++ b/src/interface/label.hpp @@ -16,7 +16,7 @@ #pragma once -#include +#include #include "editor/widget.hpp" #include "video/drawing_context.hpp" diff --git a/src/main.cpp b/src/main.cpp index 4fb6f160d94..d94a4d264b9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,7 +14,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#include +#include +#include #include #include diff --git a/src/math/rect.hpp b/src/math/rect.hpp index 03eee534f2e..85be367300f 100644 --- a/src/math/rect.hpp +++ b/src/math/rect.hpp @@ -20,7 +20,7 @@ #include #include -#include +#include #include "math/size.hpp" diff --git a/src/math/rectf.hpp b/src/math/rectf.hpp index 8a5af8b88ea..8633ff9f565 100644 --- a/src/math/rectf.hpp +++ b/src/math/rectf.hpp @@ -19,7 +19,7 @@ #include #include -#include +#include #include "math/anchor_point.hpp" #include "math/sizef.hpp" diff --git a/src/physfs/physfs_sdl.cpp b/src/physfs/physfs_sdl.cpp index b8fd3562660..d2b24c755ae 100644 --- a/src/physfs/physfs_sdl.cpp +++ b/src/physfs/physfs_sdl.cpp @@ -17,96 +17,20 @@ #include "physfs/physfs_sdl.hpp" #include -#include -#include -#include -#include +#include +#include #include "physfs/util.hpp" +#include "util/file_system.hpp" #include "util/log.hpp" #include +#include +#include +#include +#include -namespace { - -Sint64 funcSize(struct SDL_RWops* context) -{ - PHYSFS_file* file = static_cast(context->hidden.unknown.data1); - return PHYSFS_fileLength(file); -} - -Sint64 funcSeek(struct SDL_RWops* context, Sint64 offset, int whence) -{ - PHYSFS_file* file = static_cast(context->hidden.unknown.data1); - int res; - switch (whence) { - case SEEK_SET: - res = PHYSFS_seek(file, offset); - break; - case SEEK_CUR: - res = PHYSFS_seek(file, PHYSFS_tell(file) + offset); - break; - case SEEK_END: - res = PHYSFS_seek(file, PHYSFS_fileLength(file) + offset); - break; - default: - res = 0; // NOLINT - assert(false); - break; - } - if (res == 0) { - log_warning << "Error seeking in file: " << physfsutil::get_last_error() << std::endl; - return -1; - } - int i = static_cast(PHYSFS_tell(file)); - - - return i; -} - -size_t funcRead(struct SDL_RWops* context, void* ptr, size_t size, size_t maxnum) -{ - PHYSFS_file* file = static_cast(context->hidden.unknown.data1); - - PHYSFS_sint64 res = PHYSFS_readBytes(file, ptr, size * maxnum); - if (res < 0) - { - return 0; - } - else - { - return static_cast(res / size); - } -} - -size_t funcWrite(struct SDL_RWops* context, const void* ptr, size_t size, size_t num) -{ - PHYSFS_file* file = static_cast(context->hidden.unknown.data1); - - PHYSFS_sint64 res = PHYSFS_writeBytes(file, ptr, size * num); - if (res < 0) - { - return 0; - } - else - { - return static_cast(res / size); - } -} - -int funcClose(struct SDL_RWops* context) -{ - PHYSFS_file* file = static_cast(context->hidden.unknown.data1); - - PHYSFS_close(file); - delete context; - - return 0; -} - -} // namespace - -SDL_RWops* get_physfs_SDLRWops(const std::string& filename) +SDL_IOStream* get_physfs_SDLRWops(const std::string& filename) { // check this as PHYSFS seems to be buggy and still returns a // valid pointer in this case @@ -114,27 +38,18 @@ SDL_RWops* get_physfs_SDLRWops(const std::string& filename) throw std::runtime_error("Couldn't open file: empty filename"); } - PHYSFS_file* file = static_cast(PHYSFS_openRead(filename.c_str())); - if (!file) { + auto path = PHYSFS_getRealDir(filename.c_str()); + if (!path) { std::stringstream msg; - msg << "Couldn't open '" << filename << "': " - << physfsutil::get_last_error(); + msg << "File '" << filename << "' doesn't exist in any search path"; throw std::runtime_error(msg.str()); } - SDL_RWops* ops = new SDL_RWops; - ops->size = funcSize; - ops->seek = funcSeek; - ops->read = funcRead; - ops->write = funcWrite; - ops->close = funcClose; - ops->type = SDL_RWOPS_UNKNOWN; - ops->hidden.unknown.data1 = file; - - return ops; + auto full_path = FileSystem::join(path, filename); + return SDL_IOFromFile(full_path.c_str(), "rb"); } -SDL_RWops* get_writable_physfs_SDLRWops(const std::string& filename) +SDL_IOStream* get_writable_physfs_SDLRWops(const std::string& filename) { // check this as PHYSFS seems to be buggy and still returns a // valid pointer in this case @@ -142,22 +57,13 @@ SDL_RWops* get_writable_physfs_SDLRWops(const std::string& filename) throw std::runtime_error("Couldn't open file: empty filename"); } - PHYSFS_file* file = static_cast(PHYSFS_openWrite(filename.c_str())); - if (!file) { + auto path = PHYSFS_getRealDir(filename.c_str()); + if (!path) { std::stringstream msg; - msg << "Couldn't open '" << filename << "' for writing: " - << physfsutil::get_last_error(); + msg << "File '" << filename << "' doesn't exist in any search path"; throw std::runtime_error(msg.str()); } - SDL_RWops* ops = new SDL_RWops; - ops->size = funcSize; - ops->seek = funcSeek; - ops->read = funcRead; - ops->write = funcWrite; - ops->close = funcClose; - ops->type = SDL_RWOPS_UNKNOWN; - ops->hidden.unknown.data1 = file; - - return ops; + auto full_path = FileSystem::join(path, filename); + return SDL_IOFromFile(full_path.c_str(), "wb"); } diff --git a/src/physfs/physfs_sdl.hpp b/src/physfs/physfs_sdl.hpp index 51ab44aa9d5..8c3064f82d7 100644 --- a/src/physfs/physfs_sdl.hpp +++ b/src/physfs/physfs_sdl.hpp @@ -16,13 +16,14 @@ #pragma once -#include +#include +#include #include -/** The returned SDL_RWops object must be freed with SDL_RWclose(), +/** The returned SDL_IOStream object must be freed with SDL_RWclose(), SDL library functions have a flag to perform that call automatically. Do not use 'delete' or 'free()' on it. See: https://wiki.libsdl.org/SDL_RWclose */ -SDL_RWops* get_physfs_SDLRWops(const std::string& filename); -SDL_RWops* get_writable_physfs_SDLRWops(const std::string& filename); +SDL_IOStream* get_physfs_SDLRWops(const std::string& filename); +SDL_IOStream* get_writable_physfs_SDLRWops(const std::string& filename); diff --git a/src/supertux/error_handler.cpp b/src/supertux/error_handler.cpp index 97711a7cfce..66675596e83 100644 --- a/src/supertux/error_handler.cpp +++ b/src/supertux/error_handler.cpp @@ -27,7 +27,7 @@ #include #include -#include +#include #include diff --git a/src/supertux/gameconfig.cpp b/src/supertux/gameconfig.cpp index 6d875fc68db..4a41ee4816c 100644 --- a/src/supertux/gameconfig.cpp +++ b/src/supertux/gameconfig.cpp @@ -70,7 +70,7 @@ Config::Config() : locale(), keyboard_config(), joystick_config(), - mobile_controls(SDL_GetNumTouchDevices() > 0), + mobile_controls(), m_mobile_controls_scale(1), addons(), developer_mode(false), @@ -122,6 +122,9 @@ Config::Config() : #endif repository_url() { + int num_touch_devices; + SDL_GetTouchDevices(&num_touch_devices); + mobile_controls = (num_touch_devices > 0); } void @@ -323,7 +326,10 @@ Config::load() joystick_config.read(*joystick_mapping); } - config_control_mapping->get("mobile_controls", mobile_controls, SDL_GetNumTouchDevices() > 0); + int num_touch_devices; + SDL_GetTouchDevices(&num_touch_devices); + + config_control_mapping->get("mobile_controls", mobile_controls, (num_touch_devices > 0)); config_control_mapping->get("mobile_controls_scale", m_mobile_controls_scale, 1); } diff --git a/src/supertux/main.cpp b/src/supertux/main.cpp index 1ac3c34220a..4e8a8d2a4f0 100644 --- a/src/supertux/main.cpp +++ b/src/supertux/main.cpp @@ -21,8 +21,10 @@ #include #include -#include -#include +#include +#include +#include +#include #include #include #include @@ -237,9 +239,8 @@ void PhysfsSubsystem::find_mount_datadir() else { // check if we run from source dir - char* basepath_c = SDL_GetBasePath(); + const char* basepath_c = SDL_GetBasePath(); std::string basepath = basepath_c ? basepath_c : "./"; - SDL_free(basepath_c); if (FileSystem::exists(FileSystem::join(BUILD_DATA_DIR, "credits.stxt"))) { @@ -426,18 +427,18 @@ PhysfsSubsystem::~PhysfsSubsystem() SDLSubsystem::SDLSubsystem() { - Uint32 flags = SDL_INIT_TIMER | SDL_INIT_VIDEO; + Uint32 flags = SDL_INIT_VIDEO; #ifndef UBUNTU_TOUCH - flags |= SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER; + flags |= SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD; #endif - if (SDL_Init(flags) < 0) + if (SDL_Init(flags) == false) { std::stringstream msg; msg << "Couldn't initialize SDL: " << SDL_GetError(); throw std::runtime_error(msg.str()); } - if (TTF_Init() < 0) + if (TTF_Init() == false) { std::stringstream msg; msg << "Couldn't initialize SDL TTF: " << SDL_GetError(); @@ -465,8 +466,14 @@ Main::init_video() SDLSurfacePtr icon = SDLSurface::from_file(icon_fname); VideoSystem::current()->set_icon(*icon); - SDL_ShowCursor( - (g_config->custom_mouse_cursor && !g_config->custom_system_cursor) ? SDL_DISABLE : SDL_ENABLE); + if (g_config->custom_mouse_cursor && !g_config->custom_system_cursor) + { + SDL_HideCursor(); + } + else + { + SDL_ShowCursor(); + } log_info << (g_config->use_fullscreen?"fullscreen ":"window ") << " Window: " << g_config->window_size @@ -758,7 +765,7 @@ Main::run(int argc, char** argv) g_dictionary_manager.reset(); #ifdef __ANDROID__ - // SDL2 keeps shared libraries loaded after the app is closed, + // SDL3 keeps shared libraries loaded after the app is closed, // when we launch the app again the static initializers will run twice and crash the app. // So we just need to terminate the app process 'gracefully', without running destructors or atexit() functions. _exit(result); diff --git a/src/supertux/menu/addon_file_install_menu.cpp b/src/supertux/menu/addon_file_install_menu.cpp index b028135ee9e..aa4fbd59c2f 100644 --- a/src/supertux/menu/addon_file_install_menu.cpp +++ b/src/supertux/menu/addon_file_install_menu.cpp @@ -39,11 +39,11 @@ AddonFileInstallMenu::refresh() void AddonFileInstallMenu::event(const SDL_Event& event) { - if (event.type == SDL_DROPFILE) + if (event.type == SDL_EVENT_DROP_FILE) { - char* filename = event.drop.file; + const char* filename = event.drop.data; AddonManager::current()->install_addon_from_local_file(std::string(filename)); - SDL_free(filename); + m_addon_menu->refresh(); } Menu::event(event); diff --git a/src/supertux/menu/joystick_menu.cpp b/src/supertux/menu/joystick_menu.cpp index b797ac32de6..a3ea8083fa7 100644 --- a/src/supertux/menu/joystick_menu.cpp +++ b/src/supertux/menu/joystick_menu.cpp @@ -56,7 +56,7 @@ JoystickMenu::recreate_menu() add_toggle(MNID_AUTO_JOYSTICK_CFG, _("Manual Configuration"), &m_auto_joystick_cfg) - .set_help(_("Use manual configuration instead of SDL2's automatic GameController support")); + .set_help(_("Use manual configuration instead of SDL3's automatic GameController support")); if (m_input_manager.use_game_controller()) { diff --git a/src/supertux/menu/multiplayer_player_menu.cpp b/src/supertux/menu/multiplayer_player_menu.cpp index 824591b1ac6..2ce23143ccd 100644 --- a/src/supertux/menu/multiplayer_player_menu.cpp +++ b/src/supertux/menu/multiplayer_player_menu.cpp @@ -17,7 +17,7 @@ #include "supertux/menu/multiplayer_player_menu.hpp" #include -#include +#include #include "control/game_controller_manager.hpp" #include "control/input_manager.hpp" @@ -124,7 +124,7 @@ MultiplayerPlayerMenu::MultiplayerPlayerMenu(int player_id) auto controller = pair.first; std::string prefix = (pair.second == -1) ? "" : (pair.second == player_id) ? "-> " : ("[" + std::to_string(pair.second + 1) + "] "); - add_entry(prefix + std::string(SDL_GameControllerName(pair.first)), [controller, player_id] { + add_entry(prefix + std::string(SDL_GetGamepadName(pair.first)), [controller, player_id] { InputManager::current()->game_controller_manager->bind_controller(controller, player_id); auto err = InputManager::current()->game_controller_manager->rumble(controller); @@ -156,7 +156,7 @@ MultiplayerPlayerMenu::MultiplayerPlayerMenu(int player_id) auto joystick = pair.first; std::string prefix = (pair.second == -1) ? "" : (pair.second == player_id) ? "-> " : ("[" + std::to_string(pair.second + 1) + "] "); - add_entry(prefix + std::string(SDL_JoystickName(pair.first)), [joystick, player_id] { + add_entry(prefix + std::string(SDL_GetJoystickName(pair.first)), [joystick, player_id] { InputManager::current()->joystick_manager->bind_joystick(joystick, player_id); auto err = InputManager::current()->joystick_manager->rumble(joystick); diff --git a/src/supertux/menu/options_menu.cpp b/src/supertux/menu/options_menu.cpp index aa73b3a38f3..bd6bac00a5f 100644 --- a/src/supertux/menu/options_menu.cpp +++ b/src/supertux/menu/options_menu.cpp @@ -375,27 +375,27 @@ OptionsMenu::add_window_resolutions() void OptionsMenu::add_resolutions() { - int display_mode_count = SDL_GetNumDisplayModes(0); + int display_mode_count; + auto display_modes = SDL_GetFullscreenDisplayModes(0, &display_mode_count); + + if (display_modes == nullptr) + { + log_warning << "failed to get fullscreen display modes: " << SDL_GetError() << std::endl; + display_mode_count = 0; + } + std::string last_display_mode; for (int i = 0; i < display_mode_count; ++i) { - SDL_DisplayMode mode; - int ret = SDL_GetDisplayMode(0, i, &mode); - if (ret != 0) - { - log_warning << "failed to get display mode: " << SDL_GetError() << std::endl; - } - else - { - std::ostringstream out; - out << mode.w << "x" << mode.h; - if (mode.refresh_rate) - out << "@" << mode.refresh_rate; - if (last_display_mode == out.str()) - continue; - last_display_mode = out.str(); - m_resolutions.list.insert(m_resolutions.list.begin(), out.str()); - } + SDL_DisplayMode mode = *(display_modes[i]); + std::ostringstream out; + out << mode.w << "x" << mode.h; + if (mode.refresh_rate) + out << "@" << mode.refresh_rate; + if (last_display_mode == out.str()) + continue; + last_display_mode = out.str(); + m_resolutions.list.insert(m_resolutions.list.begin(), out.str()); } m_resolutions.list.push_back("Desktop"); @@ -773,7 +773,10 @@ OptionsMenu::menu_action(MenuItem& item) break; case MNID_CUSTOM_CURSOR: - SDL_ShowCursor(g_config->custom_mouse_cursor ? 0 : 1); + if (g_config->custom_mouse_cursor) + SDL_HideCursor(); + else + SDL_ShowCursor(); break; case MNID_MOBILE_CONTROLS_SCALE: diff --git a/src/supertux/screen_manager.cpp b/src/supertux/screen_manager.cpp index d42b9e80d86..e18386e3378 100644 --- a/src/supertux/screen_manager.cpp +++ b/src/supertux/screen_manager.cpp @@ -334,7 +334,7 @@ ScreenManager::process_events() switch (event.type) { - case SDL_FINGERDOWN: + case SDL_EVENT_FINGER_DOWN: { SDL_Event old_event = event; @@ -343,27 +343,27 @@ ScreenManager::process_events() if (m_mobile_controller.process_finger_down_event(event.tfinger)) break; // Event was processed by touch controls, do not generate mouse event - event2.type = SDL_MOUSEBUTTONDOWN; + event2.type = SDL_EVENT_MOUSE_BUTTON_DOWN; event2.button.button = SDL_BUTTON_LEFT; event2.button.x = Sint32(old_event.tfinger.x * window_width); event2.button.y = Sint32(old_event.tfinger.y * window_height); SDL_PushEvent(&event2); - event.type = SDL_MOUSEMOTION; + event.type = SDL_EVENT_MOUSE_MOTION; event.motion.x = event2.button.x; event.motion.y = event2.button.y; MouseCursor::current()->set_pos(event.button.x, event.button.y); break; } - case SDL_FINGERUP: + case SDL_EVENT_FINGER_UP: { SDL_Event old_event = event; // Always generate mouse up event, because the finger can generate mouse click // and then move to the screen button, and the mouse button will stay pressed SDL_Event event2; - event2.type = SDL_MOUSEBUTTONUP; + event2.type = SDL_EVENT_MOUSE_BUTTON_UP; event2.button.button = SDL_BUTTON_LEFT; event2.button.x = Sint32(old_event.tfinger.x * window_width); event2.button.y = Sint32(old_event.tfinger.y * window_height); @@ -372,20 +372,20 @@ ScreenManager::process_events() if (m_mobile_controller.process_finger_up_event(event.tfinger)) break; // Event was processed by touch controls, do not generate mouse event - event.type = SDL_MOUSEMOTION; + event.type = SDL_EVENT_MOUSE_MOTION; event.motion.x = event2.button.x; event.motion.y = event2.button.y; MouseCursor::current()->set_pos(event.button.x, event.button.y); break; } - case SDL_FINGERMOTION: + case SDL_EVENT_FINGER_MOTION: SDL_Event old_event = event; if (m_mobile_controller.process_finger_motion_event(event.tfinger)) break; // Event was processed by touch controls, do not generate mouse event - event.type = SDL_MOUSEMOTION; + event.type = SDL_EVENT_MOUSE_MOTION; event.motion.x = Sint32(old_event.tfinger.x * window_width); event.motion.y = Sint32(old_event.tfinger.y * window_height); event.motion.xrel = Sint32(old_event.tfinger.dx * window_width); @@ -401,40 +401,35 @@ ScreenManager::process_events() switch (event.type) { - case SDL_QUIT: + case SDL_EVENT_QUIT: quit(); break; - case SDL_WINDOWEVENT: - switch (event.window.event) - { - case SDL_WINDOWEVENT_RESIZED: - m_video_system.on_resize(event.window.data1, event.window.data2); - on_window_resize(); - break; + case SDL_EVENT_WINDOW_RESIZED: + m_video_system.on_resize(event.window.data1, event.window.data2); + on_window_resize(); + break; - case SDL_WINDOWEVENT_HIDDEN: - case SDL_WINDOWEVENT_FOCUS_LOST: - if (g_config->pause_on_focusloss) - { - if (session != nullptr && session->is_active() && !Level::current()->m_suppress_pause_menu) - { - session->toggle_pause(); - } - } - break; + case SDL_EVENT_WINDOW_HIDDEN: + case SDL_EVENT_WINDOW_FOCUS_LOST: + if (g_config->pause_on_focusloss) + { + if (session != nullptr && session->is_active() && !Level::current()->m_suppress_pause_menu) + { + session->toggle_pause(); + } } break; - case SDL_KEYDOWN: - if (event.key.keysym.sym == SDLK_F10) + case SDL_EVENT_KEY_DOWN: + if (event.key.key == SDLK_F10) { g_config->show_fps = !g_config->show_fps; } #ifndef EMSCRIPTEN // Emscripten builds manage this through JS code - else if (event.key.keysym.sym == SDLK_F11 || - ((event.key.keysym.mod & KMOD_LALT || event.key.keysym.mod & KMOD_RALT) && - (event.key.keysym.sym == SDLK_KP_ENTER || event.key.keysym.sym == SDLK_RETURN))) + else if (event.key.key == SDLK_F11 || + ((event.key.mod & SDL_KMOD_LALT || event.key.mod & SDL_KMOD_RALT) && + (event.key.key == SDLK_KP_ENTER || event.key.key == SDLK_RETURN))) { g_config->use_fullscreen = !g_config->use_fullscreen; m_video_system.apply_config(); @@ -443,8 +438,8 @@ ScreenManager::process_events() #endif #ifdef STEAM_BUILD // Shift+Tab opens the overlay; pause the game - else if (event.key.keysym.sym == SDLK_TAB && - (event.key.keysym.mod & KMOD_LSHIFT || event.key.keysym.mod & KMOD_RSHIFT)) + else if (event.key.key == SDLK_TAB && + (event.key.mod & SDL_KMOD_LSHIFT || event.key.mod & SDL_KMOD_RSHIFT)) { if (session != nullptr && session->is_active() && !Level::current()->m_suppress_pause_menu) { @@ -452,13 +447,13 @@ ScreenManager::process_events() } } #endif - else if (event.key.keysym.sym == SDLK_PRINTSCREEN || - event.key.keysym.sym == SDLK_F12) + else if (event.key.key == SDLK_PRINTSCREEN || + event.key.key == SDLK_F12) { m_video_system.do_take_screenshot(); } - else if (event.key.keysym.sym == SDLK_F2 && - event.key.keysym.mod & KMOD_CTRL) + else if (event.key.key == SDLK_F2 && + event.key.mod & SDL_KMOD_CTRL) { g_config->developer_mode = !g_config->developer_mode; log_info << "developer mode: " << g_config->developer_mode << std::endl; @@ -467,8 +462,8 @@ ScreenManager::process_events() // NOTE: Steam recommends leaving this behavior in. If it turns out to be // impractical for users, please add `#ifdef STEAM_BUILD` code around it. - case SDL_JOYDEVICEREMOVED: - case SDL_CONTROLLERDEVICEREMOVED: + case SDL_EVENT_JOYSTICK_REMOVED: + case SDL_EVENT_GAMEPAD_REMOVED: if (session != nullptr && session->is_active() && !Level::current()->m_suppress_pause_menu) { session->toggle_pause(); diff --git a/src/supertux/screen_manager.hpp b/src/supertux/screen_manager.hpp index a0a221c6986..71633125a27 100644 --- a/src/supertux/screen_manager.hpp +++ b/src/supertux/screen_manager.hpp @@ -19,7 +19,7 @@ #include #include -#include +#include #include "config.h" diff --git a/src/util/file_system.cpp b/src/util/file_system.cpp index 030c11836f5..4377485943b 100644 --- a/src/util/file_system.cpp +++ b/src/util/file_system.cpp @@ -35,9 +35,9 @@ #include #endif -#include +#include #if SDL_VERSION_ATLEAST(2,0,14) -#include +#include #endif #include "gui/dialog.hpp" diff --git a/src/util/timelog.hpp b/src/util/timelog.hpp index 2ab814d48d6..dfac6cd328f 100644 --- a/src/util/timelog.hpp +++ b/src/util/timelog.hpp @@ -16,7 +16,7 @@ #pragma once -#include +#include class Timelog { diff --git a/src/video/bitmap_font.cpp b/src/video/bitmap_font.cpp index fa2c8d419d7..8977c5b6940 100644 --- a/src/video/bitmap_font.cpp +++ b/src/video/bitmap_font.cpp @@ -39,10 +39,11 @@ namespace { bool vline_empty(const SDLSurfacePtr& surface, int x, int start_y, int end_y, Uint8 threshold) { const Uint8* pixels = static_cast(surface->pixels); + const SDL_PixelFormatDetails* format = SDL_GetPixelFormatDetails(surface->format); for (int y = start_y; y < end_y; ++y) { - const Uint8& p = pixels[surface->pitch*y + x*surface->format->BytesPerPixel + 3]; + const Uint8& p = pixels[surface->pitch * y + x * format->bytes_per_pixel + 3]; if (p > threshold) { return false; diff --git a/src/video/color.hpp b/src/video/color.hpp index 152145ee3dd..453c586a53f 100644 --- a/src/video/color.hpp +++ b/src/video/color.hpp @@ -21,7 +21,7 @@ #include #include -#include +#include class Color final { diff --git a/src/video/gl/gl_screen_renderer.cpp b/src/video/gl/gl_screen_renderer.cpp index 68ebfd5aca8..641a6cc7f33 100644 --- a/src/video/gl/gl_screen_renderer.cpp +++ b/src/video/gl/gl_screen_renderer.cpp @@ -1,6 +1,6 @@ // SuperTux // Copyright (C) 2006 Matthias Braun -// Updated by GiBy 2013 for SDL2 +// Updated by GiBy 2013 for SDL3 // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/src/video/gl/gl_screen_renderer.hpp b/src/video/gl/gl_screen_renderer.hpp index 0de61dd91fd..3301160346c 100644 --- a/src/video/gl/gl_screen_renderer.hpp +++ b/src/video/gl/gl_screen_renderer.hpp @@ -17,7 +17,7 @@ #pragma once -#include +#include #include "math/vector.hpp" #include "video/gl/gl_renderer.hpp" diff --git a/src/video/gl/gl_texture.cpp b/src/video/gl/gl_texture.cpp index a332106ab09..d87c305145c 100644 --- a/src/video/gl/gl_texture.cpp +++ b/src/video/gl/gl_texture.cpp @@ -99,6 +99,7 @@ GLTexture::reload(const SDL_Surface& image) m_image_height = image.h; SDLSurfacePtr convert = SDLSurface::create_rgba(m_texture_width, m_texture_height); + const SDL_PixelFormatDetails* format = SDL_GetPixelFormatDetails(convert->format); SDL_SetSurfaceBlendMode(const_cast(&image), SDL_BLENDMODE_NONE); SDL_BlitSurface(const_cast(&image), nullptr, convert.get(), nullptr); @@ -129,13 +130,13 @@ GLTexture::reload(const SDL_Surface& image) if (m_image_width != m_texture_width && m_image_height != m_texture_height) { - const int bpp = convert->format->BytesPerPixel; + const int bpp = format->bytes_per_pixel; const int x = m_image_width - 1; const int y = m_image_height - 1; Uint32 color = 0; memcpy(&color, static_cast(convert->pixels) + y * convert->pitch + x * bpp, bpp); SDL_Rect dstrect{m_image_width, m_image_height, m_texture_width, m_texture_height}; - SDL_FillRect(convert.get(), &dstrect, color); + SDL_FillSurfaceRect(convert.get(), &dstrect, color); } if (SDL_MUSTLOCK(convert)) { @@ -149,9 +150,9 @@ GLTexture::reload(const SDL_Surface& image) try { GLenum sdl_format; - if (convert->format->BytesPerPixel == 3) { + if (format->bytes_per_pixel == 3) { sdl_format = GL_RGB; - } else if (convert->format->BytesPerPixel == 4) { + } else if (format->bytes_per_pixel == 4) { sdl_format = GL_RGBA; } else { sdl_format = GL_RGBA; // NOLINT. @@ -161,11 +162,11 @@ GLTexture::reload(const SDL_Surface& image) glBindTexture(GL_TEXTURE_2D, m_handle); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); #if defined(GL_UNPACK_ROW_LENGTH) - glPixelStorei(GL_UNPACK_ROW_LENGTH, convert->pitch/convert->format->BytesPerPixel); + glPixelStorei(GL_UNPACK_ROW_LENGTH, convert->pitch/format->bytes_per_pixel); #else /* OpenGL ES doesn't support UNPACK_ROW_LENGTH, let's hope SDL didn't add * padding bytes, otherwise we need some extra code here... */ - assert(convert->pitch == static_cast(m_texture_width * convert->format->BytesPerPixel)); + assert(convert->pitch == static_cast(m_texture_width * format->bytes_per_pixel)); #endif if (SDL_MUSTLOCK(convert)) { diff --git a/src/video/gl/gl_video_system.cpp b/src/video/gl/gl_video_system.cpp index 2d2370ba83c..b0d8c17bb25 100644 --- a/src/video/gl/gl_video_system.cpp +++ b/src/video/gl/gl_video_system.cpp @@ -106,7 +106,7 @@ GLVideoSystem::GLVideoSystem(bool use_opengl33core, bool auto_opengl_version) : GLVideoSystem::~GLVideoSystem() { - SDL_GL_DeleteContext(m_glcontext); + SDL_GL_DestroyContext(m_glcontext); } std::string @@ -264,7 +264,7 @@ GLVideoSystem::apply_config() m_viewport = Viewport::from_size(target_size, m_desktop_size); #ifdef __ANDROID__ - // SDL2 on Android reports display resolution size including the camera cutout, + // SDL3 on Android reports display resolution size including the camera cutout, // however it will not draw inside the cutout, so we must use the window size here // instead of the display resolution, or the video will be rendered partly outside of the screen. m_viewport = Viewport::from_size(g_config->window_size, g_config->window_size); @@ -311,14 +311,14 @@ GLVideoSystem::flip() void GLVideoSystem::set_vsync(int mode) { - if (SDL_GL_SetSwapInterval(mode) < 0) + if (SDL_GL_SetSwapInterval(mode) == false) { log_warning << "Setting vsync mode to " << mode << " failed: " << SDL_GetError() << std::endl; if(mode != 1) { mode = 1; log_warning << "Trying to set vsync mode to 1" << std::endl; - if (SDL_GL_SetSwapInterval(1) < 0) + if (SDL_GL_SetSwapInterval(1) == false) { log_warning << "Setting vsync mode failed: " << SDL_GetError() << ". Trying to set vsync mode to 0" << std::endl; if(mode != 0) @@ -340,7 +340,9 @@ GLVideoSystem::set_vsync(int mode) int GLVideoSystem::get_vsync() const { - return SDL_GL_GetSwapInterval(); + int interval; + SDL_GL_GetSwapInterval(&interval); + return interval; } SDLSurfacePtr diff --git a/src/video/gl/gl_video_system.hpp b/src/video/gl/gl_video_system.hpp index 575a0c45aad..716650c118c 100644 --- a/src/video/gl/gl_video_system.hpp +++ b/src/video/gl/gl_video_system.hpp @@ -17,7 +17,8 @@ #pragma once #include -#include +#include +#include #include "math/size.hpp" #include "video/sdlbase_video_system.hpp" diff --git a/src/video/sdl/sdl_painter.cpp b/src/video/sdl/sdl_painter.cpp index 32fee985ba6..fd737fb68fe 100644 --- a/src/video/sdl/sdl_painter.cpp +++ b/src/video/sdl/sdl_painter.cpp @@ -16,7 +16,7 @@ #include "video/sdl/sdl_painter.hpp" -#include +#include #include #include #include @@ -119,9 +119,12 @@ void render_texture(SDL_Renderer* renderer, if (imgrect.overlaps(srcrect)) { - SDL_Rect sdl_srcrect = srcrect.to_sdl(); + SDL_FRect sdl_srcrect = SDL_FRect{static_cast(srcrect.get_left()), + static_cast(srcrect.get_top()), + static_cast(srcrect.get_width()), + static_cast(srcrect.get_height())}; SDL_FRect sdl_dstrect = dstrect.to_sdl(); - SDL_RenderCopyF(renderer, texture, &sdl_srcrect, &sdl_dstrect); + SDL_RenderTexture(renderer, texture, &sdl_srcrect, &sdl_dstrect); } else { @@ -150,13 +153,16 @@ void RenderCopyEx(SDL_Renderer* renderer, const SDL_FRect* sdl_dstrect, const double angle, const SDL_Point* center, - const SDL_RendererFlip flip, + const SDL_FlipMode flip, const Sampler& sampler) { Vector animate = sampler.get_animate(); + SDL_FRect sdl_srcrectf; + SDL_RectToFRect(sdl_srcrect, &sdl_srcrectf); + if (animate.x == 0.0f && animate.y == 0.0f) { - SDL_RenderCopyExF(renderer, texture, sdl_srcrect, sdl_dstrect, angle, nullptr, flip); + SDL_RenderTextureRotated(renderer, texture, &sdl_srcrectf, sdl_dstrect, angle, nullptr, flip); } else { @@ -172,10 +178,10 @@ void RenderCopyEx(SDL_Renderer* renderer, // // FIXME: Neither flipping nor wrap modes are supported at the // moment. wrap is treated as if it was set to 'repeat'. - int width; - int height; + float width; + float height; - SDL_QueryTexture(texture, nullptr, nullptr, &width, &height); + SDL_GetTextureSize(texture, &width, &height); animate *= g_game_time; @@ -186,14 +192,14 @@ void RenderCopyEx(SDL_Renderer* renderer, flip || angle != 0.0) { - SDL_RenderCopyExF(renderer, texture, sdl_srcrect, sdl_dstrect, angle, nullptr, flip); + SDL_RenderTextureRotated(renderer, texture, &sdl_srcrectf, sdl_dstrect, angle, nullptr, flip); } else { Rectf imgrect(Vector(), Sizef(static_cast(width), static_cast(height))); - Rect srcrect(math::positive_mod(sdl_srcrect->x + tex_off_x, width), - math::positive_mod(sdl_srcrect->y + tex_off_y, height), - Size(sdl_srcrect->w, sdl_srcrect->h)); + Rect srcrect(math::positive_mod(sdl_srcrectf.x + tex_off_x, width), + math::positive_mod(sdl_srcrectf.y + tex_off_y, height), + Size(sdl_srcrectf.w, sdl_srcrectf.h)); render_texture(renderer, texture, imgrect, srcrect, Rectf(*sdl_dstrect)); } @@ -227,19 +233,20 @@ SDLPainter::draw_texture(const TextureRequest& request) Uint8 b = static_cast(request.color.blue * 255); Uint8 a = static_cast(request.color.alpha * request.alpha * 255); + SDL_SetTextureScaleMode(texture.get_texture(), SDL_SCALEMODE_LINEAR); SDL_SetTextureColorMod(texture.get_texture(), r, g, b); SDL_SetTextureAlphaMod(texture.get_texture(), a); SDL_SetTextureBlendMode(texture.get_texture(), blend2sdl(request.blend)); - SDL_RendererFlip flip = SDL_FLIP_NONE; + SDL_FlipMode flip = SDL_FLIP_NONE; if ((request.flip & HORIZONTAL_FLIP) != 0) { - flip = static_cast(flip | SDL_FLIP_HORIZONTAL); + flip = static_cast(flip | SDL_FLIP_HORIZONTAL); } if ((request.flip & VERTICAL_FLIP) != 0) { - flip = static_cast(flip | SDL_FLIP_VERTICAL); + flip = static_cast(flip | SDL_FLIP_VERTICAL); } RenderCopyEx(m_sdl_renderer, texture.get_texture(), @@ -297,6 +304,9 @@ SDLPainter::draw_gradient(const GradientRequest& request) next_step += rect.w; } + SDL_FRect rectf; + SDL_RectToFRect(&rect, &rectf); + float p = static_cast(i) / static_cast(n == 1 ? n : n - 1); Uint8 r, g, b, a; @@ -345,7 +355,7 @@ SDLPainter::draw_gradient(const GradientRequest& request) SDL_SetRenderDrawBlendMode(m_sdl_renderer, blend2sdl(request.blend)); SDL_SetRenderDrawColor(m_sdl_renderer, r, g, b, a); - SDL_RenderFillRect(m_sdl_renderer, &rect); + SDL_RenderFillRect(m_sdl_renderer, &rectf); } } @@ -405,7 +415,7 @@ SDLPainter::draw_filled_rect(const FillRectRequest& request) SDL_SetRenderDrawBlendMode(m_sdl_renderer, SDL_BLENDMODE_BLEND); SDL_SetRenderDrawColor(m_sdl_renderer, r, g, b, a); - SDL_RenderFillRectsF(m_sdl_renderer, &*rects.begin(), static_cast(rects.size())); + SDL_RenderFillRects(m_sdl_renderer, &*rects.begin(), static_cast(rects.size())); } else { @@ -413,7 +423,7 @@ SDLPainter::draw_filled_rect(const FillRectRequest& request) { SDL_SetRenderDrawBlendMode(m_sdl_renderer, SDL_BLENDMODE_BLEND); SDL_SetRenderDrawColor(m_sdl_renderer, r, g, b, a); - SDL_RenderFillRectF(m_sdl_renderer, &rect); + SDL_RenderFillRect(m_sdl_renderer, &rect); } } } @@ -471,7 +481,7 @@ SDLPainter::draw_inverse_ellipse(const InverseEllipseRequest& request) SDL_SetRenderDrawBlendMode(m_sdl_renderer, SDL_BLENDMODE_BLEND); SDL_SetRenderDrawColor(m_sdl_renderer, r, g, b, a); - SDL_RenderFillRectsF(m_sdl_renderer, rects, 2*slices+2); + SDL_RenderFillRects(m_sdl_renderer, rects, 2*slices+2); } void @@ -484,8 +494,8 @@ SDLPainter::draw_line(const LineRequest& request) SDL_SetRenderDrawBlendMode(m_sdl_renderer, SDL_BLENDMODE_BLEND); SDL_SetRenderDrawColor(m_sdl_renderer, r, g, b, a); - SDL_RenderDrawLineF(m_sdl_renderer, request.pos.x, request.pos.y, - request.dest_pos.x, request.dest_pos.y); + SDL_RenderLine(m_sdl_renderer, request.pos.x, request.pos.y, + request.dest_pos.x, request.dest_pos.y); } namespace { @@ -525,9 +535,9 @@ draw_span_between_edges(SDL_Renderer* renderer, const Edge& e1, const Edge& e2) for (float y = e2.first.y; y < e2.second.y; y += 1.f) { - SDL_RenderDrawLineF(renderer, - e1.first.x + e1xdiff * factor1, y, - e2.first.x + e2xdiff * factor2, y); + SDL_RenderLine(renderer, + e1.first.x + e1xdiff * factor1, y, + e2.first.x + e2xdiff * factor2, y); factor1 += factorStep1; factor2 += factorStep2; } @@ -579,8 +589,11 @@ SDLPainter::clear(const Color& color) if (m_cliprect) { + SDL_FRect cliprectf; + SDL_RectToFRect(&*m_cliprect, &cliprectf); + SDL_SetRenderDrawBlendMode(m_sdl_renderer, SDL_BLENDMODE_NONE); - SDL_RenderFillRect(m_sdl_renderer, &*m_cliprect); + SDL_RenderFillRect(m_sdl_renderer, &cliprectf); } else { @@ -594,7 +607,7 @@ SDLPainter::set_clip_rect(const Rect& rect) { m_cliprect = rect.to_sdl(); - int ret = SDL_RenderSetClipRect(m_sdl_renderer, &*m_cliprect); + int ret = SDL_SetRenderClipRect(m_sdl_renderer, &*m_cliprect); if (ret < 0) { log_warning << "SDLPainter::set_clip_rect(): SDL_RenderSetClipRect() failed: " << SDL_GetError() << std::endl; @@ -606,10 +619,10 @@ SDLPainter::clear_clip_rect() { m_cliprect.reset(); - int ret = SDL_RenderSetClipRect(m_sdl_renderer, nullptr); + int ret = SDL_SetRenderClipRect(m_sdl_renderer, nullptr); if (ret < 0) { - log_warning << "SDLPainter::clear_clip_rect(): SDL_RenderSetClipRect() failed: " << SDL_GetError() << std::endl; + log_warning << "SDLPainter::clear_clip_rect(): SDL_SetRenderClipRect() failed: " << SDL_GetError() << std::endl; } } @@ -625,15 +638,15 @@ SDLPainter::get_pixel(const GetPixelRequest& request) const srcrect.w = 1; srcrect.h = 1; - Uint8 pixel[4]; - int ret = SDL_RenderReadPixels(m_sdl_renderer, &srcrect, - SDL_PIXELFORMAT_RGB888, - pixel, - 1); - if (ret != 0) + auto surface = SDL_RenderReadPixels(m_sdl_renderer, &srcrect); + auto error = SDL_GetError(); + if (error != nullptr) { - log_warning << "failed to read pixels: " << SDL_GetError() << std::endl; + log_warning << "failed to read pixels: " << error << std::endl; } + auto pixel = static_cast(surface->pixels); *(request.color_ptr) = Color::from_rgb888(pixel[2], pixel[1], pixel[0]); + + SDL_DestroySurface(surface); } diff --git a/src/video/sdl/sdl_screen_renderer.cpp b/src/video/sdl/sdl_screen_renderer.cpp index dae1de91671..dd34d3e7f5b 100644 --- a/src/video/sdl/sdl_screen_renderer.cpp +++ b/src/video/sdl/sdl_screen_renderer.cpp @@ -1,6 +1,6 @@ // SuperTux // Copyright (C) 2006 Matthias Braun -// Updated by GiBy 2013 for SDL2 +// Updated by GiBy 2013 for SDL3 // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -17,6 +17,8 @@ #include "video/sdl/sdl_screen_renderer.hpp" +#include + #include "math/rect.hpp" #include "supertux/gameconfig.hpp" #include "supertux/globals.hpp" @@ -29,26 +31,29 @@ SDLScreenRenderer::SDLScreenRenderer(SDLVideoSystem& video_system, SDL_Renderer* m_renderer(renderer), m_painter(m_video_system, *this, m_renderer) { - SDL_RendererInfo info; - if (SDL_GetRendererInfo(m_renderer, &info) != 0) + auto renderer_name = SDL_GetRendererName(m_renderer); + if (renderer_name == nullptr) { log_warning << "Couldn't get RendererInfo: " << SDL_GetError() << std::endl; } else { - log_info << "SDL_Renderer: " << info.name << std::endl; + log_info << "SDL_Renderer: " << renderer_name << std::endl; log_info << "SDL_RendererFlags: " << std::endl; - if (info.flags & SDL_RENDERER_SOFTWARE) { log_info << " SDL_RENDERER_SOFTWARE" << std::endl; } - if (info.flags & SDL_RENDERER_ACCELERATED) { log_info << " SDL_RENDERER_ACCELERATED" << std::endl; } - if (info.flags & SDL_RENDERER_PRESENTVSYNC) { log_info << " SDL_RENDERER_PRESENTVSYNC" << std::endl; } - if (info.flags & SDL_RENDERER_TARGETTEXTURE) { log_info << " SDL_RENDERER_TARGETTEXTURE" << std::endl; } - log_info << "Texture Formats: " << std::endl; - for (size_t i = 0; i < info.num_texture_formats; ++i) - { - log_info << " " << SDL_GetPixelFormatName(info.texture_formats[i]) << std::endl; - } - log_info << "Max Texture Width: " << info.max_texture_width << std::endl; - log_info << "Max Texture Height: " << info.max_texture_height << std::endl; + + // TODO: Query information !!! + + // if (info.flags & SDL_RENDERER_SOFTWARE) { log_info << " SDL_RENDERER_SOFTWARE" << std::endl; } + // if (info.flags & SDL_RENDERER_ACCELERATED) { log_info << " SDL_RENDERER_ACCELERATED" << std::endl; } + // if (info.flags & SDL_RENDERER_PRESENTVSYNC) { log_info << " SDL_RENDERER_PRESENTVSYNC" << std::endl; } + // if (info.flags & SDL_RENDERER_TARGETTEXTURE) { log_info << " SDL_RENDERER_TARGETTEXTURE" << std::endl; } + // log_info << "Texture Formats: " << std::endl; + // for (size_t i = 0; i < info.num_texture_formats; ++i) + // { + // log_info << " " << SDL_GetPixelFormatName(info.texture_formats[i]) << std::endl; + // } + // log_info << "Max Texture Width: " << info.max_texture_width << std::endl; + // log_info << "Max Texture Height: " << info.max_texture_height << std::endl; } } @@ -66,9 +71,9 @@ SDLScreenRenderer::start_draw() // SetViewport() works in scaled screen coordinates, so we have to // reset it to 1.0, 1.0 to get meaningful results - SDL_RenderSetScale(m_renderer, 1.0f, 1.0f); - SDL_RenderSetViewport(m_renderer, &sdl_viewport); - SDL_RenderSetScale(m_renderer, scale.x, scale.y); + SDL_SetRenderScale(m_renderer, 1.0f, 1.0f); + SDL_SetRenderViewport(m_renderer, &sdl_viewport); + SDL_SetRenderScale(m_renderer, scale.x, scale.y); SDL_SetRenderDrawColor(m_renderer, 0, 0, 0, 255); SDL_RenderClear(m_renderer); diff --git a/src/video/sdl/sdl_screen_renderer.hpp b/src/video/sdl/sdl_screen_renderer.hpp index 368f8d251f6..9b71394827c 100644 --- a/src/video/sdl/sdl_screen_renderer.hpp +++ b/src/video/sdl/sdl_screen_renderer.hpp @@ -16,7 +16,7 @@ #pragma once -#include +#include #include #include "math/size.hpp" diff --git a/src/video/sdl/sdl_texture.cpp b/src/video/sdl/sdl_texture.cpp index d81143368a7..e7c805ddca9 100644 --- a/src/video/sdl/sdl_texture.cpp +++ b/src/video/sdl/sdl_texture.cpp @@ -16,7 +16,7 @@ #include "video/sdl/sdl_texture.hpp" -#include +#include #include #include "video/sdl/sdl_screen_renderer.hpp" diff --git a/src/video/sdl/sdl_texture.hpp b/src/video/sdl/sdl_texture.hpp index 41f4fa1e7c0..902b99372d6 100644 --- a/src/video/sdl/sdl_texture.hpp +++ b/src/video/sdl/sdl_texture.hpp @@ -18,7 +18,7 @@ #include "video/texture.hpp" -#include +#include #include "video/sampler.hpp" diff --git a/src/video/sdl/sdl_texture_renderer.cpp b/src/video/sdl/sdl_texture_renderer.cpp index 687869a4e7a..0be0c6eb2ae 100644 --- a/src/video/sdl/sdl_texture_renderer.cpp +++ b/src/video/sdl/sdl_texture_renderer.cpp @@ -55,7 +55,7 @@ SDLTextureRenderer::start_draw() const int w = m_size.width / m_downscale; const int h = m_size.height / m_downscale; SDL_Texture* sdl_texture = SDL_CreateTexture(m_renderer, - SDL_PIXELFORMAT_RGB888, + SDL_PIXELFORMAT_XRGB8888, SDL_TEXTUREACCESS_TARGET, w, h); if (!sdl_texture) @@ -69,7 +69,7 @@ SDLTextureRenderer::start_draw() } SDL_SetRenderTarget(m_renderer, get_sdl_texture()); - SDL_RenderSetScale(m_renderer, + SDL_SetRenderScale(m_renderer, 1.0f / static_cast(m_downscale), 1.0f / static_cast(m_downscale)); } @@ -77,7 +77,7 @@ SDLTextureRenderer::start_draw() void SDLTextureRenderer::end_draw() { - SDL_RenderSetScale(m_renderer, 1.0f, 1.0f); + SDL_SetRenderScale(m_renderer, 1.0f, 1.0f); SDL_SetRenderTarget(m_renderer, nullptr); } diff --git a/src/video/sdl/sdl_texture_renderer.hpp b/src/video/sdl/sdl_texture_renderer.hpp index c50a9c75e7e..0ee1911b4ee 100644 --- a/src/video/sdl/sdl_texture_renderer.hpp +++ b/src/video/sdl/sdl_texture_renderer.hpp @@ -16,7 +16,7 @@ #pragma once -#include +#include #include #include "video/texture_ptr.hpp" diff --git a/src/video/sdl/sdl_video_system.cpp b/src/video/sdl/sdl_video_system.cpp index aec73c27faf..cec5831495c 100644 --- a/src/video/sdl/sdl_video_system.cpp +++ b/src/video/sdl/sdl_video_system.cpp @@ -18,6 +18,8 @@ #include +#include + #include "math/rect.hpp" #include "supertux/gameconfig.hpp" #include "supertux/globals.hpp" @@ -51,13 +53,12 @@ SDLVideoSystem::~SDLVideoSystem() std::string SDLVideoSystem::get_name() const { - SDL_version version; - SDL_GetVersion(&version); + auto version = SDL_GetVersion(); std::ostringstream out; out << "SDL " - << static_cast(version.major) - << "." << static_cast(version.minor) - << "." << static_cast(version.patch); + << SDL_VERSIONNUM_MAJOR(version) + << "." << SDL_VERSIONNUM_MINOR(version) + << "." << SDL_VERSIONNUM_MICRO(version); return out.str(); } @@ -66,12 +67,9 @@ SDLVideoSystem::create_window() { log_info << "Creating SDLVideoSystem" << std::endl; - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2"); - SDL_SetHint(SDL_HINT_RENDER_BATCHING, "1"); - create_sdl_window(0); - m_sdl_renderer.reset(SDL_CreateRenderer(m_sdl_window.get(), -1, 0)); + m_sdl_renderer.reset(SDL_CreateRenderer(m_sdl_window.get(), nullptr)); if (!m_sdl_renderer) { std::stringstream msg; @@ -137,30 +135,23 @@ SDLVideoSystem::make_screenshot() { int width; int height; - if (SDL_GetRendererOutputSize(m_renderer->get_sdl_renderer(), &width, &height) != 0) + if (SDL_GetCurrentRenderOutputSize(m_renderer->get_sdl_renderer(), &width, &height) != 0) { log_warning << "SDL_GetRenderOutputSize failed: " << SDL_GetError() << std::endl; return {}; } else { - SDLSurfacePtr surface = SDLSurface::create_rgba(width, height); - - SDL_LockSurface(surface.get()); - int ret = SDL_RenderReadPixels(m_renderer->get_sdl_renderer(), nullptr, - SDL_PIXELFORMAT_ABGR8888, - surface->pixels, - surface->pitch); - SDL_UnlockSurface(surface.get()); + auto surface = SDL_RenderReadPixels(m_renderer->get_sdl_renderer(), nullptr); - if (ret != 0) + if (SDL_GetError() != 0) { log_warning << "SDL_RenderReadPixels failed: " << SDL_GetError() << std::endl; return {}; } else { - return surface; + return SDLSurfacePtr(surface); } } } diff --git a/src/video/sdl/sdl_video_system.hpp b/src/video/sdl/sdl_video_system.hpp index c6265a70a0f..f42774ceffd 100644 --- a/src/video/sdl/sdl_video_system.hpp +++ b/src/video/sdl/sdl_video_system.hpp @@ -17,7 +17,7 @@ #pragma once #include -#include +#include #include "math/size.hpp" #include "video/sdlbase_video_system.hpp" diff --git a/src/video/sdl_surface.cpp b/src/video/sdl_surface.cpp index d5103ed9f1b..b7fc476d5f0 100644 --- a/src/video/sdl_surface.cpp +++ b/src/video/sdl_surface.cpp @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include "physfs/physfs_sdl.hpp" @@ -39,7 +39,8 @@ SDLSurface::create_rgba(int width, int height) Uint32 bmask = 0x00ff0000; Uint32 amask = 0xff000000; #endif - SDLSurfacePtr surface(SDL_CreateRGBSurface(0, width, height, 32, rmask, gmask, bmask, amask)); + SDLSurfacePtr surface(SDL_CreateSurface(width, height, + SDL_GetPixelFormatForMasks(32, rmask, gmask, bmask, amask))); if (!surface) { std::ostringstream out; out << "failed to create SDL_Surface: " << SDL_GetError(); @@ -63,7 +64,8 @@ SDLSurface::create_rgb(int width, int height) Uint32 bmask = 0x00ff0000; Uint32 amask = 0x00000000; #endif - SDLSurfacePtr surface(SDL_CreateRGBSurface(0, width, height, 24, rmask, gmask, bmask, amask)); + SDLSurfacePtr surface(SDL_CreateSurface(width, height, + SDL_GetPixelFormatForMasks(24, rmask, gmask, bmask, amask))); if (!surface) { std::ostringstream out; out << "failed to create SDL_Surface: " << SDL_GetError(); @@ -77,7 +79,14 @@ SDLSurfacePtr SDLSurface::from_file(const std::string& filename) { log_debug << "loading image: " << filename << std::endl; - SDLSurfacePtr surface(IMG_Load_RW(get_physfs_SDLRWops(filename), 1)); + auto stream = get_physfs_SDLRWops(filename); + if (!stream) + { + std::ostringstream msg; + msg << "Couldn't open file: " << filename; + throw std::runtime_error(msg.str()); + } + SDLSurfacePtr surface(IMG_Load_IO(stream, true)); if (!surface) { std::ostringstream msg; @@ -96,7 +105,7 @@ SDLSurface::save_png(const SDL_Surface& surface, const std::string& filename) // This does not lead to a double free when 'tmp == screen', as // SDL_PNGFormatAlpha() will increase the refcount of surface. SDLSurfacePtr tmp(SDL_PNGFormatAlpha(const_cast(&surface))); - SDL_RWops* ops; + SDL_IOStream* ops; try { ops = get_writable_physfs_SDLRWops(filename); } catch (std::exception& e) { diff --git a/src/video/sdl_surface.hpp b/src/video/sdl_surface.hpp index 9056d4a7b31..4493b687a77 100644 --- a/src/video/sdl_surface.hpp +++ b/src/video/sdl_surface.hpp @@ -17,7 +17,7 @@ #pragma once #include -#include +#include #include "video/sdl_surface_ptr.hpp" diff --git a/src/video/sdl_surface_ptr.hpp b/src/video/sdl_surface_ptr.hpp index c86f4ae3b8d..e150ee0f05f 100644 --- a/src/video/sdl_surface_ptr.hpp +++ b/src/video/sdl_surface_ptr.hpp @@ -16,7 +16,7 @@ #pragma once -#include +#include /** Simple Wrapper class around SDL_Surface that provides exception safety */ @@ -52,7 +52,7 @@ class SDLSurfacePtr final ~SDLSurfacePtr() { - SDL_FreeSurface(m_surface); + SDL_DestroySurface(m_surface); } SDL_Surface& operator*() @@ -77,13 +77,13 @@ class SDLSurfacePtr final void reset(SDL_Surface* surface) { - SDL_FreeSurface(m_surface); + SDL_DestroySurface(m_surface); m_surface = surface; } void reset(SDLSurfacePtr& other) { - SDL_FreeSurface(m_surface); + SDL_DestroySurface(m_surface); m_surface = other.m_surface; other.m_surface = nullptr; } diff --git a/src/video/sdlbase_video_system.cpp b/src/video/sdlbase_video_system.cpp index b17aacaa655..9390a274411 100644 --- a/src/video/sdlbase_video_system.cpp +++ b/src/video/sdlbase_video_system.cpp @@ -30,14 +30,14 @@ SDLBaseVideoSystem::SDLBaseVideoSystem() : m_sdl_window(nullptr, &SDL_DestroyWindow), m_desktop_size() { - SDL_DisplayMode mode; - if (SDL_GetDesktopDisplayMode(0, &mode) != 0) + auto mode = SDL_GetDesktopDisplayMode(0); + if (mode == nullptr) { log_warning << "Couldn't get desktop display mode: " << SDL_GetError() << std::endl; } else { - m_desktop_size = Size(mode.w, mode.h); + m_desktop_size = Size(mode->w, mode->h); } } @@ -80,14 +80,14 @@ SDLBaseVideoSystem::create_sdl_window(Uint32 flags) Size size; if (g_config->use_fullscreen) { + flags |= SDL_WINDOW_FULLSCREEN; + if (g_config->fullscreen_size == Size(0, 0)) { - flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; size = m_desktop_size; } else { - flags |= SDL_WINDOW_FULLSCREEN; size = g_config->fullscreen_size; } } @@ -106,10 +106,7 @@ SDLBaseVideoSystem::create_sdl_window(Uint32 flags) Android. #endif - m_sdl_window.reset(SDL_CreateWindow("SuperTux", - SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, - size.width, size.height, - flags)); + m_sdl_window.reset(SDL_CreateWindow("SuperTux", size.width, size.height, flags)); if (!m_sdl_window) { std::ostringstream msg; @@ -135,7 +132,7 @@ SDLBaseVideoSystem::create_sdl_window(Uint32 flags) void SDLBaseVideoSystem::apply_video_mode() { - const int displayidx = SDL_GetWindowDisplayIndex(m_sdl_window.get()); + const int displayidx = SDL_GetDisplayForWindow(m_sdl_window.get()); if (displayidx < 0) { log_warning << "Unable to get display index of window: " @@ -143,8 +140,8 @@ SDLBaseVideoSystem::apply_video_mode() return; } - SDL_DisplayMode display; - if (SDL_GetDesktopDisplayMode(displayidx, &display) != 0) + const SDL_DisplayMode* display = SDL_GetDesktopDisplayMode(displayidx); + if (display == nullptr) { log_warning << "Unable to get information for display number " << displayidx << ": " @@ -152,8 +149,8 @@ SDLBaseVideoSystem::apply_video_mode() return; } - m_desktop_size.width = display.w; - m_desktop_size.height = display.h; + m_desktop_size.width = display->w; + m_desktop_size.height = display->h; if (!g_config->use_fullscreen) { @@ -168,14 +165,14 @@ SDLBaseVideoSystem::apply_video_mode() } #if SDL_VERSION_ATLEAST(2,0,5) - SDL_SetWindowResizable(m_sdl_window.get(), static_cast(g_config->window_resizable)); + SDL_SetWindowResizable(m_sdl_window.get(), g_config->window_resizable); #endif } else { if (g_config->fullscreen_size == Size(0, 0)) { - if (SDL_SetWindowFullscreen(m_sdl_window.get(), SDL_WINDOW_FULLSCREEN_DESKTOP) != 0) + if (SDL_SetWindowFullscreen(m_sdl_window.get(), SDL_WINDOW_FULLSCREEN) != 0) { log_warning << "failed to switch to desktop fullscreen mode: " << SDL_GetError() << std::endl; @@ -188,15 +185,14 @@ SDLBaseVideoSystem::apply_video_mode() else { SDL_DisplayMode mode; - mode.format = SDL_PIXELFORMAT_RGB888; + mode.format = SDL_PIXELFORMAT_XRGB8888; mode.w = g_config->fullscreen_size.width; mode.h = g_config->fullscreen_size.height; mode.refresh_rate = g_config->fullscreen_refresh_rate; - mode.driverdata = nullptr; - if (SDL_SetWindowDisplayMode(m_sdl_window.get(), &mode) != 0) + if (SDL_SetWindowFullscreenMode(m_sdl_window.get(), &mode) != 0) { - log_warning << "failed to set display mode: " + log_warning << "failed to set fullscreen mode: " << mode.w << "x" << mode.h << "@" << mode.refresh_rate << ": " << SDL_GetError() << std::endl; } diff --git a/src/video/sdlbase_video_system.hpp b/src/video/sdlbase_video_system.hpp index eef9bf473e3..0d829a7328d 100644 --- a/src/video/sdlbase_video_system.hpp +++ b/src/video/sdlbase_video_system.hpp @@ -16,7 +16,7 @@ #pragma once -#include +#include #include "video/video_system.hpp" diff --git a/src/video/texture_manager.cpp b/src/video/texture_manager.cpp index 29e51c99be4..f2f5d69bba2 100644 --- a/src/video/texture_manager.cpp +++ b/src/video/texture_manager.cpp @@ -16,7 +16,7 @@ #include "video/texture_manager.hpp" -#include +#include #include #include @@ -298,15 +298,16 @@ TextureManager::create_image_surface_raw(const std::string& filename, const Rect assert(rect.valid()); const SDL_Surface& src_surface = get_surface(filename); + const SDL_PixelFormatDetails* format = SDL_GetPixelFormatDetails(src_surface.format); SDLSurfacePtr convert; - if (src_surface.format->Rmask == 0 && - src_surface.format->Gmask == 0 && - src_surface.format->Bmask == 0 && - src_surface.format->Amask == 0) + if (format->Rmask == 0 && + format->Gmask == 0 && + format->Bmask == 0 && + format->Amask == 0) { log_debug << "Wrong surface format for image " << filename << ". Compensating." << std::endl; - convert.reset(SDL_ConvertSurfaceFormat(const_cast(&src_surface), SDL_PIXELFORMAT_RGBA8888, 0)); + convert.reset(SDL_ConvertSurface(const_cast(&src_surface), SDL_PIXELFORMAT_RGBA8888)); } const SDL_Surface& surface = convert ? *convert : src_surface; @@ -317,14 +318,10 @@ TextureManager::create_image_surface_raw(const std::string& filename, const Rect log_warning << filename << ": invalid subregion requested: image=" << surface.w << "x" << surface.h << ", rect=" << rect << std::endl; - subimage = SDLSurfacePtr(SDL_CreateRGBSurface(0, - rect.get_width(), - rect.get_height(), - surface.format->BitsPerPixel, - surface.format->Rmask, - surface.format->Gmask, - surface.format->Bmask, - surface.format->Amask)); + subimage = SDLSurfacePtr( + SDL_CreateSurface(rect.get_width(), rect.get_height(), + SDL_GetPixelFormatForMasks(format->bits_per_pixel, format->Rmask, format->Gmask, format->Bmask, format->Amask)) + ); Rect clipped_rect(std::max(0, rect.left), std::max(0, rect.top), @@ -336,19 +333,21 @@ TextureManager::create_image_surface_raw(const std::string& filename, const Rect } else { - subimage = SDLSurfacePtr(SDL_CreateRGBSurfaceFrom(static_cast(surface.pixels) + - rect.top * surface.pitch + - rect.left * surface.format->BytesPerPixel, - rect.get_width(), rect.get_height(), - surface.format->BitsPerPixel, - surface.pitch, - surface.format->Rmask, - surface.format->Gmask, - surface.format->Bmask, - surface.format->Amask)); + subimage = SDLSurfacePtr(SDL_CreateSurfaceFrom( + rect.get_width(), rect.get_height(), + SDL_GetPixelFormatForMasks( + format->bits_per_pixel, + format->Rmask, + format->Gmask, + format->Bmask, + format->Amask), + static_cast(surface.pixels) + + rect.top * surface.pitch + + rect.left * format->bytes_per_pixel, surface.pitch)); + if (!subimage) { - throw std::runtime_error("SDL_CreateRGBSurfaceFrom() call failed"); + throw std::runtime_error("SDL_CreateSurfaceFrom() call failed"); } } @@ -385,7 +384,7 @@ TextureManager::create_dummy_surface() { // on error (when loading placeholder), try using empty surface, // when that fails to, just give up - SDLSurfacePtr surface(SDL_CreateRGBSurface(0, 128, 128, 8, 0, 0, 0, 0)); + SDLSurfacePtr surface(SDL_CreateSurface(128, 128, SDL_GetPixelFormatForMasks(8, 0, 0, 0, 0))); if (!surface) { throw; diff --git a/src/video/ttf_font.cpp b/src/video/ttf_font.cpp index 491d70c7691..25396fe2d48 100644 --- a/src/video/ttf_font.cpp +++ b/src/video/ttf_font.cpp @@ -36,7 +36,7 @@ TTFFont::TTFFont(const std::string& filename, int font_size, float line_spacing, m_shadow_size(shadow_size), m_border(border) { - m_font = TTF_OpenFontRW(get_physfs_SDLRWops(m_filename), 1, font_size); + m_font = TTF_OpenFontIO(get_physfs_SDLRWops(m_filename), 1, font_size); if (!m_font) { std::ostringstream msg; @@ -71,9 +71,9 @@ TTFFont::get_text_width(const std::string& text) const // Not in cache int w = 0; int h = 0; - int ret = TTF_SizeUTF8(m_font, line.c_str(), &w, &h); + int ret = TTF_GetStringSize(m_font, line.c_str(), line.length(), &w, &h); if (ret < 0) { - get_logging_instance(false) << "TTFFont::get_text_width(): " << TTF_GetError() << std::endl; + get_logging_instance(false) << "TTFFont::get_text_width(): " << SDL_GetError() << std::endl; } int const grow = std::max(get_border() * 2, get_shadow_size() * 2); line_width = w + grow; @@ -103,7 +103,7 @@ TTFFont::draw_text(Canvas& canvas, const std::string& text, const Vector& pos, FontAlignment alignment, int layer, const Color& color) { - const float init_y = pos.y - (static_cast(TTF_FontHeight(m_font)) - get_height()) / 2.0f; + const float init_y = pos.y - (static_cast(TTF_GetFontHeight(m_font)) - get_height()) / 2.0f; float min_x = pos.x; float last_y = init_y; diff --git a/src/video/ttf_font.hpp b/src/video/ttf_font.hpp index 83e0630aa43..b4b61d35cfe 100644 --- a/src/video/ttf_font.hpp +++ b/src/video/ttf_font.hpp @@ -17,7 +17,7 @@ #pragma once -#include +#include #include "math/fwd.hpp" #include "video/color.hpp" diff --git a/src/video/ttf_surface.cpp b/src/video/ttf_surface.cpp index 40d13559a90..48527fd65db 100644 --- a/src/video/ttf_surface.cpp +++ b/src/video/ttf_surface.cpp @@ -16,7 +16,7 @@ #include "video/ttf_surface.hpp" -#include +#include #include @@ -30,8 +30,8 @@ TTFSurfacePtr TTFSurface::create(const TTFFont& font, const std::string& text) { - SDLSurfacePtr text_surface(TTF_RenderUTF8_Blended(font.get_ttf_font(), - text.c_str(), + SDLSurfacePtr text_surface(TTF_RenderText_Blended(font.get_ttf_font(), + text.c_str(), text.length(), SDL_Color{255, 255, 255, 255})); if (!text_surface) { @@ -45,7 +45,7 @@ TTFSurface::create(const TTFFont& font, const std::string& text) SDLSurfacePtr target = SDLSurface::create_rgba(text_surface->w + grow, text_surface->h + grow); #if !SDL_VERSION_ATLEAST(2,0,5) - // Perform blitting in ARGB8888, instead of RGBA8888, to avoid bug in older SDL2. + // Perform blitting in ARGB8888, instead of RGBA8888, to avoid bug in older SDL3. // https://bugzilla.libsdl.org/show_bug.cgi?id=3159 target.reset(SDL_ConvertSurfaceFormat(target.get(), SDL_PIXELFORMAT_ARGB8888, 0)); #endif diff --git a/src/video/ttf_surface_manager.cpp b/src/video/ttf_surface_manager.cpp index 7e45f450510..00167738d48 100644 --- a/src/video/ttf_surface_manager.cpp +++ b/src/video/ttf_surface_manager.cpp @@ -16,7 +16,7 @@ #include "video/ttf_surface_manager.hpp" -#include +#include #include #include #include diff --git a/src/video/video_system.hpp b/src/video/video_system.hpp index 4c5b2db1fb7..df0b52bfe16 100644 --- a/src/video/video_system.hpp +++ b/src/video/video_system.hpp @@ -18,7 +18,7 @@ #include #include -#include +#include #include "math/size.hpp" #include "util/currenton.hpp" diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt index 48870ee0a32..70f459aff22 100644 --- a/tests/unit/CMakeLists.txt +++ b/tests/unit/CMakeLists.txt @@ -27,16 +27,16 @@ make_unit_test(MD5Test SOURCE md5_test.cpp make_unit_test(AATriangleTest SOURCE aatriangle_test.cpp EXTERNAL math/aatriangle.cpp - LIBRARIES SDL2 DEFINITIONS GLM_ENABLE_EXPERIMENTAL) + LIBRARIES SDL3 DEFINITIONS GLM_ENABLE_EXPERIMENTAL) make_unit_test(CollisionTest SOURCE collision_test.cpp EXTERNAL math/rectf.cpp - LIBRARIES SDL2 DEFINITIONS GLM_ENABLE_EXPERIMENTAL) + LIBRARIES SDL3 DEFINITIONS GLM_ENABLE_EXPERIMENTAL) #make_unit_test(DynamicScopedTest SOURCE dynamic_scoped_test.cpp -# LIBRARIES SDL2) +# LIBRARIES SDL3) #make_unit_test(FileSystemTest SOURCE file_system_test.cpp # EXTERNAL util/file_system.cpp util/log.cpp -# LIBRARIES SDL2 tinygettext CURL simplesquirrel LibOpenGL obstack GLEW::GLEW DEFINITIONS GLM_ENABLE_EXPERIMENTAL) +# LIBRARIES SDL3 tinygettext CURL simplesquirrel LibOpenGL obstack GLEW::GLEW DEFINITIONS GLM_ENABLE_EXPERIMENTAL) message("ALL TESTS: ${all_test_targets}") diff --git a/vcpkg.json b/vcpkg.json index c2a3260dd26..b5f615f5866 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -7,6 +7,9 @@ "libraqm", "freetype", "physfs", + "sdl3", + "sdl3-image", + "sdl3-ttf", "glm", "libpng", "zlib" @@ -15,8 +18,6 @@ "nonwasm": { "description": "Add dependencies that aren't needed for WebAssembly", "dependencies": [ - "sdl2", - "sdl2-image", "curl", "openal-soft", "libogg",