diff options
Diffstat (limited to 'src/contrib/SDL-3.2.20/docs')
43 files changed, 8207 insertions, 0 deletions
diff --git a/src/contrib/SDL-3.2.20/docs/INTRO-androidstudio.md b/src/contrib/SDL-3.2.20/docs/INTRO-androidstudio.md new file mode 100644 index 0000000..f4d8ecc --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/INTRO-androidstudio.md | |||
@@ -0,0 +1,17 @@ | |||
1 | |||
2 | # Introduction to SDL with Android Studio | ||
3 | |||
4 | We'll start by creating a simple project to build and run [hello.c](hello.c) | ||
5 | |||
6 | - Use our handy script to create a template project: | ||
7 | ```sh | ||
8 | ./build-scripts/create-android-project.py org.libsdl.hello docs/hello.c | ||
9 | ``` | ||
10 | - Run Android Studio and open the newly created build/org.libsdl.hello directory | ||
11 | - Build and run! | ||
12 | |||
13 | A more complete example is available at: | ||
14 | |||
15 | https://github.com/Ravbug/sdl3-sample | ||
16 | |||
17 | Additional information and troubleshooting is available in [README-android.md](README-android.md) | ||
diff --git a/src/contrib/SDL-3.2.20/docs/INTRO-cmake.md b/src/contrib/SDL-3.2.20/docs/INTRO-cmake.md new file mode 100644 index 0000000..05990e4 --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/INTRO-cmake.md | |||
@@ -0,0 +1,57 @@ | |||
1 | |||
2 | # Introduction to SDL with CMake | ||
3 | |||
4 | The easiest way to use SDL is to include it as a subproject in your project. | ||
5 | |||
6 | We'll start by creating a simple project to build and run [hello.c](hello.c) | ||
7 | |||
8 | # Get a copy of the SDL source: | ||
9 | ```sh | ||
10 | git clone https://github.com/libsdl-org/SDL.git vendored/SDL | ||
11 | ``` | ||
12 | |||
13 | # Create the file CMakeLists.txt | ||
14 | ```cmake | ||
15 | cmake_minimum_required(VERSION 3.16) | ||
16 | project(hello) | ||
17 | |||
18 | # set the output directory for built objects. | ||
19 | # This makes sure that the dynamic library goes into the build directory automatically. | ||
20 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/$<CONFIGURATION>") | ||
21 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/$<CONFIGURATION>") | ||
22 | |||
23 | # This assumes the SDL source is available in vendored/SDL | ||
24 | add_subdirectory(vendored/SDL EXCLUDE_FROM_ALL) | ||
25 | |||
26 | # Create your game executable target as usual | ||
27 | add_executable(hello WIN32 hello.c) | ||
28 | |||
29 | # Link to the actual SDL3 library. | ||
30 | target_link_libraries(hello PRIVATE SDL3::SDL3) | ||
31 | ``` | ||
32 | |||
33 | # Configure and Build: | ||
34 | ```sh | ||
35 | cmake -S . -B build | ||
36 | cmake --build build | ||
37 | ``` | ||
38 | |||
39 | # Run: | ||
40 | The executable should be in the `build` directory: | ||
41 | |||
42 | ```sh | ||
43 | cd build | ||
44 | ./hello | ||
45 | ``` | ||
46 | |||
47 | If there wasn't an executable there despite the above Build section running successfully, it's likely because you're following this guide using the Visual Studio toolchain, it should instead be in the `build/Debug` directory: | ||
48 | ```sh | ||
49 | cd build/Debug | ||
50 | ./hello | ||
51 | ``` | ||
52 | |||
53 | A more complete example is available at: | ||
54 | |||
55 | https://github.com/Ravbug/sdl3-sample | ||
56 | |||
57 | Additional information and troubleshooting is available in [README-cmake.md](README-cmake.md) | ||
diff --git a/src/contrib/SDL-3.2.20/docs/INTRO-emscripten.md b/src/contrib/SDL-3.2.20/docs/INTRO-emscripten.md new file mode 100644 index 0000000..a0541c8 --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/INTRO-emscripten.md | |||
@@ -0,0 +1,50 @@ | |||
1 | |||
2 | # Introduction to SDL with Emscripten | ||
3 | |||
4 | The easiest way to use SDL is to include it as a subproject in your project. | ||
5 | |||
6 | We'll start by creating a simple project to build and run [hello.c](hello.c) | ||
7 | |||
8 | First, you should have the Emscripten SDK installed from: | ||
9 | |||
10 | https://emscripten.org/docs/getting_started/downloads.html | ||
11 | |||
12 | Create the file CMakeLists.txt | ||
13 | ```cmake | ||
14 | cmake_minimum_required(VERSION 3.16) | ||
15 | project(hello) | ||
16 | |||
17 | # set the output directory for built objects. | ||
18 | # This makes sure that the dynamic library goes into the build directory automatically. | ||
19 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/$<CONFIGURATION>") | ||
20 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/$<CONFIGURATION>") | ||
21 | |||
22 | # This assumes the SDL source is available in vendored/SDL | ||
23 | add_subdirectory(vendored/SDL EXCLUDE_FROM_ALL) | ||
24 | |||
25 | # on Web targets, we need CMake to generate a HTML webpage. | ||
26 | if(EMSCRIPTEN) | ||
27 | set(CMAKE_EXECUTABLE_SUFFIX ".html" CACHE INTERNAL "") | ||
28 | endif() | ||
29 | |||
30 | # Create your game executable target as usual | ||
31 | add_executable(hello WIN32 hello.c) | ||
32 | |||
33 | # Link to the actual SDL3 library. | ||
34 | target_link_libraries(hello PRIVATE SDL3::SDL3) | ||
35 | ``` | ||
36 | |||
37 | Build: | ||
38 | ```sh | ||
39 | emcmake cmake -S . -B build | ||
40 | cd build | ||
41 | emmake make | ||
42 | ``` | ||
43 | |||
44 | You can now run your app by pointing a webserver at your build directory and connecting a web browser to it, opening hello.html | ||
45 | |||
46 | A more complete example is available at: | ||
47 | |||
48 | https://github.com/Ravbug/sdl3-sample | ||
49 | |||
50 | Additional information and troubleshooting is available in [README-emscripten.md](README-emscripten.md) | ||
diff --git a/src/contrib/SDL-3.2.20/docs/INTRO-mingw.md b/src/contrib/SDL-3.2.20/docs/INTRO-mingw.md new file mode 100644 index 0000000..d7c535d --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/INTRO-mingw.md | |||
@@ -0,0 +1,95 @@ | |||
1 | # Introduction to SDL with MinGW | ||
2 | |||
3 | Without getting deep into the history, MinGW is a long running project that aims to bring gcc to Windows. That said, there's many distributions, versions, and forks floating around. We recommend installing [MSYS2](https://www.msys2.org/), as it's the easiest way to get a modern toolchain with a package manager to help with dependency management. This would allow you to follow the MSYS2 section below. | ||
4 | |||
5 | Otherwise you'll want to follow the "Other Distributions" section below. | ||
6 | |||
7 | We'll start by creating a simple project to build and run [hello.c](hello.c). | ||
8 | |||
9 | # MSYS2 | ||
10 | |||
11 | Open the `MSYS2 UCRT64` prompt and then ensure you've installed the following packages. This will get you working toolchain, CMake, Ninja, and of course SDL3. | ||
12 | |||
13 | ```sh | ||
14 | pacman -S mingw-w64-ucrt-x86_64-gcc mingw-w64-ucrt-x86_64-ninja mingw-w64-ucrt-x86_64-cmake mingw-w64-ucrt-x86_64-sdl3 | ||
15 | ``` | ||
16 | |||
17 | ## Create the file CMakeLists.txt | ||
18 | ```cmake | ||
19 | cmake_minimum_required(VERSION 3.26) | ||
20 | project(hello C CXX) | ||
21 | |||
22 | find_package(SDL3 REQUIRED) | ||
23 | |||
24 | add_executable(hello) | ||
25 | |||
26 | target_sources(hello | ||
27 | PRIVATE | ||
28 | hello.c | ||
29 | ) | ||
30 | |||
31 | target_link_libraries(hello SDL3::SDL3) | ||
32 | ``` | ||
33 | |||
34 | ## Configure and Build: | ||
35 | ```sh | ||
36 | cmake -S . -B build | ||
37 | cmake --build build | ||
38 | ``` | ||
39 | |||
40 | ## Run: | ||
41 | |||
42 | The executable is in the `build` directory: | ||
43 | ```sh | ||
44 | cd build | ||
45 | ./hello | ||
46 | ``` | ||
47 | |||
48 | # Other Distributions | ||
49 | |||
50 | Things can get quite complicated with other distributions of MinGW. If you can't follow [the cmake intro](INTRO-cmake.md), perhaps due to issues getting cmake to understand your toolchain, this section should work. | ||
51 | |||
52 | ## Acquire SDL | ||
53 | |||
54 | Download the `SDL3-devel-<version>-mingw.zip` asset from [the latest release.](https://github.com/libsdl-org/SDL/releases/latest) Then extract it inside your project folder such that the output of `ls SDL3-<version>` looks like `INSTALL.md LICENSE.txt Makefile README.md cmake i686-w64-mingw32 x86_64-w64-mingw32`. | ||
55 | |||
56 | ## Know your Target Architecture | ||
57 | |||
58 | It is not uncommon for folks to not realize their distribution is targeting 32bit Windows despite things like the name of the toolchain, or the fact that they're running on a 64bit system. We'll ensure we know up front what we need: | ||
59 | |||
60 | Create a file named `arch.c` with the following contents: | ||
61 | ```c | ||
62 | #include <stddef.h> | ||
63 | #include <stdio.h> | ||
64 | int main() { | ||
65 | #if defined(__x86_64__) || defined(_M_X64) || defined(i386) || defined(__i386__) || defined(__i386) || defined(_M_IX86) | ||
66 | size_t ptr_size = sizeof(int*); | ||
67 | if (4 == ptr_size) puts("i686-w64-mingw32"); | ||
68 | else if (8 == ptr_size) puts("x86_64-w64-mingw32"); | ||
69 | else puts("Unknown Architecture"); | ||
70 | #else | ||
71 | puts("Unknown Architecture"); | ||
72 | #endif | ||
73 | return 0; | ||
74 | } | ||
75 | ``` | ||
76 | |||
77 | Then run | ||
78 | |||
79 | ```sh | ||
80 | gcc arch.c | ||
81 | ./a.exe | ||
82 | ``` | ||
83 | |||
84 | This should print out which library directory we'll need to use when compiling, keep this value in mind, you'll need to use it when compiling in the next section as `<arch>`. If you get "Unknown Architecture" please [report a bug](https://github.com/libsdl-org/SDL/issues). | ||
85 | |||
86 | |||
87 | ## Build and Run | ||
88 | |||
89 | Now we should have everything needed to compile and run our program. You'll need to ensure to replace `<version>` with the version of the release of SDL3 you downloaded, as well as use the `<arch>` we learned in the previous section. | ||
90 | |||
91 | ```sh | ||
92 | gcc hello.c -o hello.exe -I SDL3-<version>/<arch>/include -L SDL3-<version>/<arch>/lib -lSDL3 -mwindows | ||
93 | cp SDL3-<version>/<arch>/bin/SDL3.dll SDL3.dll | ||
94 | ./hello.exe | ||
95 | ``` | ||
diff --git a/src/contrib/SDL-3.2.20/docs/INTRO-visualstudio.md b/src/contrib/SDL-3.2.20/docs/INTRO-visualstudio.md new file mode 100644 index 0000000..4017f79 --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/INTRO-visualstudio.md | |||
@@ -0,0 +1,16 @@ | |||
1 | |||
2 | # Introduction to SDL with Visual Studio | ||
3 | |||
4 | The easiest way to use SDL is to include it as a subproject in your project. | ||
5 | |||
6 | We'll start by creating a simple project to build and run [hello.c](hello.c) | ||
7 | |||
8 | - Get a copy of the SDL source, you can clone the repo, or download the "Source Code" asset from [the latest release.](https://github.com/libsdl-org/SDL/releases/latest) | ||
9 | - If you've downloaded a release, make sure to extract the contents somewhere you can find it. | ||
10 | - Create a new project in Visual Studio, using the C++ Empty Project template | ||
11 | - Add hello.c to the Source Files | ||
12 | - Right click the solution, select add an existing project, navigate to `VisualC/SDL` from within the source you cloned or downloaded above and add SDL.vcxproj | ||
13 | - Select your main project and go to Project -> Add -> Reference and select SDL3 | ||
14 | - Select your main project and go to Project -> Properties, set the filter at the top to "All Configurations" and "All Platforms", select C/C++ -> General and add the SDL include directory to "Additional Include Directories" | ||
15 | - Build and run! | ||
16 | |||
diff --git a/src/contrib/SDL-3.2.20/docs/INTRO-xcode.md b/src/contrib/SDL-3.2.20/docs/INTRO-xcode.md new file mode 100644 index 0000000..5f0a62a --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/INTRO-xcode.md | |||
@@ -0,0 +1,16 @@ | |||
1 | |||
2 | # Introduction to SDL with Xcode | ||
3 | |||
4 | The easiest way to use SDL is to include it as a subproject in your project. | ||
5 | |||
6 | We'll start by creating a simple project to build and run [hello.c](hello.c) | ||
7 | |||
8 | - Create a new project in Xcode, using the App template and selecting Objective C as the language | ||
9 | - Remove the .h and .m files that were automatically added to the project | ||
10 | - Remove the main storyboard that was automatically added to the project | ||
11 | - On iOS projects, select the project, select the main target, select the Info tab, look for "Custom iOS Target Properties", and remove "Main storyboard base file name" and "Application Scene Manifest" | ||
12 | - Right click the project and select "Add Files to [project]", navigate to the SDL docs directory and add the file hello.c | ||
13 | - Right click the project and select "Add Files to [project]", navigate to the SDL Xcode/SDL directory and add SDL.xcodeproj | ||
14 | - Select the project, select the main target, select the General tab, look for "Frameworks, Libaries, and Embedded Content", and add SDL3.framework | ||
15 | - Build and run! | ||
16 | |||
diff --git a/src/contrib/SDL-3.2.20/docs/README-android.md b/src/contrib/SDL-3.2.20/docs/README-android.md new file mode 100644 index 0000000..e57ca81 --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-android.md | |||
@@ -0,0 +1,653 @@ | |||
1 | Android | ||
2 | ================================================================================ | ||
3 | |||
4 | Matt Styles wrote a tutorial on building SDL for Android with Visual Studio: | ||
5 | http://trederia.blogspot.de/2017/03/building-sdl2-for-android-with-visual.html | ||
6 | |||
7 | The rest of this README covers the Android gradle style build process. | ||
8 | |||
9 | |||
10 | Requirements | ||
11 | ================================================================================ | ||
12 | |||
13 | Android SDK (version 35 or later) | ||
14 | https://developer.android.com/sdk/index.html | ||
15 | |||
16 | Android NDK r15c or later | ||
17 | https://developer.android.com/tools/sdk/ndk/index.html | ||
18 | |||
19 | Minimum API level supported by SDL: 21 (Android 5.0) | ||
20 | |||
21 | |||
22 | How the port works | ||
23 | ================================================================================ | ||
24 | |||
25 | - Android applications are Java-based, optionally with parts written in C | ||
26 | - As SDL apps are C-based, we use a small Java shim that uses JNI to talk to | ||
27 | the SDL library | ||
28 | - This means that your application C code must be placed inside an Android | ||
29 | Java project, along with some C support code that communicates with Java | ||
30 | - This eventually produces a standard Android .apk package | ||
31 | |||
32 | The Android Java code implements an "Activity" and can be found in: | ||
33 | android-project/app/src/main/java/org/libsdl/app/SDLActivity.java | ||
34 | |||
35 | The Java code loads your game code, the SDL shared library, and | ||
36 | dispatches to native functions implemented in the SDL library: | ||
37 | src/core/android/SDL_android.c | ||
38 | |||
39 | |||
40 | Building a simple app | ||
41 | ================================================================================ | ||
42 | |||
43 | For simple projects you can use the script located at build-scripts/create-android-project.py | ||
44 | |||
45 | There's two ways of using it: | ||
46 | |||
47 | ./create-android-project.py com.yourcompany.yourapp < sources.list | ||
48 | ./create-android-project.py com.yourcompany.yourapp source1.c source2.c ...sourceN.c | ||
49 | |||
50 | sources.list should be a text file with a source file name in each line | ||
51 | Filenames should be specified relative to the current directory, for example if | ||
52 | you are in the build-scripts directory and want to create the testgles.c test, you'll | ||
53 | run: | ||
54 | |||
55 | ./create-android-project.py org.libsdl.testgles ../test/testgles.c | ||
56 | |||
57 | One limitation of this script is that all sources provided will be aggregated into | ||
58 | a single directory, thus all your source files should have a unique name. | ||
59 | |||
60 | Once the project is complete the script will tell you how to build the project. | ||
61 | If you want to create a signed release APK, you can use the project created by this | ||
62 | utility to generate it. | ||
63 | |||
64 | Running the script with `--help` will list all available options, and their purposes. | ||
65 | |||
66 | Finally, a word of caution: re running create-android-project.py wipes any changes you may have | ||
67 | done in the build directory for the app! | ||
68 | |||
69 | |||
70 | Building a more complex app | ||
71 | ================================================================================ | ||
72 | |||
73 | For more complex projects, follow these instructions: | ||
74 | |||
75 | 1. Get the source code for SDL and copy the 'android-project' directory located at SDL/android-project to a suitable location in your project. | ||
76 | |||
77 | The 'android-project' directory can basically be seen as a sort of starting point for the android-port of your project. It contains the glue code between the Android Java 'frontend' and the SDL code 'backend'. It also contains some standard behaviour, like how events should be handled, which you will be able to change. | ||
78 | |||
79 | 2. If you are _not_ already building SDL as a part of your project (e.g. via CMake add_subdirectory() or FetchContent) move or [symlink](https://en.wikipedia.org/wiki/Symbolic_link) the SDL directory into the 'android-project/app/jni' directory. Alternatively you can [use the SDL3 Android Archive (.aar)](#using-the-sdl3-android-archive-aar), see bellow for more details. | ||
80 | |||
81 | This is needed as SDL has to be compiled by the Android compiler. | ||
82 | |||
83 | 3. Edit 'android-project/app/build.gradle' to include any assets that your app needs by adding 'assets.srcDirs' in 'sourceSets.main'. | ||
84 | |||
85 | For example: `assets.srcDirs = ['../../assets', '../../shaders']` | ||
86 | |||
87 | If using CMake: | ||
88 | |||
89 | 4. Edit 'android-project/app/build.gradle' to set 'buildWithCMake' to true and set 'externalNativeBuild' cmake path to your top level CMakeLists.txt. | ||
90 | |||
91 | For example: `path '../../CMakeLists.txt'` | ||
92 | |||
93 | 5. Change the target containing your main function to be built as a shared library called "main" when compiling for Android. (e.g. add_executable(MyGame main.c) should become add_library(main SHARED main.c) on Android) | ||
94 | |||
95 | If using Android Makefiles: | ||
96 | |||
97 | 4. Edit 'android-project/app/jni/src/Android.mk' to include your source files. They should be separated by spaces after the 'LOCAL_SRC_FILES := ' declaration. | ||
98 | |||
99 | To build your app, run `./gradlew installDebug` or `./gradlew installRelease` in the project directory. It will build and install your .apk on any connected Android device. If you want to use Android Studio, simply open your 'android-project' directory and start building. | ||
100 | |||
101 | Additionally the [SDL_helloworld](https://github.com/libsdl-org/SDL_helloworld) project contains a small example program with a functional Android port that you can use as a reference. | ||
102 | |||
103 | Here's an explanation of the files in the Android project, so you can customize them: | ||
104 | |||
105 | android-project/app | ||
106 | build.gradle - build info including the application version and SDK | ||
107 | src/main/AndroidManifest.xml - package manifest. Among others, it contains the class name of the main Activity and the package name of the application. | ||
108 | jni/ - directory holding native code | ||
109 | jni/Application.mk - Application JNI settings, including target platform and STL library | ||
110 | jni/Android.mk - Android makefile that can call recursively the Android.mk files in all subdirectories | ||
111 | jni/CMakeLists.txt - Top-level CMake project that adds SDL as a subproject | ||
112 | jni/SDL/ - (symlink to) directory holding the SDL library files | ||
113 | jni/SDL/Android.mk - Android makefile for creating the SDL shared library | ||
114 | jni/src/ - directory holding your C/C++ source | ||
115 | jni/src/Android.mk - Android makefile that you should customize to include your source code and any library references | ||
116 | jni/src/CMakeLists.txt - CMake file that you may customize to include your source code and any library references | ||
117 | src/main/assets/ - directory holding asset files for your application | ||
118 | src/main/res/ - directory holding resources for your application | ||
119 | src/main/res/mipmap-* - directories holding icons for different phone hardware | ||
120 | src/main/res/values/strings.xml - strings used in your application, including the application name | ||
121 | src/main/java/org/libsdl/app/SDLActivity.java - the Java class handling the initialization and binding to SDL. Be very careful changing this, as the SDL library relies on this implementation. You should instead subclass this for your application. | ||
122 | |||
123 | |||
124 | Using the SDL3 Android Archive (.aar) | ||
125 | ================================================================================ | ||
126 | |||
127 | The Android archive allows use of SDL3 in your Android project, without needing to copy any SDL C or JAVA source into your project. | ||
128 | For integration with CMake/ndk-build, it uses [prefab](https://google.github.io/prefab/). | ||
129 | |||
130 | Copy the archive to a `app/libs` directory in your project and add the following to `app/gradle.build`: | ||
131 | ``` | ||
132 | android { | ||
133 | /* ... */ | ||
134 | buildFeatures { | ||
135 | prefab true | ||
136 | } | ||
137 | } | ||
138 | dependencies { | ||
139 | implementation files('libs/SDL3-X.Y.Z.aar') /* Replace with the filename of the actual SDL3-x.y.z.aar file you downloaded */ | ||
140 | /* ... */ | ||
141 | } | ||
142 | ``` | ||
143 | |||
144 | If you use CMake, add the following to your CMakeLists.txt: | ||
145 | ``` | ||
146 | find_package(SDL3 REQUIRED CONFIG) | ||
147 | target_link_libraries(yourgame PRIVATE SDL3::SDL3) | ||
148 | ``` | ||
149 | |||
150 | If you use ndk-build, add the following before `include $(BUILD_SHARED_LIBRARY)` to your `Android.mk`: | ||
151 | ``` | ||
152 | LOCAL_SHARED_LIBARARIES := SDL3 SDL3-Headers | ||
153 | ``` | ||
154 | And add the following at the bottom: | ||
155 | ``` | ||
156 | # https://google.github.io/prefab/build-systems.html | ||
157 | # Add the prefab modules to the import path. | ||
158 | $(call import-add-path,/out) | ||
159 | # Import @PROJECT_NAME@ so we can depend on it. | ||
160 | $(call import-module,prefab/@PROJECT_NAME@) | ||
161 | ``` | ||
162 | |||
163 | The `build-scripts/create-android-project.py` script can create a project using Android aar-chives from scratch: | ||
164 | ``` | ||
165 | build-scripts/create-android-project.py --variant aar com.yourcompany.yourapp < sources.list | ||
166 | ``` | ||
167 | |||
168 | Customizing your application name | ||
169 | ================================================================================ | ||
170 | |||
171 | To customize your application name, edit AndroidManifest.xml and build.gradle to replace | ||
172 | "org.libsdl.app" with an identifier for your product package. | ||
173 | |||
174 | Then create a Java class extending SDLActivity and place it in a directory | ||
175 | under src matching your package, e.g. | ||
176 | |||
177 | app/src/main/java/com/gamemaker/game/MyGame.java | ||
178 | |||
179 | Here's an example of a minimal class file: | ||
180 | |||
181 | --- MyGame.java -------------------------- | ||
182 | package com.gamemaker.game; | ||
183 | |||
184 | import org.libsdl.app.SDLActivity; | ||
185 | |||
186 | /** | ||
187 | * A sample wrapper class that just calls SDLActivity | ||
188 | */ | ||
189 | |||
190 | public class MyGame extends SDLActivity { } | ||
191 | |||
192 | ------------------------------------------ | ||
193 | |||
194 | Then replace "SDLActivity" in AndroidManifest.xml with the name of your | ||
195 | class, .e.g. "MyGame" | ||
196 | |||
197 | |||
198 | Customizing your application icon | ||
199 | ================================================================================ | ||
200 | |||
201 | Conceptually changing your icon is just replacing the "ic_launcher.png" files in | ||
202 | the drawable directories under the res directory. There are several directories | ||
203 | for different screen sizes. | ||
204 | |||
205 | |||
206 | Loading assets | ||
207 | ================================================================================ | ||
208 | |||
209 | Any files you put in the "app/src/main/assets" directory of your project | ||
210 | directory will get bundled into the application package and you can load | ||
211 | them using the standard functions in SDL_iostream.h. | ||
212 | |||
213 | There are also a few Android specific functions that allow you to get other | ||
214 | useful paths for saving and loading data: | ||
215 | * SDL_GetAndroidInternalStoragePath() | ||
216 | * SDL_GetAndroidExternalStorageState() | ||
217 | * SDL_GetAndroidExternalStoragePath() | ||
218 | * SDL_GetAndroidCachePath() | ||
219 | |||
220 | See SDL_system.h for more details on these functions. | ||
221 | |||
222 | The asset packaging system will, by default, compress certain file extensions. | ||
223 | SDL includes two asset file access mechanisms, the preferred one is the so | ||
224 | called "File Descriptor" method, which is faster and doesn't involve the Dalvik | ||
225 | GC, but given this method does not work on compressed assets, there is also the | ||
226 | "Input Stream" method, which is automatically used as a fall back by SDL. You | ||
227 | may want to keep this fact in mind when building your APK, specially when large | ||
228 | files are involved. | ||
229 | For more information on which extensions get compressed by default and how to | ||
230 | disable this behaviour, see for example: | ||
231 | |||
232 | http://ponystyle.com/blog/2010/03/26/dealing-with-asset-compression-in-android-apps/ | ||
233 | |||
234 | |||
235 | Activity lifecycle | ||
236 | ================================================================================ | ||
237 | |||
238 | On Android the application goes through a fixed life cycle and you will get | ||
239 | notifications of state changes via application events. When these events | ||
240 | are delivered you must handle them in an event callback because the OS may | ||
241 | not give you any processing time after the events are delivered. | ||
242 | |||
243 | e.g. | ||
244 | |||
245 | bool HandleAppEvents(void *userdata, SDL_Event *event) | ||
246 | { | ||
247 | switch (event->type) | ||
248 | { | ||
249 | case SDL_EVENT_TERMINATING: | ||
250 | /* Terminate the app. | ||
251 | Shut everything down before returning from this function. | ||
252 | */ | ||
253 | return false; | ||
254 | case SDL_EVENT_LOW_MEMORY: | ||
255 | /* You will get this when your app is paused and iOS wants more memory. | ||
256 | Release as much memory as possible. | ||
257 | */ | ||
258 | return false; | ||
259 | case SDL_EVENT_WILL_ENTER_BACKGROUND: | ||
260 | /* Prepare your app to go into the background. Stop loops, etc. | ||
261 | This gets called when the user hits the home button, or gets a call. | ||
262 | |||
263 | You should not make any OpenGL graphics calls or use the rendering API, | ||
264 | in addition, you should set the render target to NULL, if you're using | ||
265 | it, e.g. call SDL_SetRenderTarget(renderer, NULL). | ||
266 | */ | ||
267 | return false; | ||
268 | case SDL_EVENT_DID_ENTER_BACKGROUND: | ||
269 | /* Your app is NOT active at this point. */ | ||
270 | return false; | ||
271 | case SDL_EVENT_WILL_ENTER_FOREGROUND: | ||
272 | /* This call happens when your app is coming back to the foreground. | ||
273 | Restore all your state here. | ||
274 | */ | ||
275 | return false; | ||
276 | case SDL_EVENT_DID_ENTER_FOREGROUND: | ||
277 | /* Restart your loops here. | ||
278 | Your app is interactive and getting CPU again. | ||
279 | |||
280 | You have access to the OpenGL context or rendering API at this point. | ||
281 | However, there's a chance (on older hardware, or on systems under heavy load), | ||
282 | where the graphics context can not be restored. You should listen for the | ||
283 | event SDL_EVENT_RENDER_DEVICE_RESET and recreate your OpenGL context and | ||
284 | restore your textures when you get it, or quit the app. | ||
285 | */ | ||
286 | return false; | ||
287 | default: | ||
288 | /* No special processing, add it to the event queue */ | ||
289 | return true; | ||
290 | } | ||
291 | } | ||
292 | |||
293 | int main(int argc, char *argv[]) | ||
294 | { | ||
295 | SDL_SetEventFilter(HandleAppEvents, NULL); | ||
296 | |||
297 | ... run your main loop | ||
298 | |||
299 | return 0; | ||
300 | } | ||
301 | |||
302 | |||
303 | Note that if you are using main callbacks instead of a standard C main() function, | ||
304 | your SDL_AppEvent() callback will run as these events arrive and you do not need to | ||
305 | use SDL_SetEventFilter. | ||
306 | |||
307 | If SDL_HINT_ANDROID_BLOCK_ON_PAUSE hint is set (the default), | ||
308 | the event loop will block itself when the app is paused (ie, when the user | ||
309 | returns to the main Android dashboard). Blocking is better in terms of battery | ||
310 | use, and it allows your app to spring back to life instantaneously after resume | ||
311 | (versus polling for a resume message). | ||
312 | |||
313 | You can control activity re-creation (eg. onCreate()) behaviour. This allows you | ||
314 | to choose whether to keep or re-initialize java and native static datas, see | ||
315 | SDL_HINT_ANDROID_ALLOW_RECREATE_ACTIVITY in SDL_hints.h. | ||
316 | |||
317 | |||
318 | Insets and Safe Areas | ||
319 | ================================================================================ | ||
320 | |||
321 | As of Android 15, SDL windows cover the entire screen, extending under notches | ||
322 | and system bars. The OS expects you to take those into account when displaying | ||
323 | content and SDL provides the function SDL_GetWindowSafeArea() so you know what | ||
324 | area is available for interaction. Outside of the safe area can be potentially | ||
325 | covered by system bars or used by OS gestures. | ||
326 | |||
327 | |||
328 | Mouse / Touch events | ||
329 | ================================================================================ | ||
330 | |||
331 | In some case, SDL generates synthetic mouse (resp. touch) events for touch | ||
332 | (resp. mouse) devices. | ||
333 | To enable/disable this behavior, see SDL_hints.h: | ||
334 | - SDL_HINT_TOUCH_MOUSE_EVENTS | ||
335 | - SDL_HINT_MOUSE_TOUCH_EVENTS | ||
336 | |||
337 | |||
338 | Misc | ||
339 | ================================================================================ | ||
340 | |||
341 | For some device, it appears to works better setting explicitly GL attributes | ||
342 | before creating a window: | ||
343 | SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); | ||
344 | SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6); | ||
345 | SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); | ||
346 | |||
347 | |||
348 | Threads and the Java VM | ||
349 | ================================================================================ | ||
350 | |||
351 | For a quick tour on how Linux native threads interoperate with the Java VM, take | ||
352 | a look here: https://developer.android.com/guide/practices/jni.html | ||
353 | |||
354 | If you want to use threads in your SDL app, it's strongly recommended that you | ||
355 | do so by creating them using SDL functions. This way, the required attach/detach | ||
356 | handling is managed by SDL automagically. If you have threads created by other | ||
357 | means and they make calls to SDL functions, make sure that you call | ||
358 | Android_JNI_SetupThread() before doing anything else otherwise SDL will attach | ||
359 | your thread automatically anyway (when you make an SDL call), but it'll never | ||
360 | detach it. | ||
361 | |||
362 | |||
363 | If you ever want to use JNI in a native thread (created by "SDL_CreateThread()"), | ||
364 | it won't be able to find your java class and method because of the java class loader | ||
365 | which is different for native threads, than for java threads (eg your "main()"). | ||
366 | |||
367 | the work-around is to find class/method, in you "main()" thread, and to use them | ||
368 | in your native thread. | ||
369 | |||
370 | see: | ||
371 | https://developer.android.com/training/articles/perf-jni#faq:-why-didnt-findclass-find-my-class | ||
372 | |||
373 | |||
374 | Using STL | ||
375 | ================================================================================ | ||
376 | |||
377 | You can use STL in your project by creating an Application.mk file in the jni | ||
378 | folder and adding the following line: | ||
379 | |||
380 | APP_STL := c++_shared | ||
381 | |||
382 | For more information go here: | ||
383 | https://developer.android.com/ndk/guides/cpp-support | ||
384 | |||
385 | |||
386 | Using the emulator | ||
387 | ================================================================================ | ||
388 | |||
389 | There are some good tips and tricks for getting the most out of the | ||
390 | emulator here: https://developer.android.com/tools/devices/emulator.html | ||
391 | |||
392 | Especially useful is the info on setting up OpenGL ES 2.0 emulation. | ||
393 | |||
394 | Notice that this software emulator is incredibly slow and needs a lot of disk space. | ||
395 | Using a real device works better. | ||
396 | |||
397 | |||
398 | Troubleshooting | ||
399 | ================================================================================ | ||
400 | |||
401 | You can see if adb can see any devices with the following command: | ||
402 | |||
403 | adb devices | ||
404 | |||
405 | You can see the output of log messages on the default device with: | ||
406 | |||
407 | adb logcat | ||
408 | |||
409 | You can push files to the device with: | ||
410 | |||
411 | adb push local_file remote_path_and_file | ||
412 | |||
413 | You can push files to the SD Card at /sdcard, for example: | ||
414 | |||
415 | adb push moose.dat /sdcard/moose.dat | ||
416 | |||
417 | You can see the files on the SD card with a shell command: | ||
418 | |||
419 | adb shell ls /sdcard/ | ||
420 | |||
421 | You can start a command shell on the default device with: | ||
422 | |||
423 | adb shell | ||
424 | |||
425 | You can remove the library files of your project (and not the SDL lib files) with: | ||
426 | |||
427 | ndk-build clean | ||
428 | |||
429 | You can do a build with the following command: | ||
430 | |||
431 | ndk-build | ||
432 | |||
433 | You can see the complete command line that ndk-build is using by passing V=1 on the command line: | ||
434 | |||
435 | ndk-build V=1 | ||
436 | |||
437 | If your application crashes in native code, you can use ndk-stack to get a symbolic stack trace: | ||
438 | https://developer.android.com/ndk/guides/ndk-stack | ||
439 | |||
440 | If you want to go through the process manually, you can use addr2line to convert the | ||
441 | addresses in the stack trace to lines in your code. | ||
442 | |||
443 | For example, if your crash looks like this: | ||
444 | |||
445 | I/DEBUG ( 31): signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 400085d0 | ||
446 | I/DEBUG ( 31): r0 00000000 r1 00001000 r2 00000003 r3 400085d4 | ||
447 | I/DEBUG ( 31): r4 400085d0 r5 40008000 r6 afd41504 r7 436c6a7c | ||
448 | I/DEBUG ( 31): r8 436c6b30 r9 435c6fb0 10 435c6f9c fp 4168d82c | ||
449 | I/DEBUG ( 31): ip 8346aff0 sp 436c6a60 lr afd1c8ff pc afd1c902 cpsr 60000030 | ||
450 | I/DEBUG ( 31): #00 pc 0001c902 /system/lib/libc.so | ||
451 | I/DEBUG ( 31): #01 pc 0001ccf6 /system/lib/libc.so | ||
452 | I/DEBUG ( 31): #02 pc 000014bc /data/data/org.libsdl.app/lib/libmain.so | ||
453 | I/DEBUG ( 31): #03 pc 00001506 /data/data/org.libsdl.app/lib/libmain.so | ||
454 | |||
455 | You can see that there's a crash in the C library being called from the main code. | ||
456 | I run addr2line with the debug version of my code: | ||
457 | |||
458 | arm-eabi-addr2line -C -f -e obj/local/armeabi/libmain.so | ||
459 | |||
460 | and then paste in the number after "pc" in the call stack, from the line that I care about: | ||
461 | 000014bc | ||
462 | |||
463 | I get output from addr2line showing that it's in the quit function, in testspriteminimal.c, on line 23. | ||
464 | |||
465 | You can add logging to your code to help show what's happening: | ||
466 | |||
467 | #include <android/log.h> | ||
468 | |||
469 | __android_log_print(ANDROID_LOG_INFO, "foo", "Something happened! x = %d", x); | ||
470 | |||
471 | If you need to build without optimization turned on, you can create a file called | ||
472 | "Application.mk" in the jni directory, with the following line in it: | ||
473 | |||
474 | APP_OPTIM := debug | ||
475 | |||
476 | |||
477 | Memory debugging | ||
478 | ================================================================================ | ||
479 | |||
480 | The best (and slowest) way to debug memory issues on Android is valgrind. | ||
481 | Valgrind has support for Android out of the box, just grab code using: | ||
482 | |||
483 | git clone https://sourceware.org/git/valgrind.git | ||
484 | |||
485 | ... and follow the instructions in the file `README.android` to build it. | ||
486 | |||
487 | One thing I needed to do on macOS was change the path to the toolchain, | ||
488 | and add ranlib to the environment variables: | ||
489 | export RANLIB=$NDKROOT/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-ranlib | ||
490 | |||
491 | Once valgrind is built, you can create a wrapper script to launch your | ||
492 | application with it, changing org.libsdl.app to your package identifier: | ||
493 | |||
494 | --- start_valgrind_app ------------------- | ||
495 | #!/system/bin/sh | ||
496 | export TMPDIR=/data/data/org.libsdl.app | ||
497 | exec /data/local/Inst/bin/valgrind --log-file=/sdcard/valgrind.log --error-limit=no $* | ||
498 | ------------------------------------------ | ||
499 | |||
500 | Then push it to the device: | ||
501 | |||
502 | adb push start_valgrind_app /data/local | ||
503 | |||
504 | and make it executable: | ||
505 | |||
506 | adb shell chmod 755 /data/local/start_valgrind_app | ||
507 | |||
508 | and tell Android to use the script to launch your application: | ||
509 | |||
510 | adb shell setprop wrap.org.libsdl.app "logwrapper /data/local/start_valgrind_app" | ||
511 | |||
512 | If the setprop command says "could not set property", it's likely that | ||
513 | your package name is too long and you should make it shorter by changing | ||
514 | AndroidManifest.xml and the path to your class file in android-project/src | ||
515 | |||
516 | You can then launch your application normally and waaaaaaaiiittt for it. | ||
517 | You can monitor the startup process with the logcat command above, and | ||
518 | when it's done (or even while it's running) you can grab the valgrind | ||
519 | output file: | ||
520 | |||
521 | adb pull /sdcard/valgrind.log | ||
522 | |||
523 | When you're done instrumenting with valgrind, you can disable the wrapper: | ||
524 | |||
525 | adb shell setprop wrap.org.libsdl.app "" | ||
526 | |||
527 | |||
528 | Graphics debugging | ||
529 | ================================================================================ | ||
530 | |||
531 | If you are developing on a compatible Tegra-based tablet, NVidia provides | ||
532 | Tegra Graphics Debugger at their website. Because SDL3 dynamically loads EGL | ||
533 | and GLES libraries, you must follow their instructions for installing the | ||
534 | interposer library on a rooted device. The non-rooted instructions are not | ||
535 | compatible with applications that use SDL3 for video. | ||
536 | |||
537 | The Tegra Graphics Debugger is available from NVidia here: | ||
538 | https://developer.nvidia.com/tegra-graphics-debugger | ||
539 | |||
540 | |||
541 | A note regarding the use of the "dirty rectangles" rendering technique | ||
542 | ================================================================================ | ||
543 | |||
544 | If your app uses a variation of the "dirty rectangles" rendering technique, | ||
545 | where you only update a portion of the screen on each frame, you may notice a | ||
546 | variety of visual glitches on Android, that are not present on other platforms. | ||
547 | This is caused by SDL's use of EGL as the support system to handle OpenGL ES/ES2 | ||
548 | contexts, in particular the use of the eglSwapBuffers function. As stated in the | ||
549 | documentation for the function "The contents of ancillary buffers are always | ||
550 | undefined after calling eglSwapBuffers". | ||
551 | |||
552 | |||
553 | Ending your application | ||
554 | ================================================================================ | ||
555 | |||
556 | Two legitimate ways: | ||
557 | |||
558 | - return from your main() function. Java side will automatically terminate the | ||
559 | Activity by calling Activity.finish(). | ||
560 | |||
561 | - Android OS can decide to terminate your application by calling onDestroy() | ||
562 | (see Activity life cycle). Your application will receive an SDL_EVENT_QUIT you | ||
563 | can handle to save things and quit. | ||
564 | |||
565 | Don't call exit() as it stops the activity badly. | ||
566 | |||
567 | NB: "Back button" can be handled as a SDL_EVENT_KEY_DOWN/UP events, with Keycode | ||
568 | SDLK_AC_BACK, for any purpose. | ||
569 | |||
570 | |||
571 | Known issues | ||
572 | ================================================================================ | ||
573 | |||
574 | - The number of buttons reported for each joystick is hardcoded to be 36, which | ||
575 | is the current maximum number of buttons Android can report. | ||
576 | |||
577 | |||
578 | Building the SDL tests | ||
579 | ================================================================================ | ||
580 | |||
581 | SDL's CMake build system can create APK's for the tests. | ||
582 | It can build all tests with a single command without a dependency on gradle or Android Studio. | ||
583 | The APK's are signed with a debug certificate. | ||
584 | The only caveat is that the APK's support a single architecture. | ||
585 | |||
586 | ### Requirements | ||
587 | - SDL source tree | ||
588 | - CMake | ||
589 | - ninja or make | ||
590 | - Android Platform SDK | ||
591 | - Android NDK | ||
592 | - Android Build tools | ||
593 | - Java JDK (version should be compatible with Android) | ||
594 | - keytool (usually provided with the Java JDK), used for generating a debug certificate | ||
595 | - zip | ||
596 | |||
597 | ### CMake configuration | ||
598 | |||
599 | When configuring the CMake project, you need to use the Android NDK CMake toolchain, and pass the Android home path through `SDL_ANDROID_HOME`. | ||
600 | ``` | ||
601 | cmake .. -DCMAKE_TOOLCHAIN_FILE=<path/to/android.toolchain.cmake> -DANDROID_ABI=<android-abi> -DSDL_ANDROID_HOME=<path-to-android-sdk-home> -DANDROID_PLATFORM=23 -DSDL_TESTS=ON | ||
602 | ``` | ||
603 | |||
604 | Remarks: | ||
605 | - `android.toolchain.cmake` can usually be found at `$ANDROID_HOME/ndk/x.y.z/build/cmake/android.toolchain.cmake` | ||
606 | - `ANDROID_ABI` should be one of `arm64-v8a`, `armeabi-v7a`, `x86` or `x86_64`. | ||
607 | - When CMake is unable to find required paths, use `cmake-gui` to override required `SDL_ANDROID_` CMake cache variables. | ||
608 | |||
609 | ### Building the APK's | ||
610 | |||
611 | For the `testsprite` executable, the `testsprite-apk` target will build the associated APK: | ||
612 | ``` | ||
613 | cmake --build . --target testsprite-apk | ||
614 | ``` | ||
615 | |||
616 | APK's of all tests can be built with the `sdl-test-apks` target: | ||
617 | ``` | ||
618 | cmake --build . --target sdl-test-apks | ||
619 | ``` | ||
620 | |||
621 | ### Installation/removal of the tests | ||
622 | |||
623 | `testsprite.apk` APK can be installed on your Android machine using the `install-testsprite` target: | ||
624 | ``` | ||
625 | cmake --build . --target install-testsprite | ||
626 | ``` | ||
627 | |||
628 | APK's of all tests can be installed with the `install-sdl-test-apks` target: | ||
629 | ``` | ||
630 | cmake --build . --target install-sdl-test-apks | ||
631 | ``` | ||
632 | |||
633 | All SDL tests can be uninstalled with the `uninstall-sdl-test-apks` target: | ||
634 | ``` | ||
635 | cmake --build . --target uninstall-sdl-test-apks | ||
636 | ``` | ||
637 | |||
638 | ### Starting the tests | ||
639 | |||
640 | After installation, the tests can be started using the Android Launcher GUI. | ||
641 | Alternatively, they can also be started using CMake targets. | ||
642 | |||
643 | This command will start the testsprite executable: | ||
644 | ``` | ||
645 | cmake --build . --target start-testsprite | ||
646 | ``` | ||
647 | |||
648 | There is also a convenience target which will build, install and start a test: | ||
649 | ``` | ||
650 | cmake --build . --target build-install-start-testsprite | ||
651 | ``` | ||
652 | |||
653 | Not all tests provide a GUI. For those, you can use `adb logcat` to read the output. | ||
diff --git a/src/contrib/SDL-3.2.20/docs/README-bsd.md b/src/contrib/SDL-3.2.20/docs/README-bsd.md new file mode 100644 index 0000000..d823060 --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-bsd.md | |||
@@ -0,0 +1,6 @@ | |||
1 | # FreeBSD / OpenBSD / NetBSD | ||
2 | |||
3 | SDL is fully supported on BSD platforms, and is built using [CMake](README-cmake.md). | ||
4 | |||
5 | If you want to run on the console, you can take a look at [KMSDRM support on BSD](README-kmsbsd.md) | ||
6 | |||
diff --git a/src/contrib/SDL-3.2.20/docs/README-cmake.md b/src/contrib/SDL-3.2.20/docs/README-cmake.md new file mode 100644 index 0000000..f2e4759 --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-cmake.md | |||
@@ -0,0 +1,364 @@ | |||
1 | # CMake | ||
2 | |||
3 | [www.cmake.org](https://www.cmake.org/) | ||
4 | |||
5 | The CMake build system is supported with the following environments: | ||
6 | |||
7 | * Android | ||
8 | * Emscripten | ||
9 | * FreeBSD | ||
10 | * Haiku | ||
11 | * Linux | ||
12 | * macOS, iOS, tvOS, and visionOS with support for XCode | ||
13 | * Microsoft Visual Studio | ||
14 | * MinGW and Msys | ||
15 | * NetBSD | ||
16 | * Nintendo 3DS | ||
17 | * PlayStation 2 | ||
18 | * PlayStation Portable | ||
19 | * PlayStation Vita | ||
20 | * RISC OS | ||
21 | |||
22 | ## Building SDL on Windows | ||
23 | |||
24 | Assuming you're in the SDL source directory, building and installing to C:/SDL can be done with: | ||
25 | ```sh | ||
26 | cmake -S . -B build | ||
27 | cmake --build build --config RelWithDebInfo | ||
28 | cmake --install build --config RelWithDebInfo --prefix C:/SDL | ||
29 | ``` | ||
30 | |||
31 | ## Building SDL on UNIX | ||
32 | |||
33 | SDL will build with very few dependencies, but for full functionality you should install the packages detailed in [README-linux.md](README-linux.md). | ||
34 | |||
35 | Assuming you're in the SDL source directory, building and installing to /usr/local can be done with: | ||
36 | ```sh | ||
37 | cmake -S . -B build | ||
38 | cmake --build build | ||
39 | sudo cmake --install build --prefix /usr/local | ||
40 | ``` | ||
41 | |||
42 | ## Building SDL on macOS | ||
43 | |||
44 | Assuming you're in the SDL source directory, building and installing to ~/SDL can be done with: | ||
45 | ```sh | ||
46 | cmake -S . -B build -DSDL_FRAMEWORK=ON -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" | ||
47 | cmake --build build | ||
48 | cmake --install build --prefix ~/SDL | ||
49 | ``` | ||
50 | |||
51 | ## Building SDL tests | ||
52 | |||
53 | You can build the SDL test programs by adding `-DSDL_TESTS=ON` to the first cmake command above: | ||
54 | ```sh | ||
55 | cmake -S . -B build -DSDL_TESTS=ON | ||
56 | ``` | ||
57 | and then building normally. The test programs will be built and can be run from `build/test/`. | ||
58 | |||
59 | ## Building SDL examples | ||
60 | |||
61 | You can build the SDL example programs by adding `-DSDL_EXAMPLES=ON` to the first cmake command above: | ||
62 | ```sh | ||
63 | cmake -S . -B build -DSDL_EXAMPLES=ON | ||
64 | ``` | ||
65 | and then building normally. The example programs will be built and can be run from `build/examples/`. | ||
66 | |||
67 | ## Including SDL in your project | ||
68 | |||
69 | SDL can be included in your project in 2 major ways: | ||
70 | - using a system SDL library, provided by your (UNIX) distribution or a package manager | ||
71 | - using a vendored SDL library: this is SDL copied or symlinked in a subfolder. | ||
72 | |||
73 | The following CMake script supports both, depending on the value of `MYGAME_VENDORED`. | ||
74 | |||
75 | ```cmake | ||
76 | cmake_minimum_required(VERSION 3.5) | ||
77 | project(mygame) | ||
78 | |||
79 | # Create an option to switch between a system sdl library and a vendored SDL library | ||
80 | option(MYGAME_VENDORED "Use vendored libraries" OFF) | ||
81 | |||
82 | if(MYGAME_VENDORED) | ||
83 | # This assumes you have added SDL as a submodule in vendored/SDL | ||
84 | add_subdirectory(vendored/SDL EXCLUDE_FROM_ALL) | ||
85 | else() | ||
86 | # 1. Look for a SDL3 package, | ||
87 | # 2. look for the SDL3-shared component, and | ||
88 | # 3. fail if the shared component cannot be found. | ||
89 | find_package(SDL3 REQUIRED CONFIG REQUIRED COMPONENTS SDL3-shared) | ||
90 | endif() | ||
91 | |||
92 | # Create your game executable target as usual | ||
93 | add_executable(mygame WIN32 mygame.c) | ||
94 | |||
95 | # Link to the actual SDL3 library. | ||
96 | target_link_libraries(mygame PRIVATE SDL3::SDL3) | ||
97 | ``` | ||
98 | |||
99 | ### A system SDL library | ||
100 | |||
101 | For CMake to find SDL, it must be installed in [a default location CMake is looking for](https://cmake.org/cmake/help/latest/command/find_package.html#config-mode-search-procedure). | ||
102 | |||
103 | The following components are available, to be used as an argument of `find_package`. | ||
104 | |||
105 | | Component name | Description | | ||
106 | |----------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------| | ||
107 | | SDL3-shared | The SDL3 shared library, available through the `SDL3::SDL3-shared` target | | ||
108 | | SDL3-static | The SDL3 static library, available through the `SDL3::SDL3-static` target | | ||
109 | | SDL3_test | The SDL3_test static library, available through the `SDL3::SDL3_test` target | | ||
110 | | SDL3 | The SDL3 library, available through the `SDL3::SDL3` target. This is an alias of `SDL3::SDL3-shared` or `SDL3::SDL3-static`. This component is always available. | | ||
111 | | Headers | The SDL3 headers, available through the `SDL3::Headers` target. This component is always available. | | ||
112 | |||
113 | SDL's CMake support guarantees a `SDL3::SDL3` target. | ||
114 | Neither `SDL3::SDL3-shared` nor `SDL3::SDL3-static` are guaranteed to exist. | ||
115 | |||
116 | ### Using a vendored SDL | ||
117 | |||
118 | This only requires a copy of SDL in a subdirectory + `add_subdirectory`. | ||
119 | Alternatively, use [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html). | ||
120 | Depending on the configuration, the same targets as a system SDL package are available. | ||
121 | |||
122 | ## CMake configuration options | ||
123 | |||
124 | ### Build optimized library | ||
125 | |||
126 | By default, CMake provides 4 build types: `Debug`, `Release`, `RelWithDebInfo` and `MinSizeRel`. | ||
127 | The main difference(s) between these are the optimization options and the generation of debug info. | ||
128 | To configure SDL as an optimized `Release` library, configure SDL with: | ||
129 | ```sh | ||
130 | cmake ~/SDL -DCMAKE_BUILD_TYPE=Release | ||
131 | ``` | ||
132 | To build it, run: | ||
133 | ```sh | ||
134 | cmake --build . --config Release | ||
135 | ``` | ||
136 | |||
137 | ### Shared or static | ||
138 | |||
139 | By default, only a dynamic (=shared) SDL library is built and installed. | ||
140 | The options `-DSDL_SHARED=` and `-DSDL_STATIC=` accept boolean values to change this. | ||
141 | |||
142 | Exceptions exist: | ||
143 | - some platforms don't support dynamic libraries, so only `-DSDL_STATIC=ON` makes sense. | ||
144 | - a static Apple framework is not supported | ||
145 | |||
146 | ### Man pages | ||
147 | |||
148 | Configuring with `-DSDL_INSTALL_DOCS=TRUE` installs man pages. | ||
149 | |||
150 | We recommend package managers of unix distributions to install SDL3's man pages. | ||
151 | This adds an extra build-time dependency on Perl. | ||
152 | |||
153 | ### Pass custom compile options to the compiler | ||
154 | |||
155 | - Use [`CMAKE_<LANG>_FLAGS`](https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_FLAGS.html) to pass extra | ||
156 | flags to the compiler. | ||
157 | - Use [`CMAKE_EXE_LINKER_FLAGS`](https://cmake.org/cmake/help/latest/variable/CMAKE_EXE_LINKER_FLAGS.html) to pass extra option to the linker for executables. | ||
158 | - Use [`CMAKE_SHARED_LINKER_FLAGS`](https://cmake.org/cmake/help/latest/variable/CMAKE_SHARED_LINKER_FLAGS.html) to pass extra options to the linker for shared libraries. | ||
159 | |||
160 | #### Examples | ||
161 | |||
162 | - build a SDL library optimized for (more) modern x64 microprocessor architectures. | ||
163 | |||
164 | With gcc or clang: | ||
165 | ```sh | ||
166 | cmake ~/sdl -DCMAKE_C_FLAGS="-march=x86-64-v3" -DCMAKE_CXX_FLAGS="-march=x86-64-v3" | ||
167 | ``` | ||
168 | With Visual C: | ||
169 | ```sh | ||
170 | cmake .. -DCMAKE_C_FLAGS="/ARCH:AVX2" -DCMAKE_CXX_FLAGS="/ARCH:AVX2" | ||
171 | ``` | ||
172 | |||
173 | ### Apple | ||
174 | |||
175 | CMake documentation for cross building for Apple: | ||
176 | [link](https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-ios-tvos-visionos-or-watchos) | ||
177 | |||
178 | #### iOS/tvOS/visionOS | ||
179 | |||
180 | CMake 3.14+ natively includes support for iOS, tvOS and watchOS. visionOS requires CMake 3.28+. | ||
181 | SDL binaries may be built using Xcode or Make, possibly among other build-systems. | ||
182 | |||
183 | When using a compatible version of CMake, it should be possible to: | ||
184 | |||
185 | - build SDL dylibs, both static and dynamic dylibs | ||
186 | - build SDL frameworks, only shared | ||
187 | - build SDL test apps | ||
188 | |||
189 | #### Frameworks | ||
190 | |||
191 | Configure with `-DSDL_FRAMEWORK=ON` to build a SDL framework instead of a dylib shared library. | ||
192 | Only shared frameworks are supported, no static ones. | ||
193 | |||
194 | #### Platforms | ||
195 | |||
196 | Use `-DCMAKE_SYSTEM_NAME=<value>` to configure the platform. CMake can target only one platform at a time. | ||
197 | |||
198 | | Apple platform | `CMAKE_SYSTEM_NAME` value | | ||
199 | |-----------------|---------------------------| | ||
200 | | macOS (MacOS X) | `Darwin` | | ||
201 | | iOS | `iOS` | | ||
202 | | tvOS | `tvOS` | | ||
203 | | visionOS | `visionOS` | | ||
204 | | watchOS | `watchOS` | | ||
205 | |||
206 | #### Universal binaries | ||
207 | |||
208 | A universal binaries, can be built by configuring CMake with | ||
209 | `-DCMAKE_OSX_ARCHITECTURES=<semicolon-separated list of CPU architectures>`. | ||
210 | |||
211 | For example `-DCMAKE_OSX_ARCHITECTURES="arm64;x86_64"` will build binaries that run on both Intel cpus and Apple silicon. | ||
212 | |||
213 | SDL supports following Apple architectures: | ||
214 | |||
215 | | Platform | `CMAKE_OSX_ARCHITECTURES` value | | ||
216 | |----------------------------|---------------------------------| | ||
217 | | 64-bit ARM (Apple Silicon) | `arm64` | | ||
218 | | x86_64 | `x86_64` | | ||
219 | | 32-bit ARM | `armv7s` | | ||
220 | |||
221 | CMake documentation: [link](https://cmake.org/cmake/help/latest/variable/CMAKE_OSX_ARCHITECTURES.html) | ||
222 | |||
223 | #### Simulators and/or non-default macOS platform SDK | ||
224 | |||
225 | Use `-DCMAKE_OSX_SYSROOT=<value>` to configure a different platform SDK. | ||
226 | The value can be either the name of the SDK, or a full path to the sdk (e.g. `/full/path/to/iPhoneOS.sdk`). | ||
227 | |||
228 | | SDK | `CMAKE_OSX_SYSROOT` value | | ||
229 | |----------------------|---------------------------| | ||
230 | | iphone | `iphoneos` | | ||
231 | | iphonesimulator | `iphonesimulator` | | ||
232 | | appleTV | `appletvos` | | ||
233 | | appleTV simulator | `appletvsimulator` | | ||
234 | | visionOS | `xr` | | ||
235 | | visionOS simulator | `xrsimulator` | | ||
236 | | watchOS | `watchos` | | ||
237 | | watchOS simulator | `watchsimulator` | | ||
238 | |||
239 | Append with a version number to target a specific SDK revision: e.g. `iphoneos12.4`, `appletvos12.4`. | ||
240 | |||
241 | CMake documentation: [link](https://cmake.org/cmake/help/latest/variable/CMAKE_OSX_SYSROOT.html) | ||
242 | |||
243 | #### Examples | ||
244 | |||
245 | - for macOS, building a dylib and/or static library for x86_64 and arm64: | ||
246 | |||
247 | ```bash | ||
248 | cmake ~/sdl -DCMAKE_SYSTEM_NAME=Darwin -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" -DCMAKE_OSX_DEPLOYMENT_TARGET=10.11 | ||
249 | |||
250 | - for macOS, building an universal framework for x86_64 and arm64: | ||
251 | |||
252 | ```bash | ||
253 | cmake ~/sdl -DSDL_FRAMEWORK=ON -DCMAKE_SYSTEM_NAME=Darwin -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" -DCMAKE_OSX_DEPLOYMENT_TARGET=10.11 | ||
254 | |||
255 | - for iOS-Simulator, using the latest, installed SDK: | ||
256 | |||
257 | ```bash | ||
258 | cmake ~/sdl -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphonesimulator -DCMAKE_OSX_ARCHITECTURES=x86_64 -DCMAKE_OSX_DEPLOYMENT_TARGET=9.0 | ||
259 | ``` | ||
260 | |||
261 | - for iOS-Device, using the latest, installed SDK, 64-bit only | ||
262 | |||
263 | ```bash | ||
264 | cmake ~/sdl -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphoneos -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_DEPLOYMENT_TARGET=9.0 | ||
265 | ``` | ||
266 | |||
267 | - for iOS-Device, using the latest, installed SDK, mixed 32/64 bit | ||
268 | |||
269 | ```cmake | ||
270 | cmake ~/sdl -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphoneos -DCMAKE_OSX_ARCHITECTURES="arm64;armv7s" -DCMAKE_OSX_DEPLOYMENT_TARGET=9.0 | ||
271 | ``` | ||
272 | |||
273 | - for iOS-Device, using a specific SDK revision (iOS 12.4, in this example): | ||
274 | |||
275 | ```cmake | ||
276 | cmake ~/sdl -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphoneos12.4 -DCMAKE_OSX_ARCHITECTURES=arm64 | ||
277 | ``` | ||
278 | |||
279 | - for iOS-Simulator, using the latest, installed SDK, and building SDL test apps (as .app bundles): | ||
280 | |||
281 | ```cmake | ||
282 | cmake ~/sdl -DSDL_TESTS=1 -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphonesimulator -DCMAKE_OSX_ARCHITECTURES=x86_64 -DCMAKE_OSX_DEPLOYMENT_TARGET=9.0 | ||
283 | ``` | ||
284 | |||
285 | - for tvOS-Simulator, using the latest, installed SDK: | ||
286 | |||
287 | ```cmake | ||
288 | cmake ~/sdl -DCMAKE_SYSTEM_NAME=tvOS -DCMAKE_OSX_SYSROOT=appletvsimulator -DCMAKE_OSX_ARCHITECTURES=x86_64 -DCMAKE_OSX_DEPLOYMENT_TARGET=9.0 | ||
289 | ``` | ||
290 | |||
291 | - for tvOS-Device, using the latest, installed SDK: | ||
292 | |||
293 | ```cmake | ||
294 | cmake ~/sdl -DCMAKE_SYSTEM_NAME=tvOS -DCMAKE_OSX_SYSROOT=appletvos -DCMAKE_OSX_ARCHITECTURES=arm64` -DCMAKE_OSX_DEPLOYMENT_TARGET=9.0 | ||
295 | ``` | ||
296 | |||
297 | - for QNX/aarch64, using the latest, installed SDK: | ||
298 | |||
299 | ```cmake | ||
300 | cmake ~/sdl -DCMAKE_TOOLCHAIN_FILE=~/sdl/build-scripts/cmake-toolchain-qnx-aarch64le.cmake -DSDL_X11=0 | ||
301 | ``` | ||
302 | |||
303 | ## SDL-specific CMake options | ||
304 | |||
305 | SDL can be customized through (platform-specific) CMake options. | ||
306 | The following table shows generic options that are available for most platforms. | ||
307 | At the end of SDL CMake configuration, a table shows all CMake options along with its detected value. | ||
308 | |||
309 | | CMake option | Valid values | Description | | ||
310 | |-------------------------------|--------------|-----------------------------------------------------------------------------------------------------| | ||
311 | | `-DSDL_SHARED=` | `ON`/`OFF` | Build SDL shared library (not all platforms support this) (`libSDL3.so`/`libSDL3.dylib`/`SDL3.dll`) | | ||
312 | | `-DSDL_STATIC=` | `ON`/`OFF` | Build SDL static library (`libSDL3.a`/`SDL3-static.lib`) | | ||
313 | | `-DSDL_TEST_LIBRARY=` | `ON`/`OFF` | Build SDL test library (`libSDL3_test.a`/`SDL3_test.lib`) | | ||
314 | | `-DSDL_TESTS=` | `ON`/`OFF` | Build SDL test programs (**requires `-DSDL_TEST_LIBRARY=ON`**) | | ||
315 | | `-DSDL_DISABLE_INSTALL=` | `ON`/`OFF` | Don't create a SDL install target | | ||
316 | | `-DSDL_DISABLE_INSTALL_DOCS=` | `ON`/`OFF` | Don't install the SDL documentation | | ||
317 | | `-DSDL_INSTALL_TESTS=` | `ON`/`OFF` | Install the SDL test programs | | ||
318 | |||
319 | ### Incompatibilities | ||
320 | |||
321 | #### `SDL_LIBC=OFF` and sanitizers | ||
322 | |||
323 | Building with `-DSDL_LIBC=OFF` will make it impossible to use the sanitizer, such as the address sanitizer. | ||
324 | Configure your project with `-DSDL_LIBC=ON` to make use of sanitizers. | ||
325 | |||
326 | ## CMake FAQ | ||
327 | |||
328 | ### CMake fails to build without X11 or Wayland support | ||
329 | |||
330 | Install the required system packages prior to running CMake. | ||
331 | See [README-linux](linux#build-dependencies) for the list of dependencies on Linux. | ||
332 | Other unix operationg systems should provide similar packages. | ||
333 | |||
334 | If you **really** don't need to show windows, add `-DSDL_UNIX_CONSOLE_BUILD=ON` to the CMake configure command. | ||
335 | |||
336 | ### How do I copy a SDL3 dynamic library to another location? | ||
337 | |||
338 | Use [CMake generator expressions](https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html#target-dependent-expressions). | ||
339 | Generator expressions support multiple configurations, and are evaluated during build system generation time. | ||
340 | |||
341 | On Windows, the following example copies `SDL3.dll` to the directory where `mygame.exe` is built. | ||
342 | ```cmake | ||
343 | if(WIN32) | ||
344 | add_custom_command( | ||
345 | TARGET mygame POST_BUILD | ||
346 | COMMAND "${CMAKE_COMMAND}" -E copy $<TARGET_FILE:SDL3::SDL3-shared> $<TARGET_FILE_DIR:mygame> | ||
347 | VERBATIM | ||
348 | ) | ||
349 | endif() | ||
350 | ``` | ||
351 | On Unix systems, `$<TARGET_FILE:...>` will refer to the dynamic library (or framework), | ||
352 | and you might need to use `$<TARGET_SONAME_FILE:tgt>` instead. | ||
353 | |||
354 | Most often, you can avoid copying libraries by configuring your project with absolute [`CMAKE_LIBRARY_OUTPUT_DIRECTORY`](https://cmake.org/cmake/help/latest/variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY.html) | ||
355 | and [`CMAKE_RUNTIME_OUTPUT_DIRECTORY`](https://cmake.org/cmake/help/latest/variable/CMAKE_RUNTIME_OUTPUT_DIRECTORY.html) paths. | ||
356 | When using a multi-config generator (such as Visual Studio or Ninja Multi-Config), eventually add `/$<CONFIG>` to both paths. | ||
357 | |||
358 | ### Linking against a static SDL library fails due to relocation errors | ||
359 | |||
360 | On unix platforms, all code that ends up in shared libraries needs to be built as relocatable (=position independent) code. | ||
361 | However, by default CMake builds static libraries as non-relocatable. | ||
362 | Configuring SDL with `-DCMAKE_POSITION_INDEPENDENT_CODE=ON` will result in a static `libSDL3.a` library | ||
363 | which you can link against to create a shared library. | ||
364 | |||
diff --git a/src/contrib/SDL-3.2.20/docs/README-contributing.md b/src/contrib/SDL-3.2.20/docs/README-contributing.md new file mode 100644 index 0000000..02a37bf --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-contributing.md | |||
@@ -0,0 +1,107 @@ | |||
1 | # Contributing to SDL | ||
2 | |||
3 | We appreciate your interest in contributing to SDL, this document will describe how to report bugs, contribute code or ideas or edit documentation. | ||
4 | |||
5 | **Table Of Contents** | ||
6 | |||
7 | - [Filing a GitHub issue](#filing-a-github-issue) | ||
8 | - [Reporting a bug](#reporting-a-bug) | ||
9 | - [Suggesting enhancements](#suggesting-enhancements) | ||
10 | - [Contributing code](#contributing-code) | ||
11 | - [Forking the project](#forking-the-project) | ||
12 | - [Following the style guide](#following-the-style-guide) | ||
13 | - [Running the tests](#running-the-tests) | ||
14 | - [Opening a pull request](#opening-a-pull-request) | ||
15 | - [Continuous integration](#continuous-integration) | ||
16 | - [Contributing to the documentation](#contributing-to-the-documentation) | ||
17 | - [Editing a function documentation](#editing-a-function-documentation) | ||
18 | - [Editing the wiki](#editing-the-wiki) | ||
19 | |||
20 | ## Filing a GitHub issue | ||
21 | |||
22 | ### Reporting a bug | ||
23 | |||
24 | If you think you have found a bug and would like to report it, here are the steps you should take: | ||
25 | |||
26 | - Before opening a new issue, ensure your bug has not already been reported on the [GitHub Issues page](https://github.com/libsdl-org/SDL/issues). | ||
27 | - On the issue tracker, click on [New Issue](https://github.com/libsdl-org/SDL/issues/new). | ||
28 | - Include details about your environment, such as your Operating System and SDL version. | ||
29 | - If possible, provide a small example that reproduces your bug. | ||
30 | |||
31 | ### Suggesting enhancements | ||
32 | |||
33 | If you want to suggest changes for the project, here are the steps you should take: | ||
34 | |||
35 | - Check if the suggestion has already been made on: | ||
36 | - the [issue tracker](https://github.com/libsdl-org/SDL/issues); | ||
37 | - the [discourse forum](https://discourse.libsdl.org/); | ||
38 | - or if a [pull request](https://github.com/libsdl-org/SDL/pulls) already exists. | ||
39 | - On the issue tracker, click on [New Issue](https://github.com/libsdl-org/SDL/issues/new). | ||
40 | - Describe what change you would like to happen. | ||
41 | |||
42 | ## Contributing code | ||
43 | |||
44 | This section will cover how the process of forking the project, making a change and opening a pull request. | ||
45 | |||
46 | ### Forking the project | ||
47 | |||
48 | The first step consists in making a fork of the project, this is only necessary for the first contribution. | ||
49 | |||
50 | Head over to https://github.com/libsdl-org/SDL and click on the `Fork` button in the top right corner of your screen, you may leave the fields unchanged and click `Create Fork`. | ||
51 | |||
52 | You will be redirected to your fork of the repository, click the green `Code` button and copy the git clone link. | ||
53 | |||
54 | If you had already forked the repository, you may update it from the web page using the `Fetch upstream` button. | ||
55 | |||
56 | ### Following the style guide | ||
57 | |||
58 | Code formatting is done using a custom `.clang-format` file, you can learn more about how to run it [here](https://clang.llvm.org/docs/ClangFormat.html). | ||
59 | |||
60 | Some legacy code may not be formatted, so please avoid formatting the whole file at once and only format around your changes. | ||
61 | |||
62 | For your commit message to be properly displayed on GitHub, it should contain: | ||
63 | |||
64 | - A short description of the commit of 50 characters or less on the first line. | ||
65 | - If necessary, add a blank line followed by a long description, each line should be 72 characters or less. | ||
66 | |||
67 | For example: | ||
68 | |||
69 | ``` | ||
70 | Fix crash in SDL_FooBar. | ||
71 | |||
72 | This addresses the issue #123456 by making sure Foo was successful | ||
73 | before calling Bar. | ||
74 | ``` | ||
75 | |||
76 | ### Running the tests | ||
77 | |||
78 | Tests allow you to verify if your changes did not break any behaviour, here are the steps to follow: | ||
79 | |||
80 | - Before pushing, run the `testautomation` suite on your machine, there should be no more failing tests after your change than before. | ||
81 | - After pushing to your fork, Continuous Integration (GitHub Actions) will ensure compilation and tests still pass on other systems. | ||
82 | |||
83 | ### Opening a pull request | ||
84 | |||
85 | - Head over to your fork's GitHub page. | ||
86 | - Click on the `Contribute` button and `Open Pull Request`. | ||
87 | - Fill out the pull request template. | ||
88 | - If any changes are requested, you can add new commits to your fork and they will be automatically added to the pull request. | ||
89 | |||
90 | ### Continuous integration | ||
91 | |||
92 | For each push and/or pull request, GitHub Actions will try to build SDL and the test suite on most supported platforms. | ||
93 | |||
94 | Its behaviour can be influenced slightly by including SDL-specific tags in your commit message: | ||
95 | - `[sdl-ci-filter GLOB]` limits the platforms for which to run ci. | ||
96 | - `[sdl-ci-artifacts]` forces SDL artifacts, which can then be downloaded from the summary page. | ||
97 | - `[sdl-ci-trackmem-symbol-names]` makes sure the final report generated by `--trackmem` contains symbol names. | ||
98 | |||
99 | ## Contributing to the documentation | ||
100 | |||
101 | ### Editing a function documentation | ||
102 | |||
103 | The wiki documentation for API functions is synchronised from the headers' doxygen comments. As such, all modifications to syntax; function parameters; return value; version; related functions should be done in the header directly. | ||
104 | |||
105 | ### Editing the wiki | ||
106 | |||
107 | Other changes to the wiki should done directly from https://wiki.libsdl.org/ ... Just click the "edit" link at the bottom of any page! | ||
diff --git a/src/contrib/SDL-3.2.20/docs/README-documentation-rules.md b/src/contrib/SDL-3.2.20/docs/README-documentation-rules.md new file mode 100644 index 0000000..3151de7 --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-documentation-rules.md | |||
@@ -0,0 +1,410 @@ | |||
1 | # Rules for documentation | ||
2 | |||
3 | These are the rules for the care and feeding of wikiheaders.pl. | ||
4 | |||
5 | |||
6 | ## No style guide | ||
7 | |||
8 | When adding or editing documentation, we don't (currently) have a style guide | ||
9 | for what it should read like, so try to make it consistent with the rest of | ||
10 | the existing text. It generally should read more like technical reference | ||
11 | manuals and not sound conversational in tone. | ||
12 | |||
13 | Most of these rules are about how to make sure the documentation works on | ||
14 | a _technical_ level, as scripts need to parse it, and there are a few simple | ||
15 | rules we need to obey to cooperate with those scripts. | ||
16 | |||
17 | ## The wiki and headers share the same text. | ||
18 | |||
19 | There is a massive Perl script (`build-scripts/wikiheaders.pl`, hereafter | ||
20 | referred to as "wikiheaders") that can read both the wiki and the public | ||
21 | headers, and move changes in one across to the other. | ||
22 | |||
23 | If you prefer to use the wiki, go ahead and edit there. If you prefer to use | ||
24 | your own text editor, or command line tools to batch-process text, etc, you | ||
25 | can [clone the wiki as a git repo](https://github.com/libsdl-org/sdlwiki) and | ||
26 | work locally. | ||
27 | |||
28 | |||
29 | ## Don't taunt wikiheaders. | ||
30 | |||
31 | The script isn't magic; it's a massive pile of Regular Expressions and not | ||
32 | a full C or markdown parser. While it isn't _fragile_, if you try to do clever | ||
33 | things, you might confuse it. This is to the benefit of documentation, though, | ||
34 | where we would rather you not do surprising things. | ||
35 | |||
36 | |||
37 | ## We _sort of_ write in Doxygen format. | ||
38 | |||
39 | To document a symbol, we use something that looks like Doxygen (and Javadoc) | ||
40 | standard comment format: | ||
41 | |||
42 | ```c | ||
43 | /** | ||
44 | * This is a function that does something. | ||
45 | * | ||
46 | * It can be used for frozzling bobbles. Be aware that the Frozulator module | ||
47 | * _must_ be initialized before calling this. | ||
48 | * | ||
49 | * \param frozzlevel The amount of frozzling to perform. | ||
50 | * \param color What color bobble to frozzle. 0 is red, 1 is green. | ||
51 | * \returns the number of bobbles that were actually frozzled, -1 on error. | ||
52 | * | ||
53 | * \threadsafety Do not call this from two threads at once, or the bobbles | ||
54 | * won't all frozzle correctly! | ||
55 | * | ||
56 | * \since This function is available since SDL 7.3.1. | ||
57 | * | ||
58 | * \sa SDL_DoSomethingElse | ||
59 | */ | ||
60 | extern SDL_DECLSPEC int SDLCALL SDL_DoSomething(int frozzlevel, int color); | ||
61 | ``` | ||
62 | |||
63 | Note the `/**` at the start of the comment. That's a "Doxygen-style" comment, | ||
64 | and wikiheaders will treat this differently than a comment with one `*`, as | ||
65 | this signifies that this is not just a comment, but _documentation_. | ||
66 | |||
67 | These comments _must_ start in the first column of the line, or wikiheaders | ||
68 | will ignore them, even with the "/**" start (we should improve the script | ||
69 | someday to handle this, but currently this is a requirement). | ||
70 | |||
71 | We do _not_ parse every magic Doxygen tag, and we don't parse them in `@param` | ||
72 | format. The goal here was to mostly coexist with people that might want | ||
73 | to run Doxygen on the SDL headers, not to build Doxygen from scratch. That | ||
74 | being said, compatibility with Doxygen is not a hard requirement here. | ||
75 | |||
76 | wikiheaders uses these specific tags to turn this comment into a (hopefully) | ||
77 | well-formatted wiki page, and also can generate manpages and books in LaTeX | ||
78 | format from it! | ||
79 | |||
80 | Text markup in the headers is _always_ done in Markdown format! But less is | ||
81 | more: try not to markup text more than necessary. | ||
82 | |||
83 | |||
84 | ## Doxygen tags we support: | ||
85 | |||
86 | - `\brief one-line description` (Not required, and wikiheaders will remove tag). | ||
87 | - `\param varname description` (One for each function/macro parameter) | ||
88 | - `\returns description` (One for each function, don't use on `void` returns). | ||
89 | - `\sa` (each of these get tucked into a "See Also" section on the wiki) | ||
90 | - `\since This function is available since SDL 3.0.0.` (one per Doxygen comment) | ||
91 | - `\threadsafety description` (one per function/macro). | ||
92 | - `\deprecated description` (one per symbol, if symbol is deprecated!) | ||
93 | |||
94 | Other Doxygen things might exist in the headers, but they aren't understood | ||
95 | by wikiheaders. | ||
96 | |||
97 | |||
98 | ## Use Markdown. | ||
99 | |||
100 | The wiki also supports MediaWiki format, but we are transitioning away from it. | ||
101 | The headers always use Markdown. If you're editing the wiki from a git clone, | ||
102 | just make .md files and the wiki will know what to do with them. | ||
103 | |||
104 | |||
105 | ## Most things in the headers can be documented. | ||
106 | |||
107 | wikiheaders understands functions, typedefs, structs/unions/enums, `#defines` | ||
108 | ... basically most of what makes up a C header. Just slap a Doxygen-style | ||
109 | comment in front of most things and it'll work. | ||
110 | |||
111 | |||
112 | ## Defines right below typedefs and functions bind. | ||
113 | |||
114 | Any `#define` directly below a function or non-struct/union/enum typedef is | ||
115 | considered part of that declaration. This happens to work well with how our | ||
116 | headers work, as these defines tend to be bitflags and such that are related | ||
117 | to that symbol. | ||
118 | |||
119 | wikiheaders will include those defines in the syntax section of the wiki | ||
120 | page, and generate stub pages for each define that simply says "please refer | ||
121 | to (The Actual Symbol You Care About)" with a link. It will also pull in | ||
122 | any blank lines and most preprocessor directives for the syntax text, too. | ||
123 | |||
124 | Sometimes an unrelated define, by itself, just happens to be right below one | ||
125 | of these symbols in the header. The easiest way to deal with this is either | ||
126 | to document that define with a Doxygen-style comment, if it makes sense to do | ||
127 | so, or just add a normal C comment right above it if not, so wikiheaders | ||
128 | doesn't bind it to the previous symbol. | ||
129 | |||
130 | |||
131 | ## Don't document the `SDL_test*.h` headers. | ||
132 | |||
133 | These are in the public headers but they aren't really considered public APIs. | ||
134 | They live in a separate library that doesn't, or at least probably shouldn't, | ||
135 | ship to end users. As such, we don't want it documented on the wiki. | ||
136 | |||
137 | For now, we do this by not having any Doxygen-style comments in these files. | ||
138 | Please keep it that way! If you want to document these headers, just don't | ||
139 | use the magic two-`*` comment. | ||
140 | |||
141 | |||
142 | ## The first line is the summary. | ||
143 | |||
144 | The first line of a piece of documentation is meant to be a succinct | ||
145 | description. This is what Doxygen would call the `\brief` tag. wikiheaders | ||
146 | will split this text out until the first period (end of sentence!), and when | ||
147 | word wrapping, shuffle the overflow into a new paragraph below it. | ||
148 | |||
149 | |||
150 | ## Split paragraphs with a blank line. | ||
151 | |||
152 | And don't indent them at all (indenting in Markdown is treated as preformatted | ||
153 | text). | ||
154 | |||
155 | wikiheaders will wordwrap header comments so they fit in 80 columns, so if you | ||
156 | don't leave a blank line between paragraphs, they will smush into a single | ||
157 | block of text when wordwrapping. | ||
158 | |||
159 | |||
160 | ## Don't worry about word wrapping. | ||
161 | |||
162 | If you don't word-wrap your header edits perfectly (and you won't, I promise), | ||
163 | wikiheaders will send your change to the wiki, and then to make things match, | ||
164 | send it right back to the headers with correct word wrapping. Since this | ||
165 | happens right after you push your changes, you might as well just write | ||
166 | however you like and assume the system will clean it up for you. | ||
167 | |||
168 | |||
169 | ## Things that start with `SDL_` will automatically become wiki links. | ||
170 | |||
171 | wikiheaders knows to turn these into links to other pages, so if you reference | ||
172 | an SDL symbol in the header documentation, you don't need to link to it. | ||
173 | You can optionally wrap the symbol in backticks, and wikiheaders will know to | ||
174 | link the backticked thing. It will not generate links in three-backtick | ||
175 | code/preformatted blocks. | ||
176 | |||
177 | |||
178 | ## URLs will automatically become links. | ||
179 | |||
180 | You can use Markdown's `[link markup format](https://example.com/)`, but | ||
181 | sometimes it's clearer to list bare URLs; the URL will be visible on the | ||
182 | wiki page, but also clickable to follow the link. This is up to your judgment | ||
183 | on a case-by-case basis. | ||
184 | |||
185 | |||
186 | ## Hide stuff from wikiheaders. | ||
187 | |||
188 | If all else fails, you can block off pieces of the header with this | ||
189 | magic line (whitespace is ignored): | ||
190 | |||
191 | ```c | ||
192 | #ifndef SDL_WIKI_DOCUMENTATION_SECTION | ||
193 | ``` | ||
194 | |||
195 | Everything between this line and the next `#endif` will just be skipped by | ||
196 | wikiheaders. Note that wikiheaders is not a C preprocessor! Don't try to | ||
197 | nest conditionals or use `!defined`. | ||
198 | |||
199 | Just block off sections if you need to. And: you almost never need to. | ||
200 | |||
201 | |||
202 | ## Hide stuff from the compiler. | ||
203 | |||
204 | If you need to put something that's only of interest to wikiheaders, the | ||
205 | convention is to put it in a block like this: | ||
206 | |||
207 | ```c | ||
208 | #ifdef SDL_WIKI_DOCUMENTATION_SECTION | ||
209 | ``` | ||
210 | |||
211 | Generally this is used when there's a collection of preprocessor conditionals | ||
212 | to define the same symbol differently in different circumstances. You put | ||
213 | that symbol in this block with some reasonable generic version _and the | ||
214 | Doxygen-style comment_. Because wikiheaders doesn't care about this | ||
215 | preprocessor magic, and the C compiler can be as fancy as it wants, this is | ||
216 | strictly a useful convention. | ||
217 | |||
218 | |||
219 | ## Struct/union/enum typedefs must have the name on the first line. | ||
220 | |||
221 | This is because wikiheaders is not a full C parser. Don't write this: | ||
222 | |||
223 | ```c | ||
224 | typedef struct | ||
225 | { | ||
226 | int a; | ||
227 | int b; | ||
228 | } SDL_MyStruct; | ||
229 | ``` | ||
230 | |||
231 | ...make sure the name is at the start, too: | ||
232 | |||
233 | ```c | ||
234 | typedef struct SDL_MyStruct | ||
235 | { | ||
236 | int a; | ||
237 | int b; | ||
238 | } SDL_MyStruct; | ||
239 | ``` | ||
240 | |||
241 | wikiheaders will complain loudly if you don't do this, and exit with an | ||
242 | error message. | ||
243 | |||
244 | |||
245 | ## Don't repeat type names in `\param` and `\returns` sections. | ||
246 | |||
247 | Wikiheaders will explicitly mention the datatype for each parameter and the | ||
248 | return value, linking to the datatype's wikipage. Users reading the headers | ||
249 | can see the types in the function signature right below the documentation | ||
250 | comment. So don't mention the type a second time in the documentation if | ||
251 | possible. It looks cluttered and repetitive to do so. | ||
252 | |||
253 | |||
254 | ## Code examples go in the wiki. | ||
255 | |||
256 | We don't want the headers cluttered up with code examples. These live on the | ||
257 | wiki pages, and wikiheaders knows to not bridge them back to the headers. | ||
258 | |||
259 | Put them in a `## Code Examples` section, and make sure to wrap them in a | ||
260 | three-backtick-c section for formatting purposes. Only write code in C, | ||
261 | please. | ||
262 | |||
263 | |||
264 | ## Do you _need_ a code example? | ||
265 | |||
266 | Most code examples aren't actually useful. If your code example is just | ||
267 | `SDL_CreateWindow("Hello SDL", 640, 480, 0);` then just delete it; if all | ||
268 | you're showing is how to call a function in C, it's not a useful code example. | ||
269 | Not all functions need an example. One with complex setup or usage details | ||
270 | might, though! | ||
271 | |||
272 | |||
273 | ## Code examples are compiled by GitHub Actions. | ||
274 | |||
275 | On each change to the wiki, there is a script that pulls out all the code | ||
276 | examples into discrete C files and attempts to compile them, and complains | ||
277 | if they don't work. | ||
278 | |||
279 | |||
280 | ## Unrecognized sections are left alone in the wiki. | ||
281 | |||
282 | A wiki section that starts with `## Section Name` (or `== Section Name ==` in | ||
283 | MediaWiki format) that isn't one of the recognized names will be left alone | ||
284 | by wikiheaders. Recognized sections might get overwritten with new content | ||
285 | from the headers, but the wiki file will not have other sections cleaned out | ||
286 | (this is how Code Examples remain wiki only, for example). You can use this | ||
287 | to add Wiki-specific text, or stuff that doesn't make sense in a header, or | ||
288 | would merely clutter it up. | ||
289 | |||
290 | A possibly-incomplete list of sections that will be overwritten by changes | ||
291 | to the headers: | ||
292 | |||
293 | - The page title line, and the "brief" one-sentence description section. | ||
294 | - "Deprecated" | ||
295 | - "Header File" | ||
296 | - "Syntax" | ||
297 | - "Function Parameters" | ||
298 | - "Macro Parameters" | ||
299 | - "Fields" | ||
300 | - "Values" | ||
301 | - "Return Value" | ||
302 | - "Remarks" | ||
303 | - "Thread Safety" | ||
304 | - "Version" | ||
305 | - "See Also" | ||
306 | |||
307 | |||
308 | ## It's okay to repeat yourself. | ||
309 | |||
310 | Each individual piece of documentation becomes a separate page on the wiki, so | ||
311 | small repeated details can just exist in different pieces of documentation. If | ||
312 | it's complicated, it's not unreasonable to say "Please refer to | ||
313 | SDL_SomeOtherFunction for more details" ... wiki users can click right | ||
314 | through, header users can search for the function name. | ||
315 | |||
316 | |||
317 | ## The docs directory is bridged to the wiki, too. | ||
318 | |||
319 | You might be reading this document on the wiki! Any `README-*.md` files in | ||
320 | the docs directory are bridged to the wiki, so `docs/README-linux.md` lands | ||
321 | at https://wiki.libsdl.org/SDL3/README/linux ...these are just copied directly | ||
322 | without any further processing by wikiheaders, and changes go in both | ||
323 | directions. | ||
324 | |||
325 | |||
326 | ## The wiki can have its own pages, too. | ||
327 | |||
328 | If a page name isn't a symbol that wikiheaders sees in the headers, or a | ||
329 | README in the source's `docs` directory, or a few other exceptions, it'll | ||
330 | assume it's an unrelated wiki page and leave it alone. So feel free to | ||
331 | write any wiki-only pages that make sense and not worry about it junking | ||
332 | up the headers! | ||
333 | |||
334 | |||
335 | ## Wiki categories are (mostly) managed automatically. | ||
336 | |||
337 | The wiki will see this pattern as the last thing on a page and treat it as a | ||
338 | list of categories that page belongs to: | ||
339 | |||
340 | ``` | ||
341 | ---- | ||
342 | [CategoryStuff](CategoryStuff), [CategoryWhatever](CategoryWhatever) | ||
343 | ``` | ||
344 | |||
345 | You can use this to simply tag a page as part of a category, and the user can | ||
346 | click directly to see other pages in that category. The wiki will | ||
347 | automatically manage a `Category*` pages that list any tagged pages. | ||
348 | |||
349 | You _should not_ add tags to the public headers. They don't mean anything | ||
350 | there. wikiheaders will add a few tags that make sense when generating wiki | ||
351 | content from the header files, and it will preserve other tags already present | ||
352 | on the page, so if you want to add extra categories to something, tag it on | ||
353 | the wiki itself. | ||
354 | |||
355 | The wiki uses some magic HTML comment tags to decide how to list items on | ||
356 | Category pages and let other content live on the page as well. You can | ||
357 | see an example of this in action at: | ||
358 | |||
359 | https://raw.githubusercontent.com/libsdl-org/sdlwiki/main/SDL3/CategoryEvents.md | ||
360 | |||
361 | |||
362 | ## Categorizing the headers. | ||
363 | |||
364 | To put a symbol in a specific category, we use three approaches in SDL: | ||
365 | |||
366 | - Things in the `SDL_test*.h` headers aren't categorized at all (and you | ||
367 | shouldn't document them!) | ||
368 | - Most files are categorized by header name: we strip off the leading `SDL_` | ||
369 | and capitalize the first letter of what's left. So everything in SDL_audio.h | ||
370 | is in the "Audio" category, everything in SDL_video.h is in the "Video" | ||
371 | category, etc. | ||
372 | - If wikiheaders sees a comment like this on a line by itself... | ||
373 | ```c | ||
374 | /* WIKI CATEGORY: Blah */ | ||
375 | ``` | ||
376 | ...then all symbols below that will land in the "Blah" category. We use this | ||
377 | at the top of a few headers where the simple | ||
378 | chop-off-SDL_-and-captialize-the-first-letter trick doesn't work well, but | ||
379 | one could theoretically use this for headers that have some overlap in | ||
380 | category. | ||
381 | |||
382 | |||
383 | ## Category documentation lives in headers. | ||
384 | |||
385 | To document a category (text that lives before the item lists on a wiki | ||
386 | category page), you have to follow a simple rule: | ||
387 | |||
388 | The _first_ Doxygen-style comment in a header must start with: | ||
389 | |||
390 | ``` | ||
391 | /** | ||
392 | * # CategoryABC | ||
393 | ``` | ||
394 | |||
395 | If these conditions aren't met, wikiheaders will assume that documentation | ||
396 | belongs to whatever is below it instead of the Category. | ||
397 | |||
398 | The text of this comment will be added to the appropriate wiki Category page, | ||
399 | at the top, replacing everything in the file until it sees a line that starts | ||
400 | with an HTML comment (`<!--`), or a line that starts with `----`. Everything | ||
401 | after that in the wiki file will be preserved. | ||
402 | |||
403 | Likewise, when bridging _back_ to the headers, if wikiheaders sees one of | ||
404 | these comments, it'll copy the top section of the Category page back into the | ||
405 | comment. | ||
406 | |||
407 | Beyond stripping the initial ` * ` portion off each line, these comments are | ||
408 | treated as pure Markdown. They don't support any Doxygen tags like `\sa` or | ||
409 | `\since`. | ||
410 | |||
diff --git a/src/contrib/SDL-3.2.20/docs/README-dynapi.md b/src/contrib/SDL-3.2.20/docs/README-dynapi.md new file mode 100644 index 0000000..9c137db --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-dynapi.md | |||
@@ -0,0 +1,138 @@ | |||
1 | # Dynamic API | ||
2 | |||
3 | Originally posted on Ryan's Google+ account. | ||
4 | |||
5 | Background: | ||
6 | |||
7 | - The Steam Runtime has (at least in theory) a really kick-ass build of SDL, | ||
8 | but developers are shipping their own SDL with individual Steam games. | ||
9 | These games might stop getting updates, but a newer SDL might be needed later. | ||
10 | Certainly we'll always be fixing bugs in SDL, even if a new video target isn't | ||
11 | ever needed, and these fixes won't make it to a game shipping its own SDL. | ||
12 | - Even if we replace the SDL in those games with a compatible one, that is to | ||
13 | say, edit a developer's Steam depot (yuck!), there are developers that are | ||
14 | statically linking SDL that we can't do this for. We can't even force the | ||
15 | dynamic loader to ignore their SDL in this case, of course. | ||
16 | - If you don't ship an SDL with the game in some form, people that disabled the | ||
17 | Steam Runtime, or just tried to run the game from the command line instead of | ||
18 | Steam might find themselves unable to run the game, due to a missing dependency. | ||
19 | - If you want to ship on non-Steam platforms like GOG or Humble Bundle, or target | ||
20 | generic Linux boxes that may or may not have SDL installed, you have to ship | ||
21 | the library or risk a total failure to launch. So now, you might have to have | ||
22 | a non-Steam build plus a Steam build (that is, one with and one without SDL | ||
23 | included), which is inconvenient if you could have had one universal build | ||
24 | that works everywhere. | ||
25 | - We like the zlib license, but the biggest complaint from the open source | ||
26 | community about the license change is the static linking. The LGPL forced this | ||
27 | as a legal, not technical issue, but zlib doesn't care. Even those that aren't | ||
28 | concerned about the GNU freedoms found themselves solving the same problems: | ||
29 | swapping in a newer SDL to an older game often times can save the day. | ||
30 | Static linking stops this dead. | ||
31 | |||
32 | So here's what we did: | ||
33 | |||
34 | SDL now has, internally, a table of function pointers. So, this is what SDL_Init | ||
35 | now looks like: | ||
36 | |||
37 | ```c | ||
38 | bool SDL_Init(SDL_InitFlags flags) | ||
39 | { | ||
40 | return jump_table.SDL_Init(flags); | ||
41 | } | ||
42 | ``` | ||
43 | |||
44 | Except that is all done with a bunch of macro magic so we don't have to maintain | ||
45 | every one of these. | ||
46 | |||
47 | What is jump_table.SDL_init()? Eventually, that's a function pointer of the real | ||
48 | SDL_Init() that you've been calling all this time. But at startup, it looks more | ||
49 | like this: | ||
50 | |||
51 | ```c | ||
52 | bool SDL_Init_DEFAULT(SDL_InitFlags flags) | ||
53 | { | ||
54 | SDL_InitDynamicAPI(); | ||
55 | return jump_table.SDL_Init(flags); | ||
56 | } | ||
57 | ``` | ||
58 | |||
59 | SDL_InitDynamicAPI() fills in jump_table with all the actual SDL function | ||
60 | pointers, which means that this `_DEFAULT` function never gets called again. | ||
61 | First call to any SDL function sets the whole thing up. | ||
62 | |||
63 | So you might be asking, what was the value in that? Isn't this what the operating | ||
64 | system's dynamic loader was supposed to do for us? Yes, but now we've got this | ||
65 | level of indirection, we can do things like this: | ||
66 | |||
67 | ```bash | ||
68 | export SDL3_DYNAMIC_API=/my/actual/libSDL3.so.0 | ||
69 | ./MyGameThatIsStaticallyLinkedToSDL | ||
70 | ``` | ||
71 | |||
72 | And now, this game that is statically linked to SDL, can still be overridden | ||
73 | with a newer, or better, SDL. The statically linked one will only be used as | ||
74 | far as calling into the jump table in this case. But in cases where no override | ||
75 | is desired, the statically linked version will provide its own jump table, | ||
76 | and everyone is happy. | ||
77 | |||
78 | So now: | ||
79 | - Developers can statically link SDL, and users can still replace it. | ||
80 | (We'd still rather you ship a shared library, though!) | ||
81 | - Developers can ship an SDL with their game, Valve can override it for, say, | ||
82 | new features on SteamOS, or distros can override it for their own needs, | ||
83 | but it'll also just work in the default case. | ||
84 | - Developers can ship the same package to everyone (Humble Bundle, GOG, etc), | ||
85 | and it'll do the right thing. | ||
86 | - End users (and Valve) can update a game's SDL in almost any case, | ||
87 | to keep abandoned games running on newer platforms. | ||
88 | - Everyone develops with SDL exactly as they have been doing all along. | ||
89 | Same headers, same ABI. Just get the latest version to enable this magic. | ||
90 | |||
91 | |||
92 | A little more about SDL_InitDynamicAPI(): | ||
93 | |||
94 | Internally, InitAPI does some locking to make sure everything waits until a | ||
95 | single thread initializes everything (although even SDL_CreateThread() goes | ||
96 | through here before spinning a thread, too), and then decides if it should use | ||
97 | an external SDL library. If not, it sets up the jump table using the current | ||
98 | SDL's function pointers (which might be statically linked into a program, or in | ||
99 | a shared library of its own). If so, it loads that library and looks for and | ||
100 | calls a single function: | ||
101 | |||
102 | ```c | ||
103 | Sint32 SDL_DYNAPI_entry(Uint32 version, void *table, Uint32 tablesize); | ||
104 | ``` | ||
105 | |||
106 | That function takes a version number (more on that in a moment), the address of | ||
107 | the jump table, and the size, in bytes, of the table. | ||
108 | Now, we've got policy here: this table's layout never changes; new stuff gets | ||
109 | added to the end. Therefore SDL_DYNAPI_entry() knows that it can provide all | ||
110 | the needed functions if tablesize <= sizeof its own jump table. If tablesize is | ||
111 | bigger (say, SDL 3.0.4 is trying to load SDL 3.0.3), then we know to abort, but | ||
112 | if it's smaller, we know we can provide the entire API that the caller needs. | ||
113 | |||
114 | The version variable is a failsafe switch. | ||
115 | Right now it's always 1. This number changes when there are major API changes | ||
116 | (so we know if the tablesize might be smaller, or entries in it have changed). | ||
117 | Right now SDL_DYNAPI_entry gives up if the version doesn't match, but it's not | ||
118 | inconceivable to have a small dispatch library that only supplies this one | ||
119 | function and loads different, otherwise-incompatible SDL libraries and has the | ||
120 | right one initialize the jump table based on the version. For something that | ||
121 | must generically catch lots of different versions of SDL over time, like the | ||
122 | Steam Client, this isn't a bad option. | ||
123 | |||
124 | Finally, I'm sure some people are reading this and thinking, | ||
125 | "I don't want that overhead in my project!" | ||
126 | |||
127 | To which I would point out that the extra function call through the jump table | ||
128 | probably wouldn't even show up in a profile, but lucky you: this can all be | ||
129 | disabled. You can build SDL without this if you absolutely must, but we would | ||
130 | encourage you not to do that. However, on heavily locked down platforms like | ||
131 | iOS, or maybe when debugging, it makes sense to disable it. The way this is | ||
132 | designed in SDL, you just have to change one #define, and the entire system | ||
133 | vaporizes out, and SDL functions exactly like it always did. Most of it is | ||
134 | macro magic, so the system is contained to one C file and a few headers. | ||
135 | However, this is on by default and you have to edit a header file to turn it | ||
136 | off. Our hopes is that if we make it easy to disable, but not too easy, | ||
137 | everyone will ultimately be able to get what they want, but we've gently | ||
138 | nudged everyone towards what we think is the best solution. | ||
diff --git a/src/contrib/SDL-3.2.20/docs/README-emscripten.md b/src/contrib/SDL-3.2.20/docs/README-emscripten.md new file mode 100644 index 0000000..2b81468 --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-emscripten.md | |||
@@ -0,0 +1,350 @@ | |||
1 | # Emscripten | ||
2 | |||
3 | ## The state of things | ||
4 | |||
5 | (As of October 2024, but things move quickly and we don't update this | ||
6 | document often.) | ||
7 | |||
8 | In modern times, all the browsers you probably care about (Chrome, Firefox, | ||
9 | Edge, and Safari, on Windows, macOS, Linux, iOS and Android), support some | ||
10 | reasonable base configurations: | ||
11 | |||
12 | - WebAssembly (don't bother with asm.js any more) | ||
13 | - WebGL (which will look like OpenGL ES 2 or 3 to your app). | ||
14 | - Threads (see caveats, though!) | ||
15 | - Game controllers | ||
16 | - Autoupdating (so you can assume they have a recent version of the browser) | ||
17 | |||
18 | All this to say we're at the point where you don't have to make a lot of | ||
19 | concessions to get even a fairly complex SDL-based game up and running. | ||
20 | |||
21 | |||
22 | ## RTFM | ||
23 | |||
24 | This document is a quick rundown of some high-level details. The | ||
25 | documentation at [emscripten.org](https://emscripten.org/) is vast | ||
26 | and extremely detailed for a wide variety of topics, and you should at | ||
27 | least skim through it at some point. | ||
28 | |||
29 | |||
30 | ## Porting your app to Emscripten | ||
31 | |||
32 | Many many things just need some simple adjustments and they'll compile | ||
33 | like any other C/C++ code, as long as SDL was handling the platform-specific | ||
34 | work for your program. | ||
35 | |||
36 | First: assembly language code has to go. Replace it with C. You can even use | ||
37 | [x86 SIMD intrinsic functions in Emscripten](https://emscripten.org/docs/porting/simd.html)! | ||
38 | |||
39 | Second: Middleware has to go. If you have a third-party library you link | ||
40 | against, you either need an Emscripten port of it, or the source code to it | ||
41 | to compile yourself, or you need to remove it. | ||
42 | |||
43 | Third: If your program starts in a function called main(), you need to get | ||
44 | out of it and into a function that gets called repeatedly, and returns quickly, | ||
45 | called a mainloop. | ||
46 | |||
47 | Somewhere in your program, you probably have something that looks like a more | ||
48 | complicated version of this: | ||
49 | |||
50 | ```c | ||
51 | void main(void) | ||
52 | { | ||
53 | initialize_the_game(); | ||
54 | while (game_is_still_running) { | ||
55 | check_for_new_input(); | ||
56 | think_about_stuff(); | ||
57 | draw_the_next_frame(); | ||
58 | } | ||
59 | deinitialize_the_game(); | ||
60 | } | ||
61 | ``` | ||
62 | |||
63 | This will not work on Emscripten, because the main thread needs to be free | ||
64 | to do stuff and can't sit in this loop forever. So Emscripten lets you set up | ||
65 | a [mainloop](https://emscripten.org/docs/porting/emscripten-runtime-environment.html#browser-main-loop). | ||
66 | |||
67 | ```c | ||
68 | static void mainloop(void) /* this will run often, possibly at the monitor's refresh rate */ | ||
69 | { | ||
70 | if (!game_is_still_running) { | ||
71 | deinitialize_the_game(); | ||
72 | #ifdef __EMSCRIPTEN__ | ||
73 | emscripten_cancel_main_loop(); /* this should "kill" the app. */ | ||
74 | #else | ||
75 | exit(0); | ||
76 | #endif | ||
77 | } | ||
78 | |||
79 | check_for_new_input(); | ||
80 | think_about_stuff(); | ||
81 | draw_the_next_frame(); | ||
82 | } | ||
83 | |||
84 | void main(void) | ||
85 | { | ||
86 | initialize_the_game(); | ||
87 | #ifdef __EMSCRIPTEN__ | ||
88 | emscripten_set_main_loop(mainloop, 0, 1); | ||
89 | #else | ||
90 | while (1) { mainloop(); } | ||
91 | #endif | ||
92 | } | ||
93 | ``` | ||
94 | |||
95 | Basically, `emscripten_set_main_loop(mainloop, 0, 1);` says "run | ||
96 | `mainloop` over and over until I end the program." The function will | ||
97 | run, and return, freeing the main thread for other tasks, and then | ||
98 | run again when it's time. The `1` parameter does some magic to make | ||
99 | your main() function end immediately; this is useful because you | ||
100 | don't want any shutdown code that might be sitting below this code | ||
101 | to actually run if main() were to continue on, since we're just | ||
102 | getting started. | ||
103 | |||
104 | Another option is to use SDL' main callbacks, which handle this for you | ||
105 | without platform-specific code in your app. Please refer to | ||
106 | [the wiki](https://wiki.libsdl.org/SDL3/README/main-functions#main-callbacks-in-sdl3) | ||
107 | or `docs/README-main-functions.md` in the SDL source code. | ||
108 | |||
109 | |||
110 | |||
111 | There's a lot of little details that are beyond the scope of this | ||
112 | document, but that's the biggest initial set of hurdles to porting | ||
113 | your app to the web. | ||
114 | |||
115 | |||
116 | ## Do you need threads? | ||
117 | |||
118 | If you plan to use threads, they work on all major browsers now. HOWEVER, | ||
119 | they bring with them a lot of careful considerations. Rendering _must_ | ||
120 | be done on the main thread. This is a general guideline for many | ||
121 | platforms, but a hard requirement on the web. | ||
122 | |||
123 | Many other things also must happen on the main thread; often times SDL | ||
124 | and Emscripten make efforts to "proxy" work to the main thread that | ||
125 | must be there, but you have to be careful (and read more detailed | ||
126 | documentation than this for the finer points). | ||
127 | |||
128 | Even when using threads, your main thread needs to set an Emscripten | ||
129 | mainloop (or use SDL's main callbacks) that runs quickly and returns, or | ||
130 | things will fail to work correctly. | ||
131 | |||
132 | You should definitely read [Emscripten's pthreads docs](https://emscripten.org/docs/porting/pthreads.html) | ||
133 | for all the finer points. Mostly SDL's thread API will work as expected, | ||
134 | but is built on pthreads, so it shares the same little incompatibilities | ||
135 | that are documented there, such as where you can use a mutex, and when | ||
136 | a thread will start running, etc. | ||
137 | |||
138 | |||
139 | IMPORTANT: You have to decide to either build something that uses | ||
140 | threads or something that doesn't; you can't have one build | ||
141 | that works everywhere. This is an Emscripten (or maybe WebAssembly? | ||
142 | Or just web browsers in general?) limitation. If you aren't using | ||
143 | threads, it's easier to not enable them at all, at build time. | ||
144 | |||
145 | If you use threads, you _have to_ run from a web server that has | ||
146 | [COOP/COEP headers set correctly](https://web.dev/why-coop-coep/) | ||
147 | or your program will fail to start at all. | ||
148 | |||
149 | If building with threads, `__EMSCRIPTEN_PTHREADS__` will be defined | ||
150 | for checking with the C preprocessor, so you can build something | ||
151 | different depending on what sort of build you're compiling. | ||
152 | |||
153 | |||
154 | ## Audio | ||
155 | |||
156 | Audio works as expected at the API level, but not exactly like other | ||
157 | platforms. | ||
158 | |||
159 | You'll only see a single default audio device. Audio recording also works; | ||
160 | if the browser pops up a prompt to ask for permission to access the | ||
161 | microphone, the SDL_OpenAudioDevice call will succeed and start producing | ||
162 | silence at a regular interval. Once the user approves the request, real | ||
163 | audio data will flow. If the user denies it, the app is not informed and | ||
164 | will just continue to receive silence. | ||
165 | |||
166 | Modern web browsers will not permit web pages to produce sound before the | ||
167 | user has interacted with them (clicked or tapped on them, usually); this is | ||
168 | for several reasons, not the least of which being that no one likes when a | ||
169 | random browser tab suddenly starts making noise and the user has to scramble | ||
170 | to figure out which and silence it. | ||
171 | |||
172 | SDL will allow you to open the audio device for playback in this | ||
173 | circumstance, and your audio callback will fire, but SDL will throw the audio | ||
174 | data away until the user interacts with the page. This helps apps that depend | ||
175 | on the audio callback to make progress, and also keeps audio playback in sync | ||
176 | once the app is finally allowed to make noise. | ||
177 | |||
178 | There are two reasonable ways to deal with the silence at the app level: | ||
179 | if you are writing some sort of media player thing, where the user expects | ||
180 | there to be a volume control when you mouseover the canvas, just default | ||
181 | that control to a muted state; if the user clicks on the control to unmute | ||
182 | it, on this first click, open the audio device. This allows the media to | ||
183 | play at start, and the user can reasonably opt-in to listening. | ||
184 | |||
185 | Many games do not have this sort of UI, and are more rigid about starting | ||
186 | audio along with everything else at the start of the process. For these, your | ||
187 | best bet is to write a little Javascript that puts up a "Click here to play!" | ||
188 | UI, and upon the user clicking, remove that UI and then call the Emscripten | ||
189 | app's main() function. As far as the application knows, the audio device was | ||
190 | available to be opened as soon as the program started, and since this magic | ||
191 | happens in a little Javascript, you don't have to change your C/C++ code at | ||
192 | all to make it happen. | ||
193 | |||
194 | Please see the discussion at https://github.com/libsdl-org/SDL/issues/6385 | ||
195 | for some Javascript code to steal for this approach. | ||
196 | |||
197 | |||
198 | ## Rendering | ||
199 | |||
200 | If you use SDL's 2D render API, it will use GLES2 internally, which | ||
201 | Emscripten will turn into WebGL calls. You can also use OpenGL ES 2 | ||
202 | directly by creating a GL context and drawing into it. | ||
203 | |||
204 | If the browser (and hardware) support WebGL 2, you can create an OpenGL ES 3 | ||
205 | context. | ||
206 | |||
207 | Calling SDL_RenderPresent (or SDL_GL_SwapWindow) will not actually | ||
208 | present anything on the screen until your return from your mainloop | ||
209 | function. | ||
210 | |||
211 | |||
212 | ## Building SDL/emscripten | ||
213 | |||
214 | |||
215 | SDL currently requires at least Emscripten 3.16.0 to build. Newer versions | ||
216 | are likely to work, as well. | ||
217 | |||
218 | |||
219 | Build: | ||
220 | |||
221 | This works on Linux/Unix and macOS. Please send comments about Windows. | ||
222 | |||
223 | Make sure you've [installed emsdk](https://emscripten.org/docs/getting_started/downloads.html) | ||
224 | first, and run `source emsdk_env.sh` at the command line so it finds the | ||
225 | tools. | ||
226 | |||
227 | (These cmake options might be overkill, but this has worked for me.) | ||
228 | |||
229 | ```bash | ||
230 | mkdir build | ||
231 | cd build | ||
232 | emcmake cmake .. | ||
233 | # you can also do `emcmake cmake -G Ninja ..` and then use `ninja` instead of this command. | ||
234 | emmake make -j4 | ||
235 | ``` | ||
236 | |||
237 | If you want to build with thread support, something like this works: | ||
238 | |||
239 | ```bash | ||
240 | mkdir build | ||
241 | cd build | ||
242 | emcmake cmake -DSDL_THREADS=ON .. | ||
243 | # you can also do `emcmake cmake -G Ninja ..` and then use `ninja` instead of this command. | ||
244 | emmake make -j4 | ||
245 | ``` | ||
246 | |||
247 | To build the tests, add `-DSDL_TESTS=ON` to the `emcmake cmake` command line. | ||
248 | To build the examples, add `-DSDL_EXAMPLES=ON` to the `emcmake cmake` command line. | ||
249 | |||
250 | |||
251 | ## Building your app | ||
252 | |||
253 | You need to compile with `emcc` instead of `gcc` or `clang` or whatever, but | ||
254 | mostly it uses the same command line arguments as Clang. | ||
255 | |||
256 | Link against the libSDL3.a file you generated by building SDL. | ||
257 | |||
258 | Usually you would produce a binary like this: | ||
259 | |||
260 | ```bash | ||
261 | gcc -o mygame mygame.c # or whatever | ||
262 | ``` | ||
263 | |||
264 | But for Emscripten, you want to output something else: | ||
265 | |||
266 | ```bash | ||
267 | emcc -o index.html mygame.c | ||
268 | ``` | ||
269 | |||
270 | This will produce several files...support Javascript and WebAssembly (.wasm) | ||
271 | files. The `-o index.html` will produce a simple HTML page that loads and | ||
272 | runs your app. You will (probably) eventually want to replace or customize | ||
273 | that file and do `-o index.js` instead to just build the code pieces. | ||
274 | |||
275 | If you're working on a program of any serious size, you'll likely need to | ||
276 | link with `-s ALLOW_MEMORY_GROWTH=1 -s MAXIMUM_MEMORY=1gb` to get access | ||
277 | to more memory. If using pthreads, you'll need the `-s MAXIMUM_MEMORY=1gb` | ||
278 | or the app will fail to start on iOS browsers, but this might be a bug that | ||
279 | goes away in the future. | ||
280 | |||
281 | |||
282 | ## Data files | ||
283 | |||
284 | Your game probably has data files. Here's how to access them. | ||
285 | |||
286 | Filesystem access works like a Unix filesystem; you have a single directory | ||
287 | tree, possibly interpolated from several mounted locations, no drive letters, | ||
288 | '/' for a path separator. You can access them with standard file APIs like | ||
289 | open() or fopen() or SDL_IOStream. You can read or write from the filesystem. | ||
290 | |||
291 | By default, you probably have a "MEMFS" filesystem (all files are stored in | ||
292 | memory, but access to them is immediate and doesn't need to block). There are | ||
293 | other options, like "IDBFS" (files are stored in a local database, so they | ||
294 | don't need to be in RAM all the time and they can persist between runs of the | ||
295 | program, but access is not synchronous). You can mix and match these file | ||
296 | systems, mounting a MEMFS filesystem at one place and idbfs elsewhere, etc, | ||
297 | but that's beyond the scope of this document. Please refer to Emscripten's | ||
298 | [page on the topic](https://emscripten.org/docs/porting/files/file_systems_overview.html) | ||
299 | for more info. | ||
300 | |||
301 | The _easiest_ (but not the best) way to get at your data files is to embed | ||
302 | them in the app itself. Emscripten's linker has support for automating this. | ||
303 | |||
304 | ```bash | ||
305 | emcc -o index.html loopwave.c --embed-file ../test/sample.wav@/sounds/sample.wav | ||
306 | ``` | ||
307 | |||
308 | This will pack ../test/sample.wav in your app, and make it available at | ||
309 | "/sounds/sample.wav" at runtime. Emscripten makes sure this data is available | ||
310 | before your main() function runs, and since it's in MEMFS, you can just | ||
311 | read it like you do on other platforms. `--embed-file` can also accept a | ||
312 | directory to pack an entire tree, and you can specify the argument multiple | ||
313 | times to pack unrelated things into the final installation. | ||
314 | |||
315 | Note that this is absolutely the best approach if you have a few small | ||
316 | files to include and shouldn't worry about the issue further. However, if you | ||
317 | have hundreds of megabytes and/or thousands of files, this is not so great, | ||
318 | since the user will download it all every time they load your page, and it | ||
319 | all has to live in memory at runtime. | ||
320 | |||
321 | [Emscripten's documentation on the matter](https://emscripten.org/docs/porting/files/packaging_files.html) | ||
322 | gives other options and details, and is worth a read. | ||
323 | |||
324 | |||
325 | ## Debugging | ||
326 | |||
327 | Debugging web apps is a mixed bag. You should compile and link with | ||
328 | `-gsource-map`, which embeds a ton of source-level debugging information into | ||
329 | the build, and make sure _the app source code is available on the web server_, | ||
330 | which is often a scary proposition for various reasons. | ||
331 | |||
332 | When you debug from the browser's tools and hit a breakpoint, you can step | ||
333 | through the actual C/C++ source code, though, which can be nice. | ||
334 | |||
335 | If you try debugging in Firefox and it doesn't work well for no apparent | ||
336 | reason, try Chrome, and vice-versa. These tools are still relatively new, | ||
337 | and improving all the time. | ||
338 | |||
339 | SDL_Log() (or even plain old printf) will write to the Javascript console, | ||
340 | and honestly I find printf-style debugging to be easier than setting up a build | ||
341 | for proper debugging, so use whatever tools work best for you. | ||
342 | |||
343 | |||
344 | ## Questions? | ||
345 | |||
346 | Please give us feedback on this document at [the SDL bug tracker](https://github.com/libsdl-org/SDL/issues). | ||
347 | If something is wrong or unclear, we want to know! | ||
348 | |||
349 | |||
350 | |||
diff --git a/src/contrib/SDL-3.2.20/docs/README-gdk.md b/src/contrib/SDL-3.2.20/docs/README-gdk.md new file mode 100644 index 0000000..acba7bc --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-gdk.md | |||
@@ -0,0 +1,174 @@ | |||
1 | GDK | ||
2 | ===== | ||
3 | |||
4 | This port allows SDL applications to run via Microsoft's Game Development Kit (GDK). | ||
5 | |||
6 | Windows (GDK) and Xbox One/Xbox Series (GDKX) are both supported and all the required code is included in this public SDL release. However, only licensed Xbox developers have access to the GDKX libraries which will allow you to build the Xbox targets. | ||
7 | |||
8 | |||
9 | Requirements | ||
10 | ------------ | ||
11 | |||
12 | * Microsoft Visual Studio 2022 (in theory, it should also work in 2017 or 2019, but this has not been tested) | ||
13 | * Microsoft GDK October 2023 Update 1 or newer (public release [here](https://github.com/microsoft/GDK/releases/tag/October_2023_Update_1)) | ||
14 | * For Xbox, you will need the corresponding GDKX version (licensed developers only) | ||
15 | * To publish a package or successfully authenticate a user, you will need to create an app id/configure services in Partner Center. However, for local testing purposes (without authenticating on Xbox Live), the test identifiers used by the GDK test programs in the included solution work. | ||
16 | |||
17 | |||
18 | Windows GDK Status | ||
19 | ------ | ||
20 | |||
21 | The Windows GDK port supports the full set of Win32 APIs, renderers, controllers, input devices, etc., as the normal Windows x64 build of SDL. | ||
22 | |||
23 | * Additionally, the GDK port adds the following: | ||
24 | * Compile-time platform detection for SDL programs. The `SDL_PLATFORM_GDK` is `#define`d on every GDK platform, and the `SDL_PLATFORM_WINGDK` is `#define`d on Windows GDK, specifically. (This distinction exists because other GDK platforms support a smaller subset of functionality. This allows you to mark code for "any" GDK separate from Windows GDK.) | ||
25 | * GDK-specific setup: | ||
26 | * Initializing/uninitializing the game runtime, and initializing Xbox Live services | ||
27 | * Creating a global task queue and setting it as the default for the process. When running any async operations, passing in `NULL` as the task queue will make the task get added to the global task queue. | ||
28 | |||
29 | * An implementation on `WinMain` that performs the above GDK setup that you can use by #include'ing SDL_main.h in the source file that includes your standard main() function. If you are unable to do this, you can instead manually call `SDL_RunApp` from your entry point, passing in your `SDL_main` function and `NULL` as the parameters. To use `SDL_RunApp`, `#define SDL_MAIN_HANDLED` before `#include <SDL3/SDL_main.h>`. | ||
30 | * Global task queue callbacks are dispatched during `SDL_PumpEvents` (which is also called internally if using `SDL_PollEvent`). | ||
31 | * You can get the handle of the global task queue through `SDL_GetGDKTaskQueue`, if needed. When done with the queue, be sure to use `XTaskQueueCloseHandle` to decrement the reference count (otherwise it will cause a resource leak). | ||
32 | |||
33 | * Single-player games have some additional features available: | ||
34 | * Call `SDL_GetGDKDefaultUser` to get the default XUserHandle pointer. | ||
35 | * `SDL_GetPrefPath` still works, but only for single-player titles. | ||
36 | |||
37 | These functions mostly wrap around async APIs, and thus should be treated as synchronous alternatives. Also note that the single-player functions return on any OS errors, so be sure to validate the return values! | ||
38 | |||
39 | * What doesn't work: | ||
40 | * Compilation with anything other than through the included Visual C++ solution file | ||
41 | |||
42 | ## VisualC-GDK Solution | ||
43 | |||
44 | The included `VisualC-GDK/SDL.sln` solution includes the following targets for the Gaming.Desktop.x64 configuration: | ||
45 | |||
46 | * SDL3 (DLL) - This is the typical SDL3.dll, but for Gaming.Desktop.x64. | ||
47 | * tests/testgamecontroller - Standard SDL test program demonstrating controller functionality. | ||
48 | * tests/testgdk - GDK-specific test program that demonstrates using the global task queue to login a user into Xbox Live. | ||
49 | *NOTE*: As of the June 2022 GDK, you cannot test user logins without a valid Title ID and MSAAppId. You will need to manually change the identifiers in the `MicrosoftGame.config` to your valid IDs from Partner Center if you wish to test this. | ||
50 | * tests/testsprite - Standard SDL test program demonstrating sprite drawing functionality. | ||
51 | |||
52 | If you set one of the test programs as a startup project, you can run it directly from Visual Studio. | ||
53 | |||
54 | Windows GDK Setup, Detailed Steps | ||
55 | --------------------- | ||
56 | |||
57 | These steps assume you already have a game using SDL that runs on Windows x64 along with a corresponding Visual Studio solution file for the x64 version. If you don't have this, it's easiest to use one of the test program vcxproj files in the `VisualC-GDK` directory as a starting point, though you will still need to do most of the steps below. | ||
58 | |||
59 | ### 1. Add a Gaming.Desktop.x64 Configuration ### | ||
60 | |||
61 | In your game's existing Visual Studio Solution, go to Build > Configuration Manager. From the "Active solution platform" drop-down select "New...". From the drop-down list, select Gaming.Desktop.x64 and copy the settings from the x64 configuration. | ||
62 | |||
63 | ### 2. Build SDL3 for GDK ### | ||
64 | |||
65 | Open `VisualC-GDK/SDL.sln` in Visual Studio, you need to build the SDL3 target for the Gaming.Desktop.x64 platform (Release is recommended). You will need to copy/keep track of the `SDL3.dll`, `XCurl.dll` (which is output by Gaming.Desktop.x64), and `SDL3.lib` output files for your game project. | ||
66 | |||
67 | *Alternatively*, you could setup your solution file to instead reference the SDL3 project file targets from the SDL source, and add those projects as a dependency. This would mean that SDL3 would be built when your game is built. | ||
68 | |||
69 | ### 3. Configuring Project Settings ### | ||
70 | |||
71 | While the Gaming.Desktop.x64 configuration sets most of the required settings, there are some additional items to configure for your game project under the Gaming.Desktop.x64 Configuration: | ||
72 | |||
73 | * Under C/C++ > General > Additional Include Directories, make sure the `SDL/include` path is referenced | ||
74 | * Under Linker > General > Additional Library Directories, make sure to reference the path where the newly-built SDL3.lib are | ||
75 | * Under Linker > Input > Additional Dependencies, you need the following: | ||
76 | * `SDL3.lib` | ||
77 | * `xgameruntime.lib` | ||
78 | * `../Microsoft.Xbox.Services.GDK.C.Thunks.lib` | ||
79 | * Note that in general, the GDK libraries depend on the MSVC C/C++ runtime, so there is no way to remove this dependency from a GDK program that links against GDK. | ||
80 | |||
81 | ### 4. Setting up SDL_main ### | ||
82 | |||
83 | Rather than using your own implementation of `WinMain`, it's recommended that you instead `#include <SDL3/SDL_main.h>` and declare a standard main function. If you are unable to do this, you can instead manually call `SDL_RunApp` from your entry point, passing in your `SDL_main` function and `NULL` as the parameters; in that case `#define SDL_MAIN_HANDLED` before including SDL_main.h | ||
84 | |||
85 | ### 5. Required DLLs ### | ||
86 | |||
87 | The game will not launch in the debugger unless required DLLs are included in the directory that contains the game's .exe file. You need to make sure that the following files are copied into the directory: | ||
88 | |||
89 | * Your SDL3.dll | ||
90 | * "$(Console_GRDKExtLibRoot)Xbox.Services.API.C\DesignTime\CommonConfiguration\Neutral\Lib\Release\Microsoft.Xbox.Services.GDK.C.Thunks.dll" | ||
91 | * XCurl.dll | ||
92 | |||
93 | You can either copy these in a post-build step, or you can add the dlls into the project and set its Configuration Properties > General > Item type to "Copy file," which will also copy them into the output directory. | ||
94 | |||
95 | ### 6. Setting up MicrosoftGame.config ### | ||
96 | |||
97 | You can copy `VisualC-GDK/tests/testgdk/MicrosoftGame.config` and use that as a starting point in your project. Minimally, you will want to change the Executable Name attribute, the DefaultDisplayName, and the Description. | ||
98 | |||
99 | This file must be copied into the same directory as the game's .exe file. As with the DLLs, you can either use a post-build step or the "Copy file" item type. | ||
100 | |||
101 | For basic testing, you do not need to change anything else in `MicrosoftGame.config`. However, if you want to test any Xbox Live services (such as logging in users) _or_ publish a package, you will need to setup a Game app on Partner Center. | ||
102 | |||
103 | Then, you need to set the following values to the values from Partner Center: | ||
104 | |||
105 | * Identity tag - Name and Publisher attributes | ||
106 | * TitleId | ||
107 | * MSAAppId | ||
108 | |||
109 | ### 7. Adding Required Logos | ||
110 | |||
111 | Several logo PNG files are required to be able to launch the game, even from the debugger. You can use the sample logos provided in `VisualC-GDK/logos`. As with the other files, they must be copied into the same directory as the game's .exe file. | ||
112 | |||
113 | |||
114 | ### 8. Copying any Data Files ### | ||
115 | |||
116 | When debugging GDK games, there is no way to specify a working directory. Therefore, any required game data must also be copied into the output directory, likely in a post-build step. | ||
117 | |||
118 | |||
119 | ### 9. Build and Run from Visual Studio ### | ||
120 | |||
121 | At this point, you should be able to build and run your game from the Visual Studio Debugger. If you get any linker errors, make sure you double-check that you referenced all the required libs. | ||
122 | |||
123 | If you are testing Xbox Live functionality, it's likely you will need to change to the Sandbox for your title. To do this: | ||
124 | |||
125 | 1. Run "Desktop VS 2022 Gaming Command Prompt" from the Start Menu | ||
126 | 2. Switch the sandbox name with: | ||
127 | `XblPCSandbox SANDBOX.#` | ||
128 | 3. (To switch back to the retail sandbox): | ||
129 | `XblPCSandbox RETAIL` | ||
130 | |||
131 | ### 10. Packaging and Installing Locally | ||
132 | |||
133 | You can use one of the test program's `PackageLayout.xml` as a starting point. Minimally, you will need to change the exe to the correct name and also reference any required game data. As with the other data files, it's easiest if you have this copy to the output directory, although it's not a requirement as you can specify relative paths to files. | ||
134 | |||
135 | To create the package: | ||
136 | |||
137 | 1. Run "Desktop VS 2022 Gaming Command Prompt" from the Start Menu | ||
138 | 2. `cd` to the directory containing the `PackageLayout.xml` with the correct paths (if you use the local path as in the sample package layout, this would be from your .exe output directory) | ||
139 | 3. `mkdir Package` to create an output directory | ||
140 | 4. To package the file into the `Package` directory, use: | ||
141 | `makepkg pack /f PackageLayout.xml /lt /d . /nogameos /pc /pd Package` | ||
142 | 5. To install the package, use: | ||
143 | `wdapp install PACKAGENAME.msixvc` | ||
144 | 6. Once the package is installed, you can run it from the start menu. | ||
145 | 7. As with when running from Visual Studio, if you need to test any Xbox Live functionality you must switch to the correct sandbox. | ||
146 | |||
147 | Xbox GDKX Setup | ||
148 | --------------------- | ||
149 | In general, the same process in the Windows GDK instructions work. There are just a few additional notes: | ||
150 | * For Xbox One consoles, use the Gaming.Xbox.XboxOne.x64 target | ||
151 | * For Xbox Series consoles, use the Gaming.Xbox.Scarlett.x64 target | ||
152 | * The Xbox One target sets the `SDL_PLATFORM_XBOXONE` define and the Xbox Series target sets the `SDL_PLATFORM_XBOXSERIES` define | ||
153 | * You don't need to link against the Xbox.Services Thunks lib nor include that dll in your package (it doesn't exist for Xbox) | ||
154 | * The shader blobs for Xbox are created in a pre-build step for the Xbox targets, rather than included in the source (due to NDA and version compatibility reasons) | ||
155 | * To create a package, use: | ||
156 | `makepkg pack /f PackageLayout.xml /lt /d . /pd Package` | ||
157 | * To install the package, use: | ||
158 | `xbapp install [PACKAGE].xvc` | ||
159 | * For some reason, if you make changes that require SDL3.dll to build, and you are running through the debugger (instead of a package), you have to rebuild your .exe target for the debugger to recognize the dll has changed and needs to be transferred to the console again | ||
160 | * While there are successful releases of Xbox titles using this port, it is not as extensively tested as other targets | ||
161 | |||
162 | Troubleshooting | ||
163 | --------------- | ||
164 | |||
165 | #### Xbox Live Login does not work | ||
166 | |||
167 | As of June 2022 GDK, you must have a valid Title Id and MSAAppId in order to test Xbox Live functionality such as user login. Make sure these are set correctly in the `MicrosoftGame.config`. This means that even testgdk will not let you login without setting these properties to valid values. | ||
168 | |||
169 | Furthermore, confirm that your PC is set to the correct sandbox. | ||
170 | |||
171 | |||
172 | #### "The current user has already installed an unpackaged version of this app. A packaged version cannot replace this." error when installing | ||
173 | |||
174 | Prior to June 2022 GDK, running from the Visual Studio debugger would still locally register the app (and it would appear on the start menu). To fix this, you have to uninstall it (it's simplest to right click on it from the start menu to uninstall it). | ||
diff --git a/src/contrib/SDL-3.2.20/docs/README-haiku.md b/src/contrib/SDL-3.2.20/docs/README-haiku.md new file mode 100644 index 0000000..960bc3c --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-haiku.md | |||
@@ -0,0 +1,4 @@ | |||
1 | # Haiku OS | ||
2 | |||
3 | SDL is fully supported on Haiku OS, and is built using [CMake](README-cmake.md). | ||
4 | |||
diff --git a/src/contrib/SDL-3.2.20/docs/README-highdpi.md b/src/contrib/SDL-3.2.20/docs/README-highdpi.md new file mode 100644 index 0000000..dd3a2fa --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-highdpi.md | |||
@@ -0,0 +1,40 @@ | |||
1 | |||
2 | SDL 3.0 has new support for high DPI displays. Interfaces provided by SDL uses the platform's native coordinates unless otherwise specified. | ||
3 | |||
4 | ## Explanation | ||
5 | |||
6 | Displays now have a content display scale, which is the expected scale for content based on the DPI settings of the display. For example, a 4K display might have a 2.0 (200%) display scale, which means that the user expects UI elements to be twice as big on this display, to aid in readability. You can query the display content scale using `SDL_GetDisplayContentScale()`, and when this changes you get an `SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED` event. | ||
7 | |||
8 | The window size is now distinct from the window pixel size, and the ratio between the two is the window pixel density. If the window is created with the `SDL_WINDOW_HIGH_PIXEL_DENSITY` flag, SDL will try to match the native pixel density for the display, otherwise it will try to have the pixel size match the window size. You can query the window pixel density using `SDL_GetWindowPixelDensity()`. You can query the window pixel size using `SDL_GetWindowSizeInPixels()`, and when this changes you get an `SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED` event. You are guaranteed to get a `SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED` event when a window is created and resized, and you can use this event to create and resize your graphics context for the window. | ||
9 | |||
10 | The window has a display scale, which is the scale from the pixel resolution to the desired content size, e.g. the combination of the pixel density and the content scale. For example, a 3840x2160 window displayed at 200% on Windows, and a 1920x1080 window with the high density flag on a 2x display on macOS will both have a pixel size of 3840x2160 and a display scale of 2.0. You can query the window display scale using `SDL_GetWindowDisplayScale()`, and when this changes you get an `SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED` event. | ||
11 | |||
12 | ## Numeric example | ||
13 | |||
14 | Given a window spanning a 3840x2160 monitor set to 2x display or 200% scaling, the following tabulates the effect of creating a window with or without `SDL_WINDOW_HIGH_PIXEL_DENSITY` on macOS and Windows: | ||
15 | |||
16 | | Value | macOS (Default) | macOS (HD) | Windows (Default & HD) | | ||
17 | |--------------------------------|-----------------|------------|------------------------| | ||
18 | | `SDL_GetWindowSize()` | 1920x1080 | 1920x1080 | 3840x2160 | | ||
19 | | `SDL_GetWindowSizeInPixels()` | 1920x1080 | 3840x2160 | 3840x2160 | | ||
20 | | `SDL_GetDisplayContentScale()` | 1.0 | 1.0 | 2.0 | | ||
21 | | `SDL_GetWindowDisplayScale()` | 1.0 | 2.0 | 2.0 | | ||
22 | | `SDL_GetWindowPixelDensity()` | 1.0 | 2.0 | 1.0 | | ||
23 | |||
24 | Observe the difference between the approaches taken by macOS and Windows: | ||
25 | - The Windows and Android coordinate system always deals in physical device pixels, high DPI support is achieved by providing a content scale that tells the developer to draw objects larger. Ignoring this scale factor results in graphics appearing tiny. | ||
26 | - The macOS and iOS coordinate system always deals in window coordinates, high DPI support is achieved by providing an optional flag for the developer to request more pixels. Omitting this flag results in graphics having low detail. | ||
27 | - On Linux, X11 uses a similar approach to Windows and Wayland uses a similar approach to macOS. | ||
28 | |||
29 | ## Solution | ||
30 | |||
31 | Proper high DPI support takes into account both the content scale and the pixel density. | ||
32 | |||
33 | First, you'd create your window with the `SDL_WINDOW_HIGH_PIXEL_DENSITY` flag, assuming you want the highest detail possible. Then you'd get the window display scale to see how much your UI elements should be enlarged to be readable. | ||
34 | |||
35 | If you're using the SDL 2D renderer, SDL provides the function `SDL_ConvertEventToRenderCoordinates()` to convert mouse coordinates between window coordinates and rendering coordinates, and the more general functions `SDL_RenderCoordinatesFromWindow()` and `SDL_RenderCoordinatesToWindow()` to do other conversion between them. | ||
36 | |||
37 | If you're not using the 2D renderer, you can implement this yourself using `SDL_GetWindowPixelDensity()` as scale factor to convert from window coordinates to pixels. | ||
38 | |||
39 | Finally you'll want to test on both Windows and macOS if possible to make sure your high DPI support works in all environments. | ||
40 | |||
diff --git a/src/contrib/SDL-3.2.20/docs/README-ios.md b/src/contrib/SDL-3.2.20/docs/README-ios.md new file mode 100644 index 0000000..166d182 --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-ios.md | |||
@@ -0,0 +1,260 @@ | |||
1 | iOS | ||
2 | ====== | ||
3 | |||
4 | Building the Simple DirectMedia Layer for iOS 11.0+ | ||
5 | ============================================================================== | ||
6 | |||
7 | Please note that building SDL requires at least Xcode 12.2 and the iOS 14.2 SDK. | ||
8 | |||
9 | Instructions: | ||
10 | |||
11 | 1. Open SDL.xcodeproj (located in Xcode/SDL) in Xcode. | ||
12 | 2. Select your desired target, and hit build. | ||
13 | |||
14 | |||
15 | Using the Simple DirectMedia Layer for iOS | ||
16 | ============================================================================== | ||
17 | |||
18 | 1. Run Xcode and create a new project using the iOS Game template, selecting the Objective C language and Metal game technology. | ||
19 | 2. In the main view, delete all files except for Assets and LaunchScreen | ||
20 | 3. Right click the project in the main view, select "Add Files...", and add the SDL project, Xcode/SDL/SDL.xcodeproj | ||
21 | 4. Select the project in the main view, go to the "Info" tab and under "Custom iOS Target Properties" remove the line "Main storyboard file base name" | ||
22 | 5. Select the project in the main view, go to the "Build Settings" tab, select "All", and edit "Header Search Path" and drag over the SDL "Public Headers" folder from the left | ||
23 | 6. Select the project in the main view, go to the "Build Phases" tab, select "Link Binary With Libraries", and add SDL3.framework from "Framework-iOS" | ||
24 | 7. Select the project in the main view, go to the "General" tab, scroll down to "Frameworks, Libraries, and Embedded Content", and select "Embed & Sign" for the SDL library. | ||
25 | 8. Add the source files that you would normally have for an SDL program, making sure to have #include <SDL3/SDL_main.h> at the top of the file containing your main() function. | ||
26 | 9. Add any assets that your application needs. | ||
27 | 10. Enjoy! | ||
28 | |||
29 | |||
30 | TODO: Add information regarding App Store requirements such as icons, etc. | ||
31 | |||
32 | |||
33 | Notes -- Retina / High-DPI and window sizes | ||
34 | ============================================================================== | ||
35 | |||
36 | Window and display mode sizes in SDL are in points rather than in pixels. | ||
37 | On iOS this means that a window created on an iPhone 6 will have a size in | ||
38 | points of 375 x 667, rather than a size in pixels of 750 x 1334. All iOS apps | ||
39 | are expected to size their content based on points rather than pixels, | ||
40 | as this allows different iOS devices to have different pixel densities | ||
41 | (Retina versus non-Retina screens, etc.) without apps caring too much. | ||
42 | |||
43 | SDL_GetWindowSize() and mouse coordinates are in points rather than pixels, | ||
44 | but the window will have a much greater pixel density when the device supports | ||
45 | it, and the SDL_GetWindowSizeInPixels() can be called to determine the size | ||
46 | in pixels of the drawable screen framebuffer. | ||
47 | |||
48 | The SDL 2D rendering API will automatically handle this for you, by default | ||
49 | providing a rendering area in points, and you can call SDL_SetRenderLogicalPresentation() | ||
50 | to gain access to the higher density resolution. | ||
51 | |||
52 | Some OpenGL ES functions such as glViewport expect sizes in pixels rather than | ||
53 | sizes in points. When doing 2D rendering with OpenGL ES, an orthographic projection | ||
54 | matrix using the size in points (SDL_GetWindowSize()) can be used in order to | ||
55 | display content at the same scale no matter whether a Retina device is used or not. | ||
56 | |||
57 | |||
58 | Notes -- Application events | ||
59 | ============================================================================== | ||
60 | |||
61 | On iOS the application goes through a fixed life cycle and you will get | ||
62 | notifications of state changes via application events. When these events | ||
63 | are delivered you must handle them in an event callback because the OS may | ||
64 | not give you any processing time after the events are delivered. | ||
65 | |||
66 | e.g. | ||
67 | |||
68 | bool HandleAppEvents(void *userdata, SDL_Event *event) | ||
69 | { | ||
70 | switch (event->type) | ||
71 | { | ||
72 | case SDL_EVENT_TERMINATING: | ||
73 | /* Terminate the app. | ||
74 | Shut everything down before returning from this function. | ||
75 | */ | ||
76 | return false; | ||
77 | case SDL_EVENT_LOW_MEMORY: | ||
78 | /* You will get this when your app is paused and iOS wants more memory. | ||
79 | Release as much memory as possible. | ||
80 | */ | ||
81 | return false; | ||
82 | case SDL_EVENT_WILL_ENTER_BACKGROUND: | ||
83 | /* Prepare your app to go into the background. Stop loops, etc. | ||
84 | This gets called when the user hits the home button, or gets a call. | ||
85 | */ | ||
86 | return false; | ||
87 | case SDL_EVENT_DID_ENTER_BACKGROUND: | ||
88 | /* This will get called if the user accepted whatever sent your app to the background. | ||
89 | If the user got a phone call and canceled it, you'll instead get an SDL_EVENT_DID_ENTER_FOREGROUND event and restart your loops. | ||
90 | When you get this, you have 5 seconds to save all your state or the app will be terminated. | ||
91 | Your app is NOT active at this point. | ||
92 | */ | ||
93 | return false; | ||
94 | case SDL_EVENT_WILL_ENTER_FOREGROUND: | ||
95 | /* This call happens when your app is coming back to the foreground. | ||
96 | Restore all your state here. | ||
97 | */ | ||
98 | return false; | ||
99 | case SDL_EVENT_DID_ENTER_FOREGROUND: | ||
100 | /* Restart your loops here. | ||
101 | Your app is interactive and getting CPU again. | ||
102 | */ | ||
103 | return false; | ||
104 | default: | ||
105 | /* No special processing, add it to the event queue */ | ||
106 | return true; | ||
107 | } | ||
108 | } | ||
109 | |||
110 | int main(int argc, char *argv[]) | ||
111 | { | ||
112 | SDL_SetEventFilter(HandleAppEvents, NULL); | ||
113 | |||
114 | ... run your main loop | ||
115 | |||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | |||
120 | Note that if you are using main callbacks instead of a standard C main() function, your SDL_AppEvent() callback will run as these events arrive and you do not need to use SDL_SetEventFilter. | ||
121 | |||
122 | |||
123 | Notes -- Keyboard | ||
124 | ============================================================================== | ||
125 | |||
126 | The SDL keyboard API has been extended to support on-screen keyboards: | ||
127 | |||
128 | void SDL_StartTextInput() | ||
129 | -- enables text events and reveals the onscreen keyboard. | ||
130 | |||
131 | void SDL_StopTextInput() | ||
132 | -- disables text events and hides the onscreen keyboard. | ||
133 | |||
134 | bool SDL_TextInputActive() | ||
135 | -- returns whether or not text events are enabled (and the onscreen keyboard is visible) | ||
136 | |||
137 | |||
138 | Notes -- Mouse | ||
139 | ============================================================================== | ||
140 | |||
141 | iOS now supports Bluetooth mice on iPad, but by default will provide the mouse input as touch. In order for SDL to see the real mouse events, you should set the key UIApplicationSupportsIndirectInputEvents to true in your Info.plist | ||
142 | |||
143 | From iOS 17 onward, the key now defaults to true. | ||
144 | |||
145 | |||
146 | Notes -- Reading and Writing files | ||
147 | ============================================================================== | ||
148 | |||
149 | Each application installed on iPhone resides in a sandbox which includes its own application home directory. Your application may not access files outside this directory. | ||
150 | |||
151 | When your SDL based iPhone application starts up, it sets the working directory to the main bundle, where your application resources are stored. You cannot write to this directory. Instead, you should write document files to the directory returned by SDL_GetUserFolder(SDL_FOLDER_DOCUMENTS) and preferences to the directory returned by SDL_GetPrefPath(). | ||
152 | |||
153 | More information on this subject is available here: | ||
154 | http://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Introduction/Introduction.html | ||
155 | |||
156 | |||
157 | Notes -- xcFramework | ||
158 | ============================================================================== | ||
159 | |||
160 | The SDL.xcodeproj file now includes a target to build SDL3.xcframework. An xcframework is a new (Xcode 11) uber-framework which can handle any combination of processor type and target OS platform. | ||
161 | |||
162 | In the past, iOS devices were always an ARM variant processor, and the simulator was always i386 or x86_64, and thus libraries could be combined into a single framework for both simulator and device. With the introduction of the Apple Silicon ARM-based machines, regular frameworks would collide as CPU type was no longer sufficient to differentiate the platform. So Apple created the new xcframework library package. | ||
163 | |||
164 | The xcframework target builds into a Products directory alongside the SDL.xcodeproj file, as SDL3.xcframework. This can be brought in to any iOS project and will function properly for both simulator and device, no matter their CPUs. Note that Intel Macs cannot cross-compile for Apple Silicon Macs. If you need AS compatibility, perform this build on an Apple Silicon Mac. | ||
165 | |||
166 | This target requires Xcode 11 or later. The target will simply fail to build if attempted on older Xcodes. | ||
167 | |||
168 | In addition, on Apple platforms, main() cannot be in a dynamically loaded library. | ||
169 | However, unlike in SDL2, in SDL3 SDL_main is implemented inline in SDL_main.h, so you don't need to link against a static libSDL3main.lib, and you don't need to copy a .c file from the SDL3 source either. | ||
170 | This means that iOS apps which used the statically-linked libSDL3.lib and now link with the xcframwork can just `#include <SDL3/SDL_main.h>` in the source file that contains their standard `int main(int argc, char *argv[])` function to get a header-only SDL_main implementation that calls the `SDL_RunApp()` with your standard main function. | ||
171 | |||
172 | Using an xcFramework is similar to using a regular framework. However, issues have been seen with the build system not seeing the headers in the xcFramework. To remedy this, add the path to the xcFramework in your app's target ==> Build Settings ==> Framework Search Paths and mark it recursive (this is critical). Also critical is to remove "*.framework" from Build Settings ==> Sub-Directories to Exclude in Recursive Searches. Clean the build folder, and on your next build the build system should be able to see any of these in your code, as expected: | ||
173 | |||
174 | #include "SDL_main.h" | ||
175 | #include <SDL.h> | ||
176 | #include <SDL_main.h> | ||
177 | |||
178 | |||
179 | Notes -- iPhone SDL limitations | ||
180 | ============================================================================== | ||
181 | |||
182 | Windows: | ||
183 | Full-size, single window applications only. You cannot create multi-window SDL applications for iPhone OS. The application window will fill the display, though you have the option of turning on or off the menu-bar (pass SDL_CreateWindow() the flag SDL_WINDOW_BORDERLESS). | ||
184 | |||
185 | Textures: | ||
186 | The optimal texture formats on iOS are SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_XBGR8888, and SDL_PIXELFORMAT_RGB24 pixel formats. | ||
187 | |||
188 | |||
189 | Notes -- CoreBluetooth.framework | ||
190 | ============================================================================== | ||
191 | |||
192 | SDL_JOYSTICK_HIDAPI is disabled by default. It can give you access to a lot | ||
193 | more game controller devices, but it requires permission from the user before | ||
194 | your app will be able to talk to the Bluetooth hardware. "Made For iOS" | ||
195 | branded controllers do not need this as we don't have to speak to them | ||
196 | directly with raw bluetooth, so many apps can live without this. | ||
197 | |||
198 | You'll need to link with CoreBluetooth.framework and add something like this | ||
199 | to your Info.plist: | ||
200 | |||
201 | <key>NSBluetoothPeripheralUsageDescription</key> | ||
202 | <string>MyApp would like to remain connected to nearby bluetooth Game Controllers and Game Pads even when you're not using the app.</string> | ||
203 | |||
204 | |||
205 | Game Center | ||
206 | ============================================================================== | ||
207 | |||
208 | Game Center integration might require that you break up your main loop in order to yield control back to the system. In other words, instead of running an endless main loop, you run each frame in a callback function, using: | ||
209 | |||
210 | bool SDL_SetiOSAnimationCallback(SDL_Window * window, int interval, SDL_iOSAnimationCallback callback, void *callbackParam); | ||
211 | |||
212 | This will set up the given function to be called back on the animation callback, and then you have to return from main() to let the Cocoa event loop run. | ||
213 | |||
214 | e.g. | ||
215 | |||
216 | extern "C" | ||
217 | void ShowFrame(void*) | ||
218 | { | ||
219 | ... do event handling, frame logic and rendering ... | ||
220 | } | ||
221 | |||
222 | int main(int argc, char *argv[]) | ||
223 | { | ||
224 | ... initialize game ... | ||
225 | |||
226 | #ifdef SDL_PLATFORM_IOS | ||
227 | // Initialize the Game Center for scoring and matchmaking | ||
228 | InitGameCenter(); | ||
229 | |||
230 | // Set up the game to run in the window animation callback on iOS | ||
231 | // so that Game Center and so forth works correctly. | ||
232 | SDL_SetiOSAnimationCallback(window, 1, ShowFrame, NULL); | ||
233 | #else | ||
234 | while ( running ) { | ||
235 | ShowFrame(0); | ||
236 | DelayFrame(); | ||
237 | } | ||
238 | #endif | ||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | |||
243 | Note that if you are using main callbacks instead of a standard C main() function, your SDL_AppIterate() callback is already doing this and you don't need to use SDL_SetiOSAnimationCallback. | ||
244 | |||
245 | |||
246 | Deploying to older versions of iOS | ||
247 | ============================================================================== | ||
248 | |||
249 | SDL supports deploying to older versions of iOS than are supported by the latest version of Xcode, all the way back to iOS 11.0 | ||
250 | |||
251 | In order to do that you need to download an older version of Xcode: | ||
252 | https://developer.apple.com/download/more/?name=Xcode | ||
253 | |||
254 | Open the package contents of the older Xcode and your newer version of Xcode and copy over the folders in Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport | ||
255 | |||
256 | Then open the file Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/SDKSettings.plist and add the versions of iOS you want to deploy to the key Root/DefaultProperties/DEPLOYMENT_TARGET_SUGGESTED_VALUES | ||
257 | |||
258 | Open your project and set your deployment target to the desired version of iOS | ||
259 | |||
260 | Finally, remove GameController from the list of frameworks linked by your application and edit the build settings for "Other Linker Flags" and add -weak_framework GameController | ||
diff --git a/src/contrib/SDL-3.2.20/docs/README-kmsbsd.md b/src/contrib/SDL-3.2.20/docs/README-kmsbsd.md new file mode 100644 index 0000000..7604817 --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-kmsbsd.md | |||
@@ -0,0 +1,27 @@ | |||
1 | KMSDRM on *BSD | ||
2 | ================================================== | ||
3 | |||
4 | KMSDRM is supported on FreeBSD and OpenBSD. DragonFlyBSD works but requires being a root user. NetBSD isn't supported yet because the application will crash when creating the KMSDRM screen. | ||
5 | |||
6 | WSCONS support has been brought back, but only as an input backend. It will not be brought back as a video backend to ease maintenance. | ||
7 | |||
8 | OpenBSD note: Note that the video backend assumes that the user has read/write permissions to the /dev/drm* devices. | ||
9 | |||
10 | |||
11 | SDL WSCONS input backend features | ||
12 | =================================================== | ||
13 | 1. It is keymap-aware; it will work properly with different keymaps. | ||
14 | 2. It has mouse support. | ||
15 | 3. Accent input is supported. | ||
16 | 4. Compose keys are supported. | ||
17 | 5. AltGr and Meta Shift keys work as intended. | ||
18 | |||
19 | Partially working or no input on OpenBSD/NetBSD. | ||
20 | ================================================== | ||
21 | |||
22 | The WSCONS input backend needs read/write access to the /dev/wskbd* devices, without which it will not work properly. /dev/wsmouse must also be read/write accessible, otherwise mouse input will not work. | ||
23 | |||
24 | Partially working or no input on FreeBSD. | ||
25 | ================================================== | ||
26 | |||
27 | The evdev devices are only accessible to the root user by default. Edit devfs rules to allow access to such devices. The /dev/kbd* devices are also only accessible to the root user by default. Edit devfs rules to allow access to such devices. | ||
diff --git a/src/contrib/SDL-3.2.20/docs/README-linux.md b/src/contrib/SDL-3.2.20/docs/README-linux.md new file mode 100644 index 0000000..3f2d2c0 --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-linux.md | |||
@@ -0,0 +1,98 @@ | |||
1 | Linux | ||
2 | ================================================================================ | ||
3 | |||
4 | By default SDL will only link against glibc, the rest of the features will be | ||
5 | enabled dynamically at runtime depending on the available features on the target | ||
6 | system. So, for example if you built SDL with XRandR support and the target | ||
7 | system does not have the XRandR libraries installed, it will be disabled | ||
8 | at runtime, and you won't get a missing library error, at least with the | ||
9 | default configuration parameters. | ||
10 | |||
11 | |||
12 | Build Dependencies | ||
13 | -------------------------------------------------------------------------------- | ||
14 | |||
15 | Ubuntu 18.04, all available features enabled: | ||
16 | |||
17 | sudo apt-get install build-essential git make \ | ||
18 | pkg-config cmake ninja-build gnome-desktop-testing libasound2-dev libpulse-dev \ | ||
19 | libaudio-dev libjack-dev libsndio-dev libx11-dev libxext-dev \ | ||
20 | libxrandr-dev libxcursor-dev libxfixes-dev libxi-dev libxss-dev \ | ||
21 | libxkbcommon-dev libdrm-dev libgbm-dev libgl1-mesa-dev libgles2-mesa-dev \ | ||
22 | libegl1-mesa-dev libdbus-1-dev libibus-1.0-dev libudev-dev | ||
23 | |||
24 | Ubuntu 22.04+ can also add `libpipewire-0.3-dev libwayland-dev libdecor-0-dev liburing-dev` to that command line. | ||
25 | |||
26 | Fedora 35, all available features enabled: | ||
27 | |||
28 | sudo yum install gcc git-core make cmake \ | ||
29 | alsa-lib-devel pulseaudio-libs-devel nas-devel pipewire-devel \ | ||
30 | libX11-devel libXext-devel libXrandr-devel libXcursor-devel libXfixes-devel \ | ||
31 | libXi-devel libXScrnSaver-devel dbus-devel ibus-devel \ | ||
32 | systemd-devel mesa-libGL-devel libxkbcommon-devel mesa-libGLES-devel \ | ||
33 | mesa-libEGL-devel vulkan-devel wayland-devel wayland-protocols-devel \ | ||
34 | libdrm-devel mesa-libgbm-devel libusb-devel libdecor-devel \ | ||
35 | pipewire-jack-audio-connection-kit-devel \ | ||
36 | |||
37 | Fedora 39+ can also add `liburing-devel` to that command line. | ||
38 | |||
39 | NOTES: | ||
40 | - The sndio audio target is unavailable on Fedora (but probably not what you | ||
41 | should want to use anyhow). | ||
42 | |||
43 | openSUSE Tumbleweed: | ||
44 | |||
45 | sudo zypper in libunwind-devel libusb-1_0-devel Mesa-libGL-devel libxkbcommon-devel libdrm-devel \ | ||
46 | libgbm-devel pipewire-devel libpulse-devel sndio-devel Mesa-libEGL-devel | ||
47 | |||
48 | Arch: | ||
49 | sudo pacman -S alsa-lib cmake hidapi ibus jack libdecor libgl libpulse libusb libx11 libxcursor libxext libxinerama libxkbcommon libxrandr libxrender libxss mesa ninja pipewire sndio vulkan-driver vulkan-headers wayland wayland-protocols | ||
50 | |||
51 | |||
52 | Joystick does not work | ||
53 | -------------------------------------------------------------------------------- | ||
54 | |||
55 | If you compiled or are using a version of SDL with udev support (and you should!) | ||
56 | there's a few issues that may cause SDL to fail to detect your joystick. To | ||
57 | debug this, start by installing the evtest utility. On Ubuntu/Debian: | ||
58 | |||
59 | sudo apt-get install evtest | ||
60 | |||
61 | Then run: | ||
62 | |||
63 | sudo evtest | ||
64 | |||
65 | You'll hopefully see your joystick listed along with a name like "/dev/input/eventXX" | ||
66 | Now run: | ||
67 | |||
68 | cat /dev/input/event/XX | ||
69 | |||
70 | If you get a permission error, you need to set a udev rule to change the mode of | ||
71 | your device (see below) | ||
72 | |||
73 | Also, try: | ||
74 | |||
75 | sudo udevadm info --query=all --name=input/eventXX | ||
76 | |||
77 | If you see a line stating ID_INPUT_JOYSTICK=1, great, if you don't see it, | ||
78 | you need to set up an udev rule to force this variable. | ||
79 | |||
80 | A combined rule for the Saitek Pro Flight Rudder Pedals to fix both issues looks | ||
81 | like: | ||
82 | |||
83 | SUBSYSTEM=="input", ATTRS{idProduct}=="0763", ATTRS{idVendor}=="06a3", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1" | ||
84 | SUBSYSTEM=="input", ATTRS{idProduct}=="0764", ATTRS{idVendor}=="06a3", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1" | ||
85 | |||
86 | You can set up similar rules for your device by changing the values listed in | ||
87 | idProduct and idVendor. To obtain these values, try: | ||
88 | |||
89 | sudo udevadm info -a --name=input/eventXX | grep idVendor | ||
90 | sudo udevadm info -a --name=input/eventXX | grep idProduct | ||
91 | |||
92 | If multiple values come up for each of these, the one you want is the first one of each. | ||
93 | |||
94 | On other systems which ship with an older udev (such as CentOS), you may need | ||
95 | to set up a rule such as: | ||
96 | |||
97 | SUBSYSTEM=="input", ENV{ID_CLASS}=="joystick", ENV{ID_INPUT_JOYSTICK}="1" | ||
98 | |||
diff --git a/src/contrib/SDL-3.2.20/docs/README-macos.md b/src/contrib/SDL-3.2.20/docs/README-macos.md new file mode 100644 index 0000000..e5c75c1 --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-macos.md | |||
@@ -0,0 +1,251 @@ | |||
1 | # macOS | ||
2 | |||
3 | These instructions are for people using Apple's macOS. | ||
4 | |||
5 | From the developer's point of view, macOS is a sort of hybrid Mac and | ||
6 | Unix system, and you have the option of using either traditional | ||
7 | command line tools or Apple's IDE Xcode. | ||
8 | |||
9 | # Command Line Build | ||
10 | |||
11 | To build SDL using the command line, use the CMake build script: | ||
12 | |||
13 | ```bash | ||
14 | mkdir build | ||
15 | cd build | ||
16 | cmake .. -DCMAKE_OSX_DEPLOYMENT_TARGET=10.13 | ||
17 | cmake --build . | ||
18 | sudo cmake --install . | ||
19 | ``` | ||
20 | |||
21 | |||
22 | You can also build SDL as a Universal library (a single binary for both | ||
23 | 64-bit Intel and ARM architectures): | ||
24 | |||
25 | ```bash | ||
26 | mkdir build | ||
27 | cd build | ||
28 | cmake .. "-DCMAKE_OSX_ARCHITECTURES=arm64;x86_64" -DCMAKE_OSX_DEPLOYMENT_TARGET=10.13 | ||
29 | cmake --build . | ||
30 | sudo cmake --install . | ||
31 | ``` | ||
32 | |||
33 | Please note that building SDL requires at least Xcode 12.2 and the macOS 11.0 SDK. | ||
34 | |||
35 | To use the library once it's built, you essential have two possibilities: | ||
36 | use the traditional autoconf/automake/make method, or use Xcode. | ||
37 | |||
38 | |||
39 | # Caveats for using SDL with macOS | ||
40 | |||
41 | If you register your own NSApplicationDelegate (using [NSApp setDelegate:]), | ||
42 | SDL will not register its own. This means that SDL will not terminate using | ||
43 | SDL_Quit if it receives a termination request, it will terminate like a | ||
44 | normal app, and it will not send a SDL_EVENT_DROP_FILE when you request to open a | ||
45 | file with the app. To solve these issues, put the following code in your | ||
46 | NSApplicationDelegate implementation: | ||
47 | |||
48 | |||
49 | ```objc | ||
50 | - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender | ||
51 | { | ||
52 | if (SDL_EventEnabled(SDL_EVENT_QUIT)) { | ||
53 | SDL_Event event; | ||
54 | SDL_zero(event); | ||
55 | event.type = SDL_EVENT_QUIT; | ||
56 | SDL_PushEvent(&event); | ||
57 | } | ||
58 | |||
59 | return NSTerminateCancel; | ||
60 | } | ||
61 | |||
62 | - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename | ||
63 | { | ||
64 | if (SDL_EventEnabled(SDL_EVENT_DROP_FILE)) { | ||
65 | SDL_Event event; | ||
66 | SDL_zero(event); | ||
67 | event.type = SDL_EVENT_DROP_FILE; | ||
68 | event.drop.file = SDL_strdup([filename UTF8String]); | ||
69 | return SDL_PushEvent(&event); | ||
70 | } | ||
71 | |||
72 | return NO; | ||
73 | } | ||
74 | ``` | ||
75 | |||
76 | # Using the Simple DirectMedia Layer with a traditional Makefile | ||
77 | |||
78 | An existing build system for your SDL app has good chances to work almost | ||
79 | unchanged on macOS, as long as you link with the SDL framework. However, | ||
80 | to produce a "real" Mac binary that you can distribute to users, you need | ||
81 | to put the generated binary into a so called "bundle", which is basically | ||
82 | a fancy folder with a name like "MyCoolGame.app". | ||
83 | |||
84 | To get this build automatically, add something like the following rule to | ||
85 | your Makefile.am: | ||
86 | |||
87 | ```make | ||
88 | bundle_contents = APP_NAME.app/Contents | ||
89 | APP_NAME_bundle: EXE_NAME | ||
90 | mkdir -p $(bundle_contents)/MacOS | ||
91 | mkdir -p $(bundle_contents)/Resources | ||
92 | echo "APPL????" > $(bundle_contents)/PkgInfo | ||
93 | $(INSTALL_PROGRAM) $< $(bundle_contents)/MacOS/ | ||
94 | ``` | ||
95 | |||
96 | You should replace `EXE_NAME` with the name of the executable. `APP_NAME` is | ||
97 | what will be visible to the user in the Finder. Usually it will be the same | ||
98 | as `EXE_NAME` but capitalized. E.g. if `EXE_NAME` is "testgame" then `APP_NAME` | ||
99 | usually is "TestGame". You might also want to use `@PACKAGE@` to use the | ||
100 | package name as specified in your configure.ac file. | ||
101 | |||
102 | If your project builds more than one application, you will have to do a bit | ||
103 | more. For each of your target applications, you need a separate rule. | ||
104 | |||
105 | If you want the created bundles to be installed, you may want to add this | ||
106 | rule to your Makefile.am: | ||
107 | |||
108 | ```make | ||
109 | install-exec-hook: APP_NAME_bundle | ||
110 | rm -rf $(DESTDIR)$(prefix)/Applications/APP_NAME.app | ||
111 | mkdir -p $(DESTDIR)$(prefix)/Applications/ | ||
112 | cp -r $< /$(DESTDIR)$(prefix)Applications/ | ||
113 | ``` | ||
114 | |||
115 | This rule takes the Bundle created by the rule from step 3 and installs them | ||
116 | into "$(DESTDIR)$(prefix)/Applications/". | ||
117 | |||
118 | Again, if you want to install multiple applications, you will have to augment | ||
119 | the make rule accordingly. | ||
120 | |||
121 | But beware! That is only part of the story! With the above, you end up with | ||
122 | a barebones .app bundle, which is double-clickable from the Finder. But | ||
123 | there are some more things you should do before shipping your product... | ||
124 | |||
125 | 1. You'll need to copy the SDL framework into the Contents/Frameworks | ||
126 | folder in your bundle, so it is included along with your application. | ||
127 | |||
128 | 2. Add an 'Info.plist' to your application. That is a special XML file which | ||
129 | contains some meta-information about your application (like some copyright | ||
130 | information, the version of your app, the name of an optional icon file, | ||
131 | and other things). Part of that information is displayed by the Finder | ||
132 | when you click on the .app, or if you look at the "Get Info" window. | ||
133 | More information about Info.plist files can be found on Apple's homepage. | ||
134 | |||
135 | |||
136 | As a final remark, let me add that I use some of the techniques (and some | ||
137 | variations of them) in [Exult](https://github.com/exult/exult) and | ||
138 | [ScummVM](https://github.com/scummvm/scummvm); both are available in source on | ||
139 | the net, so feel free to take a peek at them for inspiration! | ||
140 | |||
141 | |||
142 | # Using the Simple DirectMedia Layer with Xcode | ||
143 | |||
144 | These instructions are for using Apple's Xcode IDE to build SDL applications. | ||
145 | |||
146 | ## First steps | ||
147 | |||
148 | The first thing to do is to unpack the Xcode.tar.gz archive in the | ||
149 | top level SDL directory (where the Xcode.tar.gz archive resides). | ||
150 | Because Stuffit Expander will unpack the archive into a subdirectory, | ||
151 | you should unpack the archive manually from the command line: | ||
152 | |||
153 | ```bash | ||
154 | cd [path_to_SDL_source] | ||
155 | tar zxf Xcode.tar.gz | ||
156 | ``` | ||
157 | |||
158 | This will create a new folder called Xcode, which you can browse | ||
159 | normally from the Finder. | ||
160 | |||
161 | ## Building the Framework | ||
162 | |||
163 | The SDL Library is packaged as a framework bundle, an organized | ||
164 | relocatable folder hierarchy of executable code, interface headers, | ||
165 | and additional resources. For practical purposes, you can think of a | ||
166 | framework as a more user and system-friendly shared library, whose library | ||
167 | file behaves more or less like a standard UNIX shared library. | ||
168 | |||
169 | To build the framework, simply open the framework project and build it. | ||
170 | By default, the framework bundle "SDL.framework" is installed in | ||
171 | /Library/Frameworks. Therefore, the testers and project stationary expect | ||
172 | it to be located there. However, it will function the same in any of the | ||
173 | following locations: | ||
174 | |||
175 | * ~/Library/Frameworks | ||
176 | * /Local/Library/Frameworks | ||
177 | * /System/Library/Frameworks | ||
178 | |||
179 | ## Build Options | ||
180 | |||
181 | There are two "Build Styles" (See the "Targets" tab) for SDL. | ||
182 | "Deployment" should be used if you aren't tweaking the SDL library. | ||
183 | "Development" should be used to debug SDL apps or the library itself. | ||
184 | |||
185 | ## Building the Testers | ||
186 | |||
187 | Open the SDLTest project and build away! | ||
188 | |||
189 | ## Using the Project Stationary | ||
190 | |||
191 | Copy the stationary to the indicated folders to access it from | ||
192 | the "New Project" and "Add target" menus. What could be easier? | ||
193 | |||
194 | ## Setting up a new project by hand | ||
195 | |||
196 | Some of you won't want to use the Stationary so I'll give some tips: | ||
197 | |||
198 | (this is accurate as of Xcode 12.5.) | ||
199 | |||
200 | * Click "File" -> "New" -> "Project... | ||
201 | * Choose "macOS" and then "App" from the "Application" section. | ||
202 | * Fill out the options in the next window. User interface is "XIB" and | ||
203 | Language is "Objective-C". | ||
204 | * Remove "main.m" from your project | ||
205 | * Remove "MainMenu.xib" from your project | ||
206 | * Remove "AppDelegates.*" from your project | ||
207 | * Add "\$(HOME)/Library/Frameworks/SDL.framework/Headers" to include path | ||
208 | * Add "\$(HOME)/Library/Frameworks" to the frameworks search path | ||
209 | * Add "-framework SDL -framework Foundation -framework AppKit" to "OTHER_LDFLAGS" | ||
210 | * Add your files | ||
211 | * Clean and build | ||
212 | |||
213 | ## Building from command line | ||
214 | |||
215 | Use `xcode-build` in the same directory as your .pbxproj file | ||
216 | |||
217 | ## Running your app | ||
218 | |||
219 | You can send command line args to your app by either invoking it from | ||
220 | the command line (in *.app/Contents/MacOS) or by entering them in the | ||
221 | Executables" panel of the target settings. | ||
222 | |||
223 | # Implementation Notes | ||
224 | |||
225 | Some things that may be of interest about how it all works... | ||
226 | |||
227 | ## Working directory | ||
228 | |||
229 | In SDL 1.2, the working directory of your SDL app is by default set to its | ||
230 | parent, but this is no longer the case in SDL 2.0 and later. SDL2 does not | ||
231 | change the working directory, which means it'll be whatever the command line | ||
232 | prompt that launched the program was using, or if launched by double-clicking | ||
233 | in the Finder, it will be "/", the _root of the filesystem_. Plan accordingly! | ||
234 | You can use SDL_GetBasePath() to find where the program is running from and | ||
235 | chdir() there directly. | ||
236 | |||
237 | |||
238 | ## You have a Cocoa App! | ||
239 | |||
240 | Your SDL app is essentially a Cocoa application. When your app | ||
241 | starts up and the libraries finish loading, a Cocoa procedure is called, | ||
242 | which sets up the working directory and calls your main() method. | ||
243 | You are free to modify your Cocoa app with generally no consequence | ||
244 | to SDL. You cannot, however, easily change the SDL window itself. | ||
245 | Functionality may be added in the future to help this. | ||
246 | |||
247 | # Bug reports | ||
248 | |||
249 | Bugs are tracked at [the GitHub issue tracker](https://github.com/libsdl-org/SDL/issues/). | ||
250 | Please feel free to report bugs there! | ||
251 | |||
diff --git a/src/contrib/SDL-3.2.20/docs/README-main-functions.md b/src/contrib/SDL-3.2.20/docs/README-main-functions.md new file mode 100644 index 0000000..75b9e2c --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-main-functions.md | |||
@@ -0,0 +1,236 @@ | |||
1 | # Where an SDL program starts running. | ||
2 | |||
3 | ## History | ||
4 | |||
5 | SDL has a long, complicated history with starting a program. | ||
6 | |||
7 | In most of the civilized world, an application starts in a C-callable | ||
8 | function named "main". You probably learned it a long time ago: | ||
9 | |||
10 | ```c | ||
11 | int main(int argc, char **argv) | ||
12 | { | ||
13 | printf("Hello world!\n"); | ||
14 | return 0; | ||
15 | } | ||
16 | ``` | ||
17 | |||
18 | But not all platforms work like this. Windows apps might want a different | ||
19 | function named "WinMain", for example, so SDL set out to paper over this | ||
20 | difference. | ||
21 | |||
22 | Generally how this would work is: your app would always use the "standard" | ||
23 | `main(argc, argv)` function as its entry point, and `#include` the proper | ||
24 | SDL header before that, which did some macro magic. On platforms that used | ||
25 | a standard `main`, it would do nothing and what you saw was what you got. | ||
26 | |||
27 | But those other platforms! If they needed something that _wasn't_ `main`, | ||
28 | SDL's macro magic would quietly rename your function to `SDL_main`, and | ||
29 | provide its own entry point that called it. Your app was none the wiser and | ||
30 | your code worked everywhere without changes. | ||
31 | |||
32 | |||
33 | ## The main entry point in SDL3 | ||
34 | |||
35 | Previous versions of SDL had a static library, SDLmain, that you would link | ||
36 | your app against. SDL3 still has the same macro tricks, but the static library | ||
37 | is gone. Now it's supplied by a "single-header library," which means you | ||
38 | `#include <SDL3/SDL_main.h>` and that header will insert a small amount of | ||
39 | code into the source file that included it, so you no longer have to worry | ||
40 | about linking against an extra library that you might need on some platforms. | ||
41 | You just build your app and it works. | ||
42 | |||
43 | You should _only_ include SDL_main.h from one file (the umbrella header, | ||
44 | SDL.h, does _not_ include it), and know that it will `#define main` to | ||
45 | something else, so if you use this symbol elsewhere as a variable name, etc, | ||
46 | it can cause you unexpected problems. | ||
47 | |||
48 | SDL_main.h will also include platform-specific code (WinMain or whatnot) that | ||
49 | calls your _actual_ main function. This is compiled directly into your | ||
50 | program. | ||
51 | |||
52 | If for some reason you need to include SDL_main.h in a file but also _don't_ | ||
53 | want it to generate this platform-specific code, you should define a special | ||
54 | macro before including the header: | ||
55 | |||
56 | |||
57 | ```c | ||
58 | #define SDL_MAIN_NOIMPL | ||
59 | ``` | ||
60 | |||
61 | If you are moving from SDL2, remove any references to the SDLmain static | ||
62 | library from your build system, and you should be done. Things should work as | ||
63 | they always have. | ||
64 | |||
65 | If you have never controlled your process's entry point (you are using SDL | ||
66 | as a module from a general-purpose scripting language interpreter, or you're | ||
67 | using SDL in a plugin for some otherwise-unrelated app), then there is nothing | ||
68 | required of you here; there is no startup code in SDL's entry point code that | ||
69 | is required, so using SDL_main.h is completely optional. Just start using | ||
70 | the SDL API when you are ready. | ||
71 | |||
72 | |||
73 | ## Main callbacks in SDL3 | ||
74 | |||
75 | There is a second option in SDL3 for how to structure your program. This is | ||
76 | completely optional and you can ignore it if you're happy using a standard | ||
77 | "main" function. | ||
78 | |||
79 | Some platforms would rather your program operate in chunks. Most of the time, | ||
80 | games tend to look like this at the highest level: | ||
81 | |||
82 | ```c | ||
83 | int main(int argc, char **argv) | ||
84 | { | ||
85 | initialize(); | ||
86 | while (keep_running()) { | ||
87 | handle_new_events(); | ||
88 | do_one_frame_of_stuff(); | ||
89 | } | ||
90 | deinitialize(); | ||
91 | } | ||
92 | ``` | ||
93 | |||
94 | There are platforms that would rather be in charge of that `while` loop: | ||
95 | iOS would rather you return from main() immediately and then it will let you | ||
96 | know that it's time to update and draw the next frame of video. Emscripten | ||
97 | (programs that run on a web page) absolutely requires this to function at all. | ||
98 | Video targets like Wayland can notify the app when to draw a new frame, to | ||
99 | save battery life and cooperate with the compositor more closely. | ||
100 | |||
101 | In most cases, you can add special-case code to your program to deal with this | ||
102 | on different platforms, but SDL3 offers a system to handle this transparently on | ||
103 | the app's behalf. | ||
104 | |||
105 | To use this, you have to redesign the highest level of your app a little. Once | ||
106 | you do, it'll work on all supported SDL platforms without problems and | ||
107 | `#ifdef`s in your code. | ||
108 | |||
109 | Instead of providing a "main" function, under this system, you would provide | ||
110 | several functions that SDL will call as appropriate. | ||
111 | |||
112 | Using the callback entry points works on every platform, because on platforms | ||
113 | that don't require them, we can fake them with a simple loop in an internal | ||
114 | implementation of the usual SDL_main. | ||
115 | |||
116 | The primary way we expect people to write SDL apps is still with SDL_main, and | ||
117 | this is not intended to replace it. If the app chooses to use this, it just | ||
118 | removes some platform-specific details they might have to otherwise manage, | ||
119 | and maybe removes a barrier to entry on some future platform. And you might | ||
120 | find you enjoy structuring your program like this more! | ||
121 | |||
122 | |||
123 | ## How to use main callbacks in SDL3 | ||
124 | |||
125 | To enable the callback entry points, you include SDL_main.h with an extra define, | ||
126 | from a single source file in your project: | ||
127 | |||
128 | ```c | ||
129 | #define SDL_MAIN_USE_CALLBACKS | ||
130 | #include <SDL3/SDL_main.h> | ||
131 | ``` | ||
132 | |||
133 | Once you do this, you do not write a "main" function at all (and if you do, | ||
134 | the app will likely fail to link). Instead, you provide the following | ||
135 | functions: | ||
136 | |||
137 | First: | ||
138 | |||
139 | ```c | ||
140 | SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv); | ||
141 | ``` | ||
142 | |||
143 | This will be called _once_ before anything else. argc/argv work like they | ||
144 | always do. If this returns SDL_APP_CONTINUE, the app runs. If it returns | ||
145 | SDL_APP_FAILURE, the app calls SDL_AppQuit and terminates with an exit | ||
146 | code that reports an error to the platform. If it returns SDL_APP_SUCCESS, | ||
147 | the app calls SDL_AppQuit and terminates with an exit code that reports | ||
148 | success to the platform. This function should not go into an infinite | ||
149 | mainloop; it should do any one-time startup it requires and then return. | ||
150 | |||
151 | If you want to, you can assign a pointer to `*appstate`, and this pointer | ||
152 | will be made available to you in later functions calls in their `appstate` | ||
153 | parameter. This allows you to avoid global variables, but is totally | ||
154 | optional. If you don't set this, the pointer will be NULL in later function | ||
155 | calls. | ||
156 | |||
157 | |||
158 | Then: | ||
159 | |||
160 | ```c | ||
161 | SDL_AppResult SDL_AppIterate(void *appstate); | ||
162 | ``` | ||
163 | |||
164 | This is called over and over, possibly at the refresh rate of the display or | ||
165 | some other metric that the platform dictates. This is where the heart of your | ||
166 | app runs. It should return as quickly as reasonably possible, but it's not a | ||
167 | "run one memcpy and that's all the time you have" sort of thing. The app | ||
168 | should do any game updates, and render a frame of video. If it returns | ||
169 | SDL_APP_FAILURE, SDL will call SDL_AppQuit and terminate the process with an | ||
170 | exit code that reports an error to the platform. If it returns | ||
171 | SDL_APP_SUCCESS, the app calls SDL_AppQuit and terminates with an exit code | ||
172 | that reports success to the platform. If it returns SDL_APP_CONTINUE, then | ||
173 | SDL_AppIterate will be called again at some regular frequency. The platform | ||
174 | may choose to run this more or less (perhaps less in the background, etc), | ||
175 | or it might just call this function in a loop as fast as possible. You do | ||
176 | not check the event queue in this function (SDL_AppEvent exists for that). | ||
177 | |||
178 | Next: | ||
179 | |||
180 | ```c | ||
181 | SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event); | ||
182 | ``` | ||
183 | |||
184 | This will be called whenever an SDL event arrives. Your app should not call | ||
185 | SDL_PollEvent, SDL_PumpEvent, etc, as SDL will manage all this for you. Return | ||
186 | values are the same as from SDL_AppIterate(), so you can terminate in response | ||
187 | to SDL_EVENT_QUIT, etc. | ||
188 | |||
189 | |||
190 | Finally: | ||
191 | |||
192 | ```c | ||
193 | void SDL_AppQuit(void *appstate, SDL_AppResult result); | ||
194 | ``` | ||
195 | |||
196 | This is called once before terminating the app--assuming the app isn't being | ||
197 | forcibly killed or crashed--as a last chance to clean up. After this returns, | ||
198 | SDL will call SDL_Quit so the app doesn't have to (but it's safe for the app | ||
199 | to call it, too). Process termination proceeds as if the app returned normally | ||
200 | from main(), so atexit handles will run, if your platform supports that. | ||
201 | |||
202 | If you set `*appstate` during SDL_AppInit, this is where you should free that | ||
203 | data, as this pointer will not be provided to your app again. | ||
204 | |||
205 | The SDL_AppResult value that terminated the app is provided here, in case | ||
206 | it's useful to know if this was a successful or failing run of the app. | ||
207 | |||
208 | |||
209 | ## Summary and Best Practices | ||
210 | |||
211 | - **Always Include SDL_main.h in One Source File:** When working with SDL, | ||
212 | remember that SDL_main.h must only be included in one source file in your | ||
213 | project. Including it in multiple files will lead to conflicts and undefined | ||
214 | behavior. | ||
215 | |||
216 | - **Avoid Redefining main:** If you're using SDL's entry point system (which | ||
217 | renames `main` to `SDL_main`), do not define `main` yourself. SDL takes care | ||
218 | of this for you, and redefining it can cause issues, especially when linking | ||
219 | with SDL libraries. | ||
220 | |||
221 | - **Using SDL's Callback System:** If you're working with more complex | ||
222 | scenarios, such as requiring more control over your application's flow | ||
223 | (e.g., with games or apps that need extensive event handling), consider | ||
224 | using SDL's callback system. Define the necessary callbacks and SDL will | ||
225 | handle initialization, event processing, and cleanup automatically. | ||
226 | |||
227 | - **Platform-Specific Considerations:** On platforms like Windows, SDL handles | ||
228 | the platform-specific entry point (like `WinMain`) automatically. This means | ||
229 | you don't need to worry about writing platform-specific entry code when | ||
230 | using SDL. | ||
231 | |||
232 | - **When to Skip SDL_main.h:** If you do not require SDL's custom entry point | ||
233 | (for example, if you're integrating SDL into an existing application or a | ||
234 | scripting environment), you can omit SDL_main.h. However, this will limit | ||
235 | SDL's ability to abstract away platform-specific entry point details. | ||
236 | |||
diff --git a/src/contrib/SDL-3.2.20/docs/README-migration.md b/src/contrib/SDL-3.2.20/docs/README-migration.md new file mode 100644 index 0000000..deca6d0 --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-migration.md | |||
@@ -0,0 +1,2295 @@ | |||
1 | # Migrating to SDL 3.0 | ||
2 | |||
3 | This guide provides useful information for migrating applications from SDL 2.0 to SDL 3.0. | ||
4 | |||
5 | Details on API changes are organized by SDL 2.0 header below. | ||
6 | |||
7 | The file with your main() function should include <SDL3/SDL_main.h>, as that is no longer included in SDL.h. | ||
8 | |||
9 | Functions that previously returned a negative error code now return bool. | ||
10 | |||
11 | Code that used to look like this: | ||
12 | ```c | ||
13 | if (SDL_Function() < 0 || SDL_Function() == -1) { | ||
14 | /* Failure... */ | ||
15 | } | ||
16 | ``` | ||
17 | or | ||
18 | ```c | ||
19 | if (SDL_Function() == 0) { | ||
20 | /* Success... */ | ||
21 | } | ||
22 | ``` | ||
23 | or | ||
24 | ```c | ||
25 | if (!SDL_Function()) { | ||
26 | /* Success... */ | ||
27 | } | ||
28 | ``` | ||
29 | should be changed to: | ||
30 | ```c | ||
31 | if (SDL_Function()) { | ||
32 | /* Success... */ | ||
33 | } else { | ||
34 | /* Failure... */ | ||
35 | } | ||
36 | ``` | ||
37 | This only applies to camel case functions, e.g. `SDL_[A-Z]*`. Lower case functions like SDL_strcmp() and SDL_memcmp() are unchanged, matching their C runtime counterpart. | ||
38 | |||
39 | Many functions and symbols have been renamed. We have provided a handy Python script [rename_symbols.py](https://github.com/libsdl-org/SDL/blob/main/build-scripts/rename_symbols.py) to rename SDL2 functions to their SDL3 counterparts: | ||
40 | ```sh | ||
41 | rename_symbols.py --all-symbols source_code_path | ||
42 | ``` | ||
43 | |||
44 | It's also possible to apply a semantic patch to migrate more easily to SDL3: [SDL_migration.cocci](https://github.com/libsdl-org/SDL/blob/main/build-scripts/SDL_migration.cocci) | ||
45 | |||
46 | SDL headers should now be included as `#include <SDL3/SDL.h>`. Typically that's the only SDL header you'll need in your application unless you are using OpenGL or Vulkan functionality. SDL_image, SDL_mixer, SDL_net, SDL_ttf and SDL_rtf have also their preferred include path changed: for SDL_image, it becomes `#include <SDL3_image/SDL_image.h>`. We have provided a handy Python script [rename_headers.py](https://github.com/libsdl-org/SDL/blob/main/build-scripts/rename_headers.py) to rename SDL2 headers to their SDL3 counterparts: | ||
47 | ```sh | ||
48 | rename_headers.py source_code_path | ||
49 | ``` | ||
50 | |||
51 | Some macros are renamed and/or removed in SDL3. We have provided a handy Python script [rename_macros.py](https://github.com/libsdl-org/SDL/blob/main/build-scripts/rename_macros.py) to replace these, and also add fixme comments on how to further improve the code: | ||
52 | ```sh | ||
53 | rename_macros.py source_code_path | ||
54 | ``` | ||
55 | |||
56 | |||
57 | CMake users should use this snippet to include SDL support in their project: | ||
58 | ```cmake | ||
59 | find_package(SDL3 REQUIRED CONFIG REQUIRED COMPONENTS SDL3) | ||
60 | target_link_libraries(mygame PRIVATE SDL3::SDL3) | ||
61 | ``` | ||
62 | |||
63 | Autotools users should use this snippet to include SDL support in their project: | ||
64 | ```m4 | ||
65 | PKG_CHECK_MODULES([SDL3], [sdl3]) | ||
66 | ``` | ||
67 | and then add `$SDL3_CFLAGS` to their project `CFLAGS` and `$SDL3_LIBS` to their project `LDFLAGS`. | ||
68 | |||
69 | Makefile users can use this snippet to include SDL support in their project: | ||
70 | ```make | ||
71 | CFLAGS += $(shell pkg-config sdl3 --cflags) | ||
72 | LDFLAGS += $(shell pkg-config sdl3 --libs) | ||
73 | ``` | ||
74 | |||
75 | The SDL3test library has been renamed SDL3_test. | ||
76 | |||
77 | The SDLmain library has been removed, it's been entirely replaced by SDL_main.h. | ||
78 | |||
79 | The vi format comments have been removed from source code. Vim users can use the [editorconfig plugin](https://github.com/editorconfig/editorconfig-vim) to automatically set tab spacing for the SDL coding style. | ||
80 | |||
81 | Installed SDL CMake configuration files no longer define `SDL3_PREFIX`, `SDL3_EXEC_PREFIX`, `SDL3_INCLUDE_DIR`, `SDL3_INCLUDE_DIRS`, `SDL3_BINDIR` or `SDL3_LIBDIR`. Users are expected to use [CMake generator expressions](https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html#target-dependent-expressions) with `SDL3::SDL3`, `SDL3::SDL3-shared`, `SDL3::SDL3-static` or `SDL3::Headers`. By no longer defining these CMake variables, using a system SDL3 or using a vendoring SDL3 behave in the same way. | ||
82 | |||
83 | ## SDL_atomic.h | ||
84 | |||
85 | The following structures have been renamed: | ||
86 | - SDL_atomic_t => SDL_AtomicInt | ||
87 | |||
88 | The following functions have been renamed: | ||
89 | * SDL_AtomicAdd() => SDL_AddAtomicInt() | ||
90 | * SDL_AtomicCAS() => SDL_CompareAndSwapAtomicInt() | ||
91 | * SDL_AtomicCASPtr() => SDL_CompareAndSwapAtomicPointer() | ||
92 | * SDL_AtomicGet() => SDL_GetAtomicInt() | ||
93 | * SDL_AtomicGetPtr() => SDL_GetAtomicPointer() | ||
94 | * SDL_AtomicLock() => SDL_LockSpinlock() | ||
95 | * SDL_AtomicSet() => SDL_SetAtomicInt() | ||
96 | * SDL_AtomicSetPtr() => SDL_SetAtomicPointer() | ||
97 | * SDL_AtomicTryLock() => SDL_TryLockSpinlock() | ||
98 | * SDL_AtomicUnlock() => SDL_UnlockSpinlock() | ||
99 | |||
100 | ## SDL_audio.h | ||
101 | |||
102 | The audio subsystem in SDL3 is dramatically different than SDL2. The primary way to play audio is no longer an audio callback; instead you bind SDL_AudioStreams to devices; however, there is still a callback method available if needed. | ||
103 | |||
104 | The SDL 1.2 audio compatibility API has also been removed, as it was a simplified version of the audio callback interface. | ||
105 | |||
106 | SDL3 will not implicitly initialize the audio subsystem on your behalf if you open a device without doing so. Please explicitly call SDL_Init(SDL_INIT_AUDIO) at some point. | ||
107 | |||
108 | SDL2 referred to audio devices that record sound as "capture" devices, and ones that play sound to speakers as "output" devices. In SDL3, we've changed this terminology to be "recording" devices and "playback" devices, which we hope is more clear. | ||
109 | |||
110 | SDL3's audio subsystem offers an enormous amount of power over SDL2, but if you just want a simple migration of your existing code, you can ignore most of it. The simplest migration path from SDL2 looks something like this: | ||
111 | |||
112 | In SDL2, you might have done something like this to play audio... | ||
113 | |||
114 | ```c | ||
115 | void SDLCALL MyAudioCallback(void *userdata, Uint8 * stream, int len) | ||
116 | { | ||
117 | /* Calculate a little more audio here, maybe using `userdata`, write it to `stream` */ | ||
118 | } | ||
119 | |||
120 | /* ...somewhere near startup... */ | ||
121 | SDL_AudioSpec my_desired_audio_format; | ||
122 | SDL_zero(my_desired_audio_format); | ||
123 | my_desired_audio_format.format = AUDIO_S16; | ||
124 | my_desired_audio_format.channels = 2; | ||
125 | my_desired_audio_format.freq = 44100; | ||
126 | my_desired_audio_format.samples = 1024; | ||
127 | my_desired_audio_format.callback = MyAudioCallback; | ||
128 | my_desired_audio_format.userdata = &my_audio_callback_user_data; | ||
129 | SDL_AudioDeviceID my_audio_device = SDL_OpenAudioDevice(NULL, 0, &my_desired_audio_format, NULL, 0); | ||
130 | SDL_PauseAudioDevice(my_audio_device, 0); | ||
131 | ``` | ||
132 | |||
133 | ...in SDL3, you can do this... | ||
134 | |||
135 | ```c | ||
136 | void SDLCALL MyNewAudioCallback(void *userdata, SDL_AudioStream *stream, int additional_amount, int total_amount) | ||
137 | { | ||
138 | /* Calculate a little more audio here, maybe using `userdata`, write it to `stream` | ||
139 | * | ||
140 | * If you want to use the original callback, you could do something like this: | ||
141 | */ | ||
142 | if (additional_amount > 0) { | ||
143 | Uint8 *data = SDL_stack_alloc(Uint8, additional_amount); | ||
144 | if (data) { | ||
145 | MyAudioCallback(userdata, data, additional_amount); | ||
146 | SDL_PutAudioStreamData(stream, data, additional_amount); | ||
147 | SDL_stack_free(data); | ||
148 | } | ||
149 | } | ||
150 | } | ||
151 | |||
152 | /* ...somewhere near startup... */ | ||
153 | const SDL_AudioSpec spec = { SDL_AUDIO_S16, 2, 44100 }; | ||
154 | SDL_AudioStream *stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec, MyNewAudioCallback, &my_audio_callback_user_data); | ||
155 | SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(stream)); | ||
156 | ``` | ||
157 | |||
158 | If you used SDL_QueueAudio instead of a callback in SDL2, this is also straightforward. | ||
159 | |||
160 | ```c | ||
161 | /* ...somewhere near startup... */ | ||
162 | const SDL_AudioSpec spec = { SDL_AUDIO_S16, 2, 44100 }; | ||
163 | SDL_AudioStream *stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec, NULL, NULL); | ||
164 | SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(stream)); | ||
165 | |||
166 | /* ...in your main loop... */ | ||
167 | /* calculate a little more audio into `buf`, add it to `stream` */ | ||
168 | SDL_PutAudioStreamData(stream, buf, buflen); | ||
169 | |||
170 | ``` | ||
171 | |||
172 | ...these same migration examples apply to audio recording, just using SDL_GetAudioStreamData instead of SDL_PutAudioStreamData. | ||
173 | |||
174 | SDL_AudioInit() and SDL_AudioQuit() have been removed. Instead you can call SDL_InitSubSystem() and SDL_QuitSubSystem() with SDL_INIT_AUDIO, which will properly refcount the subsystems. You can choose a specific audio driver using SDL_AUDIO_DRIVER hint. | ||
175 | |||
176 | The `SDL_AUDIO_ALLOW_*` symbols have been removed; now one may request the format they desire from the audio device, but ultimately SDL_AudioStream will manage the difference. One can use SDL_GetAudioDeviceFormat() to see what the final format is, if any "allowed" changes should be accomodated by the app. | ||
177 | |||
178 | SDL_AudioDeviceID now represents both an open audio device's handle (a "logical" device) and the instance ID that the hardware owns as long as it exists on the system (a "physical" device). The separation between device instances and device indexes is gone, and logical and physical devices are almost entirely interchangeable at the API level. | ||
179 | |||
180 | Devices are opened by physical device instance ID, and a new logical instance ID is generated by the open operation; This allows any device to be opened multiple times, possibly by unrelated pieces of code. SDL will manage the logical devices to provide a single stream of audio to the physical device behind the scenes. | ||
181 | |||
182 | Devices are not opened by an arbitrary string name anymore, but by device instance ID (or magic numbers to request a reasonable default, like a NULL string would do in SDL2). In SDL2, the string was used to open both a standard list of system devices, but also allowed for arbitrary devices, such as hostnames of network sound servers. In SDL3, many of the backends that supported arbitrary device names are obsolete and have been removed; of those that remain, arbitrary devices will be opened with a default device ID and an SDL_hint, so specific end-users can set an environment variable to fit their needs and apps don't have to concern themselves with it. | ||
183 | |||
184 | Many functions that would accept a device index and an `iscapture` parameter now just take an SDL_AudioDeviceID, as they are unique across all devices, instead of separate indices into playback and recording device lists. | ||
185 | |||
186 | Rather than iterating over audio devices using a device index, there are new functions, SDL_GetAudioPlaybackDevices() and SDL_GetAudioRecordingDevices(), to get the current list of devices, and new functions to get information about devices from their instance ID: | ||
187 | |||
188 | ```c | ||
189 | { | ||
190 | if (SDL_InitSubSystem(SDL_INIT_AUDIO)) { | ||
191 | int i, num_devices; | ||
192 | SDL_AudioDeviceID *devices = SDL_GetAudioPlaybackDevices(&num_devices); | ||
193 | if (devices) { | ||
194 | for (i = 0; i < num_devices; ++i) { | ||
195 | SDL_AudioDeviceID instance_id = devices[i]; | ||
196 | SDL_Log("AudioDevice %" SDL_PRIu32 ": %s", instance_id, SDL_GetAudioDeviceName(instance_id)); | ||
197 | } | ||
198 | SDL_free(devices); | ||
199 | } | ||
200 | SDL_QuitSubSystem(SDL_INIT_AUDIO); | ||
201 | } | ||
202 | } | ||
203 | ``` | ||
204 | |||
205 | SDL_LockAudioDevice() and SDL_UnlockAudioDevice() have been removed, since there is no callback in another thread to protect. SDL's audio subsystem and SDL_AudioStream maintain their own locks internally, so audio streams are safe to use from any thread. If the app assigns a callback to a specific stream, it can use the stream's lock through SDL_LockAudioStream() if necessary. | ||
206 | |||
207 | SDL_PauseAudioDevice() no longer takes a second argument; it always pauses the device. To unpause, use SDL_ResumeAudioDevice(). | ||
208 | |||
209 | Audio devices, opened by SDL_OpenAudioDevice(), no longer start in a paused state, as they don't begin processing audio until a stream is bound. | ||
210 | |||
211 | SDL_GetAudioDeviceStatus() has been removed; there is now SDL_AudioDevicePaused(). | ||
212 | |||
213 | SDL_QueueAudio(), SDL_DequeueAudio, and SDL_ClearQueuedAudio and SDL_GetQueuedAudioSize() have been removed; an SDL_AudioStream bound to a device provides the exact same functionality. | ||
214 | |||
215 | APIs that use channel counts used to use a Uint8 for the channel; now they use int. | ||
216 | |||
217 | SDL_AudioSpec has been reduced; now it only holds format, channel, and sample rate. SDL_GetSilenceValueForFormat() can provide the information from the SDL_AudioSpec's removed `silence` field. SDL3 now manages the removed `samples` field; apps that want more control over device latency and throughput can force a newly-opened device's sample count with the SDL_HINT_AUDIO_DEVICE_SAMPLE_FRAMES hint, but most apps should not risk messing with the defaults. The other SDL2 SDL_AudioSpec fields aren't relevant anymore. | ||
218 | |||
219 | SDL_GetAudioDeviceSpec() is removed; use SDL_GetAudioDeviceFormat() instead. | ||
220 | |||
221 | SDL_GetDefaultAudioInfo() is removed; SDL_GetAudioDeviceFormat() with SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK or SDL_AUDIO_DEVICE_DEFAULT_RECORDING. There is no replacement for querying the default device name; the string is no longer used to open devices, and SDL3 will migrate between physical devices on the fly if the system default changes, so if you must show this to the user, a generic name like "System default" is recommended. | ||
222 | |||
223 | SDL_MixAudioFormat() and SDL_MIX_MAXVOLUME have been removed in favour of SDL_MixAudio(), which now takes the audio format, and a float volume between 0.0 and 1.0. | ||
224 | |||
225 | SDL_FreeWAV has been removed and calls can be replaced with SDL_free. | ||
226 | |||
227 | SDL_LoadWAV() is a proper function now and no longer a macro (but offers the same functionality otherwise). | ||
228 | |||
229 | SDL_LoadWAV_IO() and SDL_LoadWAV() return an bool now, like most of SDL. They no longer return a pointer to an SDL_AudioSpec. | ||
230 | |||
231 | SDL_AudioCVT interface has been removed, the SDL_AudioStream interface (for audio supplied in pieces) or the new SDL_ConvertAudioSamples() function (for converting a complete audio buffer in one call) can be used instead. | ||
232 | |||
233 | Code that used to look like this: | ||
234 | ```c | ||
235 | SDL_AudioCVT cvt; | ||
236 | SDL_BuildAudioCVT(&cvt, src_format, src_channels, src_rate, dst_format, dst_channels, dst_rate); | ||
237 | cvt.len = src_len; | ||
238 | cvt.buf = (Uint8 *) SDL_malloc(src_len * cvt.len_mult); | ||
239 | SDL_memcpy(cvt.buf, src_data, src_len); | ||
240 | SDL_ConvertAudio(&cvt); | ||
241 | do_something(cvt.buf, cvt.len_cvt); | ||
242 | ``` | ||
243 | should be changed to: | ||
244 | ```c | ||
245 | Uint8 *dst_data = NULL; | ||
246 | int dst_len = 0; | ||
247 | const SDL_AudioSpec src_spec = { src_format, src_channels, src_rate }; | ||
248 | const SDL_AudioSpec dst_spec = { dst_format, dst_channels, dst_rate }; | ||
249 | if (!SDL_ConvertAudioSamples(&src_spec, src_data, src_len, &dst_spec, &dst_data, &dst_len)) { | ||
250 | /* error */ | ||
251 | } | ||
252 | do_something(dst_data, dst_len); | ||
253 | SDL_free(dst_data); | ||
254 | ``` | ||
255 | |||
256 | AUDIO_U16, AUDIO_U16LSB, AUDIO_U16MSB, and AUDIO_U16SYS have been removed. They were not heavily used, and one could not memset a buffer in this format to silence with a single byte value. Use a different audio format. | ||
257 | |||
258 | If you need to convert U16 audio data to a still-supported format at runtime, the fastest, lossless conversion is to SDL_AUDIO_S16: | ||
259 | |||
260 | ```c | ||
261 | /* this converts the buffer in-place. The buffer size does not change. */ | ||
262 | Sint16 *audio_ui16_to_si16(Uint16 *buffer, const size_t num_samples) | ||
263 | { | ||
264 | size_t i; | ||
265 | const Uint16 *src = buffer; | ||
266 | Sint16 *dst = (Sint16 *) buffer; | ||
267 | |||
268 | for (i = 0; i < num_samples; i++) { | ||
269 | dst[i] = (Sint16) (src[i] ^ 0x8000); | ||
270 | } | ||
271 | |||
272 | return dst; | ||
273 | } | ||
274 | ``` | ||
275 | |||
276 | All remaining `AUDIO_*` symbols have been renamed to `SDL_AUDIO_*` for API consistency, but othewise are identical in value and usage. | ||
277 | |||
278 | In SDL2, SDL_AudioStream would convert/resample audio data during input (via SDL_AudioStreamPut). In SDL3, it does this work when requesting audio (via SDL_GetAudioStreamData, which would have been SDL_AudioStreamGet in SDL2). The way you use an AudioStream is roughly the same, just be aware that the workload moved to a different phase. | ||
279 | |||
280 | In SDL2, SDL_AudioStreamAvailable() returns 0 if passed a NULL stream. In SDL3, the equivalent SDL_GetAudioStreamAvailable() call returns -1 and sets an error string, which matches other audiostream APIs' behavior. | ||
281 | |||
282 | In SDL2, SDL_AUDIODEVICEREMOVED events would fire for open devices with the `which` field set to the SDL_AudioDeviceID of the lost device, and in later SDL2 releases, would also fire this event with a `which` field of zero for unopened devices, to signify that the app might want to refresh the available device list. In SDL3, this event works the same, except it won't ever fire with a zero; in this case it'll return the physical device's SDL_AudioDeviceID. Any still-open SDL_AudioDeviceIDs generated from this device with SDL_OpenAudioDevice() will also fire a separate event. | ||
283 | |||
284 | The following functions have been renamed: | ||
285 | * SDL_AudioStreamAvailable() => SDL_GetAudioStreamAvailable() | ||
286 | * SDL_AudioStreamClear() => SDL_ClearAudioStream(), returns bool | ||
287 | * SDL_AudioStreamFlush() => SDL_FlushAudioStream(), returns bool | ||
288 | * SDL_AudioStreamGet() => SDL_GetAudioStreamData() | ||
289 | * SDL_AudioStreamPut() => SDL_PutAudioStreamData(), returns bool | ||
290 | * SDL_FreeAudioStream() => SDL_DestroyAudioStream() | ||
291 | * SDL_LoadWAV_RW() => SDL_LoadWAV_IO(), returns bool | ||
292 | * SDL_MixAudioFormat() => SDL_MixAudio(), returns bool | ||
293 | * SDL_NewAudioStream() => SDL_CreateAudioStream() | ||
294 | |||
295 | |||
296 | The following functions have been removed: | ||
297 | * SDL_GetNumAudioDevices() | ||
298 | * SDL_GetAudioDeviceSpec() | ||
299 | * SDL_ConvertAudio() | ||
300 | * SDL_BuildAudioCVT() | ||
301 | * SDL_OpenAudio() | ||
302 | * SDL_CloseAudio() | ||
303 | * SDL_PauseAudio() | ||
304 | * SDL_GetAudioStatus() | ||
305 | * SDL_GetAudioDeviceStatus() | ||
306 | * SDL_GetDefaultAudioInfo() | ||
307 | * SDL_LockAudio() | ||
308 | * SDL_LockAudioDevice() | ||
309 | * SDL_UnlockAudio() | ||
310 | * SDL_UnlockAudioDevice() | ||
311 | * SDL_MixAudio() | ||
312 | * SDL_QueueAudio() | ||
313 | * SDL_DequeueAudio() | ||
314 | * SDL_ClearAudioQueue() | ||
315 | * SDL_GetQueuedAudioSize() | ||
316 | |||
317 | The following symbols have been renamed: | ||
318 | * AUDIO_F32 => SDL_AUDIO_F32LE | ||
319 | * AUDIO_F32LSB => SDL_AUDIO_F32LE | ||
320 | * AUDIO_F32MSB => SDL_AUDIO_F32BE | ||
321 | * AUDIO_F32SYS => SDL_AUDIO_F32 | ||
322 | * AUDIO_S16 => SDL_AUDIO_S16LE | ||
323 | * AUDIO_S16LSB => SDL_AUDIO_S16LE | ||
324 | * AUDIO_S16MSB => SDL_AUDIO_S16BE | ||
325 | * AUDIO_S16SYS => SDL_AUDIO_S16 | ||
326 | * AUDIO_S32 => SDL_AUDIO_S32LE | ||
327 | * AUDIO_S32LSB => SDL_AUDIO_S32LE | ||
328 | * AUDIO_S32MSB => SDL_AUDIO_S32BE | ||
329 | * AUDIO_S32SYS => SDL_AUDIO_S32 | ||
330 | * AUDIO_S8 => SDL_AUDIO_S8 | ||
331 | * AUDIO_U8 => SDL_AUDIO_U8 | ||
332 | |||
333 | The following symbols have been removed: | ||
334 | * SDL_MIX_MAXVOLUME - mixer volume is now a float between 0.0 and 1.0 | ||
335 | |||
336 | ## SDL_cpuinfo.h | ||
337 | |||
338 | The intrinsics headers (mmintrin.h, etc.) have been moved to `<SDL3/SDL_intrin.h>` and are no longer automatically included in SDL.h. | ||
339 | |||
340 | SDL_Has3DNow() has been removed; there is no replacement. | ||
341 | |||
342 | SDL_HasRDTSC() has been removed; there is no replacement. Don't use the RDTSC opcode in modern times, use SDL_GetPerformanceCounter and SDL_GetPerformanceFrequency instead. | ||
343 | |||
344 | SDL_SIMDAlloc(), SDL_SIMDRealloc(), and SDL_SIMDFree() have been removed. You can use SDL_aligned_alloc() and SDL_aligned_free() with SDL_GetSIMDAlignment() to get the same functionality. | ||
345 | |||
346 | The following functions have been renamed: | ||
347 | * SDL_GetCPUCount() => SDL_GetNumLogicalCPUCores() | ||
348 | * SDL_SIMDGetAlignment() => SDL_GetSIMDAlignment() | ||
349 | |||
350 | ## SDL_endian.h | ||
351 | |||
352 | The following functions have been renamed: | ||
353 | * SDL_SwapBE16() => SDL_Swap16BE() | ||
354 | * SDL_SwapBE32() => SDL_Swap32BE() | ||
355 | * SDL_SwapBE64() => SDL_Swap64BE() | ||
356 | * SDL_SwapLE16() => SDL_Swap16LE() | ||
357 | * SDL_SwapLE32() => SDL_Swap32LE() | ||
358 | * SDL_SwapLE64() => SDL_Swap64LE() | ||
359 | |||
360 | ## SDL_error.h | ||
361 | |||
362 | The following functions have been removed: | ||
363 | * SDL_GetErrorMsg() - Can be implemented as `SDL_strlcpy(errstr, SDL_GetError(), maxlen);` | ||
364 | |||
365 | ## SDL_events.h | ||
366 | |||
367 | SDL_PRESSED and SDL_RELEASED have been removed. For the most part you can replace uses of these with true and false respectively. Events which had a field `state` to represent these values have had those fields changed to bool `down`, e.g. `event.key.state` is now `event.key.down`. | ||
368 | |||
369 | The timestamp member of the SDL_Event structure now represents nanoseconds, and is populated with SDL_GetTicksNS() | ||
370 | |||
371 | The timestamp_us member of the sensor events has been renamed sensor_timestamp and now represents nanoseconds. This value is filled in from the hardware, if available, and may not be synchronized with values returned from SDL_GetTicksNS(). | ||
372 | |||
373 | You should set the event.common.timestamp field before passing an event to SDL_PushEvent(). If the timestamp is 0 it will be filled in with SDL_GetTicksNS(). | ||
374 | |||
375 | Event memory is now managed by SDL, so you should not free the data in SDL_EVENT_DROP_FILE, and if you want to hold onto the text in SDL_EVENT_TEXT_EDITING and SDL_EVENT_TEXT_INPUT events, you should make a copy of it. SDL_TEXTINPUTEVENT_TEXT_SIZE is no longer necessary and has been removed. | ||
376 | |||
377 | Mouse events use floating point values for mouse coordinates and relative motion values. You can get sub-pixel motion depending on the platform and display scaling. | ||
378 | |||
379 | The SDL_DISPLAYEVENT_* events have been moved to top level events, and SDL_DISPLAYEVENT has been removed. In general, handling this change just means checking for the individual events instead of first checking for SDL_DISPLAYEVENT and then checking for display events. You can compare the event >= SDL_EVENT_DISPLAY_FIRST and <= SDL_EVENT_DISPLAY_LAST if you need to see whether it's a display event. | ||
380 | |||
381 | The SDL_WINDOWEVENT_* events have been moved to top level events, and SDL_WINDOWEVENT has been removed. In general, handling this change just means checking for the individual events instead of first checking for SDL_WINDOWEVENT and then checking for window events. You can compare the event >= SDL_EVENT_WINDOW_FIRST and <= SDL_EVENT_WINDOW_LAST if you need to see whether it's a window event. | ||
382 | |||
383 | The SDL_EVENT_WINDOW_RESIZED event is always sent, even in response to SDL_SetWindowSize(). | ||
384 | |||
385 | The SDL_EVENT_WINDOW_SIZE_CHANGED event has been removed, and you can use SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED to detect window backbuffer size changes. | ||
386 | |||
387 | The keysym field of key events has been removed to remove one level of indirection, and `sym` has been renamed `key`. | ||
388 | |||
389 | Code that used to look like this: | ||
390 | ```c | ||
391 | SDL_Event event; | ||
392 | SDL_Keycode key = event.key.keysym.sym; | ||
393 | SDL_Keymod mod = event.key.keysym.mod; | ||
394 | ``` | ||
395 | should be changed to: | ||
396 | ```c | ||
397 | SDL_Event event; | ||
398 | SDL_Keycode key = event.key.key; | ||
399 | SDL_Keymod mod = event.key.mod; | ||
400 | ``` | ||
401 | |||
402 | The gamepad event structures caxis, cbutton, cdevice, ctouchpad, and csensor have been renamed gaxis, gbutton, gdevice, gtouchpad, and gsensor. | ||
403 | |||
404 | The mouseX and mouseY fields of SDL_MouseWheelEvent have been renamed mouse_x and mouse_y. | ||
405 | |||
406 | The touchId and fingerId fields of SDL_TouchFingerEvent have been renamed touchID and fingerID. | ||
407 | |||
408 | The level field of SDL_JoyBatteryEvent has been split into state and percent. | ||
409 | |||
410 | The iscapture field of SDL_AudioDeviceEvent has been renamed recording. | ||
411 | |||
412 | SDL_QUERY, SDL_IGNORE, SDL_ENABLE, and SDL_DISABLE have been removed. You can use the functions SDL_SetEventEnabled() and SDL_EventEnabled() to set and query event processing state. | ||
413 | |||
414 | SDL_AddEventWatch() now returns false if it fails because it ran out of memory and couldn't add the event watch callback. | ||
415 | |||
416 | SDL_RegisterEvents() now returns 0 if it couldn't allocate any user events. | ||
417 | |||
418 | SDL_EventFilter functions now return bool. | ||
419 | |||
420 | The following symbols have been renamed: | ||
421 | * SDL_APP_DIDENTERBACKGROUND => SDL_EVENT_DID_ENTER_BACKGROUND | ||
422 | * SDL_APP_DIDENTERFOREGROUND => SDL_EVENT_DID_ENTER_FOREGROUND | ||
423 | * SDL_APP_LOWMEMORY => SDL_EVENT_LOW_MEMORY | ||
424 | * SDL_APP_TERMINATING => SDL_EVENT_TERMINATING | ||
425 | * SDL_APP_WILLENTERBACKGROUND => SDL_EVENT_WILL_ENTER_BACKGROUND | ||
426 | * SDL_APP_WILLENTERFOREGROUND => SDL_EVENT_WILL_ENTER_FOREGROUND | ||
427 | * SDL_AUDIODEVICEADDED => SDL_EVENT_AUDIO_DEVICE_ADDED | ||
428 | * SDL_AUDIODEVICEREMOVED => SDL_EVENT_AUDIO_DEVICE_REMOVED | ||
429 | * SDL_CLIPBOARDUPDATE => SDL_EVENT_CLIPBOARD_UPDATE | ||
430 | * SDL_CONTROLLERAXISMOTION => SDL_EVENT_GAMEPAD_AXIS_MOTION | ||
431 | * SDL_CONTROLLERBUTTONDOWN => SDL_EVENT_GAMEPAD_BUTTON_DOWN | ||
432 | * SDL_CONTROLLERBUTTONUP => SDL_EVENT_GAMEPAD_BUTTON_UP | ||
433 | * SDL_CONTROLLERDEVICEADDED => SDL_EVENT_GAMEPAD_ADDED | ||
434 | * SDL_CONTROLLERDEVICEREMAPPED => SDL_EVENT_GAMEPAD_REMAPPED | ||
435 | * SDL_CONTROLLERDEVICEREMOVED => SDL_EVENT_GAMEPAD_REMOVED | ||
436 | * SDL_CONTROLLERSENSORUPDATE => SDL_EVENT_GAMEPAD_SENSOR_UPDATE | ||
437 | * SDL_CONTROLLERSTEAMHANDLEUPDATED => SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED | ||
438 | * SDL_CONTROLLERTOUCHPADDOWN => SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN | ||
439 | * SDL_CONTROLLERTOUCHPADMOTION => SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION | ||
440 | * SDL_CONTROLLERTOUCHPADUP => SDL_EVENT_GAMEPAD_TOUCHPAD_UP | ||
441 | * SDL_DROPBEGIN => SDL_EVENT_DROP_BEGIN | ||
442 | * SDL_DROPCOMPLETE => SDL_EVENT_DROP_COMPLETE | ||
443 | * SDL_DROPFILE => SDL_EVENT_DROP_FILE | ||
444 | * SDL_DROPTEXT => SDL_EVENT_DROP_TEXT | ||
445 | * SDL_FINGERDOWN => SDL_EVENT_FINGER_DOWN | ||
446 | * SDL_FINGERMOTION => SDL_EVENT_FINGER_MOTION | ||
447 | * SDL_FINGERUP => SDL_EVENT_FINGER_UP | ||
448 | * SDL_FIRSTEVENT => SDL_EVENT_FIRST | ||
449 | * SDL_JOYAXISMOTION => SDL_EVENT_JOYSTICK_AXIS_MOTION | ||
450 | * SDL_JOYBALLMOTION => SDL_EVENT_JOYSTICK_BALL_MOTION | ||
451 | * SDL_JOYBATTERYUPDATED => SDL_EVENT_JOYSTICK_BATTERY_UPDATED | ||
452 | * SDL_JOYBUTTONDOWN => SDL_EVENT_JOYSTICK_BUTTON_DOWN | ||
453 | * SDL_JOYBUTTONUP => SDL_EVENT_JOYSTICK_BUTTON_UP | ||
454 | * SDL_JOYDEVICEADDED => SDL_EVENT_JOYSTICK_ADDED | ||
455 | * SDL_JOYDEVICEREMOVED => SDL_EVENT_JOYSTICK_REMOVED | ||
456 | * SDL_JOYHATMOTION => SDL_EVENT_JOYSTICK_HAT_MOTION | ||
457 | * SDL_KEYDOWN => SDL_EVENT_KEY_DOWN | ||
458 | * SDL_KEYMAPCHANGED => SDL_EVENT_KEYMAP_CHANGED | ||
459 | * SDL_KEYUP => SDL_EVENT_KEY_UP | ||
460 | * SDL_LASTEVENT => SDL_EVENT_LAST | ||
461 | * SDL_LOCALECHANGED => SDL_EVENT_LOCALE_CHANGED | ||
462 | * SDL_MOUSEBUTTONDOWN => SDL_EVENT_MOUSE_BUTTON_DOWN | ||
463 | * SDL_MOUSEBUTTONUP => SDL_EVENT_MOUSE_BUTTON_UP | ||
464 | * SDL_MOUSEMOTION => SDL_EVENT_MOUSE_MOTION | ||
465 | * SDL_MOUSEWHEEL => SDL_EVENT_MOUSE_WHEEL | ||
466 | * SDL_POLLSENTINEL => SDL_EVENT_POLL_SENTINEL | ||
467 | * SDL_QUIT => SDL_EVENT_QUIT | ||
468 | * SDL_RENDER_DEVICE_RESET => SDL_EVENT_RENDER_DEVICE_RESET | ||
469 | * SDL_RENDER_TARGETS_RESET => SDL_EVENT_RENDER_TARGETS_RESET | ||
470 | * SDL_SENSORUPDATE => SDL_EVENT_SENSOR_UPDATE | ||
471 | * SDL_TEXTEDITING => SDL_EVENT_TEXT_EDITING | ||
472 | * SDL_TEXTEDITING_EXT => SDL_EVENT_TEXT_EDITING_EXT | ||
473 | * SDL_TEXTINPUT => SDL_EVENT_TEXT_INPUT | ||
474 | * SDL_USEREVENT => SDL_EVENT_USER | ||
475 | |||
476 | The following symbols have been removed: | ||
477 | * SDL_DROPEVENT_DATA_SIZE - drop event data is dynamically allocated | ||
478 | * SDL_SYSWMEVENT - you can use SDL_SetWindowsMessageHook() and SDL_SetX11EventHook() to watch and modify system events before SDL sees them. | ||
479 | * SDL_TEXTEDITINGEVENT_TEXT_SIZE - text editing event data is dynamically allocated | ||
480 | |||
481 | The following structures have been renamed: | ||
482 | * SDL_ControllerAxisEvent => SDL_GamepadAxisEvent | ||
483 | * SDL_ControllerButtonEvent => SDL_GamepadButtonEvent | ||
484 | * SDL_ControllerDeviceEvent => SDL_GamepadDeviceEvent | ||
485 | * SDL_ControllerSensorEvent => SDL_GamepadSensorEvent | ||
486 | * SDL_ControllerTouchpadEvent => SDL_GamepadTouchpadEvent | ||
487 | |||
488 | The following functions have been removed: | ||
489 | * SDL_EventState() - replaced with SDL_SetEventEnabled() | ||
490 | * SDL_GetEventState() - replaced with SDL_EventEnabled() | ||
491 | |||
492 | The following enums have been renamed: | ||
493 | * SDL_eventaction => SDL_EventAction | ||
494 | |||
495 | The following functions have been renamed: | ||
496 | * SDL_DelEventWatch() => SDL_RemoveEventWatch() | ||
497 | |||
498 | ## SDL_gamecontroller.h | ||
499 | |||
500 | SDL_gamecontroller.h has been renamed SDL_gamepad.h, and all APIs have been renamed to match. | ||
501 | |||
502 | The SDL_EVENT_GAMEPAD_ADDED event now provides the joystick instance ID in the which member of the cdevice event structure. | ||
503 | |||
504 | The functions SDL_GetGamepads(), SDL_GetGamepadNameForID(), SDL_GetGamepadPathForID(), SDL_GetGamepadPlayerIndexForID(), SDL_GetGamepadGUIDForID(), SDL_GetGamepadVendorForID(), SDL_GetGamepadProductForID(), SDL_GetGamepadProductVersionForID(), and SDL_GetGamepadTypeForID() have been added to directly query the list of available gamepads. | ||
505 | |||
506 | The gamepad face buttons have been renamed from A/B/X/Y to North/South/East/West to indicate that they are positional rather than hardware-specific. You can use SDL_GetGamepadButtonLabel() to get the labels for the face buttons, e.g. A/B/X/Y or Cross/Circle/Square/Triangle. The hint SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS is ignored, and mappings that use this hint are translated correctly into positional buttons. Applications should provide a way for users to swap between South/East as their accept/cancel buttons, as this varies based on region and muscle memory. You can use an approach similar to the following to handle this: | ||
507 | |||
508 | ```c | ||
509 | #define CONFIRM_BUTTON SDL_GAMEPAD_BUTTON_SOUTH | ||
510 | #define CANCEL_BUTTON SDL_GAMEPAD_BUTTON_EAST | ||
511 | |||
512 | bool flipped_buttons; | ||
513 | |||
514 | void InitMappedButtons(SDL_Gamepad *gamepad) | ||
515 | { | ||
516 | if (!GetFlippedButtonSetting(&flipped_buttons)) { | ||
517 | if (SDL_GetGamepadButtonLabel(gamepad, SDL_GAMEPAD_BUTTON_SOUTH) == SDL_GAMEPAD_BUTTON_LABEL_B) { | ||
518 | flipped_buttons = true; | ||
519 | } else { | ||
520 | flipped_buttons = false; | ||
521 | } | ||
522 | } | ||
523 | } | ||
524 | |||
525 | SDL_GamepadButton GetMappedButton(SDL_GamepadButton button) | ||
526 | { | ||
527 | if (flipped_buttons) { | ||
528 | switch (button) { | ||
529 | case SDL_GAMEPAD_BUTTON_SOUTH: | ||
530 | return SDL_GAMEPAD_BUTTON_EAST; | ||
531 | case SDL_GAMEPAD_BUTTON_EAST: | ||
532 | return SDL_GAMEPAD_BUTTON_SOUTH; | ||
533 | case SDL_GAMEPAD_BUTTON_WEST: | ||
534 | return SDL_GAMEPAD_BUTTON_NORTH; | ||
535 | case SDL_GAMEPAD_BUTTON_NORTH: | ||
536 | return SDL_GAMEPAD_BUTTON_WEST; | ||
537 | default: | ||
538 | break; | ||
539 | } | ||
540 | } | ||
541 | return button; | ||
542 | } | ||
543 | |||
544 | SDL_GamepadButtonLabel GetConfirmActionLabel(SDL_Gamepad *gamepad) | ||
545 | { | ||
546 | return SDL_GetGamepadButtonLabel(gamepad, GetMappedButton(CONFIRM_BUTTON)); | ||
547 | } | ||
548 | |||
549 | SDL_GamepadButtonLabel GetCancelActionLabel(SDL_Gamepad *gamepad) | ||
550 | { | ||
551 | return SDL_GetGamepadButtonLabel(gamepad, GetMappedButton(CANCEL_BUTTON)); | ||
552 | } | ||
553 | |||
554 | void HandleGamepadEvent(SDL_Event *event) | ||
555 | { | ||
556 | if (event->type == SDL_EVENT_GAMEPAD_BUTTON_DOWN) { | ||
557 | switch (GetMappedButton(event->gbutton.button)) { | ||
558 | case CONFIRM_BUTTON: | ||
559 | /* Handle confirm action */ | ||
560 | break; | ||
561 | case CANCEL_BUTTON: | ||
562 | /* Handle cancel action */ | ||
563 | break; | ||
564 | default: | ||
565 | /* ... */ | ||
566 | break; | ||
567 | } | ||
568 | } | ||
569 | } | ||
570 | ``` | ||
571 | |||
572 | SDL_GameControllerGetSensorDataWithTimestamp() has been removed. If you want timestamps for the sensor data, you should use the sensor_timestamp member of SDL_EVENT_GAMEPAD_SENSOR_UPDATE events. | ||
573 | |||
574 | SDL_CONTROLLER_TYPE_VIRTUAL has been removed, so virtual controllers can emulate other gamepad types. If you need to know whether a controller is virtual, you can use SDL_IsJoystickVirtual(). | ||
575 | |||
576 | SDL_CONTROLLER_TYPE_AMAZON_LUNA has been removed, and can be replaced with this code: | ||
577 | ```c | ||
578 | bool SDL_IsJoystickAmazonLunaController(Uint16 vendor_id, Uint16 product_id) | ||
579 | { | ||
580 | return ((vendor_id == 0x1949 && product_id == 0x0419) || | ||
581 | (vendor_id == 0x0171 && product_id == 0x0419)); | ||
582 | } | ||
583 | ``` | ||
584 | |||
585 | SDL_CONTROLLER_TYPE_GOOGLE_STADIA has been removed, and can be replaced with this code: | ||
586 | ```c | ||
587 | bool SDL_IsJoystickGoogleStadiaController(Uint16 vendor_id, Uint16 product_id) | ||
588 | { | ||
589 | return (vendor_id == 0x18d1 && product_id == 0x9400); | ||
590 | } | ||
591 | ``` | ||
592 | |||
593 | SDL_CONTROLLER_TYPE_NVIDIA_SHIELD has been removed, and can be replaced with this code: | ||
594 | ```c | ||
595 | bool SDL_IsJoystickNVIDIASHIELDController(Uint16 vendor_id, Uint16 product_id) | ||
596 | { | ||
597 | return (vendor_id == 0x0955 && (product_id == 0x7210 || product_id == 0x7214)); | ||
598 | } | ||
599 | ``` | ||
600 | |||
601 | The inputType and outputType fields of SDL_GamepadBinding have been renamed input_type and output_type. | ||
602 | |||
603 | SDL_GetGamepadTouchpadFinger() takes a pointer to bool for the finger state instead of a pointer to Uint8. | ||
604 | |||
605 | The following enums have been renamed: | ||
606 | * SDL_GameControllerAxis => SDL_GamepadAxis | ||
607 | * SDL_GameControllerBindType => SDL_GamepadBindingType | ||
608 | * SDL_GameControllerButton => SDL_GamepadButton | ||
609 | * SDL_GameControllerType => SDL_GamepadType | ||
610 | |||
611 | The following structures have been renamed: | ||
612 | * SDL_GameController => SDL_Gamepad | ||
613 | |||
614 | The following functions have been renamed: | ||
615 | * SDL_GameControllerAddMapping() => SDL_AddGamepadMapping() | ||
616 | * SDL_GameControllerAddMappingsFromFile() => SDL_AddGamepadMappingsFromFile() | ||
617 | * SDL_GameControllerAddMappingsFromRW() => SDL_AddGamepadMappingsFromIO() | ||
618 | * SDL_GameControllerClose() => SDL_CloseGamepad() | ||
619 | * SDL_GameControllerFromInstanceID() => SDL_GetGamepadFromID() | ||
620 | * SDL_GameControllerFromPlayerIndex() => SDL_GetGamepadFromPlayerIndex() | ||
621 | * SDL_GameControllerGetAppleSFSymbolsNameForAxis() => SDL_GetGamepadAppleSFSymbolsNameForAxis() | ||
622 | * SDL_GameControllerGetAppleSFSymbolsNameForButton() => SDL_GetGamepadAppleSFSymbolsNameForButton() | ||
623 | * SDL_GameControllerGetAttached() => SDL_GamepadConnected() | ||
624 | * SDL_GameControllerGetAxis() => SDL_GetGamepadAxis() | ||
625 | * SDL_GameControllerGetAxisFromString() => SDL_GetGamepadAxisFromString() | ||
626 | * SDL_GameControllerGetButton() => SDL_GetGamepadButton() | ||
627 | * SDL_GameControllerGetButtonFromString() => SDL_GetGamepadButtonFromString() | ||
628 | * SDL_GameControllerGetFirmwareVersion() => SDL_GetGamepadFirmwareVersion() | ||
629 | * SDL_GameControllerGetJoystick() => SDL_GetGamepadJoystick() | ||
630 | * SDL_GameControllerGetNumTouchpadFingers() => SDL_GetNumGamepadTouchpadFingers() | ||
631 | * SDL_GameControllerGetNumTouchpads() => SDL_GetNumGamepadTouchpads() | ||
632 | * SDL_GameControllerGetPlayerIndex() => SDL_GetGamepadPlayerIndex() | ||
633 | * SDL_GameControllerGetProduct() => SDL_GetGamepadProduct() | ||
634 | * SDL_GameControllerGetProductVersion() => SDL_GetGamepadProductVersion() | ||
635 | * SDL_GameControllerGetSensorData() => SDL_GetGamepadSensorData(), returns bool | ||
636 | * SDL_GameControllerGetSensorDataRate() => SDL_GetGamepadSensorDataRate() | ||
637 | * SDL_GameControllerGetSerial() => SDL_GetGamepadSerial() | ||
638 | * SDL_GameControllerGetSteamHandle() => SDL_GetGamepadSteamHandle() | ||
639 | * SDL_GameControllerGetStringForAxis() => SDL_GetGamepadStringForAxis() | ||
640 | * SDL_GameControllerGetStringForButton() => SDL_GetGamepadStringForButton() | ||
641 | * SDL_GameControllerGetTouchpadFinger() => SDL_GetGamepadTouchpadFinger(), returns bool | ||
642 | * SDL_GameControllerGetType() => SDL_GetGamepadType() | ||
643 | * SDL_GameControllerGetVendor() => SDL_GetGamepadVendor() | ||
644 | * SDL_GameControllerHasAxis() => SDL_GamepadHasAxis() | ||
645 | * SDL_GameControllerHasButton() => SDL_GamepadHasButton() | ||
646 | * SDL_GameControllerHasSensor() => SDL_GamepadHasSensor() | ||
647 | * SDL_GameControllerIsSensorEnabled() => SDL_GamepadSensorEnabled() | ||
648 | * SDL_GameControllerMapping() => SDL_GetGamepadMapping() | ||
649 | * SDL_GameControllerMappingForGUID() => SDL_GetGamepadMappingForGUID() | ||
650 | * SDL_GameControllerName() => SDL_GetGamepadName() | ||
651 | * SDL_GameControllerOpen() => SDL_OpenGamepad() | ||
652 | * SDL_GameControllerPath() => SDL_GetGamepadPath() | ||
653 | * SDL_GameControllerRumble() => SDL_RumbleGamepad(), returns bool | ||
654 | * SDL_GameControllerRumbleTriggers() => SDL_RumbleGamepadTriggers(), returns bool | ||
655 | * SDL_GameControllerSendEffect() => SDL_SendGamepadEffect(), returns bool | ||
656 | * SDL_GameControllerSetLED() => SDL_SetGamepadLED(), returns bool | ||
657 | * SDL_GameControllerSetPlayerIndex() => SDL_SetGamepadPlayerIndex(), returns bool | ||
658 | * SDL_GameControllerSetSensorEnabled() => SDL_SetGamepadSensorEnabled(), returns bool | ||
659 | * SDL_GameControllerUpdate() => SDL_UpdateGamepads() | ||
660 | * SDL_IsGameController() => SDL_IsGamepad() | ||
661 | |||
662 | The following functions have been removed: | ||
663 | * SDL_GameControllerEventState() - replaced with SDL_SetGamepadEventsEnabled() and SDL_GamepadEventsEnabled() | ||
664 | * SDL_GameControllerGetBindForAxis() - replaced with SDL_GetGamepadBindings() | ||
665 | * SDL_GameControllerGetBindForButton() - replaced with SDL_GetGamepadBindings() | ||
666 | * SDL_GameControllerHasLED() - replaced with SDL_PROP_GAMEPAD_CAP_RGB_LED_BOOLEAN | ||
667 | * SDL_GameControllerHasRumble() - replaced with SDL_PROP_GAMEPAD_CAP_RUMBLE_BOOLEAN | ||
668 | * SDL_GameControllerHasRumbleTriggers() - replaced with SDL_PROP_GAMEPAD_CAP_TRIGGER_RUMBLE_BOOLEAN | ||
669 | * SDL_GameControllerMappingForDeviceIndex() - replaced with SDL_GetGamepadMappingForID() | ||
670 | * SDL_GameControllerMappingForIndex() - replaced with SDL_GetGamepadMappings() | ||
671 | * SDL_GameControllerNameForIndex() - replaced with SDL_GetGamepadNameForID() | ||
672 | * SDL_GameControllerNumMappings() - replaced with SDL_GetGamepadMappings() | ||
673 | * SDL_GameControllerPathForIndex() - replaced with SDL_GetGamepadPathForID() | ||
674 | * SDL_GameControllerTypeForIndex() - replaced with SDL_GetGamepadTypeForID() | ||
675 | |||
676 | The following symbols have been renamed: | ||
677 | * SDL_CONTROLLER_AXIS_INVALID => SDL_GAMEPAD_AXIS_INVALID | ||
678 | * SDL_CONTROLLER_AXIS_LEFTX => SDL_GAMEPAD_AXIS_LEFTX | ||
679 | * SDL_CONTROLLER_AXIS_LEFTY => SDL_GAMEPAD_AXIS_LEFTY | ||
680 | * SDL_CONTROLLER_AXIS_MAX => SDL_GAMEPAD_AXIS_COUNT | ||
681 | * SDL_CONTROLLER_AXIS_RIGHTX => SDL_GAMEPAD_AXIS_RIGHTX | ||
682 | * SDL_CONTROLLER_AXIS_RIGHTY => SDL_GAMEPAD_AXIS_RIGHTY | ||
683 | * SDL_CONTROLLER_AXIS_TRIGGERLEFT => SDL_GAMEPAD_AXIS_LEFT_TRIGGER | ||
684 | * SDL_CONTROLLER_AXIS_TRIGGERRIGHT => SDL_GAMEPAD_AXIS_RIGHT_TRIGGER | ||
685 | * SDL_CONTROLLER_BINDTYPE_AXIS => SDL_GAMEPAD_BINDTYPE_AXIS | ||
686 | * SDL_CONTROLLER_BINDTYPE_BUTTON => SDL_GAMEPAD_BINDTYPE_BUTTON | ||
687 | * SDL_CONTROLLER_BINDTYPE_HAT => SDL_GAMEPAD_BINDTYPE_HAT | ||
688 | * SDL_CONTROLLER_BINDTYPE_NONE => SDL_GAMEPAD_BINDTYPE_NONE | ||
689 | * SDL_CONTROLLER_BUTTON_A => SDL_GAMEPAD_BUTTON_SOUTH | ||
690 | * SDL_CONTROLLER_BUTTON_B => SDL_GAMEPAD_BUTTON_EAST | ||
691 | * SDL_CONTROLLER_BUTTON_BACK => SDL_GAMEPAD_BUTTON_BACK | ||
692 | * SDL_CONTROLLER_BUTTON_DPAD_DOWN => SDL_GAMEPAD_BUTTON_DPAD_DOWN | ||
693 | * SDL_CONTROLLER_BUTTON_DPAD_LEFT => SDL_GAMEPAD_BUTTON_DPAD_LEFT | ||
694 | * SDL_CONTROLLER_BUTTON_DPAD_RIGHT => SDL_GAMEPAD_BUTTON_DPAD_RIGHT | ||
695 | * SDL_CONTROLLER_BUTTON_DPAD_UP => SDL_GAMEPAD_BUTTON_DPAD_UP | ||
696 | * SDL_CONTROLLER_BUTTON_GUIDE => SDL_GAMEPAD_BUTTON_GUIDE | ||
697 | * SDL_CONTROLLER_BUTTON_INVALID => SDL_GAMEPAD_BUTTON_INVALID | ||
698 | * SDL_CONTROLLER_BUTTON_LEFTSHOULDER => SDL_GAMEPAD_BUTTON_LEFT_SHOULDER | ||
699 | * SDL_CONTROLLER_BUTTON_LEFTSTICK => SDL_GAMEPAD_BUTTON_LEFT_STICK | ||
700 | * SDL_CONTROLLER_BUTTON_MAX => SDL_GAMEPAD_BUTTON_COUNT | ||
701 | * SDL_CONTROLLER_BUTTON_MISC1 => SDL_GAMEPAD_BUTTON_MISC1 | ||
702 | * SDL_CONTROLLER_BUTTON_PADDLE1 => SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1 | ||
703 | * SDL_CONTROLLER_BUTTON_PADDLE2 => SDL_GAMEPAD_BUTTON_LEFT_PADDLE1 | ||
704 | * SDL_CONTROLLER_BUTTON_PADDLE3 => SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2 | ||
705 | * SDL_CONTROLLER_BUTTON_PADDLE4 => SDL_GAMEPAD_BUTTON_LEFT_PADDLE2 | ||
706 | * SDL_CONTROLLER_BUTTON_RIGHTSHOULDER => SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER | ||
707 | * SDL_CONTROLLER_BUTTON_RIGHTSTICK => SDL_GAMEPAD_BUTTON_RIGHT_STICK | ||
708 | * SDL_CONTROLLER_BUTTON_START => SDL_GAMEPAD_BUTTON_START | ||
709 | * SDL_CONTROLLER_BUTTON_TOUCHPAD => SDL_GAMEPAD_BUTTON_TOUCHPAD | ||
710 | * SDL_CONTROLLER_BUTTON_X => SDL_GAMEPAD_BUTTON_WEST | ||
711 | * SDL_CONTROLLER_BUTTON_Y => SDL_GAMEPAD_BUTTON_NORTH | ||
712 | * SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT => SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT | ||
713 | * SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR => SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR | ||
714 | * SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT => SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT | ||
715 | * SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO => SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO | ||
716 | * SDL_CONTROLLER_TYPE_PS3 => SDL_GAMEPAD_TYPE_PS3 | ||
717 | * SDL_CONTROLLER_TYPE_PS4 => SDL_GAMEPAD_TYPE_PS4 | ||
718 | * SDL_CONTROLLER_TYPE_PS5 => SDL_GAMEPAD_TYPE_PS5 | ||
719 | * SDL_CONTROLLER_TYPE_UNKNOWN => SDL_GAMEPAD_TYPE_STANDARD | ||
720 | * SDL_CONTROLLER_TYPE_VIRTUAL => SDL_GAMEPAD_TYPE_VIRTUAL | ||
721 | * SDL_CONTROLLER_TYPE_XBOX360 => SDL_GAMEPAD_TYPE_XBOX360 | ||
722 | * SDL_CONTROLLER_TYPE_XBOXONE => SDL_GAMEPAD_TYPE_XBOXONE | ||
723 | |||
724 | ## SDL_gesture.h | ||
725 | |||
726 | The gesture API has been removed. There is no replacement planned in SDL3. | ||
727 | However, the SDL2 code has been moved to a single-header library that can | ||
728 | be dropped into an SDL3 or SDL2 program, to continue to provide this | ||
729 | functionality to your app and aid migration. That is located in the | ||
730 | [SDL_gesture GitHub repository](https://github.com/libsdl-org/SDL_gesture). | ||
731 | |||
732 | ## SDL_guid.h | ||
733 | |||
734 | SDL_GUIDToString() returns a const pointer to the string representation of a GUID. | ||
735 | |||
736 | The following functions have been renamed: | ||
737 | * SDL_GUIDFromString() => SDL_StringToGUID() | ||
738 | |||
739 | ## SDL_haptic.h | ||
740 | |||
741 | Gamepads with simple rumble capability no longer show up in the SDL haptics interface, instead you should use SDL_RumbleGamepad(). | ||
742 | |||
743 | Rather than iterating over haptic devices using device index, there is a new function SDL_GetHaptics() to get the current list of haptic devices, and new functions to get information about haptic devices from their instance ID: | ||
744 | ```c | ||
745 | { | ||
746 | if (SDL_InitSubSystem(SDL_INIT_HAPTIC)) { | ||
747 | int i, num_haptics; | ||
748 | SDL_HapticID *haptics = SDL_GetHaptics(&num_haptics); | ||
749 | if (haptics) { | ||
750 | for (i = 0; i < num_haptics; ++i) { | ||
751 | SDL_HapticID instance_id = haptics[i]; | ||
752 | SDL_Log("Haptic %" SDL_PRIu32 ": %s", instance_id, SDL_GetHapticNameForID(instance_id)); | ||
753 | } | ||
754 | SDL_free(haptics); | ||
755 | } | ||
756 | SDL_QuitSubSystem(SDL_INIT_HAPTIC); | ||
757 | } | ||
758 | } | ||
759 | ``` | ||
760 | |||
761 | SDL_GetHapticEffectStatus() now returns bool instead of an int result. You should call SDL_GetHapticFeatures() to make sure effect status is supported before calling this function. | ||
762 | |||
763 | The following functions have been renamed: | ||
764 | * SDL_HapticClose() => SDL_CloseHaptic() | ||
765 | * SDL_HapticDestroyEffect() => SDL_DestroyHapticEffect() | ||
766 | * SDL_HapticGetEffectStatus() => SDL_GetHapticEffectStatus(), returns bool | ||
767 | * SDL_HapticNewEffect() => SDL_CreateHapticEffect() | ||
768 | * SDL_HapticNumAxes() => SDL_GetNumHapticAxes() | ||
769 | * SDL_HapticNumEffects() => SDL_GetMaxHapticEffects() | ||
770 | * SDL_HapticNumEffectsPlaying() => SDL_GetMaxHapticEffectsPlaying() | ||
771 | * SDL_HapticOpen() => SDL_OpenHaptic() | ||
772 | * SDL_HapticOpenFromJoystick() => SDL_OpenHapticFromJoystick() | ||
773 | * SDL_HapticOpenFromMouse() => SDL_OpenHapticFromMouse() | ||
774 | * SDL_HapticPause() => SDL_PauseHaptic(), returns bool | ||
775 | * SDL_HapticQuery() => SDL_GetHapticFeatures() | ||
776 | * SDL_HapticRumbleInit() => SDL_InitHapticRumble(), returns bool | ||
777 | * SDL_HapticRumblePlay() => SDL_PlayHapticRumble(), returns bool | ||
778 | * SDL_HapticRumbleStop() => SDL_StopHapticRumble(), returns bool | ||
779 | * SDL_HapticRunEffect() => SDL_RunHapticEffect(), returns bool | ||
780 | * SDL_HapticSetAutocenter() => SDL_SetHapticAutocenter(), returns bool | ||
781 | * SDL_HapticSetGain() => SDL_SetHapticGain(), returns bool | ||
782 | * SDL_HapticStopAll() => SDL_StopHapticEffects(), returns bool | ||
783 | * SDL_HapticStopEffect() => SDL_StopHapticEffect(), returns bool | ||
784 | * SDL_HapticUnpause() => SDL_ResumeHaptic(), returns bool | ||
785 | * SDL_HapticUpdateEffect() => SDL_UpdateHapticEffect(), returns bool | ||
786 | * SDL_JoystickIsHaptic() => SDL_IsJoystickHaptic() | ||
787 | * SDL_MouseIsHaptic() => SDL_IsMouseHaptic() | ||
788 | |||
789 | The following functions have been removed: | ||
790 | * SDL_HapticIndex() - replaced with SDL_GetHapticID() | ||
791 | * SDL_HapticName() - replaced with SDL_GetHapticNameForID() | ||
792 | * SDL_HapticOpened() - replaced with SDL_GetHapticFromID() | ||
793 | * SDL_NumHaptics() - replaced with SDL_GetHaptics() | ||
794 | |||
795 | ## SDL_hints.h | ||
796 | |||
797 | Calling SDL_GetHint() with the name of the hint being changed from within a hint callback will now return the new value rather than the old value. The old value is still passed as a parameter to the hint callback. | ||
798 | |||
799 | The environment variables SDL_VIDEODRIVER and SDL_AUDIODRIVER have been renamed to SDL_VIDEO_DRIVER and SDL_AUDIO_DRIVER, but the old names are still supported as a fallback. | ||
800 | |||
801 | The environment variables SDL_VIDEO_X11_WMCLASS and SDL_VIDEO_WAYLAND_WMCLASS have been removed and replaced by either using the appindentifier param to SDL_SetAppMetadata() or setting SDL_PROP_APP_METADATA_IDENTIFIER_STRING with SDL_SetAppMetadataProperty() | ||
802 | |||
803 | The environment variable AUDIODEV is used exclusively to specify the audio device for the OSS and NetBSD audio drivers. Its use in the ALSA driver has been replaced with the hint SDL_HINT_AUDIO_ALSA_DEFAULT_DEVICE and in the sndio driver with the environment variable AUDIODEVICE. | ||
804 | |||
805 | The following hints have been renamed: | ||
806 | * SDL_HINT_ALLOW_TOPMOST => SDL_HINT_WINDOW_ALLOW_TOPMOST | ||
807 | * SDL_HINT_AUDIODRIVER => SDL_HINT_AUDIO_DRIVER | ||
808 | * SDL_HINT_DIRECTINPUT_ENABLED => SDL_HINT_JOYSTICK_DIRECTINPUT | ||
809 | * SDL_HINT_GDK_TEXTINPUT_DEFAULT => SDL_HINT_GDK_TEXTINPUT_DEFAULT_TEXT | ||
810 | * SDL_HINT_JOYSTICK_GAMECUBE_RUMBLE_BRAKE => SDL_HINT_JOYSTICK_HIDAPI_GAMECUBE_RUMBLE_BRAKE | ||
811 | * SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE => SDL_HINT_JOYSTICK_ENHANCED_REPORTS | ||
812 | * SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE => SDL_HINT_JOYSTICK_ENHANCED_REPORTS | ||
813 | * SDL_HINT_LINUX_DIGITAL_HATS => SDL_HINT_JOYSTICK_LINUX_DIGITAL_HATS | ||
814 | * SDL_HINT_LINUX_HAT_DEADZONES => SDL_HINT_JOYSTICK_LINUX_HAT_DEADZONES | ||
815 | * SDL_HINT_LINUX_JOYSTICK_CLASSIC => SDL_HINT_JOYSTICK_LINUX_CLASSIC | ||
816 | * SDL_HINT_LINUX_JOYSTICK_DEADZONES => SDL_HINT_JOYSTICK_LINUX_DEADZONES | ||
817 | * SDL_HINT_VIDEODRIVER => SDL_HINT_VIDEO_DRIVER | ||
818 | * SDL_HINT_VIDEO_WAYLAND_EMULATE_MOUSE_WARP => SDL_HINT_MOUSE_EMULATE_WARP_WITH_RELATIVE | ||
819 | |||
820 | The following hints have been removed: | ||
821 | * SDL_HINT_ACCELEROMETER_AS_JOYSTICK | ||
822 | * SDL_HINT_ANDROID_BLOCK_ON_PAUSE_PAUSEAUDIO - the audio will be paused when the application is paused, and SDL_HINT_ANDROID_BLOCK_ON_PAUSE can be used to control that | ||
823 | * SDL_HINT_AUDIO_DEVICE_APP_NAME - replaced by either using the appname param to SDL_SetAppMetadata() or setting SDL_PROP_APP_METADATA_NAME_STRING with SDL_SetAppMetadataProperty() | ||
824 | * SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS - gamepad buttons are always positional | ||
825 | * SDL_HINT_GRAB_KEYBOARD - use SDL_SetWindowKeyboardGrab() instead | ||
826 | * SDL_HINT_IDLE_TIMER_DISABLED - use SDL_DisableScreenSaver() instead | ||
827 | * SDL_HINT_IME_INTERNAL_EDITING - replaced with SDL_HINT_IME_IMPLEMENTED_UI | ||
828 | * SDL_HINT_IME_SHOW_UI - replaced with SDL_HINT_IME_IMPLEMENTED_UI | ||
829 | * SDL_HINT_IME_SUPPORT_EXTENDED_TEXT - the normal text editing event has extended text | ||
830 | * SDL_HINT_MOUSE_RELATIVE_MODE_WARP - relative mode is always implemented at the hardware level or reported as unavailable | ||
831 | * SDL_HINT_MOUSE_RELATIVE_SCALING - mouse coordinates are no longer automatically scaled by the SDL renderer | ||
832 | * SDL_HINT_PS2_DYNAMIC_VSYNC - use SDL_SetRenderVSync(renderer, -1) instead | ||
833 | * SDL_HINT_RENDER_BATCHING - Render batching is always enabled, apps should call SDL_FlushRenderer() before calling into a lower-level graphics API. | ||
834 | * SDL_HINT_RENDER_LOGICAL_SIZE_MODE - the logical size mode is explicitly set with SDL_SetRenderLogicalPresentation() | ||
835 | * SDL_HINT_RENDER_OPENGL_SHADERS - shaders are always used if they are available | ||
836 | * SDL_HINT_RENDER_SCALE_QUALITY - textures now default to linear filtering, use SDL_SetTextureScaleMode(texture, SDL_SCALEMODE_NEAREST) if you want nearest pixel mode instead | ||
837 | * SDL_HINT_THREAD_STACK_SIZE - the stack size can be specified using SDL_CreateThreadWithProperties() | ||
838 | * SDL_HINT_VIDEO_EXTERNAL_CONTEXT - replaced with SDL_PROP_WINDOW_CREATE_EXTERNAL_GRAPHICS_CONTEXT_BOOLEAN in SDL_CreateWindowWithProperties() | ||
839 | * SDL_HINT_VIDEO_FOREIGN_WINDOW_OPENGL - replaced with SDL_PROP_WINDOW_CREATE_OPENGL_BOOLEAN in SDL_CreateWindowWithProperties() | ||
840 | * SDL_HINT_VIDEO_FOREIGN_WINDOW_VULKAN - replaced with SDL_PROP_WINDOW_CREATE_VULKAN_BOOLEAN in SDL_CreateWindowWithProperties() | ||
841 | * SDL_HINT_VIDEO_HIGHDPI_DISABLED - high DPI support is always enabled | ||
842 | * SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT - replaced with SDL_PROP_WINDOW_CREATE_WIN32_PIXEL_FORMAT_HWND_POINTER in SDL_CreateWindowWithProperties() | ||
843 | * SDL_HINT_VIDEO_X11_FORCE_EGL - use SDL_HINT_VIDEO_FORCE_EGL instead | ||
844 | * SDL_HINT_VIDEO_X11_XINERAMA - Xinerama no longer supported by the X11 backend | ||
845 | * SDL_HINT_VIDEO_X11_XVIDMODE - Xvidmode no longer supported by the X11 backend | ||
846 | * SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING - SDL now properly handles the 0x406D1388 Exception if no debugger intercepts it, preventing its propagation. | ||
847 | * SDL_HINT_WINDOWS_FORCE_MUTEX_CRITICAL_SECTIONS - Slim Reader/Writer Locks are always used if available | ||
848 | * SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4 - replaced with SDL_HINT_WINDOWS_CLOSE_ON_ALT_F4, defaulting to true | ||
849 | * SDL_HINT_WINRT_HANDLE_BACK_BUTTON - WinRT support was removed in SDL3. | ||
850 | * SDL_HINT_WINRT_PRIVACY_POLICY_LABEL - WinRT support was removed in SDL3. | ||
851 | * SDL_HINT_WINRT_PRIVACY_POLICY_URL - WinRT support was removed in SDL3. | ||
852 | * SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING | ||
853 | |||
854 | The following environment variables have been renamed: | ||
855 | * SDL_AUDIODRIVER => SDL_AUDIO_DRIVER | ||
856 | * SDL_PATH_DSP => AUDIODEV | ||
857 | * SDL_VIDEODRIVER => SDL_VIDEO_DRIVER | ||
858 | |||
859 | The following environment variables have been removed: | ||
860 | * SDL_AUDIO_ALSA_DEBUG - replaced by setting the hint SDL_HINT_LOGGING to "audio=debug" | ||
861 | * SDL_DISKAUDIODELAY - replaced with the hint SDL_HINT_AUDIO_DISK_TIMESCALE which allows scaling the audio time rather than specifying an absolute delay. | ||
862 | * SDL_DISKAUDIOFILE - replaced with the hint SDL_HINT_AUDIO_DISK_OUTPUT_FILE | ||
863 | * SDL_DISKAUDIOFILEIN - replaced with the hint SDL_HINT_AUDIO_DISK_INPUT_FILE | ||
864 | * SDL_DUMMYAUDIODELAY - replaced with the hint SDL_HINT_AUDIO_DUMMY_TIMESCALE which allows scaling the audio time rather than specifying an absolute delay. | ||
865 | * SDL_HAPTIC_GAIN_MAX | ||
866 | * SDL_HIDAPI_DISABLE_LIBUSB - replaced with the hint SDL_HINT_HIDAPI_LIBUSB | ||
867 | * SDL_HIDAPI_JOYSTICK_DISABLE_UDEV - replaced with the hint SDL_HINT_HIDAPI_UDEV | ||
868 | * SDL_INPUT_FREEBSD_KEEP_KBD - replaced with the hint SDL_HINT_MUTE_CONSOLE_KEYBOARD | ||
869 | * SDL_INPUT_LINUX_KEEP_KBD - replaced with the hint SDL_HINT_MUTE_CONSOLE_KEYBOARD | ||
870 | * VITA_DISABLE_TOUCH_BACK - replaced with the hint SDL_HINT_VITA_ENABLE_BACK_TOUCH | ||
871 | * VITA_DISABLE_TOUCH_FRONT - replaced with the hint SDL_HINT_VITA_ENABLE_FRONT_TOUCH | ||
872 | * VITA_MODULE_PATH - replaced with the hint SDL_HINT_VITA_MODULE_PATH | ||
873 | * VITA_PVR_OGL - replaced with the hint SDL_HINT_VITA_PVR_OPENGL | ||
874 | * VITA_PVR_SKIP_INIT - replaced with the hint SDL_HINT_VITA_PVR_INIT | ||
875 | * VITA_RESOLUTION - replaced with the hint SDL_HINT_VITA_RESOLUTION | ||
876 | |||
877 | The following functions have been removed: | ||
878 | * SDL_ClearHints() - replaced with SDL_ResetHints() | ||
879 | |||
880 | The following functions have been renamed: | ||
881 | * SDL_DelHintCallback() => SDL_RemoveHintCallback() | ||
882 | |||
883 | ## SDL_init.h | ||
884 | |||
885 | On Haiku OS, SDL no longer sets the current working directory to the executable's path during SDL_Init(). If you need this functionality, the fastest solution is to add this code directly after the call to SDL_Init: | ||
886 | |||
887 | ```c | ||
888 | { | ||
889 | const char *path = SDL_GetBasePath(); | ||
890 | if (path) { | ||
891 | chdir(path); | ||
892 | } | ||
893 | } | ||
894 | ``` | ||
895 | |||
896 | The following symbols have been renamed: | ||
897 | * SDL_INIT_GAMECONTROLLER => SDL_INIT_GAMEPAD | ||
898 | |||
899 | The following symbols have been removed: | ||
900 | * SDL_INIT_NOPARACHUTE | ||
901 | * SDL_INIT_EVERYTHING - you should only initialize the subsystems you are using | ||
902 | * SDL_INIT_TIMER - no longer needed before calling SDL_AddTimer() | ||
903 | |||
904 | ## SDL_joystick.h | ||
905 | |||
906 | SDL_JoystickID has changed from Sint32 to Uint32, with an invalid ID being 0. | ||
907 | |||
908 | Rather than iterating over joysticks using device index, there is a new function SDL_GetJoysticks() to get the current list of joysticks, and new functions to get information about joysticks from their instance ID: | ||
909 | ```c | ||
910 | { | ||
911 | if (SDL_InitSubSystem(SDL_INIT_JOYSTICK)) { | ||
912 | int i, num_joysticks; | ||
913 | SDL_JoystickID *joysticks = SDL_GetJoysticks(&num_joysticks); | ||
914 | if (joysticks) { | ||
915 | for (i = 0; i < num_joysticks; ++i) { | ||
916 | SDL_JoystickID instance_id = joysticks[i]; | ||
917 | const char *name = SDL_GetJoystickNameForID(instance_id); | ||
918 | const char *path = SDL_GetJoystickPathForID(instance_id); | ||
919 | |||
920 | SDL_Log("Joystick %" SDL_PRIu32 ": %s%s%s VID 0x%.4x, PID 0x%.4x", | ||
921 | instance_id, name ? name : "Unknown", path ? ", " : "", path ? path : "", SDL_GetJoystickVendorForID(instance_id), SDL_GetJoystickProductForID(instance_id)); | ||
922 | } | ||
923 | SDL_free(joysticks); | ||
924 | } | ||
925 | SDL_QuitSubSystem(SDL_INIT_JOYSTICK); | ||
926 | } | ||
927 | } | ||
928 | ``` | ||
929 | |||
930 | The SDL_EVENT_JOYSTICK_ADDED event now provides the joystick instance ID in the `which` member of the jdevice event structure. | ||
931 | |||
932 | The functions SDL_GetJoysticks(), SDL_GetJoystickNameForID(), SDL_GetJoystickPathForID(), SDL_GetJoystickPlayerIndexForID(), SDL_GetJoystickGUIDForID(), SDL_GetJoystickVendorForID(), SDL_GetJoystickProductForID(), SDL_GetJoystickProductVersionForID(), and SDL_GetJoystickTypeForID() have been added to directly query the list of available joysticks. | ||
933 | |||
934 | SDL_AttachVirtualJoystick() now returns the joystick instance ID instead of a device index, and returns 0 if there was an error. | ||
935 | |||
936 | SDL_VirtualJoystickDesc version should not be set to SDL_VIRTUAL_JOYSTICK_DESC_VERSION, instead the structure should be initialized using SDL_INIT_INTERFACE(). | ||
937 | |||
938 | The following functions have been renamed: | ||
939 | * SDL_JoystickAttachVirtualEx() => SDL_AttachVirtualJoystick() | ||
940 | * SDL_JoystickClose() => SDL_CloseJoystick() | ||
941 | * SDL_JoystickDetachVirtual() => SDL_DetachVirtualJoystick(), returns bool | ||
942 | * SDL_JoystickFromInstanceID() => SDL_GetJoystickFromID() | ||
943 | * SDL_JoystickFromPlayerIndex() => SDL_GetJoystickFromPlayerIndex() | ||
944 | * SDL_JoystickGetAttached() => SDL_JoystickConnected() | ||
945 | * SDL_JoystickGetAxis() => SDL_GetJoystickAxis() | ||
946 | * SDL_JoystickGetAxisInitialState() => SDL_GetJoystickAxisInitialState() | ||
947 | * SDL_JoystickGetBall() => SDL_GetJoystickBall(), returns bool | ||
948 | * SDL_JoystickGetButton() => SDL_GetJoystickButton() | ||
949 | * SDL_JoystickGetFirmwareVersion() => SDL_GetJoystickFirmwareVersion() | ||
950 | * SDL_JoystickGetGUID() => SDL_GetJoystickGUID() | ||
951 | * SDL_JoystickGetGUIDFromString() => SDL_StringToGUID() | ||
952 | * SDL_JoystickGetHat() => SDL_GetJoystickHat() | ||
953 | * SDL_JoystickGetPlayerIndex() => SDL_GetJoystickPlayerIndex() | ||
954 | * SDL_JoystickGetProduct() => SDL_GetJoystickProduct() | ||
955 | * SDL_JoystickGetProductVersion() => SDL_GetJoystickProductVersion() | ||
956 | * SDL_JoystickGetSerial() => SDL_GetJoystickSerial() | ||
957 | * SDL_JoystickGetType() => SDL_GetJoystickType() | ||
958 | * SDL_JoystickGetVendor() => SDL_GetJoystickVendor() | ||
959 | * SDL_JoystickInstanceID() => SDL_GetJoystickID() | ||
960 | * SDL_JoystickIsVirtual() => SDL_IsJoystickVirtual() | ||
961 | * SDL_JoystickName() => SDL_GetJoystickName() | ||
962 | * SDL_JoystickNumAxes() => SDL_GetNumJoystickAxes() | ||
963 | * SDL_JoystickNumBalls() => SDL_GetNumJoystickBalls() | ||
964 | * SDL_JoystickNumButtons() => SDL_GetNumJoystickButtons() | ||
965 | * SDL_JoystickNumHats() => SDL_GetNumJoystickHats() | ||
966 | * SDL_JoystickOpen() => SDL_OpenJoystick() | ||
967 | * SDL_JoystickPath() => SDL_GetJoystickPath() | ||
968 | * SDL_JoystickRumble() => SDL_RumbleJoystick(), returns bool | ||
969 | * SDL_JoystickRumbleTriggers() => SDL_RumbleJoystickTriggers(), returns bool | ||
970 | * SDL_JoystickSendEffect() => SDL_SendJoystickEffect(), returns bool | ||
971 | * SDL_JoystickSetLED() => SDL_SetJoystickLED(), returns bool | ||
972 | * SDL_JoystickSetPlayerIndex() => SDL_SetJoystickPlayerIndex(), returns bool | ||
973 | * SDL_JoystickSetVirtualAxis() => SDL_SetJoystickVirtualAxis(), returns bool | ||
974 | * SDL_JoystickSetVirtualButton() => SDL_SetJoystickVirtualButton(), returns bool | ||
975 | * SDL_JoystickSetVirtualHat() => SDL_SetJoystickVirtualHat(), returns bool | ||
976 | * SDL_JoystickUpdate() => SDL_UpdateJoysticks() | ||
977 | |||
978 | The following symbols have been renamed: | ||
979 | * SDL_JOYSTICK_TYPE_GAMECONTROLLER => SDL_JOYSTICK_TYPE_GAMEPAD | ||
980 | |||
981 | The following functions have been removed: | ||
982 | * SDL_JoystickAttachVirtual() - replaced with SDL_AttachVirtualJoystick() | ||
983 | * SDL_JoystickCurrentPowerLevel() - replaced with SDL_GetJoystickConnectionState() and SDL_GetJoystickPowerInfo() | ||
984 | * SDL_JoystickEventState() - replaced with SDL_SetJoystickEventsEnabled() and SDL_JoystickEventsEnabled() | ||
985 | * SDL_JoystickGetDeviceGUID() - replaced with SDL_GetJoystickGUIDForID() | ||
986 | * SDL_JoystickGetDeviceInstanceID() | ||
987 | * SDL_JoystickGetDevicePlayerIndex() - replaced with SDL_GetJoystickPlayerIndexForID() | ||
988 | * SDL_JoystickGetDeviceProduct() - replaced with SDL_GetJoystickProductForID() | ||
989 | * SDL_JoystickGetDeviceProductVersion() - replaced with SDL_GetJoystickProductVersionForID() | ||
990 | * SDL_JoystickGetDeviceType() - replaced with SDL_GetJoystickTypeForID() | ||
991 | * SDL_JoystickGetDeviceVendor() - replaced with SDL_GetJoystickVendorForID() | ||
992 | * SDL_JoystickGetGUIDString() - replaced with SDL_GUIDToString() | ||
993 | * SDL_JoystickHasLED() - replaced with SDL_PROP_JOYSTICK_CAP_RGB_LED_BOOLEAN | ||
994 | * SDL_JoystickHasRumble() - replaced with SDL_PROP_JOYSTICK_CAP_RUMBLE_BOOLEAN | ||
995 | * SDL_JoystickHasRumbleTriggers() - replaced with SDL_PROP_JOYSTICK_CAP_TRIGGER_RUMBLE_BOOLEAN | ||
996 | * SDL_JoystickNameForIndex() - replaced with SDL_GetJoystickNameForID() | ||
997 | * SDL_JoystickPathForIndex() - replaced with SDL_GetJoystickPathForID() | ||
998 | * SDL_NumJoysticks() - replaced with SDL_GetJoysticks() | ||
999 | * SDL_VIRTUAL_JOYSTICK_DESC_VERSION - no longer needed | ||
1000 | |||
1001 | The following symbols have been removed: | ||
1002 | * SDL_IPHONE_MAX_GFORCE | ||
1003 | * SDL_JOYBALLMOTION | ||
1004 | |||
1005 | |||
1006 | The following structures have been renamed: | ||
1007 | * SDL_JoystickGUID => SDL_GUID | ||
1008 | |||
1009 | ## SDL_keyboard.h | ||
1010 | |||
1011 | Text input is no longer automatically enabled when initializing video, you should call SDL_StartTextInput() when you want to receive text input and call SDL_StopTextInput() when you are done. Starting text input may shown an input method editor (IME) and cause key up/down events to be skipped, so should only be enabled when the application wants text input. | ||
1012 | |||
1013 | The text input state hase been changed to be window-specific. SDL_StartTextInput(), SDL_StopTextInput(), SDL_TextInputActive(), and SDL_ClearComposition() all now take a window parameter. | ||
1014 | |||
1015 | SDL_GetDefaultKeyFromScancode(), SDL_GetKeyFromScancode(), and SDL_GetScancodeFromKey() take an SDL_Keymod parameter and use that to provide the correct result based on keyboard modifier state. | ||
1016 | |||
1017 | SDL_GetKeyboardState() returns a pointer to bool instead of Uint8. | ||
1018 | |||
1019 | The following functions have been renamed: | ||
1020 | * SDL_IsScreenKeyboardShown() => SDL_ScreenKeyboardShown() | ||
1021 | * SDL_IsTextInputActive() => SDL_TextInputActive() | ||
1022 | |||
1023 | The following functions have been removed: | ||
1024 | * SDL_IsTextInputShown() | ||
1025 | * SDL_SetTextInputRect() - replaced with SDL_SetTextInputArea() | ||
1026 | |||
1027 | The following structures have been removed: | ||
1028 | * SDL_Keysym | ||
1029 | |||
1030 | ## SDL_keycode.h | ||
1031 | |||
1032 | SDL_Keycode is now Uint32 and the SDLK_* constants are now defines instead of an enum, to more clearly reflect that they are a subset of the possible values of an SDL_Keycode. | ||
1033 | |||
1034 | In addition to the `SDLK_SCANCODE_MASK` bit found on key codes that directly map to scancodes, there is now the | ||
1035 | `SDLK_EXTENDED_MASK` bit used to denote key codes that don't have a corresponding scancode, and aren't a unicode value. | ||
1036 | |||
1037 | The following symbols have been removed: | ||
1038 | |||
1039 | * KMOD_RESERVED - No replacement. A bit named "RESERVED" probably shouldn't be used in an app, but if you need it, this was equivalent to KMOD_SCROLL (0x8000) in SDL2. | ||
1040 | * SDLK_WWW | ||
1041 | * SDLK_MAIL | ||
1042 | * SDLK_CALCULATOR | ||
1043 | * SDLK_COMPUTER | ||
1044 | * SDLK_BRIGHTNESSDOWN | ||
1045 | * SDLK_BRIGHTNESSUP | ||
1046 | * SDLK_DISPLAYSWITCH | ||
1047 | * SDLK_KBDILLUMTOGGLE | ||
1048 | * SDLK_KBDILLUMDOWN | ||
1049 | * SDLK_KBDILLUMUP | ||
1050 | * SDLK_APP1 | ||
1051 | * SDLK_APP2 | ||
1052 | |||
1053 | |||
1054 | The following symbols have been renamed: | ||
1055 | * KMOD_ALT => SDL_KMOD_ALT | ||
1056 | * KMOD_CAPS => SDL_KMOD_CAPS | ||
1057 | * KMOD_CTRL => SDL_KMOD_CTRL | ||
1058 | * KMOD_GUI => SDL_KMOD_GUI | ||
1059 | * KMOD_LALT => SDL_KMOD_LALT | ||
1060 | * KMOD_LCTRL => SDL_KMOD_LCTRL | ||
1061 | * KMOD_LGUI => SDL_KMOD_LGUI | ||
1062 | * KMOD_LSHIFT => SDL_KMOD_LSHIFT | ||
1063 | * KMOD_MODE => SDL_KMOD_MODE | ||
1064 | * KMOD_NONE => SDL_KMOD_NONE | ||
1065 | * KMOD_NUM => SDL_KMOD_NUM | ||
1066 | * KMOD_RALT => SDL_KMOD_RALT | ||
1067 | * KMOD_RCTRL => SDL_KMOD_RCTRL | ||
1068 | * KMOD_RGUI => SDL_KMOD_RGUI | ||
1069 | * KMOD_RSHIFT => SDL_KMOD_RSHIFT | ||
1070 | * KMOD_SCROLL => SDL_KMOD_SCROLL | ||
1071 | * KMOD_SHIFT => SDL_KMOD_SHIFT | ||
1072 | * SDLK_AUDIOFASTFORWARD => SDLK_MEDIA_FAST_FORWARD | ||
1073 | * SDLK_AUDIOMUTE => SDLK_MUTE | ||
1074 | * SDLK_AUDIONEXT => SDLK_MEDIA_NEXT_TRACK | ||
1075 | * SDLK_AUDIOPLAY => SDLK_MEDIA_PLAY | ||
1076 | * SDLK_AUDIOPREV => SDLK_MEDIA_PREVIOUS_TRACK | ||
1077 | * SDLK_AUDIOREWIND => SDLK_MEDIA_REWIND | ||
1078 | * SDLK_AUDIOSTOP => SDLK_MEDIA_STOP | ||
1079 | * SDLK_BACKQUOTE => SDLK_GRAVE | ||
1080 | * SDLK_EJECT => SDLK_MEDIA_EJECT | ||
1081 | * SDLK_MEDIASELECT => SDLK_MEDIA_SELECT | ||
1082 | * SDLK_QUOTE => SDLK_APOSTROPHE | ||
1083 | * SDLK_QUOTEDBL => SDLK_DBLAPOSTROPHE | ||
1084 | * SDLK_a => SDLK_A | ||
1085 | * SDLK_b => SDLK_B | ||
1086 | * SDLK_c => SDLK_C | ||
1087 | * SDLK_d => SDLK_D | ||
1088 | * SDLK_e => SDLK_E | ||
1089 | * SDLK_f => SDLK_F | ||
1090 | * SDLK_g => SDLK_G | ||
1091 | * SDLK_h => SDLK_H | ||
1092 | * SDLK_i => SDLK_I | ||
1093 | * SDLK_j => SDLK_J | ||
1094 | * SDLK_k => SDLK_K | ||
1095 | * SDLK_l => SDLK_L | ||
1096 | * SDLK_m => SDLK_M | ||
1097 | * SDLK_n => SDLK_N | ||
1098 | * SDLK_o => SDLK_O | ||
1099 | * SDLK_p => SDLK_P | ||
1100 | * SDLK_q => SDLK_Q | ||
1101 | * SDLK_r => SDLK_R | ||
1102 | * SDLK_s => SDLK_S | ||
1103 | * SDLK_t => SDLK_T | ||
1104 | * SDLK_u => SDLK_U | ||
1105 | * SDLK_v => SDLK_V | ||
1106 | * SDLK_w => SDLK_W | ||
1107 | * SDLK_x => SDLK_X | ||
1108 | * SDLK_y => SDLK_Y | ||
1109 | * SDLK_z => SDLK_Z | ||
1110 | |||
1111 | ## SDL_loadso.h | ||
1112 | |||
1113 | Shared object handles are now `SDL_SharedObject *`, an opaque type, instead of `void *`. This is just for type-safety and there is no functional difference. | ||
1114 | |||
1115 | SDL_LoadFunction() now returns `SDL_FunctionPointer` instead of `void *`, and should be cast to the appropriate function type. You can define SDL_FUNCTION_POINTER_IS_VOID_POINTER in your project to restore the previous behavior. | ||
1116 | |||
1117 | ## SDL_log.h | ||
1118 | |||
1119 | SDL_Log() no longer prints a log prefix by default for SDL_LOG_PRIORITY_INFO and below. The log prefixes can be customized with SDL_SetLogPriorityPrefix(). | ||
1120 | |||
1121 | The following macros have been removed: | ||
1122 | * SDL_MAX_LOG_MESSAGE - there's no message length limit anymore. If you need an artificial limit, this used to be 4096 in SDL versions before 2.0.24. | ||
1123 | |||
1124 | The following functions have been renamed: | ||
1125 | * SDL_LogGetOutputFunction() => SDL_GetLogOutputFunction() | ||
1126 | * SDL_LogGetPriority() => SDL_GetLogPriority() | ||
1127 | * SDL_LogResetPriorities() => SDL_ResetLogPriorities() | ||
1128 | * SDL_LogSetAllPriority() => SDL_SetLogPriorities() | ||
1129 | * SDL_LogSetOutputFunction() => SDL_SetLogOutputFunction() | ||
1130 | * SDL_LogSetPriority() => SDL_SetLogPriority() | ||
1131 | |||
1132 | The following symbols have been renamed: | ||
1133 | * SDL_NUM_LOG_PRIORITIES => SDL_LOG_PRIORITY_COUNT | ||
1134 | |||
1135 | ## SDL_main.h | ||
1136 | |||
1137 | SDL3 doesn't have a static libSDLmain to link against anymore. | ||
1138 | Instead SDL_main.h is now a header-only library **and not included by SDL.h anymore**. | ||
1139 | |||
1140 | Using it is really simple: Just `#include <SDL3/SDL_main.h>` in the source file with your standard | ||
1141 | `int main(int argc, char* argv[])` function. See docs/README-main-functions.md for details. | ||
1142 | |||
1143 | Several platform-specific entry point functions have been removed as unnecessary. If for some reason you explicitly need them, here are easy replacements: | ||
1144 | |||
1145 | ```c | ||
1146 | #define SDL_UIKitRunApp(ARGC, ARGV, MAIN_FUNC) SDL_RunApp(ARGC, ARGV, MAIN_FUNC, NULL) | ||
1147 | #define SDL_GDKRunApp(MAIN_FUNC, RESERVED) SDL_RunApp(0, NULL, MAIN_FUNC, RESERVED) | ||
1148 | ``` | ||
1149 | |||
1150 | The following functions have been removed: | ||
1151 | * SDL_WinRTRunApp() - WinRT support was removed in SDL3. | ||
1152 | |||
1153 | |||
1154 | ## SDL_messagebox.h | ||
1155 | |||
1156 | The buttonid field of SDL_MessageBoxButtonData has been renamed buttonID. | ||
1157 | |||
1158 | The following symbols have been renamed: | ||
1159 | * SDL_MESSAGEBOX_COLOR_MAX => SDL_MESSAGEBOX_COLOR_COUNT | ||
1160 | |||
1161 | ## SDL_metal.h | ||
1162 | |||
1163 | SDL_Metal_GetDrawableSize() has been removed. SDL_GetWindowSizeInPixels() can be used in its place. | ||
1164 | |||
1165 | ## SDL_mouse.h | ||
1166 | |||
1167 | SDL_ShowCursor() has been split into three functions: SDL_ShowCursor(), SDL_HideCursor(), and SDL_CursorVisible() | ||
1168 | |||
1169 | SDL_GetMouseState(), SDL_GetGlobalMouseState(), SDL_GetRelativeMouseState(), SDL_WarpMouseInWindow(), and SDL_WarpMouseGlobal() all use floating point mouse positions, to provide sub-pixel precision on platforms that support it. | ||
1170 | |||
1171 | SDL_SystemCursor's items from SDL2 have been renamed to match CSS cursor names. | ||
1172 | |||
1173 | The following functions have been renamed: | ||
1174 | * SDL_FreeCursor() => SDL_DestroyCursor() | ||
1175 | |||
1176 | The following functions have been removed: | ||
1177 | * SDL_SetRelativeMouseMode() - replaced with SDL_SetWindowRelativeMouseMode() | ||
1178 | * SDL_GetRelativeMouseMode() - replaced with SDL_GetWindowRelativeMouseMode() | ||
1179 | |||
1180 | The following symbols have been renamed: | ||
1181 | * SDL_BUTTON => SDL_BUTTON_MASK | ||
1182 | * SDL_NUM_SYSTEM_CURSORS => SDL_SYSTEM_CURSOR_COUNT | ||
1183 | * SDL_SYSTEM_CURSOR_ARROW => SDL_SYSTEM_CURSOR_DEFAULT | ||
1184 | * SDL_SYSTEM_CURSOR_HAND => SDL_SYSTEM_CURSOR_POINTER | ||
1185 | * SDL_SYSTEM_CURSOR_IBEAM => SDL_SYSTEM_CURSOR_TEXT | ||
1186 | * SDL_SYSTEM_CURSOR_NO => SDL_SYSTEM_CURSOR_NOT_ALLOWED | ||
1187 | * SDL_SYSTEM_CURSOR_SIZEALL => SDL_SYSTEM_CURSOR_MOVE | ||
1188 | * SDL_SYSTEM_CURSOR_SIZENESW => SDL_SYSTEM_CURSOR_NESW_RESIZE | ||
1189 | * SDL_SYSTEM_CURSOR_SIZENS => SDL_SYSTEM_CURSOR_NS_RESIZE | ||
1190 | * SDL_SYSTEM_CURSOR_SIZENWSE => SDL_SYSTEM_CURSOR_NWSE_RESIZE | ||
1191 | * SDL_SYSTEM_CURSOR_SIZEWE => SDL_SYSTEM_CURSOR_EW_RESIZE | ||
1192 | * SDL_SYSTEM_CURSOR_WAITARROW => SDL_SYSTEM_CURSOR_PROGRESS | ||
1193 | |||
1194 | ## SDL_mutex.h | ||
1195 | |||
1196 | SDL_MUTEX_MAXWAIT has been removed; it suggested there was a maximum timeout one could outlive, instead of an infinite wait. Instead, pass a -1 to functions that accepted this symbol. | ||
1197 | |||
1198 | SDL_MUTEX_TIMEDOUT has been removed, the wait functions return true if the operation succeeded or false if they timed out. | ||
1199 | |||
1200 | SDL_LockMutex(), SDL_UnlockMutex(), SDL_WaitSemaphore(), SDL_SignalSemaphore(), SDL_WaitCondition(), SDL_SignalCondition(), and SDL_BroadcastCondition() now return void; if the object is valid (including being a NULL pointer, which returns immediately), these functions never fail. If the object is invalid or the caller does something illegal, like unlock another thread's mutex, this is considered undefined behavior. | ||
1201 | |||
1202 | SDL_TryWaitSemaphore(), SDL_WaitSemaphoreTimeout(), and SDL_WaitConditionTimeout() now return true if the operation succeeded or false if they timed out. | ||
1203 | |||
1204 | The following functions have been renamed: | ||
1205 | * SDL_CondBroadcast() => SDL_BroadcastCondition() | ||
1206 | * SDL_CondSignal() => SDL_SignalCondition() | ||
1207 | * SDL_CondWait() => SDL_WaitCondition() | ||
1208 | * SDL_CondWaitTimeout() => SDL_WaitConditionTimeout(), returns bool | ||
1209 | * SDL_CreateCond() => SDL_CreateCondition() | ||
1210 | * SDL_DestroyCond() => SDL_DestroyCondition() | ||
1211 | * SDL_SemPost() => SDL_SignalSemaphore() | ||
1212 | * SDL_SemTryWait() => SDL_TryWaitSemaphore(), returns bool | ||
1213 | * SDL_SemValue() => SDL_GetSemaphoreValue() | ||
1214 | * SDL_SemWait() => SDL_WaitSemaphore() | ||
1215 | * SDL_SemWaitTimeout() => SDL_WaitSemaphoreTimeout(), returns bool | ||
1216 | |||
1217 | The following symbols have been renamed: | ||
1218 | * SDL_cond => SDL_Condition | ||
1219 | * SDL_mutex => SDL_Mutex | ||
1220 | * SDL_sem => SDL_Semaphore | ||
1221 | |||
1222 | ## SDL_pixels.h | ||
1223 | |||
1224 | SDL_PixelFormat has been renamed SDL_PixelFormatDetails and just describes the pixel format, it does not include a palette for indexed pixel types. | ||
1225 | |||
1226 | SDL_PixelFormatEnum has been renamed SDL_PixelFormat and is used instead of Uint32 for API functions that refer to pixel format by enumerated value. | ||
1227 | |||
1228 | SDL_MapRGB(), SDL_MapRGBA(), SDL_GetRGB(), and SDL_GetRGBA() take an optional palette parameter for indexed color lookups. | ||
1229 | |||
1230 | Code that used to look like this: | ||
1231 | ```c | ||
1232 | SDL_GetRGBA(pixel, surface->format, &r, &g, &b, &a); | ||
1233 | ``` | ||
1234 | should be changed to: | ||
1235 | ```c | ||
1236 | SDL_GetRGBA(pixel, SDL_GetPixelFormatDetails(surface->format), SDL_GetSurfacePalette(surface), &r, &g, &b, &a); | ||
1237 | ``` | ||
1238 | |||
1239 | Code that used to look like this: | ||
1240 | ```c | ||
1241 | pixel = SDL_MapRGBA(surface->format, r, g, b, a); | ||
1242 | ``` | ||
1243 | should be changed to: | ||
1244 | ```c | ||
1245 | pixel = SDL_MapSurfaceRGBA(surface, r, g, b, a); | ||
1246 | ``` | ||
1247 | |||
1248 | SDL_CalculateGammaRamp has been removed, because SDL_SetWindowGammaRamp has been removed as well due to poor support in modern operating systems (see [SDL_video.h](#sdl_videoh)). | ||
1249 | |||
1250 | The following functions have been renamed: | ||
1251 | * SDL_AllocFormat() => SDL_GetPixelFormatDetails() | ||
1252 | * SDL_AllocPalette() => SDL_CreatePalette() | ||
1253 | * SDL_FreePalette() => SDL_DestroyPalette() | ||
1254 | * SDL_MasksToPixelFormatEnum() => SDL_GetPixelFormatForMasks() | ||
1255 | * SDL_PixelFormatEnumToMasks() => SDL_GetMasksForPixelFormat(), returns bool | ||
1256 | |||
1257 | The following symbols have been renamed: | ||
1258 | * SDL_PIXELFORMAT_BGR444 => SDL_PIXELFORMAT_XBGR4444 | ||
1259 | * SDL_PIXELFORMAT_BGR555 => SDL_PIXELFORMAT_XBGR1555 | ||
1260 | * SDL_PIXELFORMAT_BGR888 => SDL_PIXELFORMAT_XBGR8888 | ||
1261 | * SDL_PIXELFORMAT_RGB444 => SDL_PIXELFORMAT_XRGB4444 | ||
1262 | * SDL_PIXELFORMAT_RGB555 => SDL_PIXELFORMAT_XRGB1555 | ||
1263 | * SDL_PIXELFORMAT_RGB888 => SDL_PIXELFORMAT_XRGB8888 | ||
1264 | |||
1265 | The following functions have been removed: | ||
1266 | * SDL_FreeFormat() | ||
1267 | * SDL_SetPixelFormatPalette() | ||
1268 | * SDL_CalculateGammaRamp() | ||
1269 | |||
1270 | The following macros have been removed: | ||
1271 | * SDL_Colour - use SDL_Color instead | ||
1272 | |||
1273 | The following structures have been renamed: | ||
1274 | * SDL_PixelFormat => SDL_PixelFormatDetails | ||
1275 | |||
1276 | ## SDL_platform.h | ||
1277 | |||
1278 | The following platform preprocessor macros have been renamed: | ||
1279 | |||
1280 | | SDL2 | SDL3 | | ||
1281 | |-------------------|---------------------------| | ||
1282 | | `__3DS__` | `SDL_PLATFORM_3DS` | | ||
1283 | | `__AIX__` | `SDL_PLATFORM_AIX` | | ||
1284 | | `__ANDROID__` | `SDL_PLATFORM_ANDROID` | | ||
1285 | | `__APPLE__` | `SDL_PLATFORM_APPLE` | | ||
1286 | | `__BSDI__` | `SDL_PLATFORM_BSDI` | | ||
1287 | | `__CYGWIN_` | `SDL_PLATFORM_CYGWIN` | | ||
1288 | | `__EMSCRIPTEN__` | `SDL_PLATFORM_EMSCRIPTEN` | | ||
1289 | | `__FREEBSD__` | `SDL_PLATFORM_FREEBSD` | | ||
1290 | | `__GDK__` | `SDL_PLATFORM_GDK` | | ||
1291 | | `__HAIKU__` | `SDL_PLATFORM_HAIKU` | | ||
1292 | | `__HPUX__` | `SDL_PLATFORM_HPUX` | | ||
1293 | | `__IPHONEOS__` | `SDL_PLATFORM_IOS` | | ||
1294 | | `__IRIX__` | `SDL_PLATFORM_IRIX` | | ||
1295 | | `__LINUX__` | `SDL_PLATFORM_LINUX` | | ||
1296 | | `__MACOSX__` | `SDL_PLATFORM_MACOS` | | ||
1297 | | `__NETBSD__` | `SDL_PLATFORM_NETBSD` | | ||
1298 | | `__OPENBSD__` | `SDL_PLATFORM_OPENBSD` | | ||
1299 | | `__OS2__` | `SDL_PLATFORM_OS2` | | ||
1300 | | `__OSF__` | `SDL_PLATFORM_OSF` | | ||
1301 | | `__PS2__` | `SDL_PLATFORM_PS2` | | ||
1302 | | `__PSP__` | `SDL_PLATFORM_PSP` | | ||
1303 | | `__QNXNTO__` | `SDL_PLATFORM_QNXNTO` | | ||
1304 | | `__RISCOS__` | `SDL_PLATFORM_RISCOS` | | ||
1305 | | `__SOLARIS__` | `SDL_PLATFORM_SOLARIS` | | ||
1306 | | `__TVOS__` | `SDL_PLATFORM_TVOS` | | ||
1307 | | `__unix__` | `SDL_PLATFORM_UNI` | | ||
1308 | | `__VITA__` | `SDL_PLATFORM_VITA` | | ||
1309 | | `__WIN32__` | `SDL_PLATFORM_WIN32` | | ||
1310 | | `__WINGDK__` | `SDL_PLATFORM_WINGDK` | | ||
1311 | | `__XBOXONE__` | `SDL_PLATFORM_XBOXONE` | | ||
1312 | | `__XBOXSERIES__` | `SDL_PLATFORM_XBOXSERIES` | | ||
1313 | |||
1314 | You can use the Python script [rename_macros.py](https://github.com/libsdl-org/SDL/blob/main/build-scripts/rename_macros.py) to automatically rename these in your source code. | ||
1315 | |||
1316 | A new macro `SDL_PLATFORM_WINDOWS` has been added that is true for all Windows platforms, including Xbox, GDK, etc. | ||
1317 | |||
1318 | The following platform preprocessor macros have been removed: | ||
1319 | * `__DREAMCAST__` | ||
1320 | * `__NACL__` | ||
1321 | * `__PNACL__` | ||
1322 | * `__WINDOWS__` | ||
1323 | * `__WINRT__` | ||
1324 | |||
1325 | |||
1326 | ## SDL_quit.h | ||
1327 | |||
1328 | SDL_quit.h has been completely removed. It only had one symbol in it--SDL_QuitRequested--and if you want it, you can just add this to your app... | ||
1329 | |||
1330 | ```c | ||
1331 | #define SDL_QuitRequested() (SDL_PumpEvents(), (SDL_PeepEvents(NULL,0,SDL_PEEKEVENT,SDL_EVENT_QUIT,SDL_EVENT_QUIT) > 0)) | ||
1332 | ``` | ||
1333 | |||
1334 | ...but this macro is sort of messy, calling two functions in sequence in an expression. | ||
1335 | |||
1336 | The following macros have been removed: | ||
1337 | * SDL_QuitRequested - call SDL_PumpEvents() then SDL_PeepEvents() directly, instead. | ||
1338 | |||
1339 | ## SDL_rect.h | ||
1340 | |||
1341 | The following functions have been renamed: | ||
1342 | * SDL_EncloseFPoints() => SDL_GetRectEnclosingPointsFloat() | ||
1343 | * SDL_EnclosePoints() => SDL_GetRectEnclosingPoints() | ||
1344 | * SDL_FRectEmpty() => SDL_RectEmptyFloat() | ||
1345 | * SDL_FRectEquals() => SDL_RectsEqualFloat() | ||
1346 | * SDL_FRectEqualsEpsilon() => SDL_RectsEqualEpsilon() | ||
1347 | * SDL_HasIntersection() => SDL_HasRectIntersection() | ||
1348 | * SDL_HasIntersectionF() => SDL_HasRectIntersectionFloat() | ||
1349 | * SDL_IntersectFRect() => SDL_GetRectIntersectionFloat() | ||
1350 | * SDL_IntersectFRectAndLine() => SDL_GetRectAndLineIntersectionFloat() | ||
1351 | * SDL_IntersectRect() => SDL_GetRectIntersection() | ||
1352 | * SDL_IntersectRectAndLine() => SDL_GetRectAndLineIntersection() | ||
1353 | * SDL_PointInFRect() => SDL_PointInRectFloat() | ||
1354 | * SDL_RectEquals() => SDL_RectsEqual() | ||
1355 | * SDL_UnionFRect() => SDL_GetRectUnionFloat(), returns bool | ||
1356 | * SDL_UnionRect() => SDL_GetRectUnion(), returns bool | ||
1357 | |||
1358 | ## SDL_render.h | ||
1359 | |||
1360 | The 2D renderer API always uses batching in SDL3. There is no magic to turn | ||
1361 | it on and off; it doesn't matter if you select a specific renderer or try to | ||
1362 | use any hint. This means that all apps that use SDL3's 2D renderer and also | ||
1363 | want to call directly into the platform's lower-layer graphics API _must_ call | ||
1364 | SDL_FlushRenderer() before doing so. This will make sure any pending rendering | ||
1365 | work from SDL is done before the app starts directly drawing. | ||
1366 | |||
1367 | SDL_GetRenderDriverInfo() has been removed, since most of the information it reported were | ||
1368 | estimates and could not be accurate before creating a renderer. Often times this function | ||
1369 | was used to figure out the index of a driver, so one would call it in a for-loop, looking | ||
1370 | for the driver named "opengl" or whatnot. SDL_GetRenderDriver() has been added for this | ||
1371 | functionality, which returns only the name of the driver. | ||
1372 | |||
1373 | SDL_CreateRenderer()'s second argument is no longer an integer index, but a | ||
1374 | `const char *` representing a renderer's name; if you were just using a for-loop to find | ||
1375 | which index is the "opengl" or whatnot driver, you can just pass that string directly | ||
1376 | here, now. Passing NULL is the same as passing -1 here in SDL2, to signify you want SDL | ||
1377 | to decide for you. | ||
1378 | |||
1379 | SDL_CreateRenderer()'s flags parameter has been removed. See specific flags below for how to achieve the same functionality in SDL 3.0. | ||
1380 | |||
1381 | SDL_CreateWindowAndRenderer() now takes the window title as the first parameter. | ||
1382 | |||
1383 | SDL_GetRendererInfo() has been removed. The name of a renderer can be retrieved using SDL_GetRendererName(), and the other information is available as properties on the renderer. | ||
1384 | |||
1385 | Textures are created with SDL_SCALEMODE_LINEAR by default, and use SDL_BLENDMODE_BLEND by default if they are created with a format that has an alpha channel. | ||
1386 | |||
1387 | SDL_QueryTexture() has been removed. The properties of the texture can be queried using SDL_PROP_TEXTURE_FORMAT_NUMBER, SDL_PROP_TEXTURE_ACCESS_NUMBER, SDL_PROP_TEXTURE_WIDTH_NUMBER, and SDL_PROP_TEXTURE_HEIGHT_NUMBER. A function SDL_GetTextureSize() has been added to get the size of the texture as floating point values. | ||
1388 | |||
1389 | Mouse and touch events are no longer filtered to change their coordinates, instead you | ||
1390 | can call SDL_ConvertEventToRenderCoordinates() to explicitly map event coordinates into | ||
1391 | the rendering viewport. | ||
1392 | |||
1393 | SDL_RenderWindowToLogical() and SDL_RenderLogicalToWindow() have been renamed SDL_RenderCoordinatesFromWindow() and SDL_RenderCoordinatesToWindow() and take floating point coordinates in both directions. | ||
1394 | |||
1395 | The viewport, clipping state, and scale for render targets are now persistent and will remain set whenever they are active. | ||
1396 | |||
1397 | SDL_Vertex has been changed to use floating point colors, in the range of [0..1] for SDR content. | ||
1398 | |||
1399 | SDL_RenderReadPixels() returns a surface instead of filling in preallocated memory. | ||
1400 | |||
1401 | SDL_RenderSetLogicalSize() (now called SDL_SetRenderLogicalPresentation()) in SDL2 would modify the scaling and viewport state. In SDL3, logical presentation maintains its state separately, so the app can use its own viewport and scaling while also setting a logical size. | ||
1402 | |||
1403 | The following functions have been renamed: | ||
1404 | * SDL_GetRendererOutputSize() => SDL_GetCurrentRenderOutputSize(), returns bool | ||
1405 | * SDL_RenderCopy() => SDL_RenderTexture(), returns bool | ||
1406 | * SDL_RenderCopyEx() => SDL_RenderTextureRotated(), returns bool | ||
1407 | * SDL_RenderCopyExF() => SDL_RenderTextureRotated(), returns bool | ||
1408 | * SDL_RenderCopyF() => SDL_RenderTexture(), returns bool | ||
1409 | * SDL_RenderDrawLine() => SDL_RenderLine(), returns bool | ||
1410 | * SDL_RenderDrawLineF() => SDL_RenderLine(), returns bool | ||
1411 | * SDL_RenderDrawLines() => SDL_RenderLines(), returns bool | ||
1412 | * SDL_RenderDrawLinesF() => SDL_RenderLines(), returns bool | ||
1413 | * SDL_RenderDrawPoint() => SDL_RenderPoint(), returns bool | ||
1414 | * SDL_RenderDrawPointF() => SDL_RenderPoint(), returns bool | ||
1415 | * SDL_RenderDrawPoints() => SDL_RenderPoints(), returns bool | ||
1416 | * SDL_RenderDrawPointsF() => SDL_RenderPoints(), returns bool | ||
1417 | * SDL_RenderDrawRect() => SDL_RenderRect(), returns bool | ||
1418 | * SDL_RenderDrawRectF() => SDL_RenderRect(), returns bool | ||
1419 | * SDL_RenderDrawRects() => SDL_RenderRects(), returns bool | ||
1420 | * SDL_RenderDrawRectsF() => SDL_RenderRects(), returns bool | ||
1421 | * SDL_RenderFillRectF() => SDL_RenderFillRect(), returns bool | ||
1422 | * SDL_RenderFillRectsF() => SDL_RenderFillRects(), returns bool | ||
1423 | * SDL_RenderFlush() => SDL_FlushRenderer(), returns bool | ||
1424 | * SDL_RenderGetClipRect() => SDL_GetRenderClipRect(), returns bool | ||
1425 | * SDL_RenderGetIntegerScale() => SDL_GetRenderIntegerScale() | ||
1426 | * SDL_RenderGetLogicalSize() => SDL_GetRenderLogicalPresentation(), returns bool | ||
1427 | * SDL_RenderGetMetalCommandEncoder() => SDL_GetRenderMetalCommandEncoder() | ||
1428 | * SDL_RenderGetMetalLayer() => SDL_GetRenderMetalLayer() | ||
1429 | * SDL_RenderGetScale() => SDL_GetRenderScale(), returns bool | ||
1430 | * SDL_RenderGetViewport() => SDL_GetRenderViewport(), returns bool | ||
1431 | * SDL_RenderGetWindow() => SDL_GetRenderWindow() | ||
1432 | * SDL_RenderIsClipEnabled() => SDL_RenderClipEnabled() | ||
1433 | * SDL_RenderLogicalToWindow() => SDL_RenderCoordinatesToWindow(), returns bool | ||
1434 | * SDL_RenderSetClipRect() => SDL_SetRenderClipRect(), returns bool | ||
1435 | * SDL_RenderSetLogicalSize() => SDL_SetRenderLogicalPresentation(), returns bool | ||
1436 | * SDL_RenderSetScale() => SDL_SetRenderScale(), returns bool | ||
1437 | * SDL_RenderSetVSync() => SDL_SetRenderVSync(), returns bool | ||
1438 | * SDL_RenderSetViewport() => SDL_SetRenderViewport(), returns bool | ||
1439 | * SDL_RenderWindowToLogical() => SDL_RenderCoordinatesFromWindow(), returns bool | ||
1440 | |||
1441 | The following functions have been removed: | ||
1442 | * SDL_GL_BindTexture() - use SDL_GetTextureProperties() to get the OpenGL texture ID and bind the texture directly | ||
1443 | * SDL_GL_UnbindTexture() - use SDL_GetTextureProperties() to get the OpenGL texture ID and unbind the texture directly | ||
1444 | * SDL_GetTextureUserData() - use SDL_GetTextureProperties() instead | ||
1445 | * SDL_RenderGetIntegerScale() | ||
1446 | * SDL_RenderSetIntegerScale() - this is now explicit with SDL_LOGICAL_PRESENTATION_INTEGER_SCALE | ||
1447 | * SDL_RenderTargetSupported() - render targets are always supported | ||
1448 | * SDL_SetTextureUserData() - use SDL_GetTextureProperties() instead | ||
1449 | |||
1450 | The following enums have been renamed: | ||
1451 | * SDL_RendererFlip => SDL_FlipMode - moved to SDL_surface.h | ||
1452 | |||
1453 | The following symbols have been renamed: | ||
1454 | * SDL_ScaleModeLinear => SDL_SCALEMODE_LINEAR | ||
1455 | * SDL_ScaleModeNearest => SDL_SCALEMODE_NEAREST | ||
1456 | |||
1457 | The following symbols have been removed: | ||
1458 | * SDL_RENDERER_ACCELERATED - all renderers except `SDL_SOFTWARE_RENDERER` are accelerated | ||
1459 | * SDL_RENDERER_PRESENTVSYNC - replaced with SDL_PROP_RENDERER_CREATE_PRESENT_VSYNC_NUMBER during renderer creation and SDL_PROP_RENDERER_VSYNC_NUMBER after renderer creation | ||
1460 | * SDL_RENDERER_SOFTWARE - you can check whether the name of the renderer is `SDL_SOFTWARE_RENDERER` | ||
1461 | * SDL_RENDERER_TARGETTEXTURE - all renderers support target texture functionality | ||
1462 | * SDL_ScaleModeBest = use SDL_SCALEMODE_LINEAR instead | ||
1463 | |||
1464 | ## SDL_rwops.h | ||
1465 | |||
1466 | The following symbols have been renamed: | ||
1467 | * RW_SEEK_CUR => SDL_IO_SEEK_CUR | ||
1468 | * RW_SEEK_END => SDL_IO_SEEK_END | ||
1469 | * RW_SEEK_SET => SDL_IO_SEEK_SET | ||
1470 | |||
1471 | SDL_rwops.h is now named SDL_iostream.h | ||
1472 | |||
1473 | SDL_RWops is now an opaque structure, and has been renamed to SDL_IOStream. The SDL3 APIs to create an SDL_IOStream (SDL_IOFromFile, etc) are renamed but otherwise still function as they did in SDL2. However, to make a custom SDL_IOStream with app-provided function pointers, call SDL_OpenIO and provide the function pointers through there. To call into an SDL_IOStream's functionality, use the standard APIs (SDL_ReadIO, etc), as the function pointers are internal. | ||
1474 | |||
1475 | SDL_IOStream is not to be confused with the unrelated standard C++ iostream class! | ||
1476 | |||
1477 | The RWops function pointers are now in a separate structure called SDL_IOStreamInterface, which is provided to SDL_OpenIO when creating a custom SDL_IOStream implementation. All the functions now take a `void *` userdata argument for their first parameter instead of an SDL_IOStream, since that's now an opaque structure. | ||
1478 | |||
1479 | SDL_RWread and SDL_RWwrite (and the read and write function pointers) have a different function signature in SDL3, in addition to being renamed. | ||
1480 | |||
1481 | Previously they looked more like stdio: | ||
1482 | |||
1483 | ```c | ||
1484 | size_t SDL_RWread(SDL_RWops *context, void *ptr, size_t size, size_t maxnum); | ||
1485 | size_t SDL_RWwrite(SDL_RWops *context, const void *ptr, size_t size, size_t maxnum); | ||
1486 | ``` | ||
1487 | |||
1488 | But now they look more like POSIX: | ||
1489 | |||
1490 | ```c | ||
1491 | size_t SDL_ReadIO(SDL_IOStream *context, void *ptr, size_t size); | ||
1492 | size_t SDL_WriteIO(SDL_IOStream *context, const void *ptr, size_t size); | ||
1493 | ``` | ||
1494 | |||
1495 | Code that used to look like this: | ||
1496 | ```c | ||
1497 | size_t custom_read(void *ptr, size_t size, size_t nitems, SDL_RWops *stream) | ||
1498 | { | ||
1499 | return SDL_RWread(stream, ptr, size, nitems); | ||
1500 | } | ||
1501 | ``` | ||
1502 | should be changed to: | ||
1503 | ```c | ||
1504 | size_t custom_read(void *ptr, size_t size, size_t nitems, SDL_IOStream *stream) | ||
1505 | { | ||
1506 | if (size > 0 && nitems > 0) { | ||
1507 | return SDL_ReadIO(stream, ptr, size * nitems) / size; | ||
1508 | } | ||
1509 | return 0; | ||
1510 | } | ||
1511 | ``` | ||
1512 | |||
1513 | SDL_RWops::type was removed; it wasn't meaningful for app-provided implementations at all, and wasn't much use for SDL's internal implementations, either. If you _have_ to identify the type, you can examine the SDL_IOStream's properties to detect built-in implementations. | ||
1514 | |||
1515 | SDL_IOStreamInterface::close implementations should clean up their own userdata, but not call SDL_CloseIO on themselves; now the contract is always that SDL_CloseIO is called, which calls `->close` before freeing the opaque object. | ||
1516 | |||
1517 | SDL_AllocRW(), SDL_FreeRW(), SDL_RWclose() and direct access to the `->close` function pointer have been removed from the API, so there's only one path to manage RWops lifetimes now: SDL_OpenIO() and SDL_CloseIO(). | ||
1518 | |||
1519 | SDL_RWFromFP has been removed from the API, due to issues when the SDL library uses a different C runtime from the application. | ||
1520 | |||
1521 | You can implement this in your own code easily: | ||
1522 | ```c | ||
1523 | #include <stdio.h> | ||
1524 | |||
1525 | typedef struct IOStreamStdioFPData | ||
1526 | { | ||
1527 | FILE *fp; | ||
1528 | bool autoclose; | ||
1529 | } IOStreamStdioFPData; | ||
1530 | |||
1531 | static Sint64 SDLCALL stdio_seek(void *userdata, Sint64 offset, int whence) | ||
1532 | { | ||
1533 | FILE *fp = ((IOStreamStdioFPData *) userdata)->fp; | ||
1534 | int stdiowhence; | ||
1535 | |||
1536 | switch (whence) { | ||
1537 | case SDL_IO_SEEK_SET: | ||
1538 | stdiowhence = SEEK_SET; | ||
1539 | break; | ||
1540 | case SDL_IO_SEEK_CUR: | ||
1541 | stdiowhence = SEEK_CUR; | ||
1542 | break; | ||
1543 | case SDL_IO_SEEK_END: | ||
1544 | stdiowhence = SEEK_END; | ||
1545 | break; | ||
1546 | default: | ||
1547 | SDL_SetError("Unknown value for 'whence'"); | ||
1548 | return -1; | ||
1549 | } | ||
1550 | |||
1551 | if (fseek(fp, (fseek_off_t)offset, stdiowhence) == 0) { | ||
1552 | const Sint64 pos = ftell(fp); | ||
1553 | if (pos < 0) { | ||
1554 | SDL_SetError("Couldn't get stream offset"); | ||
1555 | return -1; | ||
1556 | } | ||
1557 | return pos; | ||
1558 | } | ||
1559 | SDL_SetError("Couldn't seek in stream"); | ||
1560 | return -1; | ||
1561 | } | ||
1562 | |||
1563 | static size_t SDLCALL stdio_read(void *userdata, void *ptr, size_t size, SDL_IOStatus *status) | ||
1564 | { | ||
1565 | FILE *fp = ((IOStreamStdioFPData *) userdata)->fp; | ||
1566 | const size_t bytes = fread(ptr, 1, size, fp); | ||
1567 | if (bytes == 0 && ferror(fp)) { | ||
1568 | SDL_SetError("Couldn't read stream"); | ||
1569 | } | ||
1570 | return bytes; | ||
1571 | } | ||
1572 | |||
1573 | static size_t SDLCALL stdio_write(void *userdata, const void *ptr, size_t size, SDL_IOStatus *status) | ||
1574 | { | ||
1575 | FILE *fp = ((IOStreamStdioFPData *) userdata)->fp; | ||
1576 | const size_t bytes = fwrite(ptr, 1, size, fp); | ||
1577 | if (bytes == 0 && ferror(fp)) { | ||
1578 | SDL_SetError("Couldn't write stream"); | ||
1579 | } | ||
1580 | return bytes; | ||
1581 | } | ||
1582 | |||
1583 | static bool SDLCALL stdio_close(void *userdata) | ||
1584 | { | ||
1585 | IOStreamStdioData *rwopsdata = (IOStreamStdioData *) userdata; | ||
1586 | bool status = true; | ||
1587 | if (rwopsdata->autoclose) { | ||
1588 | if (fclose(rwopsdata->fp) != 0) { | ||
1589 | SDL_SetError("Couldn't close stream"); | ||
1590 | status = false; | ||
1591 | } | ||
1592 | } | ||
1593 | return status; | ||
1594 | } | ||
1595 | |||
1596 | SDL_IOStream *SDL_RWFromFP(FILE *fp, bool autoclose) | ||
1597 | { | ||
1598 | SDL_IOStreamInterface iface; | ||
1599 | IOStreamStdioFPData *rwopsdata; | ||
1600 | SDL_IOStream *rwops; | ||
1601 | |||
1602 | rwopsdata = (IOStreamStdioFPData *) SDL_malloc(sizeof (*rwopsdata)); | ||
1603 | if (!rwopsdata) { | ||
1604 | return NULL; | ||
1605 | } | ||
1606 | |||
1607 | SDL_INIT_INTERFACE(&iface); | ||
1608 | /* There's no stdio_size because SDL_GetIOSize emulates it the same way we'd do it for stdio anyhow. */ | ||
1609 | iface.seek = stdio_seek; | ||
1610 | iface.read = stdio_read; | ||
1611 | iface.write = stdio_write; | ||
1612 | iface.close = stdio_close; | ||
1613 | |||
1614 | rwopsdata->fp = fp; | ||
1615 | rwopsdata->autoclose = autoclose; | ||
1616 | |||
1617 | rwops = SDL_OpenIO(&iface, rwopsdata); | ||
1618 | if (!rwops) { | ||
1619 | iface.close(rwopsdata); | ||
1620 | } | ||
1621 | return rwops; | ||
1622 | } | ||
1623 | ``` | ||
1624 | |||
1625 | The internal `FILE *` is available through a standard SDL_IOStream property, for streams made through SDL_IOFromFile() that use stdio behind the scenes; apps use this pointer at their own risk and should make sure that SDL and the app are using the same C runtime. | ||
1626 | |||
1627 | On Apple platforms, SDL_RWFromFile (now called SDL_IOFromFile) no longer tries to read from inside the app bundle's resource directory, instead now using the specified path unchanged. One can use SDL_GetBasePath() to find the resource directory on these platforms. | ||
1628 | |||
1629 | |||
1630 | The functions SDL_ReadU8(), SDL_ReadU16LE(), SDL_ReadU16BE(), SDL_ReadU32LE(), SDL_ReadU32BE(), SDL_ReadU64LE(), and SDL_ReadU64BE() now return true if the read succeeded and false if it didn't, and store the data in a pointer passed in as a parameter. | ||
1631 | |||
1632 | The following functions have been renamed: | ||
1633 | * SDL_RWFromConstMem() => SDL_IOFromConstMem() | ||
1634 | * SDL_RWFromFile() => SDL_IOFromFile() | ||
1635 | * SDL_RWFromMem() => SDL_IOFromMem() | ||
1636 | * SDL_RWclose() => SDL_CloseIO(), returns bool | ||
1637 | * SDL_RWread() => SDL_ReadIO() | ||
1638 | * SDL_RWseek() => SDL_SeekIO() | ||
1639 | * SDL_RWsize() => SDL_GetIOSize() | ||
1640 | * SDL_RWtell() => SDL_TellIO() | ||
1641 | * SDL_RWwrite() => SDL_WriteIO() | ||
1642 | * SDL_ReadBE16() => SDL_ReadU16BE() | ||
1643 | * SDL_ReadBE32() => SDL_ReadU32BE() | ||
1644 | * SDL_ReadBE64() => SDL_ReadU64BE() | ||
1645 | * SDL_ReadLE16() => SDL_ReadU16LE() | ||
1646 | * SDL_ReadLE32() => SDL_ReadU32LE() | ||
1647 | * SDL_ReadLE64() => SDL_ReadU64LE() | ||
1648 | * SDL_WriteBE16() => SDL_WriteU16BE() | ||
1649 | * SDL_WriteBE32() => SDL_WriteU32BE() | ||
1650 | * SDL_WriteBE64() => SDL_WriteU64BE() | ||
1651 | * SDL_WriteLE16() => SDL_WriteU16LE() | ||
1652 | * SDL_WriteLE32() => SDL_WriteU32LE() | ||
1653 | * SDL_WriteLE64() => SDL_WriteU64LE() | ||
1654 | |||
1655 | |||
1656 | The following structures have been renamed: | ||
1657 | * SDL_RWops => SDL_IOStream | ||
1658 | |||
1659 | ## SDL_scancode.h | ||
1660 | |||
1661 | The following symbols have been removed: | ||
1662 | * SDL_SCANCODE_WWW | ||
1663 | * SDL_SCANCODE_MAIL | ||
1664 | * SDL_SCANCODE_CALCULATOR | ||
1665 | * SDL_SCANCODE_COMPUTER | ||
1666 | * SDL_SCANCODE_BRIGHTNESSDOWN | ||
1667 | * SDL_SCANCODE_BRIGHTNESSUP | ||
1668 | * SDL_SCANCODE_DISPLAYSWITCH | ||
1669 | * SDL_SCANCODE_KBDILLUMTOGGLE | ||
1670 | * SDL_SCANCODE_KBDILLUMDOWN | ||
1671 | * SDL_SCANCODE_KBDILLUMUP | ||
1672 | * SDL_SCANCODE_APP1 | ||
1673 | * SDL_SCANCODE_APP2 | ||
1674 | |||
1675 | The following symbols have been renamed: | ||
1676 | * SDL_NUM_SCANCODES => SDL_SCANCODE_COUNT | ||
1677 | * SDL_SCANCODE_AUDIOFASTFORWARD => SDL_SCANCODE_MEDIA_FAST_FORWARD | ||
1678 | * SDL_SCANCODE_AUDIOMUTE => SDL_SCANCODE_MUTE | ||
1679 | * SDL_SCANCODE_AUDIONEXT => SDL_SCANCODE_MEDIA_NEXT_TRACK | ||
1680 | * SDL_SCANCODE_AUDIOPLAY => SDL_SCANCODE_MEDIA_PLAY | ||
1681 | * SDL_SCANCODE_AUDIOPREV => SDL_SCANCODE_MEDIA_PREVIOUS_TRACK | ||
1682 | * SDL_SCANCODE_AUDIOREWIND => SDL_SCANCODE_MEDIA_REWIND | ||
1683 | * SDL_SCANCODE_AUDIOSTOP => SDL_SCANCODE_MEDIA_STOP | ||
1684 | * SDL_SCANCODE_EJECT => SDL_SCANCODE_MEDIA_EJECT | ||
1685 | * SDL_SCANCODE_MEDIASELECT => SDL_SCANCODE_MEDIA_SELECT | ||
1686 | |||
1687 | ## SDL_sensor.h | ||
1688 | |||
1689 | SDL_SensorID has changed from Sint32 to Uint32, with an invalid ID being 0. | ||
1690 | |||
1691 | Rather than iterating over sensors using device index, there is a new function SDL_GetSensors() to get the current list of sensors, and new functions to get information about sensors from their instance ID: | ||
1692 | ```c | ||
1693 | { | ||
1694 | if (SDL_InitSubSystem(SDL_INIT_SENSOR)) { | ||
1695 | int i, num_sensors; | ||
1696 | SDL_SensorID *sensors = SDL_GetSensors(&num_sensors); | ||
1697 | if (sensors) { | ||
1698 | for (i = 0; i < num_sensors; ++i) { | ||
1699 | SDL_Log("Sensor %" SDL_PRIu32 ": %s, type %d, platform type %d", | ||
1700 | sensors[i], | ||
1701 | SDL_GetSensorNameForID(sensors[i]), | ||
1702 | SDL_GetSensorTypeForID(sensors[i]), | ||
1703 | SDL_GetSensorNonPortableTypeForID(sensors[i])); | ||
1704 | } | ||
1705 | SDL_free(sensors); | ||
1706 | } | ||
1707 | SDL_QuitSubSystem(SDL_INIT_SENSOR); | ||
1708 | } | ||
1709 | } | ||
1710 | ``` | ||
1711 | |||
1712 | Removed SDL_SensorGetDataWithTimestamp(), if you want timestamps for the sensor data, you should use the sensor_timestamp member of SDL_EVENT_SENSOR_UPDATE events. | ||
1713 | |||
1714 | |||
1715 | The following functions have been renamed: | ||
1716 | * SDL_SensorClose() => SDL_CloseSensor() | ||
1717 | * SDL_SensorFromInstanceID() => SDL_GetSensorFromID() | ||
1718 | * SDL_SensorGetData() => SDL_GetSensorData(), returns bool | ||
1719 | * SDL_SensorGetInstanceID() => SDL_GetSensorID() | ||
1720 | * SDL_SensorGetName() => SDL_GetSensorName() | ||
1721 | * SDL_SensorGetNonPortableType() => SDL_GetSensorNonPortableType() | ||
1722 | * SDL_SensorGetType() => SDL_GetSensorType() | ||
1723 | * SDL_SensorOpen() => SDL_OpenSensor() | ||
1724 | * SDL_SensorUpdate() => SDL_UpdateSensors() | ||
1725 | |||
1726 | The following functions have been removed: | ||
1727 | * SDL_LockSensors() | ||
1728 | * SDL_NumSensors() - replaced with SDL_GetSensors() | ||
1729 | * SDL_SensorGetDeviceInstanceID() | ||
1730 | * SDL_SensorGetDeviceName() - replaced with SDL_GetSensorNameForID() | ||
1731 | * SDL_SensorGetDeviceNonPortableType() - replaced with SDL_GetSensorNonPortableTypeForID() | ||
1732 | * SDL_SensorGetDeviceType() - replaced with SDL_GetSensorTypeForID() | ||
1733 | * SDL_UnlockSensors() | ||
1734 | |||
1735 | ## SDL_shape.h | ||
1736 | |||
1737 | This header has been removed and a simplified version of this API has been added as SDL_SetWindowShape() in SDL_video.h. See test/testshape.c for an example. | ||
1738 | |||
1739 | ## SDL_stdinc.h | ||
1740 | |||
1741 | The standard C headers like stdio.h and stdlib.h are no longer included, you should include them directly in your project if you use non-SDL C runtime functions. | ||
1742 | M_PI is no longer defined in SDL_stdinc.h, you can use the new symbols SDL_PI_D (double) and SDL_PI_F (float) instead. | ||
1743 | |||
1744 | bool is now defined as bool, and is 1 byte instead of the size of an int. | ||
1745 | |||
1746 | SDL3 attempts to apply consistency to case-insensitive string functions. In SDL2, things like SDL_strcasecmp() would usually only work on English letters, and depending on the user's locale, possibly not even those. In SDL3, consistency is applied: | ||
1747 | |||
1748 | - Many things that don't care about case-insensitivity, like SDL_strcmp(), continue to work with any null-terminated string of bytes, even if it happens to be malformed UTF-8. | ||
1749 | - SDL_strcasecmp() expects valid UTF-8 strings, and will attempt to support _most_ Unicode characters with a technique known as "case-folding," which is to say it can match 'A' and 'a', and also 'Η' and 'η', but ALSO 'ß' and "ss". This is _probably_ how most apps assumed it worked in SDL2 and won't need any changes. | ||
1750 | - SDL_strncasecmp() works the same, but the third parameter takes _bytes_, as before, so SDL_strlen() can continue to be used with it. If a string hits the limit in the middle of a codepoint, the half-processed bytes of the codepoint will be treated as a collection of U+0xFFFD (REPLACEMENT CHARACTER) codepoints, which you probably don't want. | ||
1751 | - SDL_wcscasecmp() and SDL_wcsncasecmp() work the same way but operate on UTF-16 or UTF-32 encoded strings, depending on what the platform considers "wchar_t" to be. SDL_wcsncasecmp's third parameter is number of wchar_t values, not bytes, but UTF-16 has the same concerns as UTF-8 for variable-length codepoints. | ||
1752 | - SDL_strcasestr() expects valid UTF-8 strings, and will compare codepoints using case-folding. | ||
1753 | - SDL_tolower() and SDL_toupper() continue to only work on single bytes (even though the parameter is an `int`) and _only_ converts low-ASCII English A through Z. | ||
1754 | - SDL_strlwr() and SDL_strupr() operates on individual bytes (not UTF-8 codepoints) and only change low-ASCII English 'A' through 'Z'. These functions do not check the string for valid UTF-8 encoding. | ||
1755 | - The ctype.h replacement SDL_is*() functions (SDL_isalpha, SDL_isdigit, etc) only work on low-ASCII characters and ignore user locale, assuming English. This makes these functions consistent in SDL3, but applications need to be careful to understand their limits. | ||
1756 | |||
1757 | Please note that the case-folding technique used by SDL3 will not produce correct results for the "Turkish 'I'"; this one letter is a surprisingly hard problem in the Unicode world, and since these functions do not specify the human language in use, we have chosen to ignore this problem. | ||
1758 | |||
1759 | SDL_strtoll(), SDL_strtoull(), SDL_lltoa(), and SDL_ulltoa() use long long values instead of 64-bit values, to match their C runtime counterparts. | ||
1760 | |||
1761 | SDL_setenv() is not thread-safe and has been renamed SDL_setenv_unsafe(). | ||
1762 | |||
1763 | The following macros have been removed: | ||
1764 | * SDL_TABLESIZE() - use SDL_arraysize() instead | ||
1765 | |||
1766 | The following functions have been renamed: | ||
1767 | * SDL_size_add_overflow() => SDL_size_add_check_overflow(), returns bool | ||
1768 | * SDL_size_mul_overflow() => SDL_size_mul_check_overflow(), returns bool | ||
1769 | * SDL_strtokr() => SDL_strtok_r() | ||
1770 | |||
1771 | The following functions have been removed: | ||
1772 | * SDL_memcpy4() | ||
1773 | |||
1774 | The following symbols have been renamed: | ||
1775 | * SDL_FALSE => false | ||
1776 | * SDL_TRUE => true | ||
1777 | * SDL_bool => bool | ||
1778 | |||
1779 | ## SDL_surface.h | ||
1780 | |||
1781 | SDL_Surface has been simplified and internal details are no longer in the public structure. | ||
1782 | |||
1783 | The `format` member of SDL_Surface is now an enumerated pixel format value. You can get the full details of the pixel format by calling `SDL_GetPixelFormatDetails(surface->format)`. You can get the palette associated with the surface by calling SDL_GetSurfacePalette(). You can get the clip rectangle by calling SDL_GetSurfaceClipRect(). | ||
1784 | |||
1785 | The userdata member of SDL_Surface has been replaced with a more general properties interface, which can be queried with SDL_GetSurfaceProperties() | ||
1786 | |||
1787 | Indexed format surfaces no longer have a palette by default. Surfaces without a palette will copy the pixels untranslated between surfaces. | ||
1788 | |||
1789 | Code that used to look like this: | ||
1790 | ```c | ||
1791 | SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormat(0, 32, 32, 8, SDL_PIXELFORMAT_INDEX8); | ||
1792 | SDL_Palette *palette = surface->format->palette; | ||
1793 | ... | ||
1794 | ``` | ||
1795 | should be changed to: | ||
1796 | ```c | ||
1797 | SDL_Surface *surface = SDL_CreateSurface(32, 32, SDL_PIXELFORMAT_INDEX8); | ||
1798 | SDL_Palette *palette = SDL_CreateSurfacePalette(surface); | ||
1799 | ... | ||
1800 | ``` | ||
1801 | |||
1802 | Removed the unused 'flags' parameter from SDL_ConvertSurface. | ||
1803 | |||
1804 | SDL_CreateRGBSurface() and SDL_CreateRGBSurfaceWithFormat() have been combined into a new function SDL_CreateSurface(). | ||
1805 | SDL_CreateRGBSurfaceFrom() and SDL_CreateRGBSurfaceWithFormatFrom() have been combined into a new function SDL_CreateSurfaceFrom(), and the parameter order has changed for consistency with SDL_CreateSurface(). | ||
1806 | |||
1807 | You can implement the old functions in your own code easily: | ||
1808 | ```c | ||
1809 | SDL_Surface *SDL_CreateRGBSurface(Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) | ||
1810 | { | ||
1811 | return SDL_CreateSurface(width, height, | ||
1812 | SDL_GetPixelFormatForMasks(depth, Rmask, Gmask, Bmask, Amask)); | ||
1813 | } | ||
1814 | |||
1815 | SDL_Surface *SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int width, int height, int depth, Uint32 format) | ||
1816 | { | ||
1817 | return SDL_CreateSurface(width, height, format); | ||
1818 | } | ||
1819 | |||
1820 | SDL_Surface *SDL_CreateRGBSurfaceFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) | ||
1821 | { | ||
1822 | return SDL_CreateSurfaceFrom(width, height, | ||
1823 | SDL_GetPixelFormatForMasks(depth, Rmask, Gmask, Bmask, Amask), | ||
1824 | pixels, pitch); | ||
1825 | } | ||
1826 | |||
1827 | SDL_Surface *SDL_CreateRGBSurfaceWithFormatFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 format) | ||
1828 | { | ||
1829 | return SDL_CreateSurfaceFrom(width, height, format, pixels, pitch); | ||
1830 | } | ||
1831 | |||
1832 | ``` | ||
1833 | |||
1834 | But if you're migrating your code which uses masks, you probably have a format in mind, possibly one of these: | ||
1835 | ```c | ||
1836 | // Various mask (R, G, B, A) and their corresponding format: | ||
1837 | 0xFF000000 0x00FF0000 0x0000FF00 0x000000FF => SDL_PIXELFORMAT_RGBA8888 | ||
1838 | 0x00FF0000 0x0000FF00 0x000000FF 0xFF000000 => SDL_PIXELFORMAT_ARGB8888 | ||
1839 | 0x0000FF00 0x00FF0000 0xFF000000 0x000000FF => SDL_PIXELFORMAT_BGRA8888 | ||
1840 | 0x000000FF 0x0000FF00 0x00FF0000 0xFF000000 => SDL_PIXELFORMAT_ABGR8888 | ||
1841 | 0x0000F800 0x000007E0 0x0000001F 0x00000000 => SDL_PIXELFORMAT_RGB565 | ||
1842 | ``` | ||
1843 | |||
1844 | SDL_BlitSurface() and SDL_BlitSurfaceScaled() now have a const `dstrect` parameter and do not fill it in with the final destination rectangle. | ||
1845 | |||
1846 | SDL_BlitSurfaceScaled() and SDL_BlitSurfaceUncheckedScaled() now take a scale parameter. | ||
1847 | |||
1848 | SDL_PixelFormat is used instead of Uint32 for API functions that refer to pixel format by enumerated value. | ||
1849 | |||
1850 | SDL_SetSurfaceColorKey() takes an bool to enable and disable colorkey. RLE acceleration isn't controlled by the parameter, you should use SDL_SetSurfaceRLE() to change that separately. | ||
1851 | |||
1852 | SDL_SetSurfaceRLE() takes an bool to enable and disable RLE acceleration. | ||
1853 | |||
1854 | The following functions have been renamed: | ||
1855 | * SDL_BlitScaled() => SDL_BlitSurfaceScaled(), returns bool | ||
1856 | * SDL_ConvertSurfaceFormat() => SDL_ConvertSurface() | ||
1857 | * SDL_FillRect() => SDL_FillSurfaceRect(), returns bool | ||
1858 | * SDL_FillRects() => SDL_FillSurfaceRects(), returns bool | ||
1859 | * SDL_FreeSurface() => SDL_DestroySurface() | ||
1860 | * SDL_GetClipRect() => SDL_GetSurfaceClipRect(), returns bool | ||
1861 | * SDL_GetColorKey() => SDL_GetSurfaceColorKey(), returns bool | ||
1862 | * SDL_HasColorKey() => SDL_SurfaceHasColorKey() | ||
1863 | * SDL_HasSurfaceRLE() => SDL_SurfaceHasRLE() | ||
1864 | * SDL_LoadBMP_RW() => SDL_LoadBMP_IO() | ||
1865 | * SDL_LowerBlit() => SDL_BlitSurfaceUnchecked(), returns bool | ||
1866 | * SDL_LowerBlitScaled() => SDL_BlitSurfaceUncheckedScaled(), returns bool | ||
1867 | * SDL_SaveBMP_RW() => SDL_SaveBMP_IO(), returns bool | ||
1868 | * SDL_SetClipRect() => SDL_SetSurfaceClipRect() | ||
1869 | * SDL_SetColorKey() => SDL_SetSurfaceColorKey(), returns bool | ||
1870 | * SDL_UpperBlit() => SDL_BlitSurface(), returns bool | ||
1871 | * SDL_UpperBlitScaled() => SDL_BlitSurfaceScaled(), returns bool | ||
1872 | |||
1873 | The following symbols have been removed: | ||
1874 | * SDL_SWSURFACE | ||
1875 | |||
1876 | The following functions have been removed: | ||
1877 | * SDL_FreeFormat() | ||
1878 | * SDL_GetYUVConversionMode() | ||
1879 | * SDL_GetYUVConversionModeForResolution() | ||
1880 | * SDL_SetYUVConversionMode() - use SDL_SetSurfaceColorspace() to set the surface colorspace and SDL_PROP_TEXTURE_CREATE_COLORSPACE_NUMBER with SDL_CreateTextureWithProperties() to set the texture colorspace. The default colorspace for YUV pixel formats is SDL_COLORSPACE_JPEG. | ||
1881 | * SDL_SoftStretch() - use SDL_StretchSurface() with SDL_SCALEMODE_NEAREST | ||
1882 | * SDL_SoftStretchLinear() - use SDL_StretchSurface() with SDL_SCALEMODE_LINEAR | ||
1883 | |||
1884 | The following symbols have been renamed: | ||
1885 | * SDL_PREALLOC => SDL_SURFACE_PREALLOCATED | ||
1886 | * SDL_SIMD_ALIGNED => SDL_SURFACE_SIMD_ALIGNED | ||
1887 | |||
1888 | ## SDL_system.h | ||
1889 | |||
1890 | SDL_WindowsMessageHook has changed signatures so the message may be modified and it can block further message processing. | ||
1891 | |||
1892 | SDL_RequestAndroidPermission is no longer a blocking call; the caller now provides a callback function that fires when a response is available. | ||
1893 | |||
1894 | SDL_iPhoneSetAnimationCallback() and SDL_iPhoneSetEventPump() have been renamed to SDL_SetiOSAnimationCallback() and SDL_SetiOSEventPump(), respectively. SDL2 has had macros to provide this new name with the old symbol since the introduction of the iPad, but now the correctly-named symbol is the only option. | ||
1895 | |||
1896 | SDL_IsAndroidTV() has been renamed SDL_IsTV() and is no longer Android-specific; an app running on an Apple TV device will also return true, for example. | ||
1897 | |||
1898 | The following functions have been removed: | ||
1899 | * SDL_GetWinRTFSPathUNICODE() - WinRT support was removed in SDL3. | ||
1900 | * SDL_GetWinRTFSPathUTF8() - WinRT support was removed in SDL3. | ||
1901 | * SDL_RenderGetD3D11Device() - replaced with the "SDL.renderer.d3d11.device" property | ||
1902 | * SDL_RenderGetD3D12Device() - replaced with the "SDL.renderer.d3d12.device" property | ||
1903 | * SDL_RenderGetD3D9Device() - replaced with the "SDL.renderer.d3d9.device" property | ||
1904 | * SDL_WinRTGetDeviceFamily() - WinRT support was removed in SDL3. | ||
1905 | |||
1906 | The following functions have been renamed: | ||
1907 | * SDL_AndroidBackButton() => SDL_SendAndroidBackButton() | ||
1908 | * SDL_AndroidGetActivity() => SDL_GetAndroidActivity() | ||
1909 | * SDL_AndroidGetExternalStoragePath() => SDL_GetAndroidExternalStoragePath() | ||
1910 | * SDL_AndroidGetExternalStorageState() => SDL_GetAndroidExternalStorageState() | ||
1911 | * SDL_AndroidGetInternalStoragePath() => SDL_GetAndroidInternalStoragePath() | ||
1912 | * SDL_AndroidGetJNIEnv() => SDL_GetAndroidJNIEnv() | ||
1913 | * SDL_AndroidRequestPermission() => SDL_RequestAndroidPermission(), returns bool | ||
1914 | * SDL_AndroidRequestPermissionCallback() => SDL_RequestAndroidPermissionCallback() | ||
1915 | * SDL_AndroidSendMessage() => SDL_SendAndroidMessage(), returns bool | ||
1916 | * SDL_AndroidShowToast() => SDL_ShowAndroidToast(), returns bool | ||
1917 | * SDL_DXGIGetOutputInfo() => SDL_GetDXGIOutputInfo(), returns bool | ||
1918 | * SDL_Direct3D9GetAdapterIndex() => SDL_GetDirect3D9AdapterIndex() | ||
1919 | * SDL_GDKGetDefaultUser() => SDL_GetGDKDefaultUser(), returns bool | ||
1920 | * SDL_GDKGetTaskQueue() => SDL_GetGDKTaskQueue(), returns bool | ||
1921 | * SDL_IsAndroidTV() => SDL_IsTV() | ||
1922 | * SDL_LinuxSetThreadPriority() => SDL_SetLinuxThreadPriority(), returns bool | ||
1923 | * SDL_LinuxSetThreadPriorityAndPolicy() => SDL_SetLinuxThreadPriorityAndPolicy(), returns bool | ||
1924 | * SDL_OnApplicationDidBecomeActive() => SDL_OnApplicationDidEnterForeground() | ||
1925 | * SDL_OnApplicationWillResignActive() => SDL_OnApplicationWillEnterBackground() | ||
1926 | * SDL_iOSSetAnimationCallback() => SDL_SetiOSAnimationCallback(), returns bool | ||
1927 | * SDL_iOSSetEventPump() => SDL_SetiOSEventPump() | ||
1928 | * SDL_iPhoneSetAnimationCallback() => SDL_SetiOSAnimationCallback(), returns bool | ||
1929 | * SDL_iPhoneSetEventPump() => SDL_SetiOSEventPump() | ||
1930 | |||
1931 | ## SDL_syswm.h | ||
1932 | |||
1933 | This header has been removed. | ||
1934 | |||
1935 | The Windows and X11 events are now available via callbacks which you can set with SDL_SetWindowsMessageHook() and SDL_SetX11EventHook(). | ||
1936 | |||
1937 | The information previously available in SDL_GetWindowWMInfo() is now available as window properties, e.g. | ||
1938 | ```c | ||
1939 | SDL_SysWMinfo info; | ||
1940 | SDL_VERSION(&info.version); | ||
1941 | |||
1942 | #if defined(__WIN32__) | ||
1943 | HWND hwnd = NULL; | ||
1944 | if (SDL_GetWindowWMInfo(window, &info) && info.subsystem == SDL_SYSWM_WINDOWS) { | ||
1945 | hwnd = info.info.win.window; | ||
1946 | } | ||
1947 | if (hwnd) { | ||
1948 | ... | ||
1949 | } | ||
1950 | #elif defined(__MACOSX__) | ||
1951 | NSWindow *nswindow = NULL; | ||
1952 | if (SDL_GetWindowWMInfo(window, &info) && info.subsystem == SDL_SYSWM_COCOA) { | ||
1953 | nswindow = (__bridge NSWindow *)info.info.cocoa.window; | ||
1954 | } | ||
1955 | if (nswindow) { | ||
1956 | ... | ||
1957 | } | ||
1958 | #elif defined(__LINUX__) | ||
1959 | if (SDL_GetWindowWMInfo(window, &info)) { | ||
1960 | if (info.subsystem == SDL_SYSWM_X11) { | ||
1961 | Display *xdisplay = info.info.x11.display; | ||
1962 | Window xwindow = info.info.x11.window; | ||
1963 | if (xdisplay && xwindow) { | ||
1964 | ... | ||
1965 | } | ||
1966 | } else if (info.subsystem == SDL_SYSWM_WAYLAND) { | ||
1967 | struct wl_display *display = info.info.wl.display; | ||
1968 | struct wl_surface *surface = info.info.wl.surface; | ||
1969 | if (display && surface) { | ||
1970 | ... | ||
1971 | } | ||
1972 | } | ||
1973 | } | ||
1974 | #elif defined(__IPHONEOS__) | ||
1975 | UIWindow *uiwindow = NULL; | ||
1976 | if (SDL_GetWindowWMInfo(window, &info) && info.subsystem == SDL_SYSWM_UIKIT) { | ||
1977 | uiwindow = (__bridge UIWindow *)info.info.uikit.window; | ||
1978 | } | ||
1979 | if (uiwindow) { | ||
1980 | GLuint framebuffer = info.info.uikit.framebuffer; | ||
1981 | GLuint colorbuffer = info.info.uikit.colorbuffer; | ||
1982 | GLuint resolveFramebuffer = info.info.uikit.resolveFramebuffer; | ||
1983 | ... | ||
1984 | } | ||
1985 | #endif | ||
1986 | ``` | ||
1987 | becomes: | ||
1988 | ```c | ||
1989 | #if defined(SDL_PLATFORM_WIN32) | ||
1990 | HWND hwnd = (HWND)SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL); | ||
1991 | if (hwnd) { | ||
1992 | ... | ||
1993 | } | ||
1994 | #elif defined(SDL_PLATFORM_MACOS) | ||
1995 | NSWindow *nswindow = (__bridge NSWindow *)SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_COCOA_WINDOW_POINTER, NULL); | ||
1996 | if (nswindow) { | ||
1997 | ... | ||
1998 | } | ||
1999 | #elif defined(SDL_PLATFORM_LINUX) | ||
2000 | if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "x11") == 0) { | ||
2001 | Display *xdisplay = (Display *)SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_X11_DISPLAY_POINTER, NULL); | ||
2002 | Window xwindow = (Window)SDL_GetNumberProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0); | ||
2003 | if (xdisplay && xwindow) { | ||
2004 | ... | ||
2005 | } | ||
2006 | } else if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "wayland") == 0) { | ||
2007 | struct wl_display *display = (struct wl_display *)SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_WAYLAND_DISPLAY_POINTER, NULL); | ||
2008 | struct wl_surface *surface = (struct wl_surface *)SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, NULL); | ||
2009 | if (display && surface) { | ||
2010 | ... | ||
2011 | } | ||
2012 | } | ||
2013 | #elif defined(SDL_PLATFORM_IOS) | ||
2014 | SDL_PropertiesID props = SDL_GetWindowProperties(window); | ||
2015 | UIWindow *uiwindow = (__bridge UIWindow *)SDL_GetPointerProperty(props, SDL_PROP_WINDOW_UIKIT_WINDOW_POINTER, NULL); | ||
2016 | if (uiwindow) { | ||
2017 | GLuint framebuffer = (GLuint)SDL_GetNumberProperty(props, SDL_PROP_WINDOW_UIKIT_OPENGL_FRAMEBUFFER_NUMBER, 0); | ||
2018 | GLuint colorbuffer = (GLuint)SDL_GetNumberProperty(props, SDL_PROP_WINDOW_UIKIT_OPENGL_RENDERBUFFER_NUMBER, 0); | ||
2019 | GLuint resolveFramebuffer = (GLuint)SDL_GetNumberProperty(props, SDL_PROP_WINDOW_UIKIT_OPENGL_RESOLVE_FRAMEBUFFER_NUMBER, 0); | ||
2020 | ... | ||
2021 | } | ||
2022 | #endif | ||
2023 | ``` | ||
2024 | |||
2025 | ## SDL_thread.h | ||
2026 | |||
2027 | SDL_CreateThreadWithStackSize has been replaced with SDL_CreateThreadWithProperties. | ||
2028 | |||
2029 | SDL_CreateThread and SDL_CreateThreadWithProperties now take beginthread/endthread function pointers on all platforms (ignoring them on most), and have been replaced with macros that hide this detail on all platforms. This works the same as before at the source code level, but the actual function signature that is called in SDL has changed. The library's exported symbol is SDL_CreateThreadRuntime, and looking for "SDL_CreateThread" in the DLL/Shared Library/Dylib will fail. You should not call this directly, but instead always use the macro! | ||
2030 | |||
2031 | SDL_GetTLS() and SDL_SetTLS() take a pointer to a TLS ID, and will automatically initialize it in a thread-safe way as needed. | ||
2032 | |||
2033 | The following functions have been renamed: | ||
2034 | * SDL_SetThreadPriority() => SDL_SetCurrentThreadPriority() | ||
2035 | * SDL_TLSCleanup() => SDL_CleanupTLS() | ||
2036 | * SDL_TLSGet() => SDL_GetTLS() | ||
2037 | * SDL_TLSSet() => SDL_SetTLS(), returns bool | ||
2038 | * SDL_ThreadID() => SDL_GetCurrentThreadID() | ||
2039 | |||
2040 | The following functions have been removed: | ||
2041 | * SDL_TLSCreate() - TLS IDs are automatically allocated as needed. | ||
2042 | |||
2043 | The following symbols have been renamed: | ||
2044 | * SDL_threadID => SDL_ThreadID | ||
2045 | |||
2046 | ## SDL_timer.h | ||
2047 | |||
2048 | SDL_GetTicks() now returns a 64-bit value. Instead of using the SDL_TICKS_PASSED macro, you can directly compare tick values, e.g. | ||
2049 | ```c | ||
2050 | Uint32 deadline = SDL_GetTicks() + 1000; | ||
2051 | ... | ||
2052 | if (SDL_TICKS_PASSED(SDL_GetTicks(), deadline)) { | ||
2053 | ... | ||
2054 | } | ||
2055 | ``` | ||
2056 | becomes: | ||
2057 | ```c | ||
2058 | Uint64 deadline = SDL_GetTicks() + 1000 | ||
2059 | ... | ||
2060 | if (SDL_GetTicks() >= deadline) { | ||
2061 | ... | ||
2062 | } | ||
2063 | ``` | ||
2064 | |||
2065 | If you were using this macro for other things besides SDL ticks values, you can define it in your own code as: | ||
2066 | ```c | ||
2067 | #define SDL_TICKS_PASSED(A, B) ((Sint32)((B) - (A)) <= 0) | ||
2068 | ``` | ||
2069 | |||
2070 | The callback passed to SDL_AddTimer() has changed parameters to: | ||
2071 | ```c | ||
2072 | Uint32 SDLCALL TimerCallback(void *userdata, SDL_TimerID timerID, Uint32 interval); | ||
2073 | ```` | ||
2074 | |||
2075 | ## SDL_touch.h | ||
2076 | |||
2077 | SDL_GetTouchName is replaced with SDL_GetTouchDeviceName(), which takes an SDL_TouchID instead of an index. | ||
2078 | |||
2079 | SDL_TouchID and SDL_FingerID are now Uint64 with 0 being an invalid value. | ||
2080 | |||
2081 | Rather than iterating over touch devices using an index, there is a new function SDL_GetTouchDevices() to get the available devices. | ||
2082 | |||
2083 | Rather than iterating over touch fingers using an index, there is a new function SDL_GetTouchFingers() to get the current set of active fingers. | ||
2084 | |||
2085 | The following functions have been removed: | ||
2086 | * SDL_GetNumTouchDevices() - replaced with SDL_GetTouchDevices() | ||
2087 | * SDL_GetNumTouchFingers() - replaced with SDL_GetTouchFingers() | ||
2088 | * SDL_GetTouchDevice() - replaced with SDL_GetTouchDevices() | ||
2089 | * SDL_GetTouchFinger() - replaced with SDL_GetTouchFingers() | ||
2090 | |||
2091 | |||
2092 | ## SDL_version.h | ||
2093 | |||
2094 | SDL_GetRevisionNumber() has been removed from the API, it always returned 0 in SDL 2.0. | ||
2095 | |||
2096 | SDL_GetVersion() returns the version number, which can be directly compared with another version wrapped with SDL_VERSIONNUM(). | ||
2097 | |||
2098 | The following structures have been removed: | ||
2099 | * SDL_version | ||
2100 | |||
2101 | The following symbols have been renamed: | ||
2102 | * SDL_COMPILEDVERSION => SDL_VERSION | ||
2103 | * SDL_PATCHLEVEL => SDL_MICRO_VERSION | ||
2104 | |||
2105 | ## SDL_video.h | ||
2106 | |||
2107 | Several video backends have had their names lower-cased ("kmsdrm", "rpi", "android", "psp", "ps2", "vita"). SDL already does a case-insensitive compare for SDL_HINT_VIDEO_DRIVER tests, but if your app is calling SDL_GetVideoDriver() or SDL_GetCurrentVideoDriver() and doing case-sensitive compares on those strings, please update your code. | ||
2108 | |||
2109 | SDL_VideoInit() and SDL_VideoQuit() have been removed. Instead you can call SDL_InitSubSystem() and SDL_QuitSubSystem() with SDL_INIT_VIDEO, which will properly refcount the subsystems. You can choose a specific video driver using SDL_HINT_VIDEO_DRIVER. | ||
2110 | |||
2111 | Rather than iterating over displays using display index, there is a new function SDL_GetDisplays() to get the current list of displays, and functions which used to take a display index now take SDL_DisplayID, with an invalid ID being 0. | ||
2112 | ```c | ||
2113 | { | ||
2114 | if (SDL_InitSubSystem(SDL_INIT_VIDEO)) { | ||
2115 | int i, num_displays = 0; | ||
2116 | SDL_DisplayID *displays = SDL_GetDisplays(&num_displays); | ||
2117 | if (displays) { | ||
2118 | for (i = 0; i < num_displays; ++i) { | ||
2119 | SDL_DisplayID instance_id = displays[i]; | ||
2120 | const char *name = SDL_GetDisplayName(instance_id); | ||
2121 | |||
2122 | SDL_Log("Display %" SDL_PRIu32 ": %s", instance_id, name ? name : "Unknown"); | ||
2123 | } | ||
2124 | SDL_free(displays); | ||
2125 | } | ||
2126 | SDL_QuitSubSystem(SDL_INIT_VIDEO); | ||
2127 | } | ||
2128 | } | ||
2129 | ``` | ||
2130 | |||
2131 | SDL_CreateWindow() has been simplified and no longer takes a window position. You can use SDL_CreateWindowWithProperties() if you need to set the window position when creating it, e.g. | ||
2132 | ```c | ||
2133 | SDL_PropertiesID props = SDL_CreateProperties(); | ||
2134 | SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, title); | ||
2135 | SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, x); | ||
2136 | SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, y); | ||
2137 | SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, width); | ||
2138 | SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, height); | ||
2139 | // For window flags you should use separate window creation properties, | ||
2140 | // but for easier migration from SDL2 you can use the following: | ||
2141 | SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_FLAGS_NUMBER, flags); | ||
2142 | pWindow = SDL_CreateWindowWithProperties(props); | ||
2143 | SDL_DestroyProperties(props); | ||
2144 | if (window) { | ||
2145 | ... | ||
2146 | } | ||
2147 | ``` | ||
2148 | |||
2149 | The SDL_WINDOWPOS_UNDEFINED_DISPLAY() and SDL_WINDOWPOS_CENTERED_DISPLAY() macros take a display ID instead of display index. The display ID 0 has a special meaning in this case, and is used to indicate the primary display. | ||
2150 | |||
2151 | The SDL_WINDOW_SHOWN flag has been removed. Windows are shown by default and can be created hidden by using the SDL_WINDOW_HIDDEN flag. | ||
2152 | |||
2153 | The SDL_WINDOW_SKIP_TASKBAR flag has been replaced by the SDL_WINDOW_UTILITY flag, which has the same functionality. | ||
2154 | |||
2155 | SDL_DisplayMode now includes the pixel density which can be greater than 1.0 for display modes that have a higher pixel size than the mode size. You should use SDL_GetWindowSizeInPixels() to get the actual pixel size of the window back buffer. | ||
2156 | |||
2157 | The refresh rate in SDL_DisplayMode is now a float, as well as being represented as a precise fraction with numerator and denominator. | ||
2158 | |||
2159 | Rather than iterating over display modes using an index, there is a new function SDL_GetFullscreenDisplayModes() to get the list of available fullscreen modes on a display. | ||
2160 | ```c | ||
2161 | { | ||
2162 | SDL_DisplayID display = SDL_GetPrimaryDisplay(); | ||
2163 | int num_modes = 0; | ||
2164 | SDL_DisplayMode **modes = SDL_GetFullscreenDisplayModes(display, &num_modes); | ||
2165 | if (modes) { | ||
2166 | for (i = 0; i < num_modes; ++i) { | ||
2167 | SDL_DisplayMode *mode = modes[i]; | ||
2168 | SDL_Log("Display %" SDL_PRIu32 " mode %d: %dx%d@%gx %gHz", | ||
2169 | display, i, mode->w, mode->h, mode->pixel_density, mode->refresh_rate); | ||
2170 | } | ||
2171 | SDL_free(modes); | ||
2172 | } | ||
2173 | } | ||
2174 | ``` | ||
2175 | |||
2176 | SDL_GetDesktopDisplayMode() and SDL_GetCurrentDisplayMode() return pointers to display modes rather than filling in application memory. | ||
2177 | |||
2178 | Windows now have an explicit fullscreen mode that is set, using SDL_SetWindowFullscreenMode(). The fullscreen mode for a window can be queried with SDL_GetWindowFullscreenMode(), which returns a pointer to the mode, or NULL if the window will be fullscreen desktop. SDL_SetWindowFullscreen() just takes a boolean value, setting the correct fullscreen state based on the selected mode. | ||
2179 | |||
2180 | SDL_WINDOW_FULLSCREEN_DESKTOP has been removed, and you can call SDL_GetWindowFullscreenMode() to see whether an exclusive fullscreen mode will be used or the borderless fullscreen desktop mode will be used when the window is fullscreen. | ||
2181 | |||
2182 | SDL_SetWindowBrightness(), SDL_GetWindowBrightness, SDL_SetWindowGammaRamp(), and SDL_GetWindowGammaRamp have been removed from the API, because they interact poorly with modern operating systems and aren't able to limit their effects to the SDL window. | ||
2183 | |||
2184 | Programs which have access to shaders can implement more robust versions of those functions using custom shader code rendered as a post-process effect. | ||
2185 | |||
2186 | Removed SDL_GL_CONTEXT_EGL from OpenGL configuration attributes. You can instead use `SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);` | ||
2187 | |||
2188 | SDL_GL_GetProcAddress() and SDL_EGL_GetProcAddress() now return `SDL_FunctionPointer` instead of `void *`, and should be cast to the appropriate function type. You can define SDL_FUNCTION_POINTER_IS_VOID_POINTER in your project to restore the previous behavior. | ||
2189 | |||
2190 | SDL_GL_DeleteContext() has been renamed to SDL_GL_DestroyContext to match SDL naming conventions (and glX/EGL!). | ||
2191 | |||
2192 | SDL_GL_GetSwapInterval() takes the interval as an output parameter and returns true if the function succeeds or false if there was an error. | ||
2193 | |||
2194 | SDL_GL_GetDrawableSize() has been removed. SDL_GetWindowSizeInPixels() can be used in its place. | ||
2195 | |||
2196 | The SDL_WINDOW_TOOLTIP and SDL_WINDOW_POPUP_MENU window flags are now supported on Windows, Mac (Cocoa), X11, and Wayland. Creating windows with these flags must happen via the `SDL_CreatePopupWindow()` function. This function requires passing in the handle to a valid parent window for the popup, and the popup window is positioned relative to the parent. | ||
2197 | |||
2198 | SDL_WindowFlags is used instead of Uint32 for API functions that refer to window flags, and has been extended to 64 bits. | ||
2199 | |||
2200 | SDL_GetWindowOpacity() directly returns the opacity instead of using an out parameter. | ||
2201 | |||
2202 | The following functions have been renamed: | ||
2203 | * SDL_GL_DeleteContext() => SDL_GL_DestroyContext(), returns bool | ||
2204 | * SDL_GetClosestDisplayMode() => SDL_GetClosestFullscreenDisplayMode(), returns bool | ||
2205 | * SDL_GetDisplayOrientation() => SDL_GetCurrentDisplayOrientation() | ||
2206 | * SDL_GetPointDisplayIndex() => SDL_GetDisplayForPoint() | ||
2207 | * SDL_GetRectDisplayIndex() => SDL_GetDisplayForRect() | ||
2208 | * SDL_GetWindowDisplayIndex() => SDL_GetDisplayForWindow() | ||
2209 | * SDL_GetWindowDisplayMode() => SDL_GetWindowFullscreenMode() | ||
2210 | * SDL_HasWindowSurface() => SDL_WindowHasSurface() | ||
2211 | * SDL_IsScreenSaverEnabled() => SDL_ScreenSaverEnabled() | ||
2212 | * SDL_SetWindowDisplayMode() => SDL_SetWindowFullscreenMode(), returns bool | ||
2213 | |||
2214 | The following functions have been removed: | ||
2215 | * SDL_GetDisplayDPI() - not reliable across platforms, approximately replaced by multiplying SDL_GetWindowDisplayScale() times 160 on iPhone and Android, and 96 on other platforms. | ||
2216 | * SDL_GetDisplayMode() | ||
2217 | * SDL_GetNumDisplayModes() - replaced with SDL_GetFullscreenDisplayModes() | ||
2218 | * SDL_GetNumVideoDisplays() - replaced with SDL_GetDisplays() | ||
2219 | * SDL_SetWindowGrab() - use SDL_SetWindowMouseGrab() instead, along with SDL_SetWindowKeyboardGrab() if you also set SDL_HINT_GRAB_KEYBOARD. | ||
2220 | * SDL_GetWindowGrab() - use SDL_GetWindowMouseGrab() instead, along with SDL_GetWindowKeyboardGrab() if you also set SDL_HINT_GRAB_KEYBOARD. | ||
2221 | * SDL_GetWindowData() - use SDL_GetPointerProperty() instead, along with SDL_GetWindowProperties() | ||
2222 | * SDL_SetWindowData() - use SDL_SetPointerProperty() instead, along with SDL_GetWindowProperties() | ||
2223 | * SDL_CreateWindowFrom() - use SDL_CreateWindowWithProperties() with the properties that allow you to wrap an existing window | ||
2224 | * SDL_SetWindowInputFocus() - use SDL_RaiseWindow() instead | ||
2225 | * SDL_SetWindowModalFor() - use SDL_SetWindowParent() with SDL_SetWindowModal() instead | ||
2226 | * SDL_SetWindowBrightness() - use a shader or other in-game effect. | ||
2227 | * SDL_GetWindowBrightness() - use a shader or other in-game effect. | ||
2228 | * SDL_SetWindowGammaRamp() - use a shader or other in-game effect. | ||
2229 | * SDL_GetWindowGammaRamp() - use a shader or other in-game effect. | ||
2230 | |||
2231 | The SDL_Window id type is named SDL_WindowID | ||
2232 | |||
2233 | The following environment variables have been removed: | ||
2234 | * SDL_VIDEO_GL_DRIVER - replaced with the hint SDL_HINT_OPENGL_LIBRARY | ||
2235 | * SDL_VIDEO_EGL_DRIVER - replaced with the hint SDL_HINT_EGL_LIBRARY | ||
2236 | |||
2237 | The following symbols have been renamed: | ||
2238 | * SDL_DISPLAYEVENT_DISCONNECTED => SDL_EVENT_DISPLAY_REMOVED | ||
2239 | * SDL_DISPLAYEVENT_MOVED => SDL_EVENT_DISPLAY_MOVED | ||
2240 | * SDL_DISPLAYEVENT_ORIENTATION => SDL_EVENT_DISPLAY_ORIENTATION | ||
2241 | * SDL_GLattr => SDL_GLAttr | ||
2242 | * SDL_GLcontextFlag => SDL_GLContextFlag | ||
2243 | * SDL_GLcontextReleaseFlag => SDL_GLContextReleaseFlag | ||
2244 | * SDL_GLprofile => SDL_GLProfile | ||
2245 | * SDL_WINDOWEVENT_CLOSE => SDL_EVENT_WINDOW_CLOSE_REQUESTED | ||
2246 | * SDL_WINDOWEVENT_DISPLAY_CHANGED => SDL_EVENT_WINDOW_DISPLAY_CHANGED | ||
2247 | * SDL_WINDOWEVENT_ENTER => SDL_EVENT_WINDOW_MOUSE_ENTER | ||
2248 | * SDL_WINDOWEVENT_EXPOSED => SDL_EVENT_WINDOW_EXPOSED | ||
2249 | * SDL_WINDOWEVENT_FOCUS_GAINED => SDL_EVENT_WINDOW_FOCUS_GAINED | ||
2250 | * SDL_WINDOWEVENT_FOCUS_LOST => SDL_EVENT_WINDOW_FOCUS_LOST | ||
2251 | * SDL_WINDOWEVENT_HIDDEN => SDL_EVENT_WINDOW_HIDDEN | ||
2252 | * SDL_WINDOWEVENT_HIT_TEST => SDL_EVENT_WINDOW_HIT_TEST | ||
2253 | * SDL_WINDOWEVENT_ICCPROF_CHANGED => SDL_EVENT_WINDOW_ICCPROF_CHANGED | ||
2254 | * SDL_WINDOWEVENT_LEAVE => SDL_EVENT_WINDOW_MOUSE_LEAVE | ||
2255 | * SDL_WINDOWEVENT_MAXIMIZED => SDL_EVENT_WINDOW_MAXIMIZED | ||
2256 | * SDL_WINDOWEVENT_MINIMIZED => SDL_EVENT_WINDOW_MINIMIZED | ||
2257 | * SDL_WINDOWEVENT_MOVED => SDL_EVENT_WINDOW_MOVED | ||
2258 | * SDL_WINDOWEVENT_RESIZED => SDL_EVENT_WINDOW_RESIZED | ||
2259 | * SDL_WINDOWEVENT_RESTORED => SDL_EVENT_WINDOW_RESTORED | ||
2260 | * SDL_WINDOWEVENT_SHOWN => SDL_EVENT_WINDOW_SHOWN | ||
2261 | * SDL_WINDOW_ALLOW_HIGHDPI => SDL_WINDOW_HIGH_PIXEL_DENSITY | ||
2262 | * SDL_WINDOW_INPUT_GRABBED => SDL_WINDOW_MOUSE_GRABBED | ||
2263 | |||
2264 | The following symbols have been removed: | ||
2265 | * SDL_WINDOWEVENT_SIZE_CHANGED - handle the SDL_EVENT_WINDOW_RESIZED and SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED events instead | ||
2266 | * SDL_WINDOWEVENT_TAKE_FOCUS | ||
2267 | |||
2268 | The following window operations are now considered to be asynchronous requests and should not be assumed to succeed unless | ||
2269 | a corresponding event has been received: | ||
2270 | * SDL_SetWindowSize() (SDL_EVENT_WINDOW_RESIZED) | ||
2271 | * SDL_SetWindowPosition() (SDL_EVENT_WINDOW_MOVED) | ||
2272 | * SDL_MinimizeWindow() (SDL_EVENT_WINDOW_MINIMIZED) | ||
2273 | * SDL_MaximizeWindow() (SDL_EVENT_WINDOW_MAXIMIZED) | ||
2274 | * SDL_RestoreWindow() (SDL_EVENT_WINDOW_RESTORED) | ||
2275 | * SDL_SetWindowFullscreen() (SDL_EVENT_WINDOW_ENTER_FULLSCREEN / SDL_EVENT_WINDOW_LEAVE_FULLSCREEN) | ||
2276 | |||
2277 | If it is required that operations be applied immediately after one of the preceding calls, the `SDL_SyncWindow()` function | ||
2278 | will attempt to wait until all pending window operations have completed. The `SDL_HINT_VIDEO_SYNC_WINDOW_OPERATIONS` hint | ||
2279 | can also be set to automatically synchronize after all calls to an asynchronous window operation, mimicking the behavior | ||
2280 | of SDL 2. Be aware that synchronizing can potentially block for long periods of time, as it may have to wait for window | ||
2281 | animations to complete. Also note that windowing systems can deny or not precisely obey these requests (e.g. windows may | ||
2282 | not be allowed to be larger than the usable desktop space or placed offscreen), so a corresponding event may never arrive | ||
2283 | or not contain the expected values. | ||
2284 | |||
2285 | ## SDL_vulkan.h | ||
2286 | |||
2287 | SDL_Vulkan_GetInstanceExtensions() no longer takes a window parameter, and no longer makes the app allocate query/allocate space for the result, instead returning a static const internal string. | ||
2288 | |||
2289 | SDL_Vulkan_GetVkGetInstanceProcAddr() now returns `SDL_FunctionPointer` instead of `void *`, and should be cast to PFN_vkGetInstanceProcAddr. | ||
2290 | |||
2291 | SDL_Vulkan_CreateSurface() now takes a VkAllocationCallbacks pointer as its third parameter. If you don't have an allocator to supply, pass a NULL here to use the system default allocator (SDL2 always used the system default allocator here). | ||
2292 | |||
2293 | SDL_Vulkan_GetDrawableSize() has been removed. SDL_GetWindowSizeInPixels() can be used in its place. | ||
2294 | |||
2295 | SDL_vulkanInstance and SDL_vulkanSurface have been removed. They were for compatibility with Tizen, who had built their own Vulkan interface into SDL2, but these apps will need changes for the SDL3 API if they are upgraded anyhow. | ||
diff --git a/src/contrib/SDL-3.2.20/docs/README-n3ds.md b/src/contrib/SDL-3.2.20/docs/README-n3ds.md new file mode 100644 index 0000000..8f95473 --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-n3ds.md | |||
@@ -0,0 +1,28 @@ | |||
1 | # Nintendo 3DS | ||
2 | |||
3 | SDL port for the Nintendo 3DS [Homebrew toolchain](https://devkitpro.org/) contributed by: | ||
4 | |||
5 | - [Pierre Wendling](https://github.com/FtZPetruska) | ||
6 | |||
7 | Credits to: | ||
8 | |||
9 | - The awesome people who ported SDL to other homebrew platforms. | ||
10 | - The Devkitpro team for making all the tools necessary to achieve this. | ||
11 | |||
12 | ## Building | ||
13 | |||
14 | To build for the Nintendo 3DS, make sure you have devkitARM and cmake installed and run: | ||
15 | |||
16 | ```bash | ||
17 | cmake -S. -Bbuild -DCMAKE_TOOLCHAIN_FILE="$DEVKITPRO/cmake/3DS.cmake" -DCMAKE_BUILD_TYPE=Release | ||
18 | cmake --build build | ||
19 | cmake --install build | ||
20 | ``` | ||
21 | |||
22 | ## Notes | ||
23 | |||
24 | - Currently only software rendering is supported. | ||
25 | - SDL3_main should be used to ensure ROMFS is enabled - this is done with `#include <SDL3/SDL_main.h>` in the source file that contains your main function. | ||
26 | - By default, the extra L2 cache and higher clock speeds of the New 2/3DS lineup are enabled. If you wish to turn it off, use `osSetSpeedupEnable(false)` in your main function. | ||
27 | - `SDL_GetBasePath` returns the romfs root instead of the executable's directory. | ||
28 | - The Nintendo 3DS uses a cooperative threading model on a single core, meaning a thread will never yield unless done manually through the `SDL_Delay` functions, or blocking waits (`SDL_LockMutex`, `SDL_WaitSemaphore`, `SDL_WaitCondition`, `SDL_WaitThread`). To avoid starving other threads, `SDL_TryWaitSemaphore` and `SDL_WaitSemaphoreTimeout` will yield if they fail to acquire the semaphore, see https://github.com/libsdl-org/SDL/pull/6776 for more information. | ||
diff --git a/src/contrib/SDL-3.2.20/docs/README-ngage.md b/src/contrib/SDL-3.2.20/docs/README-ngage.md new file mode 100644 index 0000000..84192b0 --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-ngage.md | |||
@@ -0,0 +1,5 @@ | |||
1 | Support for the Nokia N-Gage has been removed from SDL3 (but will make a | ||
2 | comeback when newer compilers are available for the platform). | ||
3 | |||
4 | SDL2 still supports this platform. | ||
5 | |||
diff --git a/src/contrib/SDL-3.2.20/docs/README-platforms.md b/src/contrib/SDL-3.2.20/docs/README-platforms.md new file mode 100644 index 0000000..46a054a --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-platforms.md | |||
@@ -0,0 +1,40 @@ | |||
1 | # Platforms | ||
2 | |||
3 | ## Supported Platforms | ||
4 | |||
5 | - [Android](README-android.md) | ||
6 | - [Emscripten](README-emscripten.md) | ||
7 | - [FreeBSD](README-bsd.md) | ||
8 | - [Haiku OS](README-haiku.md) | ||
9 | - [iOS](README-ios.md) | ||
10 | - [Linux](README-linux.md) | ||
11 | - [macOS](README-macos.md) | ||
12 | - [NetBSD](README-bsd.md) | ||
13 | - [Nintendo Switch](README-switch.md) | ||
14 | - [Nintendo 3DS](README-n3ds.md) | ||
15 | - [OpenBSD](README-bsd.md) | ||
16 | - [PlayStation 2](README-ps2.md) | ||
17 | - [PlayStation 4](README-ps4.md) | ||
18 | - [PlayStation 5](README-ps5.md) | ||
19 | - [PlayStation Portable](README-psp.md) | ||
20 | - [PlayStation Vita](README-vita.md) | ||
21 | - [RISC OS](README-riscos.md) | ||
22 | - [SteamOS](README-steamos.md) | ||
23 | - [tvOS](README-ios.md) | ||
24 | - [Windows](README-windows.md) | ||
25 | - [Windows GDK](README-gdk.md) | ||
26 | - [Xbox](README-gdk.md) | ||
27 | |||
28 | ## Unsupported Platforms | ||
29 | |||
30 | If your favorite system is listed below, we aren't working on it. However, if you send reasonable patches and are willing to support the port in the long term, we are happy to take a look! | ||
31 | |||
32 | All of these still work with [SDL2](/SDL2), which is an incompatible API, but an option if you need to support these platforms still. | ||
33 | |||
34 | - Google Stadia | ||
35 | - NaCL | ||
36 | - Nokia N-Gage | ||
37 | - OS/2 | ||
38 | - QNX | ||
39 | - WinPhone | ||
40 | - WinRT/UWP | ||
diff --git a/src/contrib/SDL-3.2.20/docs/README-porting.md b/src/contrib/SDL-3.2.20/docs/README-porting.md new file mode 100644 index 0000000..ada1d67 --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-porting.md | |||
@@ -0,0 +1,65 @@ | |||
1 | Porting | ||
2 | ======= | ||
3 | |||
4 | * Porting To A New Platform | ||
5 | |||
6 | The first thing you have to do when porting to a new platform, is look at | ||
7 | include/SDL_platform.h and create an entry there for your operating system. | ||
8 | The standard format is "SDL_PLATFORM_X", where X is the name of the OS. | ||
9 | Ideally SDL_platform_defines.h will be able to auto-detect the system it's building | ||
10 | on based on C preprocessor symbols. | ||
11 | |||
12 | There are two basic ways of building SDL at the moment: | ||
13 | |||
14 | 1. CMake: cmake -S . -B build && cmake --build build && cmake --install install | ||
15 | |||
16 | If you have a system that supports CMake, then you might try this. Edit CMakeLists.txt, | ||
17 | |||
18 | take a look at the large section labelled: | ||
19 | |||
20 | "Platform-specific options and settings!" | ||
21 | |||
22 | Add a section for your platform, and then re-run 'cmake -S . -B build' and build! | ||
23 | |||
24 | 2. Using an IDE: | ||
25 | |||
26 | If you're using an IDE or other non-configure build system, you'll probably want to create a custom `SDL_build_config.h` for your platform. Edit `include/build_config/SDL_build_config.h`, add a section for your platform, and create a custom `SDL_build_config_{platform}.h`, based on `SDL_build_config_minimal.h` and `SDL_build_config.h.cmake` | ||
27 | |||
28 | Add the top level include directory to the header search path, and then add | ||
29 | the following sources to the project: | ||
30 | |||
31 | src/*.c | ||
32 | src/atomic/*.c | ||
33 | src/audio/*.c | ||
34 | src/cpuinfo/*.c | ||
35 | src/events/*.c | ||
36 | src/file/*.c | ||
37 | src/haptic/*.c | ||
38 | src/joystick/*.c | ||
39 | src/power/*.c | ||
40 | src/render/*.c | ||
41 | src/render/software/*.c | ||
42 | src/stdlib/*.c | ||
43 | src/thread/*.c | ||
44 | src/timer/*.c | ||
45 | src/video/*.c | ||
46 | src/audio/disk/*.c | ||
47 | src/audio/dummy/*.c | ||
48 | src/filesystem/dummy/*.c | ||
49 | src/video/dummy/*.c | ||
50 | src/haptic/dummy/*.c | ||
51 | src/joystick/dummy/*.c | ||
52 | src/thread/generic/*.c | ||
53 | src/timer/dummy/*.c | ||
54 | src/loadso/dummy/*.c | ||
55 | |||
56 | |||
57 | Once you have a working library without any drivers, you can go back to each | ||
58 | of the major subsystems and start implementing drivers for your platform. | ||
59 | |||
60 | If you have any questions, don't hesitate to ask on the SDL mailing list: | ||
61 | http://www.libsdl.org/mailing-list.php | ||
62 | |||
63 | Enjoy! | ||
64 | Sam Lantinga (slouken@libsdl.org) | ||
65 | |||
diff --git a/src/contrib/SDL-3.2.20/docs/README-ps2.md b/src/contrib/SDL-3.2.20/docs/README-ps2.md new file mode 100644 index 0000000..d358565 --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-ps2.md | |||
@@ -0,0 +1,47 @@ | |||
1 | PS2 | ||
2 | ====== | ||
3 | SDL port for the Sony Playstation 2 contributed by: | ||
4 | - Francisco Javier Trujillo Mata | ||
5 | |||
6 | |||
7 | Credit to | ||
8 | - The guys that ported SDL to PSP & Vita because I'm taking them as reference. | ||
9 | - David G. F. for helping me with several issues and tests. | ||
10 | |||
11 | ## Building | ||
12 | To build SDL library for the PS2, make sure you have the latest PS2Dev status and run: | ||
13 | ```bash | ||
14 | cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=$PS2DEV/ps2sdk/ps2dev.cmake | ||
15 | cmake --build build | ||
16 | cmake --install build | ||
17 | ``` | ||
18 | |||
19 | ## Notes | ||
20 | If you trying to debug a SDL app through [ps2client](https://github.com/ps2dev/ps2client) you need to avoid the IOP reset, otherwise you will lose the connection with your computer. | ||
21 | So to avoid the reset of the IOP CPU, you need to call to the macro `SDL_PS2_SKIP_IOP_RESET();`. | ||
22 | It could be something similar as: | ||
23 | ```c | ||
24 | ..... | ||
25 | |||
26 | SDL_PS2_SKIP_IOP_RESET(); | ||
27 | |||
28 | int main(int argc, char *argv[]) | ||
29 | { | ||
30 | ..... | ||
31 | ``` | ||
32 | For a release binary is recommendable to reset the IOP always. | ||
33 | |||
34 | Remember to do a clean compilation every time you enable or disable the `SDL_PS2_SKIP_IOP_RESET` otherwise the change won't be reflected. | ||
35 | |||
36 | ## Getting PS2 Dev | ||
37 | [Installing PS2 Dev](https://github.com/ps2dev/ps2dev) | ||
38 | |||
39 | ## Running on PCSX2 Emulator | ||
40 | [PCSX2](https://github.com/PCSX2/pcsx2) | ||
41 | |||
42 | [More PCSX2 information](https://pcsx2.net/) | ||
43 | |||
44 | ## To Do | ||
45 | - PS2 Screen Keyboard | ||
46 | - Dialogs | ||
47 | - Others | ||
diff --git a/src/contrib/SDL-3.2.20/docs/README-ps4.md b/src/contrib/SDL-3.2.20/docs/README-ps4.md new file mode 100644 index 0000000..29b5a93 --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-ps4.md | |||
@@ -0,0 +1,3 @@ | |||
1 | # Sony PlayStation 4 | ||
2 | |||
3 | SDL3 runs on the PS4! There are commercial games shipping with this port. This port is kept in a separate repository, but is available for free, under the zlib license, to anyone that is under NDA for PlayStation development with Sony. Please contact Ryan (icculus at icculus dot org) for details. | ||
diff --git a/src/contrib/SDL-3.2.20/docs/README-ps5.md b/src/contrib/SDL-3.2.20/docs/README-ps5.md new file mode 100644 index 0000000..55470d4 --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-ps5.md | |||
@@ -0,0 +1,3 @@ | |||
1 | # Sony PlayStation 5 | ||
2 | |||
3 | SDL3 runs on the PS5! There are commercial games shipping with this port. This port is kept in a separate repository, but is available for free, under the zlib license, to anyone that is under NDA for PlayStation development with Sony. Please contact Ryan (icculus at icculus dot org) for details. | ||
diff --git a/src/contrib/SDL-3.2.20/docs/README-psp.md b/src/contrib/SDL-3.2.20/docs/README-psp.md new file mode 100644 index 0000000..65d2af2 --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-psp.md | |||
@@ -0,0 +1,36 @@ | |||
1 | PSP | ||
2 | ====== | ||
3 | SDL port for the Sony PSP contributed by: | ||
4 | - Captian Lex | ||
5 | - Francisco Javier Trujillo Mata | ||
6 | - Wouter Wijsman | ||
7 | |||
8 | |||
9 | Credit to | ||
10 | Marcus R.Brown,Jim Paris,Matthew H for the original SDL 1.2 for PSP | ||
11 | Geecko for his PSP GU lib "Glib2d" | ||
12 | |||
13 | ## Building | ||
14 | To build SDL library for the PSP, make sure you have the latest PSPDev status and run: | ||
15 | ```bash | ||
16 | cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=$PSPDEV/psp/share/pspdev.cmake | ||
17 | cmake --build build | ||
18 | cmake --install build | ||
19 | ``` | ||
20 | |||
21 | |||
22 | ## Getting PSP Dev | ||
23 | [Installing PSP Dev](https://github.com/pspdev/pspdev) | ||
24 | |||
25 | ## Running on PPSSPP Emulator | ||
26 | [PPSSPP](https://github.com/hrydgard/ppsspp) | ||
27 | |||
28 | [Build Instructions](https://github.com/hrydgard/ppsspp/wiki/Build-instructions) | ||
29 | |||
30 | |||
31 | ## Compiling a HelloWorld | ||
32 | [PSP Hello World](https://pspdev.github.io/basic_programs.html#hello-world) | ||
33 | |||
34 | ## To Do | ||
35 | - PSP Screen Keyboard | ||
36 | - Dialogs | ||
diff --git a/src/contrib/SDL-3.2.20/docs/README-riscos.md b/src/contrib/SDL-3.2.20/docs/README-riscos.md new file mode 100644 index 0000000..5af80a7 --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-riscos.md | |||
@@ -0,0 +1,35 @@ | |||
1 | RISC OS | ||
2 | ======= | ||
3 | |||
4 | Requirements: | ||
5 | |||
6 | * RISC OS 3.5 or later. | ||
7 | * [SharedUnixLibrary](http://www.riscos.info/packages/LibraryDetails.html#SharedUnixLibraryarm). | ||
8 | * [DigitalRenderer](http://www.riscos.info/packages/LibraryDetails.html#DRendererarm), for audio support. | ||
9 | * [Iconv](http://www.netsurf-browser.org/projects/iconv/), for `SDL_iconv` and related functions. | ||
10 | |||
11 | |||
12 | Compiling: | ||
13 | ---------- | ||
14 | |||
15 | Currently, SDL for RISC OS only supports compiling with GCCSDK under Linux. | ||
16 | |||
17 | The following commands can be used to build SDL for RISC OS using CMake: | ||
18 | |||
19 | cmake -Bbuild-riscos -DCMAKE_TOOLCHAIN_FILE=$GCCSDK_INSTALL_ENV/toolchain-riscos.cmake -DRISCOS=ON -DCMAKE_INSTALL_PREFIX=$GCCSDK_INSTALL_ENV -DCMAKE_BUILD_TYPE=Release | ||
20 | cmake --build build-riscos | ||
21 | cmake --install build-riscos | ||
22 | |||
23 | When using GCCSDK 4.7.4 release 6 or earlier versions, the builtin atomic functions are broken, meaning it's currently necessary to compile with `-DSDL_GCC_ATOMICS=OFF` using CMake. Newer versions of GCCSDK don't have this problem. | ||
24 | |||
25 | |||
26 | Current level of implementation | ||
27 | ------------------------------- | ||
28 | |||
29 | The video driver currently provides full screen video support with keyboard and mouse input. Windowed mode is not yet supported, but is planned in the future. Only software rendering is supported. | ||
30 | |||
31 | The filesystem APIs return either Unix-style paths or RISC OS-style paths based on the value of the `__riscosify_control` symbol, as is standard for UnixLib functions. | ||
32 | |||
33 | The audio, loadso, thread and timer APIs are currently provided by UnixLib. | ||
34 | |||
35 | The joystick, locale and power APIs are not yet implemented. | ||
diff --git a/src/contrib/SDL-3.2.20/docs/README-steamos.md b/src/contrib/SDL-3.2.20/docs/README-steamos.md new file mode 100644 index 0000000..0feab9a --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-steamos.md | |||
@@ -0,0 +1,10 @@ | |||
1 | # SteamOS | ||
2 | |||
3 | SteamOS is literally a Linux system, and uses the same binaries you distribute to generic Linux Steam users, so generally speaking, all the other [Linux advice](README-linux.md) applies. | ||
4 | |||
5 | If you are shipping a Linux game on Steam, or explicitly targeting SteamOS, the system is guaranteed to provide SDL. The Steam Client will set up the dynamic loader path so that a known-good copy of SDL is available to any program that needs it before launching a game. Steam provides all major versions of SDL to date, in this manner, for both x86 and amd64, in addition to several add-on libraries like `SDL_image` and `SDL_mixer`. When shipping a Linux game on Steam, do not ship a build of SDL with your game. Link against SDL as normal, and expect it to be available on the player's system. This allows Valve to make fixes and improvements to their SDL and those fixes to flow on to your game. | ||
6 | |||
7 | We are obsessive about SDL3 having a backwards-compatible ABI. Whether you build your game using the Steam Runtime SDK or just about any other copy of SDL, it _should_ work with the one that ships with Steam. | ||
8 | |||
9 | In fact, it's not a bad idea to just copy the SDL build out of the Steam Runtime if you plan to ship a Linux game for non-Steam platforms, too, since you know it's definitely well-built. | ||
10 | |||
diff --git a/src/contrib/SDL-3.2.20/docs/README-strings.md b/src/contrib/SDL-3.2.20/docs/README-strings.md new file mode 100644 index 0000000..ea86b8d --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-strings.md | |||
@@ -0,0 +1,7 @@ | |||
1 | # String policies in SDL3. | ||
2 | |||
3 | ## Encoding. | ||
4 | |||
5 | Unless otherwise specified, all strings in SDL, across all platforms, are | ||
6 | UTF-8 encoded and can represent the full range of [Unicode](https://unicode.org). | ||
7 | |||
diff --git a/src/contrib/SDL-3.2.20/docs/README-switch.md b/src/contrib/SDL-3.2.20/docs/README-switch.md new file mode 100644 index 0000000..16b7acd --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-switch.md | |||
@@ -0,0 +1,3 @@ | |||
1 | # Nintendo Switch | ||
2 | |||
3 | SDL3 runs on the Nintendo Switch! There are commercial games shipping with this port. This port is kept in a separate repository, but is available for free, under the zlib license, to anyone that is under NDA for Switch development with Nintendo. Please contact Ryan (icculus at icculus dot org) for details. | ||
diff --git a/src/contrib/SDL-3.2.20/docs/README-touch.md b/src/contrib/SDL-3.2.20/docs/README-touch.md new file mode 100644 index 0000000..05edc2c --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-touch.md | |||
@@ -0,0 +1,81 @@ | |||
1 | Touch | ||
2 | =========================================================================== | ||
3 | System Specific Notes | ||
4 | =========================================================================== | ||
5 | Linux: | ||
6 | The linux touch system is currently based off event streams, and proc/bus/devices. The active user must be given permissions to read /dev/input/TOUCHDEVICE, where TOUCHDEVICE is the event stream for your device. Currently only Wacom tablets are supported. If you have an unsupported tablet contact me at jim.tla+sdl_touch@gmail.com and I will help you get support for it. | ||
7 | |||
8 | Mac: | ||
9 | The Mac and iPhone APIs are pretty. If your touch device supports them then you'll be fine. If it doesn't, then there isn't much we can do. | ||
10 | |||
11 | iPhone: | ||
12 | Works out of box. | ||
13 | |||
14 | Windows: | ||
15 | Unfortunately there is no windows support as of yet. Support for Windows 7 is planned, but we currently have no way to test. If you have a Windows 7 WM_TOUCH supported device, and are willing to help test please contact me at jim.tla+sdl_touch@gmail.com | ||
16 | |||
17 | |||
18 | Events | ||
19 | =========================================================================== | ||
20 | SDL_EVENT_FINGER_DOWN: | ||
21 | Sent when a finger (or stylus) is placed on a touch device. | ||
22 | Fields: | ||
23 | * event.tfinger.touchId - the Id of the touch device. | ||
24 | * event.tfinger.fingerId - the Id of the finger which just went down. | ||
25 | * event.tfinger.x - the x coordinate of the touch (0..1) | ||
26 | * event.tfinger.y - the y coordinate of the touch (0..1) | ||
27 | * event.tfinger.pressure - the pressure of the touch (0..1) | ||
28 | |||
29 | SDL_EVENT_FINGER_MOTION: | ||
30 | Sent when a finger (or stylus) is moved on the touch device. | ||
31 | Fields: | ||
32 | Same as SDL_EVENT_FINGER_DOWN but with additional: | ||
33 | * event.tfinger.dx - change in x coordinate during this motion event. | ||
34 | * event.tfinger.dy - change in y coordinate during this motion event. | ||
35 | |||
36 | SDL_EVENT_FINGER_UP: | ||
37 | Sent when a finger (or stylus) is lifted from the touch device. | ||
38 | Fields: | ||
39 | Same as SDL_EVENT_FINGER_DOWN. | ||
40 | |||
41 | |||
42 | Functions | ||
43 | =========================================================================== | ||
44 | SDL provides the ability to access the underlying SDL_Finger structures. | ||
45 | These structures should _never_ be modified. | ||
46 | |||
47 | The following functions are included from SDL_touch.h | ||
48 | |||
49 | Devices are tracked by instance ID, of type SDL_TouchID. | ||
50 | |||
51 | To get a list of available device SDL_TouchID values, call SDL_GetTouchDevices(). | ||
52 | This returns an array of device IDs, terminated by a zero ID. Optionally, you can | ||
53 | get a count of IDs by passing a non-NULL int* to SDL_GetTouchDevices() if you'd | ||
54 | rather not iterate the whole array to get this number. | ||
55 | |||
56 | A SDL_TouchID may be used to get pointers to SDL_Finger. | ||
57 | |||
58 | SDL_GetNumTouchFingers(touchID) may be used to get the number of fingers currently down on the device. | ||
59 | |||
60 | The most common reason to access SDL_Finger is to query the fingers outside the event. In most cases accessing the fingers is using the event. This would be accomplished by code like the following: | ||
61 | |||
62 | float x = event.tfinger.x; | ||
63 | float y = event.tfinger.y; | ||
64 | |||
65 | |||
66 | |||
67 | To get a SDL_Finger, call SDL_GetTouchFinger(SDL_TouchID touchID, int index), where touchID is a SDL_TouchID, and index is the requested finger. | ||
68 | This returns a SDL_Finger *, or NULL if the finger does not exist, or has been removed. | ||
69 | A SDL_Finger is guaranteed to be persistent for the duration of a touch, but it will be de-allocated as soon as the finger is removed. This occurs when the SDL_EVENT_FINGER_UP event is _added_ to the event queue, and thus _before_ the SDL_EVENT_FINGER_UP event is polled. | ||
70 | As a result, be very careful to check for NULL return values. | ||
71 | |||
72 | A SDL_Finger has the following fields: | ||
73 | * x, y: | ||
74 | The current coordinates of the touch. | ||
75 | * pressure: | ||
76 | The pressure of the touch. | ||
77 | |||
78 | |||
79 | Please direct questions/comments to: | ||
80 | jim.tla+sdl_touch@gmail.com | ||
81 | (original author, API was changed since) | ||
diff --git a/src/contrib/SDL-3.2.20/docs/README-versions.md b/src/contrib/SDL-3.2.20/docs/README-versions.md new file mode 100644 index 0000000..6c2d920 --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-versions.md | |||
@@ -0,0 +1,48 @@ | |||
1 | # Versioning | ||
2 | |||
3 | ## Since 3.2.0 | ||
4 | |||
5 | SDL follows an "odd/even" versioning policy, similar to GLib, GTK, Flatpak | ||
6 | and older versions of the Linux kernel: | ||
7 | |||
8 | * If the minor version (second part) and the patch version (third part) is | ||
9 | divisible by 2 (for example 3.2.6, 3.4.0), this indicates a version of | ||
10 | SDL that is believed to be stable and suitable for production use. | ||
11 | |||
12 | * In stable releases, the patchlevel or micro version (third part) | ||
13 | indicates bugfix releases. Bugfix releases may add small changes | ||
14 | to the ABI, so newer patch versions are backwards-compatible but | ||
15 | not fully forwards-compatible. For example, programs built against | ||
16 | SDL 3.2.0 should work fine with SDL 3.2.8, but programs built against | ||
17 | SDL 3.2.8 may not work with 3.2.0. | ||
18 | |||
19 | * The minor version increases when significant changes are made that | ||
20 | require longer development or testing time, e.g. major new functionality, | ||
21 | or revamping support for a platform. Newer minor versions are | ||
22 | backwards-compatible, but not fully forwards-compatible. For example, | ||
23 | programs built against SDL 3.2.x should work fine with SDL 3.4.x, | ||
24 | but programs built against SDL 3.4.x may not work with 3.2.x. | ||
25 | |||
26 | * If the minor version (second part) or patch version (third part) is not | ||
27 | divisible by 2 (for example 3.2.9, 3.3.x), this indicates a development | ||
28 | prerelease of SDL that is not suitable for stable software distributions. | ||
29 | Use with caution. | ||
30 | |||
31 | * The patchlevel or micro version (third part) increases with each prerelease. | ||
32 | |||
33 | * Prereleases are backwards-compatible with older stable branches. | ||
34 | For example, programs built against SDL 3.2.x should work fine with | ||
35 | SDL 3.3.x, but programs built against SDL 3.3.x may not work with 3.2.x. | ||
36 | |||
37 | * Prereleases are not guaranteed to be backwards-compatible with each other. | ||
38 | For example, new API or ABI added in 3.3.0 might be removed or changed in | ||
39 | 3.3.1. If this would be a problem for you, please do not use prereleases. | ||
40 | |||
41 | * Only use a prerelease if you can guarantee that you will promptly upgrade | ||
42 | to the stable release that follows it. For example, do not use 3.3.x | ||
43 | unless you will be able to upgrade to 3.4.0 when it becomes available. | ||
44 | |||
45 | * Software distributions that have a freeze policy (in particular Linux | ||
46 | distributions with a release cycle, such as Debian and Fedora) | ||
47 | should only package stable releases, and not prereleases. | ||
48 | |||
diff --git a/src/contrib/SDL-3.2.20/docs/README-vita.md b/src/contrib/SDL-3.2.20/docs/README-vita.md new file mode 100644 index 0000000..8d7e70b --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-vita.md | |||
@@ -0,0 +1,33 @@ | |||
1 | PS Vita | ||
2 | ======= | ||
3 | SDL port for the Sony Playstation Vita and Sony Playstation TV | ||
4 | |||
5 | Credit to | ||
6 | * xerpi, cpasjuste and rsn8887 for initial (vita2d) port | ||
7 | * vitasdk/dolcesdk devs | ||
8 | * CBPS discord (Namely Graphene and SonicMastr) | ||
9 | |||
10 | Building | ||
11 | -------- | ||
12 | To build for the PSVita, make sure you have vitasdk and cmake installed and run: | ||
13 | ```sh | ||
14 | cmake -S. -Bbuild -DCMAKE_TOOLCHAIN_FILE=${VITASDK}/share/vita.toolchain.cmake -DCMAKE_BUILD_TYPE=Release | ||
15 | cmake --build build | ||
16 | cmake --install build | ||
17 | ``` | ||
18 | |||
19 | |||
20 | Notes | ||
21 | ----- | ||
22 | * gles1/gles2 support and renderers are disabled by default and can be enabled by configuring with `-DVIDEO_VITA_PVR=ON` | ||
23 | These renderers support 720p and 1080i resolutions. These can be specified with: | ||
24 | `SDL_SetHint(SDL_HINT_VITA_RESOLUTION, "720");` and `SDL_SetHint(SDL_HINT_VITA_RESOLUTION, "1080");` | ||
25 | * Desktop GL 1.X and 2.X support and renderers are also disabled by default and also can be enabled with `-DVIDEO_VITA_PVR=ON` as long as gl4es4vita is present in your SDK. | ||
26 | They support the same resolutions as the gles1/gles2 backends and require specifying `SDL_SetHint(SDL_HINT_VITA_PVR_OPENGL, "1");` | ||
27 | anytime before video subsystem initialization. | ||
28 | * gles2 support via PIB is disabled by default and can be enabled by configuring with `-DVIDEO_VITA_PIB=ON` | ||
29 | * By default SDL emits mouse events for touch events on every touchscreen. | ||
30 | Vita has two touchscreens, so it's recommended to use `SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");` and handle touch events instead. | ||
31 | Individual touchscreens can be disabled with: | ||
32 | `SDL_SetHint(SDL_HINT_VITA_ENABLE_FRONT_TOUCH, "0");` and `SDL_SetHint(SDL_HINT_VITA_ENABLE_BACK_TOUCH, "0");` | ||
33 | * Support for L2/R2/R3/R3 buttons, haptic feedback and gamepad led only available on PSTV, or when using external ds4 gamepad on vita. | ||
diff --git a/src/contrib/SDL-3.2.20/docs/README-wayland.md b/src/contrib/SDL-3.2.20/docs/README-wayland.md new file mode 100644 index 0000000..75a9b90 --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-wayland.md | |||
@@ -0,0 +1,242 @@ | |||
1 | Wayland | ||
2 | ======= | ||
3 | Wayland is a replacement for the X11 window system protocol and architecture and is favored over X11 by default in SDL3 | ||
4 | for communicating with desktop compositors. It works well for the majority of applications, however, applications may | ||
5 | encounter limitations or behavior that is different from other windowing systems. | ||
6 | |||
7 | ## Common issues: | ||
8 | |||
9 | ### Legacy, DPI-unaware applications are blurry | ||
10 | |||
11 | - Wayland handles high-DPI displays by scaling the desktop, which causes applications that are not designed to be | ||
12 | DPI-aware to be automatically scaled by the window manager, which results in them being blurry. SDL can _attempt_ to | ||
13 | scale these applications such that they will be output with a 1:1 pixel aspect, however this may be buggy, especially | ||
14 | with odd-sized windows and/or scale factors that aren't quarter-increments (125%, 150%, etc...). To enable this, set | ||
15 | the environment variable `SDL_VIDEO_WAYLAND_SCALE_TO_DISPLAY=1` | ||
16 | |||
17 | ### Window decorations are missing, or the decorations look strange | ||
18 | |||
19 | - On some desktops (i.e. GNOME), Wayland applications use a library | ||
20 | called [libdecor](https://gitlab.freedesktop.org/libdecor/libdecor) to provide window decorations. If this library is | ||
21 | not installed, the decorations will be missing. This library uses plugins to generate different decoration styles, and | ||
22 | if a plugin to generate native-looking decorations is not installed (i.e. the GTK plugin), the decorations will not | ||
23 | appear to be 'native'. | ||
24 | |||
25 | ### Windows do not appear immediately after creation | ||
26 | |||
27 | - Wayland requires that the application initially present a buffer before the window becomes visible. Additionally, | ||
28 | applications _must_ have an event loop and processes messages on a regular basis, or the application can appear | ||
29 | unresponsive to both the user and desktop compositor. | ||
30 | |||
31 | ### The display reported as the primary by ```SDL_GetPrimaryDisplay()``` is incorrect | ||
32 | |||
33 | - Wayland doesn't natively have the concept of a primary display, so SDL attempts to determine it by querying various | ||
34 | system settings, and falling back to a selection algorithm if this fails. If it is incorrect, it can be manually | ||
35 | overridden by setting the ```SDL_VIDEO_DISPLAY_PRIORITY``` hint. | ||
36 | |||
37 | ### ```SDL_SetWindowPosition()``` doesn't work on non-popup windows | ||
38 | |||
39 | - Wayland does not allow toplevel windows to position themselves programmatically. | ||
40 | |||
41 | ### Retrieving the global mouse cursor position when the cursor is outside a window doesn't work | ||
42 | |||
43 | - Wayland only provides applications with the cursor position within the borders of the application windows. Querying | ||
44 | the global position when an application window does not have mouse focus returns 0,0 as the actual cursor position is | ||
45 | unknown. In most cases, applications don't actually need the global cursor position and should use the window-relative | ||
46 | coordinates as provided by the mouse movement event or from ```SDL_GetMouseState()``` instead. | ||
47 | |||
48 | ### Warping the mouse cursor to or from a point outside the window doesn't work | ||
49 | |||
50 | - The cursor can be warped only within the window with mouse focus, provided that the `zwp_pointer_confinement_v1` | ||
51 | protocol is supported by the compositor. | ||
52 | |||
53 | ### The application icon can't be set via ```SDL_SetWindowIcon()``` | ||
54 | |||
55 | - Wayland requires compositor support for the `xdg-toplevel-icon-v1` protocol to set window icons programmatically. | ||
56 | Otherwise, the launcher icon from the associated desktop entry file, aka a `.desktop` file, will typically be used. | ||
57 | Please see the [Desktop Entry Specification](https://specifications.freedesktop.org/desktop-entry-spec/latest/) for | ||
58 | more information on the format of this file. Note that if your application manually sets the application ID via the | ||
59 | `SDL_APP_ID` hint string, the desktop entry file name should match the application ID. For example, if your | ||
60 | application ID is set to `org.my_org.sdl_app`, the desktop entry file should be named `org.my_org.sdl_app.desktop`. | ||
61 | |||
62 | ### Keyboard grabs don't work when running under XWayland | ||
63 | |||
64 | - On GNOME based desktops, the dconf setting `org/gnome/mutter/wayland/xwayland-allow-grabs` must be enabled. | ||
65 | |||
66 | ## Using custom Wayland windowing protocols with SDL windows | ||
67 | |||
68 | Under normal operation, an `SDL_Window` corresponds to an XDG toplevel window, which provides a standard desktop window. | ||
69 | If an application wishes to use a different windowing protocol with an SDL window (e.g. wlr_layer_shell) while still | ||
70 | having SDL handle input and rendering, it needs to create a custom, roleless surface and attach that surface to its own | ||
71 | toplevel window. | ||
72 | |||
73 | This is done by using `SDL_CreateWindowWithProperties()` and setting the | ||
74 | `SDL_PROP_WINDOW_CREATE_WAYLAND_SURFACE_ROLE_CUSTOM_BOOLEAN` property to `true`. Once the window has been | ||
75 | successfully created, the `wl_display` and `wl_surface` objects can then be retrieved from the | ||
76 | `SDL_PROP_WINDOW_WAYLAND_DISPLAY_POINTER` and `SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER` properties respectively. | ||
77 | |||
78 | Surfaces don't receive any size change notifications, so if an application changes the window size, it must inform SDL | ||
79 | that the surface size has changed by calling SDL_SetWindowSize() with the new dimensions. | ||
80 | |||
81 | Custom surfaces will automatically handle scaling internally if the window was created with the | ||
82 | `SDL_PROP_WINDOW_CREATE_HIGH_PIXEL_DENSITY_BOOLEAN` property set to `true`. In this case, applications should | ||
83 | not manually attach viewports or change the surface scale value, as SDL will handle this internally. Calls | ||
84 | to `SDL_SetWindowSize()` should use the logical size of the window, and `SDL_GetWindowSizeInPixels()` should be used to | ||
85 | query the size of the backbuffer surface in pixels. If this property is not set or is `false`, applications can | ||
86 | attach their own viewports or change the surface scale manually, and the SDL backend will not interfere or change any | ||
87 | values internally. In this case, calls to `SDL_SetWindowSize()` should pass the requested surface size in pixels, not | ||
88 | the logical window size, as no scaling calculations will be done internally. | ||
89 | |||
90 | All window functions that control window state aside from `SDL_SetWindowSize()` are no-ops with custom surfaces. | ||
91 | |||
92 | Please see the minimal example in `tests/testwaylandcustom.c` for an example of how to use a custom, roleless surface | ||
93 | and attach it to an application-managed toplevel window. | ||
94 | |||
95 | ## Importing external surfaces into SDL windows | ||
96 | |||
97 | Wayland windows and surfaces are more intrinsically tied to the client library than other windowing systems, therefore, | ||
98 | when importing surfaces, it is necessary for both SDL and the application or toolkit to use the same `wl_display` | ||
99 | object. This can be set/queried via the global `SDL_PROP_GLOBAL_VIDEO_WAYLAND_WL_DISPLAY_POINTER` property. To | ||
100 | import an external `wl_display`, set this property before initializing the SDL video subsystem, and read the value to | ||
101 | export the internal `wl_display` after the video subsystem has been initialized. Setting this property after the video | ||
102 | subsystem has been initialized has no effect, and reading it when the video subsystem is uninitialized will either | ||
103 | return the user provided value, if one was set while in the uninitialized state, or NULL. | ||
104 | |||
105 | Once this is done, and the application has created or obtained the `wl_surface` to be wrapped in an `SDL_Window`, the | ||
106 | window is created with `SDL_CreateWindowWithProperties()` with the | ||
107 | `SDL_PROP_WINDOW_CREATE_WAYLAND_WL_SURFACE_POINTER` property to set to the `wl_surface` object that is to be | ||
108 | imported by SDL. | ||
109 | |||
110 | SDL receives no notification regarding size changes on external surfaces or toplevel windows, so if the external surface | ||
111 | needs to be resized, SDL must be informed by calling SDL_SetWindowSize() with the new dimensions. | ||
112 | |||
113 | If desired, SDL can automatically handle the scaling for the surface by setting the | ||
114 | `SDL_PROP_WINDOW_CREATE_HIGH_PIXEL_DENSITY_BOOLEAN` property to `true`, however, if the surface being imported | ||
115 | already has, or will have, a viewport/fractional scale manager attached to it by the application or an external toolkit, | ||
116 | a protocol violation will result. Avoid setting this property if importing surfaces from toolkits such as Qt or GTK. | ||
117 | |||
118 | If the window is flagged as high pixel density, calls to `SDL_SetWindowSize()` should pass the logical size of the | ||
119 | window and `SDL_GetWindowSizeInPixels()` should be used to retrieve the backbuffer size in pixels. Otherwise, calls to | ||
120 | `SDL_SetWindowSize()` should pass the requested surface size in pixels, not the logical window size, as no scaling | ||
121 | calculations will be done internally. | ||
122 | |||
123 | All window functions that control window state aside from `SDL_SetWindowSize()` are no-ops with external surfaces. | ||
124 | |||
125 | An example of how to use external surfaces with a `wl_display` owned by SDL can be seen in `tests/testnativewayland.c`, | ||
126 | and the following is a minimal example of interoperation with Qt 6, with Qt owning the `wl_display`: | ||
127 | |||
128 | ```c++ | ||
129 | #include <QApplication> | ||
130 | #include <QWindow> | ||
131 | #include <qpa/qplatformnativeinterface.h> | ||
132 | |||
133 | #include <SDL3/SDL.h> | ||
134 | |||
135 | int main(int argc, char *argv[]) | ||
136 | { | ||
137 | int ret = -1; | ||
138 | int done = 0; | ||
139 | SDL_PropertiesID props; | ||
140 | SDL_Event e; | ||
141 | SDL_Window *sdlWindow = NULL; | ||
142 | SDL_Renderer *sdlRenderer = NULL; | ||
143 | struct wl_display *display = NULL; | ||
144 | struct wl_surface *surface = NULL; | ||
145 | |||
146 | /* Initialize Qt */ | ||
147 | QApplication qtApp(argc, argv); | ||
148 | QWindow qtWindow; | ||
149 | |||
150 | /* The windowing system must be Wayland. */ | ||
151 | if (QApplication::platformName() != "wayland") { | ||
152 | goto exit; | ||
153 | } | ||
154 | |||
155 | { | ||
156 | /* Get the wl_display object from Qt */ | ||
157 | QNativeInterface::QWaylandApplication *qtWlApp = qtApp.nativeInterface<QNativeInterface::QWaylandApplication>(); | ||
158 | display = qtWlApp->display(); | ||
159 | |||
160 | if (!display) { | ||
161 | goto exit; | ||
162 | } | ||
163 | } | ||
164 | |||
165 | /* Set SDL to use the existing wl_display object from Qt and initialize. */ | ||
166 | SDL_SetPointerProperty(SDL_GetGlobalProperties(), SDL_PROP_GLOBAL_VIDEO_WAYLAND_WL_DISPLAY_POINTER, display); | ||
167 | SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS); | ||
168 | |||
169 | /* Create a basic, frameless QWindow */ | ||
170 | qtWindow.setFlags(Qt::FramelessWindowHint); | ||
171 | qtWindow.setGeometry(0, 0, 640, 480); | ||
172 | qtWindow.show(); | ||
173 | |||
174 | { | ||
175 | /* Get the native wl_surface backing resource for the window */ | ||
176 | QPlatformNativeInterface *qtNative = qtApp.platformNativeInterface(); | ||
177 | surface = (struct wl_surface *)qtNative->nativeResourceForWindow("surface", &qtWindow); | ||
178 | |||
179 | if (!surface) { | ||
180 | goto exit; | ||
181 | } | ||
182 | } | ||
183 | |||
184 | /* Create a window that wraps the wl_surface from the QWindow. | ||
185 | * Qt objects should not be flagged as DPI-aware or protocol violations will result. | ||
186 | */ | ||
187 | props = SDL_CreateProperties(); | ||
188 | SDL_SetPointerProperty(props, SDL_PROP_WINDOW_CREATE_WAYLAND_WL_SURFACE_POINTER, surface); | ||
189 | SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_OPENGL_BOOLEAN, true); | ||
190 | SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, 640); | ||
191 | SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, 480); | ||
192 | sdlWindow = SDL_CreateWindowWithProperties(props); | ||
193 | SDL_DestroyProperties(props); | ||
194 | if (!sdlWindow) { | ||
195 | goto exit; | ||
196 | } | ||
197 | |||
198 | /* Create a renderer */ | ||
199 | sdlRenderer = SDL_CreateRenderer(sdlWindow, NULL); | ||
200 | if (!sdlRenderer) { | ||
201 | goto exit; | ||
202 | } | ||
203 | |||
204 | /* Draw a blue screen for the window until ESC is pressed or the window is no longer visible. */ | ||
205 | while (!done) { | ||
206 | while (SDL_PollEvent(&e)) { | ||
207 | if (e.type == SDL_EVENT_KEY_DOWN && e.key.key == SDLK_ESCAPE) { | ||
208 | done = 1; | ||
209 | } | ||
210 | } | ||
211 | |||
212 | qtApp.processEvents(); | ||
213 | |||
214 | /* Update the backbuffer size if the window scale changed. */ | ||
215 | qreal scale = qtWindow.devicePixelRatio(); | ||
216 | SDL_SetWindowSize(sdlWindow, SDL_lround(640. * scale), SDL_lround(480. * scale)); | ||
217 | |||
218 | if (qtWindow.isVisible()) { | ||
219 | SDL_SetRenderDrawColor(sdlRenderer, 0, 0, 255, SDL_ALPHA_OPAQUE); | ||
220 | SDL_RenderClear(sdlRenderer); | ||
221 | SDL_RenderPresent(sdlRenderer); | ||
222 | } else { | ||
223 | done = 1; | ||
224 | } | ||
225 | } | ||
226 | |||
227 | ret = 0; | ||
228 | |||
229 | exit: | ||
230 | /* Cleanup */ | ||
231 | if (sdlRenderer) { | ||
232 | SDL_DestroyRenderer(sdlRenderer); | ||
233 | } | ||
234 | if (sdlWindow) { | ||
235 | SDL_DestroyWindow(sdlWindow); | ||
236 | } | ||
237 | |||
238 | SDL_Quit(); | ||
239 | return ret; | ||
240 | } | ||
241 | ``` | ||
242 | |||
diff --git a/src/contrib/SDL-3.2.20/docs/README-windows.md b/src/contrib/SDL-3.2.20/docs/README-windows.md new file mode 100644 index 0000000..1e6d464 --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README-windows.md | |||
@@ -0,0 +1,128 @@ | |||
1 | # Windows | ||
2 | |||
3 | ## Old systems | ||
4 | |||
5 | WinRT, Windows Phone, and UWP are no longer supported. | ||
6 | |||
7 | All desktop Windows versions, back to Windows XP, are still supported. | ||
8 | |||
9 | ## LLVM and Intel C++ compiler support | ||
10 | |||
11 | SDL will build with the Visual Studio project files with LLVM-based compilers, such as the Intel oneAPI C++ | ||
12 | compiler, but you'll have to manually add the "-msse3" command line option | ||
13 | to at least the SDL_audiocvt.c source file, and possibly others. This may | ||
14 | not be necessary if you build SDL with CMake instead of the included Visual | ||
15 | Studio solution. | ||
16 | |||
17 | Details are here: https://github.com/libsdl-org/SDL/issues/5186 | ||
18 | |||
19 | ## MinGW-w64 compiler support | ||
20 | |||
21 | SDL can be built with MinGW-w64 and CMake. Minimum tested MinGW-w64 version is 8.0.3. | ||
22 | |||
23 | On a Windows host, you first need to install and set up the MSYS2 environment, which provides the MinGW-w64 toolchain. Install MSYS2, typically to `C:\msys64`, and follow the instructions on the MSYS2 wiki to use the MinGW-w64 shell to update all components in the MSYS2 environment. This generally amounts to running `pacman -Syuu` from the mingw64 shell, but refer to MSYS2's documentation for more details. Once the MSYS2 environment has been updated, install the x86_64 MinGW toolchain from the mingw64 shell with the command `pacman -S mingw-w64-x86_64-toolchain`. (You can additionally install `mingw-w64-i686-toolchain` if you intend to build 32-bit binaries as well. The remainder of this section assumes you only want to build 64-bit binaries.) | ||
24 | |||
25 | To build and install SDL, you can use PowerShell or any CMake-compatible IDE. First, install CMake, Ninja, and Git. These tools can be installed using any number of tools, such as the MSYS2's `pacman`, `winget`, `Chocolatey`, or by manually downloading and running the installers. Clone SDL to an appropriate location with `git` and run the following commands from the root of the cloned repository: | ||
26 | |||
27 | ```sh | ||
28 | mkdir build | ||
29 | cmake -S . -B build -G Ninja -DCMAKE_TOOLCHAIN_FILE=build-scripts/cmake-toolchain-mingw64-x86_64.cmake | ||
30 | cmake --build build --parallel | ||
31 | cmake --install build --prefix C:/Libraries | ||
32 | ``` | ||
33 | |||
34 | This installs SDL to `C:\Libraries`. You can specify another directory of your choice as desired. Ensure that your `CMAKE_PREFIX_PATH` includes `C:\Libraries` when you want to build against this copy of SDL. The simplest way to do this is to pass it to CMake as an option at configuration time: | ||
35 | |||
36 | ```sh | ||
37 | cmake .. -G Ninja -DCMAKE_PREFIX_PATH=C:/Libraries | ||
38 | ``` | ||
39 | |||
40 | You will also need to configure CMake to use the MinGW-w64 toolchain to build your own project. Here is a minimal toolchain file that you could use for this purpose: | ||
41 | |||
42 | ``` | ||
43 | set(CMAKE_SYSTEM_NAME Windows) | ||
44 | set(CMAKE_SYSTEM_PROCESSOR x86_64) | ||
45 | |||
46 | find_program(CMAKE_C_COMPILER NAMES x86_64-w64-mingw32-gcc REQUIRED) | ||
47 | find_program(CMAKE_CXX_COMPILER NAMES x86_64-w64-mingw32-g++ REQUIRED) | ||
48 | find_program(CMAKE_RC_COMPILER NAMES x86_64-w64-mingw32-windres windres REQUIRED) | ||
49 | ``` | ||
50 | |||
51 | Save this in your project and refer to it at configuration time with the option `-DCMAKE_TOOLCHAIN_FILE`. | ||
52 | |||
53 | On Windows, you also need to copy `SDL3.dll` to an appropriate directory so that the game can find it at runtime. For guidance, see [README-cmake.md](README-cmake.md#how-do-i-copy-a-sdl3-dynamic-library-to-another-location). | ||
54 | |||
55 | Below is a minimal `CMakeLists.txt` file to build your game linked against a system SDL that was built with the MinGW-w64 toolchain. See [README-cmake.md](README-cmake.md) for more details on including SDL in your CMake project. | ||
56 | |||
57 | ```cmake | ||
58 | cmake_minimum_required(VERSION 3.15) | ||
59 | project(mygame) | ||
60 | |||
61 | find_package(SDL3 REQUIRED CONFIG COMPONENTS SDL3-shared) | ||
62 | |||
63 | add_executable(mygame WIN32 mygame.c) | ||
64 | target_link_libraries(mygame PRIVATE SDL3::SDL3) | ||
65 | |||
66 | # On Windows, copy SDL3.dll to the build directory | ||
67 | if(WIN32) | ||
68 | add_custom_command( | ||
69 | TARGET mygame POST_BUILD | ||
70 | COMMAND "${CMAKE_COMMAND}" -E copy $<TARGET_FILE:SDL3::SDL3-shared> $<TARGET_FILE_DIR:mygame> | ||
71 | VERBATIM | ||
72 | ) | ||
73 | endif() | ||
74 | ``` | ||
75 | |||
76 | ## OpenGL ES 2.x support | ||
77 | |||
78 | SDL has support for OpenGL ES 2.x under Windows via two alternative | ||
79 | implementations. | ||
80 | |||
81 | The most straightforward method consists in running your app in a system with | ||
82 | a graphic card paired with a relatively recent (as of November of 2013) driver | ||
83 | which supports the WGL_EXT_create_context_es2_profile extension. Vendors known | ||
84 | to ship said extension on Windows currently include nVidia and Intel. | ||
85 | |||
86 | The other method involves using the | ||
87 | [ANGLE library](https://code.google.com/p/angleproject/). If an OpenGL ES 2.x | ||
88 | context is requested and no WGL_EXT_create_context_es2_profile extension is | ||
89 | found, SDL will try to load the libEGL.dll library provided by ANGLE. | ||
90 | |||
91 | To obtain the ANGLE binaries, you can either compile from source from | ||
92 | https://chromium.googlesource.com/angle/angle or copy the relevant binaries | ||
93 | from a recent Chrome/Chromium install for Windows. The files you need are: | ||
94 | |||
95 | - libEGL.dll | ||
96 | - libGLESv2.dll | ||
97 | - d3dcompiler_46.dll (supports Windows Vista or later, better shader | ||
98 | compiler) *or* d3dcompiler_43.dll (supports Windows XP or later) | ||
99 | |||
100 | If you compile ANGLE from source, you can configure it so it does not need the | ||
101 | d3dcompiler_* DLL at all (for details on this, see their documentation). | ||
102 | However, by default SDL will try to preload the d3dcompiler_46.dll to | ||
103 | comply with ANGLE's requirements. If you wish SDL to preload | ||
104 | d3dcompiler_43.dll (to support Windows XP) or to skip this step at all, you | ||
105 | can use the SDL_HINT_VIDEO_WIN_D3DCOMPILER hint (see SDL_hints.h for more | ||
106 | details). | ||
107 | |||
108 | Known Bugs: | ||
109 | |||
110 | - SDL_GL_SetSwapInterval is currently a no op when using ANGLE. It appears | ||
111 | that there's a bug in the library which prevents the window contents from | ||
112 | refreshing if this is set to anything other than the default value. | ||
113 | |||
114 | ## Vulkan Surface Support | ||
115 | |||
116 | Support for creating Vulkan surfaces is configured on by default. To disable | ||
117 | it change the value of `SDL_VIDEO_VULKAN` to 0 in `SDL_config_windows.h`. You | ||
118 | must install the [Vulkan SDK](https://www.lunarg.com/vulkan-sdk/) in order to | ||
119 | use Vulkan graphics in your application. | ||
120 | |||
121 | ## Transparent Window Support | ||
122 | |||
123 | SDL uses the Desktop Window Manager (DWM) to create transparent windows. DWM is | ||
124 | always enabled from Windows 8 and above. Windows 7 only enables DWM with Aero Glass | ||
125 | theme. | ||
126 | |||
127 | However, it cannot be guaranteed to work on all hardware configurations (an example | ||
128 | is hybrid GPU systems, such as NVIDIA Optimus laptops). | ||
diff --git a/src/contrib/SDL-3.2.20/docs/README.md b/src/contrib/SDL-3.2.20/docs/README.md new file mode 100644 index 0000000..d0f5a54 --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/README.md | |||
@@ -0,0 +1,45 @@ | |||
1 | # Simple DirectMedia Layer | ||
2 | |||
3 | https://www.libsdl.org/ | ||
4 | |||
5 | Simple DirectMedia Layer is a cross-platform development library designed | ||
6 | to provide low level access to audio, keyboard, mouse, joystick, and graphics | ||
7 | hardware. It is used by video playback software, emulators, and popular games | ||
8 | including Valve's award winning catalog and many Humble Bundle games. | ||
9 | |||
10 | SDL officially supports Windows, macOS, Linux, iOS, Android, Xbox, PlayStation 4/5, Nintendo Switch, and many other platforms. | ||
11 | |||
12 | SDL is written in C, works natively with C++, and there are bindings | ||
13 | available for several other languages, including C# and Python. | ||
14 | |||
15 | This library is distributed under the zlib license, which can be found | ||
16 | in the file "LICENSE.txt". | ||
17 | |||
18 | Information on building SDL with CMake is available in [README-cmake.md](README-cmake.md) | ||
19 | |||
20 | The best way to learn how to use SDL is to check out the header files in | ||
21 | the "include" subdirectory and the programs in the "examples" subdirectory. | ||
22 | The header files and test programs are well commented and always up to date. | ||
23 | |||
24 | Information on reporting bugs and contributing is available in [README-contributing.md](README-contributing.md) | ||
25 | |||
26 | More documentation and FAQs are available online at the [wiki](http://wiki.libsdl.org/) | ||
27 | |||
28 | - [Migrating from SDL 2.0](README-migration.md) | ||
29 | - [main()](README-main-functions.md) | ||
30 | - [High DPI Support](README-highdpi.md) | ||
31 | - [Touch](README-touch.md) | ||
32 | - [Supported platforms](README-platforms.md) | ||
33 | - [Porting information](README-porting.md) | ||
34 | |||
35 | If you need help with the library, or just want to discuss SDL related | ||
36 | issues, you can join the [SDL Discourse](https://discourse.libsdl.org/), | ||
37 | which can be used as a web forum or a mailing list, at your preference. | ||
38 | |||
39 | If you want to report bugs or contribute patches, please submit them to | ||
40 | [our bug tracker](https://github.com/libsdl-org/SDL/issues) | ||
41 | |||
42 | Enjoy! | ||
43 | |||
44 | |||
45 | Sam Lantinga <mailto:slouken@libsdl.org> | ||
diff --git a/src/contrib/SDL-3.2.20/docs/doxyfile b/src/contrib/SDL-3.2.20/docs/doxyfile new file mode 100644 index 0000000..c8891d8 --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/doxyfile | |||
@@ -0,0 +1,1564 @@ | |||
1 | # Doxyfile 1.5.9 | ||
2 | |||
3 | # This file describes the settings to be used by the documentation system | ||
4 | # doxygen (www.doxygen.org) for a project | ||
5 | # | ||
6 | # All text after a hash (#) is considered a comment and will be ignored | ||
7 | # The format is: | ||
8 | # TAG = value [value, ...] | ||
9 | # For lists items can also be appended using: | ||
10 | # TAG += value [value, ...] | ||
11 | # Values that contain spaces should be placed between quotes (" ") | ||
12 | |||
13 | #--------------------------------------------------------------------------- | ||
14 | # Project related configuration options | ||
15 | #--------------------------------------------------------------------------- | ||
16 | |||
17 | # This tag specifies the encoding used for all characters in the config file | ||
18 | # that follow. The default is UTF-8 which is also the encoding used for all | ||
19 | # text before the first occurrence of this tag. Doxygen uses libiconv (or the | ||
20 | # iconv built into libc) for the transcoding. See | ||
21 | # http://www.gnu.org/software/libiconv for the list of possible encodings. | ||
22 | |||
23 | DOXYFILE_ENCODING = UTF-8 | ||
24 | |||
25 | # The PROJECT_NAME tag is a single word (or a sequence of words surrounded | ||
26 | # by quotes) that should identify the project. | ||
27 | |||
28 | PROJECT_NAME = SDL | ||
29 | |||
30 | # The PROJECT_NUMBER tag can be used to enter a project or revision number. | ||
31 | # This could be handy for archiving the generated documentation or | ||
32 | # if some version control system is used. | ||
33 | |||
34 | PROJECT_NUMBER = 3.0 | ||
35 | |||
36 | # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) | ||
37 | # base path where the generated documentation will be put. | ||
38 | # If a relative path is entered, it will be relative to the location | ||
39 | # where doxygen was started. If left blank the current directory will be used. | ||
40 | |||
41 | OUTPUT_DIRECTORY = ./output | ||
42 | |||
43 | # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create | ||
44 | # 4096 sub-directories (in 2 levels) under the output directory of each output | ||
45 | # format and will distribute the generated files over these directories. | ||
46 | # Enabling this option can be useful when feeding doxygen a huge amount of | ||
47 | # source files, where putting all generated files in the same directory would | ||
48 | # otherwise cause performance problems for the file system. | ||
49 | |||
50 | CREATE_SUBDIRS = YES | ||
51 | |||
52 | # The OUTPUT_LANGUAGE tag is used to specify the language in which all | ||
53 | # documentation generated by doxygen is written. Doxygen will use this | ||
54 | # information to generate all constant output in the proper language. | ||
55 | # The default language is English, other supported languages are: | ||
56 | # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, | ||
57 | # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, | ||
58 | # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English | ||
59 | # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, | ||
60 | # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, | ||
61 | # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. | ||
62 | |||
63 | OUTPUT_LANGUAGE = English | ||
64 | |||
65 | # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will | ||
66 | # include brief member descriptions after the members that are listed in | ||
67 | # the file and class documentation (similar to JavaDoc). | ||
68 | # Set to NO to disable this. | ||
69 | |||
70 | BRIEF_MEMBER_DESC = YES | ||
71 | |||
72 | # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend | ||
73 | # the brief description of a member or function before the detailed description. | ||
74 | # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the | ||
75 | # brief descriptions will be completely suppressed. | ||
76 | |||
77 | REPEAT_BRIEF = YES | ||
78 | |||
79 | # This tag implements a quasi-intelligent brief description abbreviator | ||
80 | # that is used to form the text in various listings. Each string | ||
81 | # in this list, if found as the leading text of the brief description, will be | ||
82 | # stripped from the text and the result after processing the whole list, is | ||
83 | # used as the annotated text. Otherwise, the brief description is used as-is. | ||
84 | # If left blank, the following values are used ("$name" is automatically | ||
85 | # replaced with the name of the entity): "The $name class" "The $name widget" | ||
86 | # "The $name file" "is" "provides" "specifies" "contains" | ||
87 | # "represents" "a" "an" "the" | ||
88 | |||
89 | ABBREVIATE_BRIEF = "The $name class" \ | ||
90 | "The $name widget" \ | ||
91 | "The $name file" \ | ||
92 | is \ | ||
93 | provides \ | ||
94 | specifies \ | ||
95 | contains \ | ||
96 | represents \ | ||
97 | a \ | ||
98 | an \ | ||
99 | the | ||
100 | |||
101 | # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then | ||
102 | # Doxygen will generate a detailed section even if there is only a brief | ||
103 | # description. | ||
104 | |||
105 | ALWAYS_DETAILED_SEC = YES | ||
106 | |||
107 | # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all | ||
108 | # inherited members of a class in the documentation of that class as if those | ||
109 | # members were ordinary class members. Constructors, destructors and assignment | ||
110 | # operators of the base classes will not be shown. | ||
111 | |||
112 | INLINE_INHERITED_MEMB = NO | ||
113 | |||
114 | # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full | ||
115 | # path before files name in the file list and in the header files. If set | ||
116 | # to NO the shortest path that makes the file name unique will be used. | ||
117 | |||
118 | FULL_PATH_NAMES = YES | ||
119 | |||
120 | # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag | ||
121 | # can be used to strip a user-defined part of the path. Stripping is | ||
122 | # only done if one of the specified strings matches the left-hand part of | ||
123 | # the path. The tag can be used to show relative paths in the file list. | ||
124 | # If left blank the directory from which doxygen is run is used as the | ||
125 | # path to strip. | ||
126 | |||
127 | STRIP_FROM_PATH = | ||
128 | |||
129 | # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of | ||
130 | # the path mentioned in the documentation of a class, which tells | ||
131 | # the reader which header file to include in order to use a class. | ||
132 | # If left blank only the name of the header file containing the class | ||
133 | # definition is used. Otherwise one should specify the include paths that | ||
134 | # are normally passed to the compiler using the -I flag. | ||
135 | |||
136 | STRIP_FROM_INC_PATH = | ||
137 | |||
138 | # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter | ||
139 | # (but less readable) file names. This can be useful is your file systems | ||
140 | # doesn't support long names like on DOS, Mac, or CD-ROM. | ||
141 | |||
142 | SHORT_NAMES = NO | ||
143 | |||
144 | # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen | ||
145 | # will interpret the first line (until the first dot) of a JavaDoc-style | ||
146 | # comment as the brief description. If set to NO, the JavaDoc | ||
147 | # comments will behave just like regular Qt-style comments | ||
148 | # (thus requiring an explicit @brief command for a brief description.) | ||
149 | |||
150 | JAVADOC_AUTOBRIEF = NO | ||
151 | |||
152 | # If the QT_AUTOBRIEF tag is set to YES then Doxygen will | ||
153 | # interpret the first line (until the first dot) of a Qt-style | ||
154 | # comment as the brief description. If set to NO, the comments | ||
155 | # will behave just like regular Qt-style comments (thus requiring | ||
156 | # an explicit \brief command for a brief description.) | ||
157 | |||
158 | QT_AUTOBRIEF = NO | ||
159 | |||
160 | # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen | ||
161 | # treat a multi-line C++ special comment block (i.e. a block of //! or /// | ||
162 | # comments) as a brief description. This used to be the default behaviour. | ||
163 | # The new default is to treat a multi-line C++ comment block as a detailed | ||
164 | # description. Set this tag to YES if you prefer the old behaviour instead. | ||
165 | |||
166 | MULTILINE_CPP_IS_BRIEF = NO | ||
167 | |||
168 | # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented | ||
169 | # member inherits the documentation from any documented member that it | ||
170 | # re-implements. | ||
171 | |||
172 | INHERIT_DOCS = YES | ||
173 | |||
174 | # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce | ||
175 | # a new page for each member. If set to NO, the documentation of a member will | ||
176 | # be part of the file/class/namespace that contains it. | ||
177 | |||
178 | SEPARATE_MEMBER_PAGES = NO | ||
179 | |||
180 | # The TAB_SIZE tag can be used to set the number of spaces in a tab. | ||
181 | # Doxygen uses this value to replace tabs by spaces in code fragments. | ||
182 | |||
183 | TAB_SIZE = 8 | ||
184 | |||
185 | # This tag can be used to specify a number of aliases that acts | ||
186 | # as commands in the documentation. An alias has the form "name=value". | ||
187 | # For example adding "sideeffect=\par Side Effects:\n" will allow you to | ||
188 | # put the command \sideeffect (or @sideeffect) in the documentation, which | ||
189 | # will result in a user-defined paragraph with heading "Side Effects:". | ||
190 | # You can put \n's in the value part of an alias to insert newlines. | ||
191 | |||
192 | ALIASES = "defined=\"\def\"" \ | ||
193 | "discussion=\"\par Discussion:\n\"" | ||
194 | |||
195 | # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C | ||
196 | # sources only. Doxygen will then generate output that is more tailored for C. | ||
197 | # For instance, some of the names that are used will be different. The list | ||
198 | # of all members will be omitted, etc. | ||
199 | |||
200 | OPTIMIZE_OUTPUT_FOR_C = YES | ||
201 | |||
202 | # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java | ||
203 | # sources only. Doxygen will then generate output that is more tailored for | ||
204 | # Java. For instance, namespaces will be presented as packages, qualified | ||
205 | # scopes will look different, etc. | ||
206 | |||
207 | OPTIMIZE_OUTPUT_JAVA = NO | ||
208 | |||
209 | # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran | ||
210 | # sources only. Doxygen will then generate output that is more tailored for | ||
211 | # Fortran. | ||
212 | |||
213 | OPTIMIZE_FOR_FORTRAN = NO | ||
214 | |||
215 | # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL | ||
216 | # sources. Doxygen will then generate output that is tailored for | ||
217 | # VHDL. | ||
218 | |||
219 | OPTIMIZE_OUTPUT_VHDL = NO | ||
220 | |||
221 | # Doxygen selects the parser to use depending on the extension of the files it parses. | ||
222 | # With this tag you can assign which parser to use for a given extension. | ||
223 | # Doxygen has a built-in mapping, but you can override or extend it using this tag. | ||
224 | # The format is ext=language, where ext is a file extension, and language is one of | ||
225 | # the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, | ||
226 | # Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat | ||
227 | # .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), | ||
228 | # use: inc=Fortran f=C. Note that for custom extensions you also need to set | ||
229 | # FILE_PATTERNS otherwise the files are not read by doxygen. | ||
230 | |||
231 | EXTENSION_MAPPING = | ||
232 | |||
233 | # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want | ||
234 | # to include (a tag file for) the STL sources as input, then you should | ||
235 | # set this tag to YES in order to let doxygen match functions declarations and | ||
236 | # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. | ||
237 | # func(std::string) {}). This also make the inheritance and collaboration | ||
238 | # diagrams that involve STL classes more complete and accurate. | ||
239 | |||
240 | BUILTIN_STL_SUPPORT = YES | ||
241 | |||
242 | # If you use Microsoft's C++/CLI language, you should set this option to YES to | ||
243 | # enable parsing support. | ||
244 | |||
245 | CPP_CLI_SUPPORT = NO | ||
246 | |||
247 | # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. | ||
248 | # Doxygen will parse them like normal C++ but will assume all classes use public | ||
249 | # instead of private inheritance when no explicit protection keyword is present. | ||
250 | |||
251 | SIP_SUPPORT = NO | ||
252 | |||
253 | # For Microsoft's IDL there are propget and propput attributes to indicate getter | ||
254 | # and setter methods for a property. Setting this option to YES (the default) | ||
255 | # will make doxygen to replace the get and set methods by a property in the | ||
256 | # documentation. This will only work if the methods are indeed getting or | ||
257 | # setting a simple type. If this is not the case, or you want to show the | ||
258 | # methods anyway, you should set this option to NO. | ||
259 | |||
260 | IDL_PROPERTY_SUPPORT = YES | ||
261 | |||
262 | # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC | ||
263 | # tag is set to YES, then doxygen will reuse the documentation of the first | ||
264 | # member in the group (if any) for the other members of the group. By default | ||
265 | # all members of a group must be documented explicitly. | ||
266 | |||
267 | DISTRIBUTE_GROUP_DOC = NO | ||
268 | |||
269 | # Set the SUBGROUPING tag to YES (the default) to allow class member groups of | ||
270 | # the same type (for instance a group of public functions) to be put as a | ||
271 | # subgroup of that type (e.g. under the Public Functions section). Set it to | ||
272 | # NO to prevent subgrouping. Alternatively, this can be done per class using | ||
273 | # the \nosubgrouping command. | ||
274 | |||
275 | SUBGROUPING = YES | ||
276 | |||
277 | # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum | ||
278 | # is documented as struct, union, or enum with the name of the typedef. So | ||
279 | # typedef struct TypeS {} TypeT, will appear in the documentation as a struct | ||
280 | # with name TypeT. When disabled the typedef will appear as a member of a file, | ||
281 | # namespace, or class. And the struct will be named TypeS. This can typically | ||
282 | # be useful for C code in case the coding convention dictates that all compound | ||
283 | # types are typedef'ed and only the typedef is referenced, never the tag name. | ||
284 | |||
285 | TYPEDEF_HIDES_STRUCT = YES | ||
286 | |||
287 | # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to | ||
288 | # determine which symbols to keep in memory and which to flush to disk. | ||
289 | # When the cache is full, less often used symbols will be written to disk. | ||
290 | # For small to medium size projects (<1000 input files) the default value is | ||
291 | # probably good enough. For larger projects a too small cache size can cause | ||
292 | # doxygen to be busy swapping symbols to and from disk most of the time | ||
293 | # causing a significant performance penality. | ||
294 | # If the system has enough physical memory increasing the cache will improve the | ||
295 | # performance by keeping more symbols in memory. Note that the value works on | ||
296 | # a logarithmic scale so increasing the size by one will rougly double the | ||
297 | # memory usage. The cache size is given by this formula: | ||
298 | # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, | ||
299 | # corresponding to a cache size of 2^16 = 65536 symbols | ||
300 | |||
301 | SYMBOL_CACHE_SIZE = 0 | ||
302 | |||
303 | #--------------------------------------------------------------------------- | ||
304 | # Build related configuration options | ||
305 | #--------------------------------------------------------------------------- | ||
306 | |||
307 | # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in | ||
308 | # documentation are documented, even if no documentation was available. | ||
309 | # Private class members and static file members will be hidden unless | ||
310 | # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES | ||
311 | |||
312 | EXTRACT_ALL = YES | ||
313 | |||
314 | # If the EXTRACT_PRIVATE tag is set to YES all private members of a class | ||
315 | # will be included in the documentation. | ||
316 | |||
317 | EXTRACT_PRIVATE = YES | ||
318 | |||
319 | # If the EXTRACT_STATIC tag is set to YES all static members of a file | ||
320 | # will be included in the documentation. | ||
321 | |||
322 | EXTRACT_STATIC = YES | ||
323 | |||
324 | # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) | ||
325 | # defined locally in source files will be included in the documentation. | ||
326 | # If set to NO only classes defined in header files are included. | ||
327 | |||
328 | EXTRACT_LOCAL_CLASSES = YES | ||
329 | |||
330 | # This flag is only useful for Objective-C code. When set to YES local | ||
331 | # methods, which are defined in the implementation section but not in | ||
332 | # the interface are included in the documentation. | ||
333 | # If set to NO (the default) only methods in the interface are included. | ||
334 | |||
335 | EXTRACT_LOCAL_METHODS = YES | ||
336 | |||
337 | # If this flag is set to YES, the members of anonymous namespaces will be | ||
338 | # extracted and appear in the documentation as a namespace called | ||
339 | # 'anonymous_namespace{file}', where file will be replaced with the base | ||
340 | # name of the file that contains the anonymous namespace. By default | ||
341 | # anonymous namespace are hidden. | ||
342 | |||
343 | EXTRACT_ANON_NSPACES = YES | ||
344 | |||
345 | # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all | ||
346 | # undocumented members of documented classes, files or namespaces. | ||
347 | # If set to NO (the default) these members will be included in the | ||
348 | # various overviews, but no documentation section is generated. | ||
349 | # This option has no effect if EXTRACT_ALL is enabled. | ||
350 | |||
351 | HIDE_UNDOC_MEMBERS = NO | ||
352 | |||
353 | # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all | ||
354 | # undocumented classes that are normally visible in the class hierarchy. | ||
355 | # If set to NO (the default) these classes will be included in the various | ||
356 | # overviews. This option has no effect if EXTRACT_ALL is enabled. | ||
357 | |||
358 | HIDE_UNDOC_CLASSES = NO | ||
359 | |||
360 | # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all | ||
361 | # friend (class|struct|union) declarations. | ||
362 | # If set to NO (the default) these declarations will be included in the | ||
363 | # documentation. | ||
364 | |||
365 | HIDE_FRIEND_COMPOUNDS = NO | ||
366 | |||
367 | # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any | ||
368 | # documentation blocks found inside the body of a function. | ||
369 | # If set to NO (the default) these blocks will be appended to the | ||
370 | # function's detailed documentation block. | ||
371 | |||
372 | HIDE_IN_BODY_DOCS = NO | ||
373 | |||
374 | # The INTERNAL_DOCS tag determines if documentation | ||
375 | # that is typed after a \internal command is included. If the tag is set | ||
376 | # to NO (the default) then the documentation will be excluded. | ||
377 | # Set it to YES to include the internal documentation. | ||
378 | |||
379 | INTERNAL_DOCS = YES | ||
380 | |||
381 | # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate | ||
382 | # file names in lower-case letters. If set to YES upper-case letters are also | ||
383 | # allowed. This is useful if you have classes or files whose names only differ | ||
384 | # in case and if your file system supports case sensitive file names. Windows | ||
385 | # and Mac users are advised to set this option to NO. | ||
386 | |||
387 | CASE_SENSE_NAMES = NO | ||
388 | |||
389 | # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen | ||
390 | # will show members with their full class and namespace scopes in the | ||
391 | # documentation. If set to YES the scope will be hidden. | ||
392 | |||
393 | HIDE_SCOPE_NAMES = NO | ||
394 | |||
395 | # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen | ||
396 | # will put a list of the files that are included by a file in the documentation | ||
397 | # of that file. | ||
398 | |||
399 | SHOW_INCLUDE_FILES = YES | ||
400 | |||
401 | # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] | ||
402 | # is inserted in the documentation for inline members. | ||
403 | |||
404 | INLINE_INFO = YES | ||
405 | |||
406 | # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen | ||
407 | # will sort the (detailed) documentation of file and class members | ||
408 | # alphabetically by member name. If set to NO the members will appear in | ||
409 | # declaration order. | ||
410 | |||
411 | SORT_MEMBER_DOCS = YES | ||
412 | |||
413 | # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the | ||
414 | # brief documentation of file, namespace and class members alphabetically | ||
415 | # by member name. If set to NO (the default) the members will appear in | ||
416 | # declaration order. | ||
417 | |||
418 | SORT_BRIEF_DOCS = NO | ||
419 | |||
420 | # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the | ||
421 | # hierarchy of group names into alphabetical order. If set to NO (the default) | ||
422 | # the group names will appear in their defined order. | ||
423 | |||
424 | SORT_GROUP_NAMES = NO | ||
425 | |||
426 | # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be | ||
427 | # sorted by fully-qualified names, including namespaces. If set to | ||
428 | # NO (the default), the class list will be sorted only by class name, | ||
429 | # not including the namespace part. | ||
430 | # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. | ||
431 | # Note: This option applies only to the class list, not to the | ||
432 | # alphabetical list. | ||
433 | |||
434 | SORT_BY_SCOPE_NAME = NO | ||
435 | |||
436 | # The GENERATE_TODOLIST tag can be used to enable (YES) or | ||
437 | # disable (NO) the todo list. This list is created by putting \todo | ||
438 | # commands in the documentation. | ||
439 | |||
440 | GENERATE_TODOLIST = YES | ||
441 | |||
442 | # The GENERATE_TESTLIST tag can be used to enable (YES) or | ||
443 | # disable (NO) the test list. This list is created by putting \test | ||
444 | # commands in the documentation. | ||
445 | |||
446 | GENERATE_TESTLIST = YES | ||
447 | |||
448 | # The GENERATE_BUGLIST tag can be used to enable (YES) or | ||
449 | # disable (NO) the bug list. This list is created by putting \bug | ||
450 | # commands in the documentation. | ||
451 | |||
452 | GENERATE_BUGLIST = YES | ||
453 | |||
454 | # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or | ||
455 | # disable (NO) the deprecated list. This list is created by putting | ||
456 | # \deprecated commands in the documentation. | ||
457 | |||
458 | GENERATE_DEPRECATEDLIST= YES | ||
459 | |||
460 | # The ENABLED_SECTIONS tag can be used to enable conditional | ||
461 | # documentation sections, marked by \if sectionname ... \endif. | ||
462 | |||
463 | ENABLED_SECTIONS = | ||
464 | |||
465 | # The MAX_INITIALIZER_LINES tag determines the maximum number of lines | ||
466 | # the initial value of a variable or define consists of for it to appear in | ||
467 | # the documentation. If the initializer consists of more lines than specified | ||
468 | # here it will be hidden. Use a value of 0 to hide initializers completely. | ||
469 | # The appearance of the initializer of individual variables and defines in the | ||
470 | # documentation can be controlled using \showinitializer or \hideinitializer | ||
471 | # command in the documentation regardless of this setting. | ||
472 | |||
473 | MAX_INITIALIZER_LINES = 30 | ||
474 | |||
475 | # If the sources in your project are distributed over multiple directories | ||
476 | # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy | ||
477 | # in the documentation. The default is NO. | ||
478 | |||
479 | SHOW_DIRECTORIES = YES | ||
480 | |||
481 | # Set the SHOW_FILES tag to NO to disable the generation of the Files page. | ||
482 | # This will remove the Files entry from the Quick Index and from the | ||
483 | # Folder Tree View (if specified). The default is YES. | ||
484 | |||
485 | SHOW_FILES = YES | ||
486 | |||
487 | # Set the SHOW_NAMESPACES tag to NO to disable the generation of the | ||
488 | # Namespaces page. This will remove the Namespaces entry from the Quick Index | ||
489 | # and from the Folder Tree View (if specified). The default is YES. | ||
490 | |||
491 | SHOW_NAMESPACES = YES | ||
492 | |||
493 | # The FILE_VERSION_FILTER tag can be used to specify a program or script that | ||
494 | # doxygen should invoke to get the current version for each file (typically from | ||
495 | # the version control system). Doxygen will invoke the program by executing (via | ||
496 | # popen()) the command <command> <input-file>, where <command> is the value of | ||
497 | # the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file | ||
498 | # provided by doxygen. Whatever the program writes to standard output | ||
499 | # is used as the file version. See the manual for examples. | ||
500 | |||
501 | FILE_VERSION_FILTER = | ||
502 | |||
503 | # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by | ||
504 | # doxygen. The layout file controls the global structure of the generated output files | ||
505 | # in an output format independent way. The create the layout file that represents | ||
506 | # doxygen's defaults, run doxygen with the -l option. You can optionally specify a | ||
507 | # file name after the option, if omitted DoxygenLayout.xml will be used as the name | ||
508 | # of the layout file. | ||
509 | |||
510 | LAYOUT_FILE = | ||
511 | |||
512 | #--------------------------------------------------------------------------- | ||
513 | # configuration options related to warning and progress messages | ||
514 | #--------------------------------------------------------------------------- | ||
515 | |||
516 | # The QUIET tag can be used to turn on/off the messages that are generated | ||
517 | # by doxygen. Possible values are YES and NO. If left blank NO is used. | ||
518 | |||
519 | QUIET = NO | ||
520 | |||
521 | # The WARNINGS tag can be used to turn on/off the warning messages that are | ||
522 | # generated by doxygen. Possible values are YES and NO. If left blank | ||
523 | # NO is used. | ||
524 | |||
525 | WARNINGS = YES | ||
526 | |||
527 | # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings | ||
528 | # for undocumented members. If EXTRACT_ALL is set to YES then this flag will | ||
529 | # automatically be disabled. | ||
530 | |||
531 | WARN_IF_UNDOCUMENTED = YES | ||
532 | |||
533 | # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for | ||
534 | # potential errors in the documentation, such as not documenting some | ||
535 | # parameters in a documented function, or documenting parameters that | ||
536 | # don't exist or using markup commands wrongly. | ||
537 | |||
538 | WARN_IF_DOC_ERROR = YES | ||
539 | |||
540 | # This WARN_NO_PARAMDOC option can be abled to get warnings for | ||
541 | # functions that are documented, but have no documentation for their parameters | ||
542 | # or return value. If set to NO (the default) doxygen will only warn about | ||
543 | # wrong or incomplete parameter documentation, but not about the absence of | ||
544 | # documentation. | ||
545 | |||
546 | WARN_NO_PARAMDOC = YES | ||
547 | |||
548 | # The WARN_FORMAT tag determines the format of the warning messages that | ||
549 | # doxygen can produce. The string should contain the $file, $line, and $text | ||
550 | # tags, which will be replaced by the file and line number from which the | ||
551 | # warning originated and the warning text. Optionally the format may contain | ||
552 | # $version, which will be replaced by the version of the file (if it could | ||
553 | # be obtained via FILE_VERSION_FILTER) | ||
554 | |||
555 | WARN_FORMAT = "$file:$line: $text" | ||
556 | |||
557 | # The WARN_LOGFILE tag can be used to specify a file to which warning | ||
558 | # and error messages should be written. If left blank the output is written | ||
559 | # to stderr. | ||
560 | |||
561 | WARN_LOGFILE = ./doxygen_warn.txt | ||
562 | |||
563 | #--------------------------------------------------------------------------- | ||
564 | # configuration options related to the input files | ||
565 | #--------------------------------------------------------------------------- | ||
566 | |||
567 | # The INPUT tag can be used to specify the files and/or directories that contain | ||
568 | # documented source files. You may enter file names like "myfile.cpp" or | ||
569 | # directories like "/usr/src/myproject". Separate the files or directories | ||
570 | # with spaces. | ||
571 | |||
572 | INPUT = . ../include | ||
573 | |||
574 | # This tag can be used to specify the character encoding of the source files | ||
575 | # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is | ||
576 | # also the default input encoding. Doxygen uses libiconv (or the iconv built | ||
577 | # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for | ||
578 | # the list of possible encodings. | ||
579 | |||
580 | INPUT_ENCODING = UTF-8 | ||
581 | |||
582 | # If the value of the INPUT tag contains directories, you can use the | ||
583 | # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp | ||
584 | # and *.h) to filter out the source-files in the directories. If left | ||
585 | # blank the following patterns are tested: | ||
586 | # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx | ||
587 | # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 | ||
588 | |||
589 | FILE_PATTERNS = *.c \ | ||
590 | *.cc \ | ||
591 | *.cxx \ | ||
592 | *.cpp \ | ||
593 | *.c++ \ | ||
594 | *.d \ | ||
595 | *.java \ | ||
596 | *.ii \ | ||
597 | *.ixx \ | ||
598 | *.ipp \ | ||
599 | *.i++ \ | ||
600 | *.inl \ | ||
601 | *.h \ | ||
602 | *.hh \ | ||
603 | *.hxx \ | ||
604 | *.hpp \ | ||
605 | *.h++ \ | ||
606 | *.idl \ | ||
607 | *.odl \ | ||
608 | *.cs \ | ||
609 | *.php \ | ||
610 | *.php3 \ | ||
611 | *.inc \ | ||
612 | *.m \ | ||
613 | *.mm \ | ||
614 | *.dox \ | ||
615 | *.py \ | ||
616 | *.f90 \ | ||
617 | *.f \ | ||
618 | *.vhd \ | ||
619 | *.vhdl \ | ||
620 | *.h.in \ | ||
621 | *.h.default \ | ||
622 | *.md | ||
623 | |||
624 | # The RECURSIVE tag can be used to turn specify whether or not subdirectories | ||
625 | # should be searched for input files as well. Possible values are YES and NO. | ||
626 | # If left blank NO is used. | ||
627 | |||
628 | RECURSIVE = YES | ||
629 | |||
630 | # The EXCLUDE tag can be used to specify files and/or directories that should | ||
631 | # excluded from the INPUT source files. This way you can easily exclude a | ||
632 | # subdirectory from a directory tree whose root is specified with the INPUT tag. | ||
633 | |||
634 | EXCLUDE = \ | ||
635 | ../include/SDL3/SDL_egl.h \ | ||
636 | ../include/SDL3/SDL_opengl.h \ | ||
637 | ../include/SDL3/SDL_opengl_glext.h \ | ||
638 | ../include/SDL3/SDL_opengles.h \ | ||
639 | ../include/SDL3/SDL_opengles2.h \ | ||
640 | ../include/SDL3/SDL_opengles2_gl2.h \ | ||
641 | ../include/SDL3/SDL_opengles2_gl2ext.h \ | ||
642 | ../include/SDL3/SDL_opengles2_gl2platform.h \ | ||
643 | ../include/SDL3/SDL_opengles2_khrplatform.h \ | ||
644 | ../include/build_config \ | ||
645 | ./release_checklist.md \ | ||
646 | |||
647 | |||
648 | # The EXCLUDE_SYMLINKS tag can be used select whether or not files or | ||
649 | # directories that are symbolic links (a Unix filesystem feature) are excluded | ||
650 | # from the input. | ||
651 | |||
652 | EXCLUDE_SYMLINKS = NO | ||
653 | |||
654 | # If the value of the INPUT tag contains directories, you can use the | ||
655 | # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude | ||
656 | # certain files from those directories. Note that the wildcards are matched | ||
657 | # against the file with absolute path, so to exclude all test directories | ||
658 | # for example use the pattern */test/* | ||
659 | |||
660 | EXCLUDE_PATTERNS = | ||
661 | |||
662 | # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names | ||
663 | # (namespaces, classes, functions, etc.) that should be excluded from the | ||
664 | # output. The symbol name can be a fully qualified name, a word, or if the | ||
665 | # wildcard * is used, a substring. Examples: ANamespace, AClass, | ||
666 | # AClass::ANamespace, ANamespace::*Test | ||
667 | |||
668 | EXCLUDE_SYMBOLS = | ||
669 | |||
670 | # The EXAMPLE_PATH tag can be used to specify one or more files or | ||
671 | # directories that contain example code fragments that are included (see | ||
672 | # the \include command). | ||
673 | |||
674 | EXAMPLE_PATH = | ||
675 | |||
676 | # If the value of the EXAMPLE_PATH tag contains directories, you can use the | ||
677 | # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp | ||
678 | # and *.h) to filter out the source-files in the directories. If left | ||
679 | # blank all files are included. | ||
680 | |||
681 | EXAMPLE_PATTERNS = * | ||
682 | |||
683 | # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be | ||
684 | # searched for input files to be used with the \include or \dontinclude | ||
685 | # commands irrespective of the value of the RECURSIVE tag. | ||
686 | # Possible values are YES and NO. If left blank NO is used. | ||
687 | |||
688 | EXAMPLE_RECURSIVE = YES | ||
689 | |||
690 | # The IMAGE_PATH tag can be used to specify one or more files or | ||
691 | # directories that contain image that are included in the documentation (see | ||
692 | # the \image command). | ||
693 | |||
694 | IMAGE_PATH = | ||
695 | |||
696 | # The INPUT_FILTER tag can be used to specify a program that doxygen should | ||
697 | # invoke to filter for each input file. Doxygen will invoke the filter program | ||
698 | # by executing (via popen()) the command <filter> <input-file>, where <filter> | ||
699 | # is the value of the INPUT_FILTER tag, and <input-file> is the name of an | ||
700 | # input file. Doxygen will then use the output that the filter program writes | ||
701 | # to standard output. If FILTER_PATTERNS is specified, this tag will be | ||
702 | # ignored. | ||
703 | |||
704 | INPUT_FILTER = | ||
705 | |||
706 | # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern | ||
707 | # basis. Doxygen will compare the file name with each pattern and apply the | ||
708 | # filter if there is a match. The filters are a list of the form: | ||
709 | # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further | ||
710 | # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER | ||
711 | # is applied to all files. | ||
712 | |||
713 | FILTER_PATTERNS = | ||
714 | |||
715 | # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using | ||
716 | # INPUT_FILTER) will be used to filter the input files when producing source | ||
717 | # files to browse (i.e. when SOURCE_BROWSER is set to YES). | ||
718 | |||
719 | FILTER_SOURCE_FILES = NO | ||
720 | |||
721 | #--------------------------------------------------------------------------- | ||
722 | # configuration options related to source browsing | ||
723 | #--------------------------------------------------------------------------- | ||
724 | |||
725 | # If the SOURCE_BROWSER tag is set to YES then a list of source files will | ||
726 | # be generated. Documented entities will be cross-referenced with these sources. | ||
727 | # Note: To get rid of all source code in the generated output, make sure also | ||
728 | # VERBATIM_HEADERS is set to NO. | ||
729 | |||
730 | SOURCE_BROWSER = YES | ||
731 | |||
732 | # Setting the INLINE_SOURCES tag to YES will include the body | ||
733 | # of functions and classes directly in the documentation. | ||
734 | |||
735 | INLINE_SOURCES = YES | ||
736 | |||
737 | # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct | ||
738 | # doxygen to hide any special comment blocks from generated source code | ||
739 | # fragments. Normal C and C++ comments will always remain visible. | ||
740 | |||
741 | STRIP_CODE_COMMENTS = NO | ||
742 | |||
743 | # If the REFERENCED_BY_RELATION tag is set to YES | ||
744 | # then for each documented function all documented | ||
745 | # functions referencing it will be listed. | ||
746 | |||
747 | REFERENCED_BY_RELATION = YES | ||
748 | |||
749 | # If the REFERENCES_RELATION tag is set to YES | ||
750 | # then for each documented function all documented entities | ||
751 | # called/used by that function will be listed. | ||
752 | |||
753 | REFERENCES_RELATION = YES | ||
754 | |||
755 | # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) | ||
756 | # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from | ||
757 | # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will | ||
758 | # link to the source code. Otherwise they will link to the documentation. | ||
759 | |||
760 | REFERENCES_LINK_SOURCE = YES | ||
761 | |||
762 | # If the USE_HTAGS tag is set to YES then the references to source code | ||
763 | # will point to the HTML generated by the htags(1) tool instead of doxygen | ||
764 | # built-in source browser. The htags tool is part of GNU's global source | ||
765 | # tagging system (see http://www.gnu.org/software/global/global.html). You | ||
766 | # will need version 4.8.6 or higher. | ||
767 | |||
768 | USE_HTAGS = NO | ||
769 | |||
770 | # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen | ||
771 | # will generate a verbatim copy of the header file for each class for | ||
772 | # which an include is specified. Set to NO to disable this. | ||
773 | |||
774 | VERBATIM_HEADERS = YES | ||
775 | |||
776 | #--------------------------------------------------------------------------- | ||
777 | # configuration options related to the alphabetical class index | ||
778 | #--------------------------------------------------------------------------- | ||
779 | |||
780 | # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index | ||
781 | # of all compounds will be generated. Enable this if the project | ||
782 | # contains a lot of classes, structs, unions or interfaces. | ||
783 | |||
784 | ALPHABETICAL_INDEX = YES | ||
785 | |||
786 | # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then | ||
787 | # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns | ||
788 | # in which this list will be split (can be a number in the range [1..20]) | ||
789 | |||
790 | COLS_IN_ALPHA_INDEX = 5 | ||
791 | |||
792 | # In case all classes in a project start with a common prefix, all | ||
793 | # classes will be put under the same header in the alphabetical index. | ||
794 | # The IGNORE_PREFIX tag can be used to specify one or more prefixes that | ||
795 | # should be ignored while generating the index headers. | ||
796 | |||
797 | IGNORE_PREFIX = SDL_ \ | ||
798 | SDL | ||
799 | |||
800 | #--------------------------------------------------------------------------- | ||
801 | # configuration options related to the HTML output | ||
802 | #--------------------------------------------------------------------------- | ||
803 | |||
804 | # If the GENERATE_HTML tag is set to YES (the default) Doxygen will | ||
805 | # generate HTML output. | ||
806 | |||
807 | GENERATE_HTML = YES | ||
808 | |||
809 | # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. | ||
810 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be | ||
811 | # put in front of it. If left blank `html' will be used as the default path. | ||
812 | |||
813 | HTML_OUTPUT = html | ||
814 | |||
815 | # The HTML_FILE_EXTENSION tag can be used to specify the file extension for | ||
816 | # each generated HTML page (for example: .htm,.php,.asp). If it is left blank | ||
817 | # doxygen will generate files with .html extension. | ||
818 | |||
819 | HTML_FILE_EXTENSION = .html | ||
820 | |||
821 | # The HTML_HEADER tag can be used to specify a personal HTML header for | ||
822 | # each generated HTML page. If it is left blank doxygen will generate a | ||
823 | # standard header. | ||
824 | |||
825 | HTML_HEADER = | ||
826 | |||
827 | # The HTML_FOOTER tag can be used to specify a personal HTML footer for | ||
828 | # each generated HTML page. If it is left blank doxygen will generate a | ||
829 | # standard footer. | ||
830 | |||
831 | HTML_FOOTER = | ||
832 | |||
833 | # The HTML_STYLESHEET tag can be used to specify a user-defined cascading | ||
834 | # style sheet that is used by each HTML page. It can be used to | ||
835 | # fine-tune the look of the HTML output. If the tag is left blank doxygen | ||
836 | # will generate a default style sheet. Note that doxygen will try to copy | ||
837 | # the style sheet file to the HTML output directory, so don't put your own | ||
838 | # stylesheet in the HTML output directory as well, or it will be erased! | ||
839 | |||
840 | HTML_STYLESHEET = | ||
841 | |||
842 | # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, | ||
843 | # files or namespaces will be aligned in HTML using tables. If set to | ||
844 | # NO a bullet list will be used. | ||
845 | |||
846 | HTML_ALIGN_MEMBERS = YES | ||
847 | |||
848 | # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML | ||
849 | # documentation will contain sections that can be hidden and shown after the | ||
850 | # page has loaded. For this to work a browser that supports | ||
851 | # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox | ||
852 | # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). | ||
853 | |||
854 | HTML_DYNAMIC_SECTIONS = YES | ||
855 | |||
856 | # If the GENERATE_DOCSET tag is set to YES, additional index files | ||
857 | # will be generated that can be used as input for Apple's Xcode 3 | ||
858 | # integrated development environment, introduced with OSX 10.5 (Leopard). | ||
859 | # To create a documentation set, doxygen will generate a Makefile in the | ||
860 | # HTML output directory. Running make will produce the docset in that | ||
861 | # directory and running "make install" will install the docset in | ||
862 | # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find | ||
863 | # it at startup. | ||
864 | # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. | ||
865 | |||
866 | GENERATE_DOCSET = NO | ||
867 | |||
868 | # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the | ||
869 | # feed. A documentation feed provides an umbrella under which multiple | ||
870 | # documentation sets from a single provider (such as a company or product suite) | ||
871 | # can be grouped. | ||
872 | |||
873 | DOCSET_FEEDNAME = "SDL 3.0 Doxygen" | ||
874 | |||
875 | # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that | ||
876 | # should uniquely identify the documentation set bundle. This should be a | ||
877 | # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen | ||
878 | # will append .docset to the name. | ||
879 | |||
880 | DOCSET_BUNDLE_ID = org.libsdl.sdl30 | ||
881 | |||
882 | # If the GENERATE_HTMLHELP tag is set to YES, additional index files | ||
883 | # will be generated that can be used as input for tools like the | ||
884 | # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) | ||
885 | # of the generated HTML documentation. | ||
886 | |||
887 | GENERATE_HTMLHELP = NO | ||
888 | |||
889 | # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can | ||
890 | # be used to specify the file name of the resulting .chm file. You | ||
891 | # can add a path in front of the file if the result should not be | ||
892 | # written to the html output directory. | ||
893 | |||
894 | CHM_FILE = ./sdl30.chm | ||
895 | |||
896 | # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can | ||
897 | # be used to specify the location (absolute path including file name) of | ||
898 | # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run | ||
899 | # the HTML help compiler on the generated index.hhp. | ||
900 | |||
901 | HHC_LOCATION = | ||
902 | |||
903 | # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag | ||
904 | # controls if a separate .chi index file is generated (YES) or that | ||
905 | # it should be included in the master .chm file (NO). | ||
906 | |||
907 | GENERATE_CHI = NO | ||
908 | |||
909 | # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING | ||
910 | # is used to encode HtmlHelp index (hhk), content (hhc) and project file | ||
911 | # content. | ||
912 | |||
913 | CHM_INDEX_ENCODING = | ||
914 | |||
915 | # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag | ||
916 | # controls whether a binary table of contents is generated (YES) or a | ||
917 | # normal table of contents (NO) in the .chm file. | ||
918 | |||
919 | BINARY_TOC = NO | ||
920 | |||
921 | # The TOC_EXPAND flag can be set to YES to add extra items for group members | ||
922 | # to the contents of the HTML help documentation and to the tree view. | ||
923 | |||
924 | TOC_EXPAND = YES | ||
925 | |||
926 | # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER | ||
927 | # are set, an additional index file will be generated that can be used as input for | ||
928 | # Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated | ||
929 | # HTML documentation. | ||
930 | |||
931 | GENERATE_QHP = NO | ||
932 | |||
933 | # If the QHG_LOCATION tag is specified, the QCH_FILE tag can | ||
934 | # be used to specify the file name of the resulting .qch file. | ||
935 | # The path specified is relative to the HTML output folder. | ||
936 | |||
937 | QCH_FILE = | ||
938 | |||
939 | # The QHP_NAMESPACE tag specifies the namespace to use when generating | ||
940 | # Qt Help Project output. For more information please see | ||
941 | # http://doc.trolltech.com/qthelpproject.html#namespace | ||
942 | |||
943 | QHP_NAMESPACE = | ||
944 | |||
945 | # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating | ||
946 | # Qt Help Project output. For more information please see | ||
947 | # http://doc.trolltech.com/qthelpproject.html#virtual-folders | ||
948 | |||
949 | QHP_VIRTUAL_FOLDER = doc | ||
950 | |||
951 | # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. | ||
952 | # For more information please see | ||
953 | # http://doc.trolltech.com/qthelpproject.html#custom-filters | ||
954 | |||
955 | QHP_CUST_FILTER_NAME = | ||
956 | |||
957 | # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see | ||
958 | # <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>. | ||
959 | |||
960 | QHP_CUST_FILTER_ATTRS = | ||
961 | |||
962 | # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's | ||
963 | # filter section matches. | ||
964 | # <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>. | ||
965 | |||
966 | QHP_SECT_FILTER_ATTRS = | ||
967 | |||
968 | # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can | ||
969 | # be used to specify the location of Qt's qhelpgenerator. | ||
970 | # If non-empty doxygen will try to run qhelpgenerator on the generated | ||
971 | # .qhp file. | ||
972 | |||
973 | QHG_LOCATION = | ||
974 | |||
975 | # The DISABLE_INDEX tag can be used to turn on/off the condensed index at | ||
976 | # top of each HTML page. The value NO (the default) enables the index and | ||
977 | # the value YES disables it. | ||
978 | |||
979 | DISABLE_INDEX = NO | ||
980 | |||
981 | # This tag can be used to set the number of enum values (range [1..20]) | ||
982 | # that doxygen will group on one line in the generated HTML documentation. | ||
983 | |||
984 | ENUM_VALUES_PER_LINE = 1 | ||
985 | |||
986 | # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index | ||
987 | # structure should be generated to display hierarchical information. | ||
988 | # If the tag value is set to FRAME, a side panel will be generated | ||
989 | # containing a tree-like index structure (just like the one that | ||
990 | # is generated for HTML Help). For this to work a browser that supports | ||
991 | # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, | ||
992 | # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are | ||
993 | # probably better off using the HTML help feature. Other possible values | ||
994 | # for this tag are: HIERARCHIES, which will generate the Groups, Directories, | ||
995 | # and Class Hierarchy pages using a tree view instead of an ordered list; | ||
996 | # ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which | ||
997 | # disables this behavior completely. For backwards compatibility with previous | ||
998 | # releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE | ||
999 | # respectively. | ||
1000 | |||
1001 | GENERATE_TREEVIEW = ALL | ||
1002 | |||
1003 | # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be | ||
1004 | # used to set the initial width (in pixels) of the frame in which the tree | ||
1005 | # is shown. | ||
1006 | |||
1007 | TREEVIEW_WIDTH = 250 | ||
1008 | |||
1009 | # Use this tag to change the font size of Latex formulas included | ||
1010 | # as images in the HTML documentation. The default is 10. Note that | ||
1011 | # when you change the font size after a successful doxygen run you need | ||
1012 | # to manually remove any form_*.png images from the HTML output directory | ||
1013 | # to force them to be regenerated. | ||
1014 | |||
1015 | FORMULA_FONTSIZE = 10 | ||
1016 | |||
1017 | #--------------------------------------------------------------------------- | ||
1018 | # configuration options related to the LaTeX output | ||
1019 | #--------------------------------------------------------------------------- | ||
1020 | |||
1021 | # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will | ||
1022 | # generate Latex output. | ||
1023 | |||
1024 | GENERATE_LATEX = NO | ||
1025 | |||
1026 | # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. | ||
1027 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be | ||
1028 | # put in front of it. If left blank `latex' will be used as the default path. | ||
1029 | |||
1030 | LATEX_OUTPUT = latex | ||
1031 | |||
1032 | # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be | ||
1033 | # invoked. If left blank `latex' will be used as the default command name. | ||
1034 | |||
1035 | LATEX_CMD_NAME = latex | ||
1036 | |||
1037 | # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to | ||
1038 | # generate index for LaTeX. If left blank `makeindex' will be used as the | ||
1039 | # default command name. | ||
1040 | |||
1041 | MAKEINDEX_CMD_NAME = makeindex | ||
1042 | |||
1043 | # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact | ||
1044 | # LaTeX documents. This may be useful for small projects and may help to | ||
1045 | # save some trees in general. | ||
1046 | |||
1047 | COMPACT_LATEX = NO | ||
1048 | |||
1049 | # The PAPER_TYPE tag can be used to set the paper type that is used | ||
1050 | # by the printer. Possible values are: a4, a4wide, letter, legal and | ||
1051 | # executive. If left blank a4wide will be used. | ||
1052 | |||
1053 | PAPER_TYPE = a4wide | ||
1054 | |||
1055 | # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX | ||
1056 | # packages that should be included in the LaTeX output. | ||
1057 | |||
1058 | EXTRA_PACKAGES = | ||
1059 | |||
1060 | # The LATEX_HEADER tag can be used to specify a personal LaTeX header for | ||
1061 | # the generated latex document. The header should contain everything until | ||
1062 | # the first chapter. If it is left blank doxygen will generate a | ||
1063 | # standard header. Notice: only use this tag if you know what you are doing! | ||
1064 | |||
1065 | LATEX_HEADER = | ||
1066 | |||
1067 | # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated | ||
1068 | # is prepared for conversion to pdf (using ps2pdf). The pdf file will | ||
1069 | # contain links (just like the HTML output) instead of page references | ||
1070 | # This makes the output suitable for online browsing using a pdf viewer. | ||
1071 | |||
1072 | PDF_HYPERLINKS = YES | ||
1073 | |||
1074 | # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of | ||
1075 | # plain latex in the generated Makefile. Set this option to YES to get a | ||
1076 | # higher quality PDF documentation. | ||
1077 | |||
1078 | USE_PDFLATEX = YES | ||
1079 | |||
1080 | # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. | ||
1081 | # command to the generated LaTeX files. This will instruct LaTeX to keep | ||
1082 | # running if errors occur, instead of asking the user for help. | ||
1083 | # This option is also used when generating formulas in HTML. | ||
1084 | |||
1085 | LATEX_BATCHMODE = NO | ||
1086 | |||
1087 | # If LATEX_HIDE_INDICES is set to YES then doxygen will not | ||
1088 | # include the index chapters (such as File Index, Compound Index, etc.) | ||
1089 | # in the output. | ||
1090 | |||
1091 | LATEX_HIDE_INDICES = NO | ||
1092 | |||
1093 | # If LATEX_SOURCE_CODE is set to YES then doxygen will include | ||
1094 | # source code with syntax highlighting in the LaTeX output. | ||
1095 | # Note that which sources are shown also depends on other settings | ||
1096 | # such as SOURCE_BROWSER. | ||
1097 | |||
1098 | LATEX_SOURCE_CODE = NO | ||
1099 | |||
1100 | #--------------------------------------------------------------------------- | ||
1101 | # configuration options related to the RTF output | ||
1102 | #--------------------------------------------------------------------------- | ||
1103 | |||
1104 | # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output | ||
1105 | # The RTF output is optimized for Word 97 and may not look very pretty with | ||
1106 | # other RTF readers or editors. | ||
1107 | |||
1108 | GENERATE_RTF = NO | ||
1109 | |||
1110 | # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. | ||
1111 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be | ||
1112 | # put in front of it. If left blank `rtf' will be used as the default path. | ||
1113 | |||
1114 | RTF_OUTPUT = rtf | ||
1115 | |||
1116 | # If the COMPACT_RTF tag is set to YES Doxygen generates more compact | ||
1117 | # RTF documents. This may be useful for small projects and may help to | ||
1118 | # save some trees in general. | ||
1119 | |||
1120 | COMPACT_RTF = NO | ||
1121 | |||
1122 | # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated | ||
1123 | # will contain hyperlink fields. The RTF file will | ||
1124 | # contain links (just like the HTML output) instead of page references. | ||
1125 | # This makes the output suitable for online browsing using WORD or other | ||
1126 | # programs which support those fields. | ||
1127 | # Note: wordpad (write) and others do not support links. | ||
1128 | |||
1129 | RTF_HYPERLINKS = NO | ||
1130 | |||
1131 | # Load stylesheet definitions from file. Syntax is similar to doxygen's | ||
1132 | # config file, i.e. a series of assignments. You only have to provide | ||
1133 | # replacements, missing definitions are set to their default value. | ||
1134 | |||
1135 | RTF_STYLESHEET_FILE = | ||
1136 | |||
1137 | # Set optional variables used in the generation of an rtf document. | ||
1138 | # Syntax is similar to doxygen's config file. | ||
1139 | |||
1140 | RTF_EXTENSIONS_FILE = | ||
1141 | |||
1142 | #--------------------------------------------------------------------------- | ||
1143 | # configuration options related to the man page output | ||
1144 | #--------------------------------------------------------------------------- | ||
1145 | |||
1146 | # If the GENERATE_MAN tag is set to YES (the default) Doxygen will | ||
1147 | # generate man pages | ||
1148 | |||
1149 | GENERATE_MAN = NO | ||
1150 | |||
1151 | # The MAN_OUTPUT tag is used to specify where the man pages will be put. | ||
1152 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be | ||
1153 | # put in front of it. If left blank `man' will be used as the default path. | ||
1154 | |||
1155 | MAN_OUTPUT = man | ||
1156 | |||
1157 | # The MAN_EXTENSION tag determines the extension that is added to | ||
1158 | # the generated man pages (default is the subroutine's section .3) | ||
1159 | |||
1160 | MAN_EXTENSION = .3 | ||
1161 | |||
1162 | # If the MAN_LINKS tag is set to YES and Doxygen generates man output, | ||
1163 | # then it will generate one additional man file for each entity | ||
1164 | # documented in the real man page(s). These additional files | ||
1165 | # only source the real man page, but without them the man command | ||
1166 | # would be unable to find the correct page. The default is NO. | ||
1167 | |||
1168 | MAN_LINKS = NO | ||
1169 | |||
1170 | #--------------------------------------------------------------------------- | ||
1171 | # configuration options related to the XML output | ||
1172 | #--------------------------------------------------------------------------- | ||
1173 | |||
1174 | # If the GENERATE_XML tag is set to YES Doxygen will | ||
1175 | # generate an XML file that captures the structure of | ||
1176 | # the code including all documentation. | ||
1177 | |||
1178 | GENERATE_XML = NO | ||
1179 | |||
1180 | # The XML_OUTPUT tag is used to specify where the XML pages will be put. | ||
1181 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be | ||
1182 | # put in front of it. If left blank `xml' will be used as the default path. | ||
1183 | |||
1184 | XML_OUTPUT = xml | ||
1185 | |||
1186 | # The XML_SCHEMA tag can be used to specify an XML schema, | ||
1187 | # which can be used by a validating XML parser to check the | ||
1188 | # syntax of the XML files. | ||
1189 | |||
1190 | XML_SCHEMA = | ||
1191 | |||
1192 | # The XML_DTD tag can be used to specify an XML DTD, | ||
1193 | # which can be used by a validating XML parser to check the | ||
1194 | # syntax of the XML files. | ||
1195 | |||
1196 | XML_DTD = | ||
1197 | |||
1198 | # If the XML_PROGRAMLISTING tag is set to YES Doxygen will | ||
1199 | # dump the program listings (including syntax highlighting | ||
1200 | # and cross-referencing information) to the XML output. Note that | ||
1201 | # enabling this will significantly increase the size of the XML output. | ||
1202 | |||
1203 | XML_PROGRAMLISTING = YES | ||
1204 | |||
1205 | #--------------------------------------------------------------------------- | ||
1206 | # configuration options for the AutoGen Definitions output | ||
1207 | #--------------------------------------------------------------------------- | ||
1208 | |||
1209 | # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will | ||
1210 | # generate an AutoGen Definitions (see autogen.sf.net) file | ||
1211 | # that captures the structure of the code including all | ||
1212 | # documentation. Note that this feature is still experimental | ||
1213 | # and incomplete at the moment. | ||
1214 | |||
1215 | GENERATE_AUTOGEN_DEF = NO | ||
1216 | |||
1217 | #--------------------------------------------------------------------------- | ||
1218 | # configuration options related to the Perl module output | ||
1219 | #--------------------------------------------------------------------------- | ||
1220 | |||
1221 | # If the GENERATE_PERLMOD tag is set to YES Doxygen will | ||
1222 | # generate a Perl module file that captures the structure of | ||
1223 | # the code including all documentation. Note that this | ||
1224 | # feature is still experimental and incomplete at the | ||
1225 | # moment. | ||
1226 | |||
1227 | GENERATE_PERLMOD = NO | ||
1228 | |||
1229 | # If the PERLMOD_LATEX tag is set to YES Doxygen will generate | ||
1230 | # the necessary Makefile rules, Perl scripts and LaTeX code to be able | ||
1231 | # to generate PDF and DVI output from the Perl module output. | ||
1232 | |||
1233 | PERLMOD_LATEX = NO | ||
1234 | |||
1235 | # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be | ||
1236 | # nicely formatted so it can be parsed by a human reader. This is useful | ||
1237 | # if you want to understand what is going on. On the other hand, if this | ||
1238 | # tag is set to NO the size of the Perl module output will be much smaller | ||
1239 | # and Perl will parse it just the same. | ||
1240 | |||
1241 | PERLMOD_PRETTY = YES | ||
1242 | |||
1243 | # The names of the make variables in the generated doxyrules.make file | ||
1244 | # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. | ||
1245 | # This is useful so different doxyrules.make files included by the same | ||
1246 | # Makefile don't overwrite each other's variables. | ||
1247 | |||
1248 | PERLMOD_MAKEVAR_PREFIX = | ||
1249 | |||
1250 | #--------------------------------------------------------------------------- | ||
1251 | # Configuration options related to the preprocessor | ||
1252 | #--------------------------------------------------------------------------- | ||
1253 | |||
1254 | # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will | ||
1255 | # evaluate all C-preprocessor directives found in the sources and include | ||
1256 | # files. | ||
1257 | |||
1258 | ENABLE_PREPROCESSING = YES | ||
1259 | |||
1260 | # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro | ||
1261 | # names in the source code. If set to NO (the default) only conditional | ||
1262 | # compilation will be performed. Macro expansion can be done in a controlled | ||
1263 | # way by setting EXPAND_ONLY_PREDEF to YES. | ||
1264 | |||
1265 | MACRO_EXPANSION = YES | ||
1266 | |||
1267 | # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES | ||
1268 | # then the macro expansion is limited to the macros specified with the | ||
1269 | # PREDEFINED and EXPAND_AS_DEFINED tags. | ||
1270 | |||
1271 | EXPAND_ONLY_PREDEF = YES | ||
1272 | |||
1273 | # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files | ||
1274 | # in the INCLUDE_PATH (see below) will be search if a #include is found. | ||
1275 | |||
1276 | SEARCH_INCLUDES = YES | ||
1277 | |||
1278 | # The INCLUDE_PATH tag can be used to specify one or more directories that | ||
1279 | # contain include files that are not input files but should be processed by | ||
1280 | # the preprocessor. | ||
1281 | |||
1282 | INCLUDE_PATH = | ||
1283 | |||
1284 | # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard | ||
1285 | # patterns (like *.h and *.hpp) to filter out the header-files in the | ||
1286 | # directories. If left blank, the patterns specified with FILE_PATTERNS will | ||
1287 | # be used. | ||
1288 | |||
1289 | INCLUDE_FILE_PATTERNS = | ||
1290 | |||
1291 | # The PREDEFINED tag can be used to specify one or more macro names that | ||
1292 | # are defined before the preprocessor is started (similar to the -D option of | ||
1293 | # gcc). The argument of the tag is a list of macros of the form: name | ||
1294 | # or name=definition (no spaces). If the definition and the = are | ||
1295 | # omitted =1 is assumed. To prevent a macro definition from being | ||
1296 | # undefined via #undef or recursively expanded use the := operator | ||
1297 | # instead of the = operator. | ||
1298 | |||
1299 | PREDEFINED = DOXYGEN_SHOULD_IGNORE_THIS=1 \ | ||
1300 | SDL_DECLSPEC= \ | ||
1301 | SDL_DECLSPEC_TEMP= \ | ||
1302 | SDLCALL= \ | ||
1303 | _WIN32=1 | ||
1304 | |||
1305 | # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then | ||
1306 | # this tag can be used to specify a list of macro names that should be expanded. | ||
1307 | # The macro definition that is found in the sources will be used. | ||
1308 | # Use the PREDEFINED tag if you want to use a different macro definition. | ||
1309 | |||
1310 | EXPAND_AS_DEFINED = | ||
1311 | |||
1312 | # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then | ||
1313 | # doxygen's preprocessor will remove all function-like macros that are alone | ||
1314 | # on a line, have an all uppercase name, and do not end with a semicolon. Such | ||
1315 | # function macros are typically used for boiler-plate code, and will confuse | ||
1316 | # the parser if not removed. | ||
1317 | |||
1318 | SKIP_FUNCTION_MACROS = YES | ||
1319 | |||
1320 | #--------------------------------------------------------------------------- | ||
1321 | # Configuration::additions related to external references | ||
1322 | #--------------------------------------------------------------------------- | ||
1323 | |||
1324 | # The TAGFILES option can be used to specify one or more tagfiles. | ||
1325 | # Optionally an initial location of the external documentation | ||
1326 | # can be added for each tagfile. The format of a tag file without | ||
1327 | # this location is as follows: | ||
1328 | # TAGFILES = file1 file2 ... | ||
1329 | # Adding location for the tag files is done as follows: | ||
1330 | # TAGFILES = file1=loc1 "file2 = loc2" ... | ||
1331 | # where "loc1" and "loc2" can be relative or absolute paths or | ||
1332 | # URLs. If a location is present for each tag, the installdox tool | ||
1333 | # does not have to be run to correct the links. | ||
1334 | # Note that each tag file must have a unique name | ||
1335 | # (where the name does NOT include the path) | ||
1336 | # If a tag file is not located in the directory in which doxygen | ||
1337 | # is run, you must also specify the path to the tagfile here. | ||
1338 | |||
1339 | TAGFILES = | ||
1340 | |||
1341 | # When a file name is specified after GENERATE_TAGFILE, doxygen will create | ||
1342 | # a tag file that is based on the input files it reads. | ||
1343 | |||
1344 | GENERATE_TAGFILE = ./SDL.tag | ||
1345 | |||
1346 | # If the ALLEXTERNALS tag is set to YES all external classes will be listed | ||
1347 | # in the class index. If set to NO only the inherited external classes | ||
1348 | # will be listed. | ||
1349 | |||
1350 | ALLEXTERNALS = NO | ||
1351 | |||
1352 | # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed | ||
1353 | # in the modules index. If set to NO, only the current project's groups will | ||
1354 | # be listed. | ||
1355 | |||
1356 | EXTERNAL_GROUPS = YES | ||
1357 | |||
1358 | # The PERL_PATH should be the absolute path and name of the perl script | ||
1359 | # interpreter (i.e. the result of `which perl'). | ||
1360 | |||
1361 | PERL_PATH = c:\Perl\bin\perl.exe | ||
1362 | |||
1363 | #--------------------------------------------------------------------------- | ||
1364 | # Configuration options related to the dot tool | ||
1365 | #--------------------------------------------------------------------------- | ||
1366 | |||
1367 | # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will | ||
1368 | # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base | ||
1369 | # or super classes. Setting the tag to NO turns the diagrams off. Note that | ||
1370 | # this option is superseded by the HAVE_DOT option below. This is only a | ||
1371 | # fallback. It is recommended to install and use dot, since it yields more | ||
1372 | # powerful graphs. | ||
1373 | |||
1374 | CLASS_DIAGRAMS = YES | ||
1375 | |||
1376 | # You can define message sequence charts within doxygen comments using the \msc | ||
1377 | # command. Doxygen will then run the mscgen tool (see | ||
1378 | # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the | ||
1379 | # documentation. The MSCGEN_PATH tag allows you to specify the directory where | ||
1380 | # the mscgen tool resides. If left empty the tool is assumed to be found in the | ||
1381 | # default search path. | ||
1382 | |||
1383 | MSCGEN_PATH = | ||
1384 | |||
1385 | # If set to YES, the inheritance and collaboration graphs will hide | ||
1386 | # inheritance and usage relations if the target is undocumented | ||
1387 | # or is not a class. | ||
1388 | |||
1389 | HIDE_UNDOC_RELATIONS = YES | ||
1390 | |||
1391 | # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is | ||
1392 | # available from the path. This tool is part of Graphviz, a graph visualization | ||
1393 | # toolkit from AT&T and Lucent Bell Labs. The other options in this section | ||
1394 | # have no effect if this option is set to NO (the default) | ||
1395 | |||
1396 | HAVE_DOT = YES | ||
1397 | |||
1398 | # By default doxygen will write a font called FreeSans.ttf to the output | ||
1399 | # directory and reference it in all dot files that doxygen generates. This | ||
1400 | # font does not include all possible unicode characters however, so when you need | ||
1401 | # these (or just want a differently looking font) you can specify the font name | ||
1402 | # using DOT_FONTNAME. You need need to make sure dot is able to find the font, | ||
1403 | # which can be done by putting it in a standard location or by setting the | ||
1404 | # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory | ||
1405 | # containing the font. | ||
1406 | |||
1407 | DOT_FONTNAME = FreeSans | ||
1408 | |||
1409 | # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. | ||
1410 | # The default size is 10pt. | ||
1411 | |||
1412 | DOT_FONTSIZE = 10 | ||
1413 | |||
1414 | # By default doxygen will tell dot to use the output directory to look for the | ||
1415 | # FreeSans.ttf font (which doxygen will put there itself). If you specify a | ||
1416 | # different font using DOT_FONTNAME you can set the path where dot | ||
1417 | # can find it using this tag. | ||
1418 | |||
1419 | DOT_FONTPATH = | ||
1420 | |||
1421 | # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen | ||
1422 | # will generate a graph for each documented class showing the direct and | ||
1423 | # indirect inheritance relations. Setting this tag to YES will force the | ||
1424 | # the CLASS_DIAGRAMS tag to NO. | ||
1425 | |||
1426 | CLASS_GRAPH = YES | ||
1427 | |||
1428 | # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen | ||
1429 | # will generate a graph for each documented class showing the direct and | ||
1430 | # indirect implementation dependencies (inheritance, containment, and | ||
1431 | # class references variables) of the class with other documented classes. | ||
1432 | |||
1433 | COLLABORATION_GRAPH = YES | ||
1434 | |||
1435 | # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen | ||
1436 | # will generate a graph for groups, showing the direct groups dependencies | ||
1437 | |||
1438 | GROUP_GRAPHS = YES | ||
1439 | |||
1440 | # If the UML_LOOK tag is set to YES doxygen will generate inheritance and | ||
1441 | # collaboration diagrams in a style similar to the OMG's Unified Modeling | ||
1442 | # Language. | ||
1443 | |||
1444 | UML_LOOK = NO | ||
1445 | |||
1446 | # If set to YES, the inheritance and collaboration graphs will show the | ||
1447 | # relations between templates and their instances. | ||
1448 | |||
1449 | TEMPLATE_RELATIONS = YES | ||
1450 | |||
1451 | # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT | ||
1452 | # tags are set to YES then doxygen will generate a graph for each documented | ||
1453 | # file showing the direct and indirect include dependencies of the file with | ||
1454 | # other documented files. | ||
1455 | |||
1456 | INCLUDE_GRAPH = YES | ||
1457 | |||
1458 | # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and | ||
1459 | # HAVE_DOT tags are set to YES then doxygen will generate a graph for each | ||
1460 | # documented header file showing the documented files that directly or | ||
1461 | # indirectly include this file. | ||
1462 | |||
1463 | INCLUDED_BY_GRAPH = YES | ||
1464 | |||
1465 | # If the CALL_GRAPH and HAVE_DOT options are set to YES then | ||
1466 | # doxygen will generate a call dependency graph for every global function | ||
1467 | # or class method. Note that enabling this option will significantly increase | ||
1468 | # the time of a run. So in most cases it will be better to enable call graphs | ||
1469 | # for selected functions only using the \callgraph command. | ||
1470 | |||
1471 | CALL_GRAPH = NO | ||
1472 | |||
1473 | # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then | ||
1474 | # doxygen will generate a caller dependency graph for every global function | ||
1475 | # or class method. Note that enabling this option will significantly increase | ||
1476 | # the time of a run. So in most cases it will be better to enable caller | ||
1477 | # graphs for selected functions only using the \callergraph command. | ||
1478 | |||
1479 | CALLER_GRAPH = NO | ||
1480 | |||
1481 | # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen | ||
1482 | # will graphical hierarchy of all classes instead of a textual one. | ||
1483 | |||
1484 | GRAPHICAL_HIERARCHY = YES | ||
1485 | |||
1486 | # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES | ||
1487 | # then doxygen will show the dependencies a directory has on other directories | ||
1488 | # in a graphical way. The dependency relations are determined by the #include | ||
1489 | # relations between the files in the directories. | ||
1490 | |||
1491 | DIRECTORY_GRAPH = YES | ||
1492 | |||
1493 | # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images | ||
1494 | # generated by dot. Possible values are png, jpg, or gif | ||
1495 | # If left blank png will be used. | ||
1496 | |||
1497 | DOT_IMAGE_FORMAT = png | ||
1498 | |||
1499 | # The tag DOT_PATH can be used to specify the path where the dot tool can be | ||
1500 | # found. If left blank, it is assumed the dot tool can be found in the path. | ||
1501 | |||
1502 | DOT_PATH = | ||
1503 | |||
1504 | # The DOTFILE_DIRS tag can be used to specify one or more directories that | ||
1505 | # contain dot files that are included in the documentation (see the | ||
1506 | # \dotfile command). | ||
1507 | |||
1508 | DOTFILE_DIRS = | ||
1509 | |||
1510 | # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of | ||
1511 | # nodes that will be shown in the graph. If the number of nodes in a graph | ||
1512 | # becomes larger than this value, doxygen will truncate the graph, which is | ||
1513 | # visualized by representing a node as a red box. Note that doxygen if the | ||
1514 | # number of direct children of the root node in a graph is already larger than | ||
1515 | # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note | ||
1516 | # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. | ||
1517 | |||
1518 | DOT_GRAPH_MAX_NODES = 60 | ||
1519 | |||
1520 | # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the | ||
1521 | # graphs generated by dot. A depth value of 3 means that only nodes reachable | ||
1522 | # from the root by following a path via at most 3 edges will be shown. Nodes | ||
1523 | # that lay further from the root node will be omitted. Note that setting this | ||
1524 | # option to 1 or 2 may greatly reduce the computation time needed for large | ||
1525 | # code bases. Also note that the size of a graph can be further restricted by | ||
1526 | # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. | ||
1527 | |||
1528 | MAX_DOT_GRAPH_DEPTH = 2 | ||
1529 | |||
1530 | # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent | ||
1531 | # background. This is disabled by default, because dot on Windows does not | ||
1532 | # seem to support this out of the box. Warning: Depending on the platform used, | ||
1533 | # enabling this option may lead to badly anti-aliased labels on the edges of | ||
1534 | # a graph (i.e. they become hard to read). | ||
1535 | |||
1536 | DOT_TRANSPARENT = NO | ||
1537 | |||
1538 | # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output | ||
1539 | # files in one run (i.e. multiple -o and -T options on the command line). This | ||
1540 | # makes dot run faster, but since only newer versions of dot (>1.8.10) | ||
1541 | # support this, this feature is disabled by default. | ||
1542 | |||
1543 | DOT_MULTI_TARGETS = YES | ||
1544 | |||
1545 | # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will | ||
1546 | # generate a legend page explaining the meaning of the various boxes and | ||
1547 | # arrows in the dot generated graphs. | ||
1548 | |||
1549 | GENERATE_LEGEND = YES | ||
1550 | |||
1551 | # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will | ||
1552 | # remove the intermediate dot files that are used to generate | ||
1553 | # the various graphs. | ||
1554 | |||
1555 | DOT_CLEANUP = YES | ||
1556 | |||
1557 | #--------------------------------------------------------------------------- | ||
1558 | # Options related to the search engine | ||
1559 | #--------------------------------------------------------------------------- | ||
1560 | |||
1561 | # The SEARCHENGINE tag specifies whether or not a search engine should be | ||
1562 | # used. If set to NO the values of all tags below this one will be ignored. | ||
1563 | |||
1564 | SEARCHENGINE = NO | ||
diff --git a/src/contrib/SDL-3.2.20/docs/hello.c b/src/contrib/SDL-3.2.20/docs/hello.c new file mode 100644 index 0000000..a825ea1 --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/hello.c | |||
@@ -0,0 +1,68 @@ | |||
1 | /* | ||
2 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
3 | |||
4 | This software is provided 'as-is', without any express or implied | ||
5 | warranty. In no event will the authors be held liable for any damages | ||
6 | arising from the use of this software. | ||
7 | |||
8 | Permission is granted to anyone to use this software for any purpose, | ||
9 | including commercial applications, and to alter it and redistribute it | ||
10 | freely. | ||
11 | */ | ||
12 | #define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ | ||
13 | #include <SDL3/SDL.h> | ||
14 | #include <SDL3/SDL_main.h> | ||
15 | |||
16 | static SDL_Window *window = NULL; | ||
17 | static SDL_Renderer *renderer = NULL; | ||
18 | |||
19 | /* This function runs once at startup. */ | ||
20 | SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) | ||
21 | { | ||
22 | /* Create the window */ | ||
23 | if (!SDL_CreateWindowAndRenderer("Hello World", 800, 600, SDL_WINDOW_FULLSCREEN, &window, &renderer)) { | ||
24 | SDL_Log("Couldn't create window and renderer: %s", SDL_GetError()); | ||
25 | return SDL_APP_FAILURE; | ||
26 | } | ||
27 | return SDL_APP_CONTINUE; | ||
28 | } | ||
29 | |||
30 | /* This function runs when a new event (mouse input, keypresses, etc) occurs. */ | ||
31 | SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) | ||
32 | { | ||
33 | if (event->type == SDL_EVENT_KEY_DOWN || | ||
34 | event->type == SDL_EVENT_QUIT) { | ||
35 | return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ | ||
36 | } | ||
37 | return SDL_APP_CONTINUE; | ||
38 | } | ||
39 | |||
40 | /* This function runs once per frame, and is the heart of the program. */ | ||
41 | SDL_AppResult SDL_AppIterate(void *appstate) | ||
42 | { | ||
43 | const char *message = "Hello World!"; | ||
44 | int w = 0, h = 0; | ||
45 | float x, y; | ||
46 | const float scale = 4.0f; | ||
47 | |||
48 | /* Center the message and scale it up */ | ||
49 | SDL_GetRenderOutputSize(renderer, &w, &h); | ||
50 | SDL_SetRenderScale(renderer, scale, scale); | ||
51 | x = ((w / scale) - SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE * SDL_strlen(message)) / 2; | ||
52 | y = ((h / scale) - SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE) / 2; | ||
53 | |||
54 | /* Draw the message */ | ||
55 | SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); | ||
56 | SDL_RenderClear(renderer); | ||
57 | SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); | ||
58 | SDL_RenderDebugText(renderer, x, y, message); | ||
59 | SDL_RenderPresent(renderer); | ||
60 | |||
61 | return SDL_APP_CONTINUE; | ||
62 | } | ||
63 | |||
64 | /* This function runs once at shutdown. */ | ||
65 | void SDL_AppQuit(void *appstate, SDL_AppResult result) | ||
66 | { | ||
67 | } | ||
68 | |||
diff --git a/src/contrib/SDL-3.2.20/docs/release_checklist.md b/src/contrib/SDL-3.2.20/docs/release_checklist.md new file mode 100644 index 0000000..56fb23d --- /dev/null +++ b/src/contrib/SDL-3.2.20/docs/release_checklist.md | |||
@@ -0,0 +1,52 @@ | |||
1 | # Release checklist | ||
2 | |||
3 | * Run `build-scripts/create-release.py -R libsdl-org/SDL --ref <branch>` to do | ||
4 | a dry run creating the release assets. Verify that the archives are correct. | ||
5 | |||
6 | * Tag the release, e.g. `git tag release-3.8.0; git push --tags` | ||
7 | |||
8 | * Run `build-scripts/create-release.py -R libsdl-org/SDL --ref <release-tag>` | ||
9 | to have GitHub Actions create release assets. This makes sure the revision | ||
10 | string baked into the archives is correct. | ||
11 | |||
12 | * Verify that the source archive REVISION.txt has the correct release tag. | ||
13 | |||
14 | * Sign the source archives and upload everything to libsdl.org | ||
15 | |||
16 | * Create a GitHub release and attach the archives you just generated. | ||
17 | |||
18 | ## New feature release | ||
19 | |||
20 | * Update `WhatsNew.txt` | ||
21 | |||
22 | * Bump version number to 3.EVEN.0: | ||
23 | |||
24 | * `./build-scripts/update-version.sh 3 EVEN 0` | ||
25 | |||
26 | * Do the release | ||
27 | |||
28 | * Immediately create a branch for patch releases, e.g. `git branch release-3.EVEN.x` | ||
29 | |||
30 | * Bump version number from 3.EVEN.0 to 3.(EVEN+1).0 | ||
31 | |||
32 | * `./build-scripts/update-version.sh 3 EVEN+1 0` | ||
33 | |||
34 | * Update the website file include/header.inc.php to reflect the new version | ||
35 | |||
36 | ## New bugfix release | ||
37 | |||
38 | * Bump version number from 3.Y.Z to 3.Y.(Z+1) (Y is even) | ||
39 | |||
40 | * `./build-scripts/update-version.sh 3 Y Z+1` | ||
41 | |||
42 | * Do the release | ||
43 | |||
44 | * Update the website file include/header.inc.php to reflect the new version | ||
45 | |||
46 | ## New development prerelease | ||
47 | |||
48 | * Bump version number from 3.Y.Z to 3.Y.(Z+1) (Y is odd) | ||
49 | |||
50 | * `./build-scripts/update-version.sh 3 Y Z+1` | ||
51 | |||
52 | * Do the release | ||