From 60127460b0364001222e4eb06d63560c5ac61b00 Mon Sep 17 00:00:00 2001 From: SDL Wiki Bot Date: Tue, 28 Feb 2023 17:30:22 +0000 Subject: [PATCH] Sync SDL3 wiki -> header --- docs/README-.md | 12 +- docs/README-android.md | 28 +- docs/README-cmake.md | 4 +- docs/README-dynapi.md | 108 +- docs/README-gdk.md | 306 ++--- docs/README-git.md | 38 +- docs/README-hg.md | 14 +- docs/README-ios.md | 22 +- docs/README-kmsbsd.md | 54 +- docs/README-linux.md | 184 +-- docs/README-macos.md | 14 +- docs/README-migration.md | 2170 ++++++++++++++++++------------------ docs/README-ngage.md | 88 +- docs/README-ps2.md | 2 +- docs/README-psp.md | 2 +- docs/README-raspberrypi.md | 40 +- docs/README-riscos.md | 70 +- docs/README-touch.md | 2 +- docs/README-versions.md | 120 +- docs/README-visualc.md | 226 ++-- docs/README-vita.md | 66 +- docs/README-windows.md | 116 +- docs/README-winrt.md | 130 +-- 23 files changed, 1908 insertions(+), 1908 deletions(-) diff --git a/docs/README-.md b/docs/README-.md index 32fbd0941..0c0235e64 100644 --- a/docs/README-.md +++ b/docs/README-.md @@ -1,6 +1,6 @@ -# - - -- [raspberrypi](raspberrypi) - - +# + + +- [raspberrypi](raspberrypi) + + diff --git a/docs/README-android.md b/docs/README-android.md index 01a79d8ed..3b8406a3a 100644 --- a/docs/README-android.md +++ b/docs/README-android.md @@ -23,9 +23,9 @@ How the port works ================================================================================ - Android applications are Java-based, optionally with parts written in C -- As SDL apps are C-based, we use a small Java shim that uses JNI to talk to +- As SDL apps are C-based, we use a small Java shim that uses JNI to talk to the SDL library -- This means that your application C code must be placed inside an Android +- This means that your application C code must be placed inside an Android Java project, along with some C support code that communicates with Java - This eventually produces a standard Android .apk package @@ -66,7 +66,7 @@ done in the build directory for the app! For more complex projects, follow these instructions: - + 1. Copy the android-project directory wherever you want to keep your projects and rename it to the name of your project. 2. Move or symlink this SDL directory into the "/app/jni" directory @@ -129,15 +129,15 @@ Here's an example of a minimal class file: --- MyGame.java -------------------------- package com.gamemaker.game; - - import org.libsdl.app.SDLActivity; - + + import org.libsdl.app.SDLActivity; + /** - * A sample wrapper class that just calls SDLActivity - */ - + * A sample wrapper class that just calls SDLActivity + */ + public class MyGame extends SDLActivity { } - + ------------------------------------------ Then replace "SDLActivity" in AndroidManifest.xml with the name of your @@ -176,7 +176,7 @@ may want to keep this fact in mind when building your APK, specially when large files are involved. For more information on which extensions get compressed by default and how to disable this behaviour, see for example: - + http://ponystyle.com/blog/2010/03/26/dealing-with-asset-compression-in-android-apps/ @@ -347,7 +347,7 @@ I get output from addr2line showing that it's in the quit function, in testsprit You can add logging to your code to help show what's happening: #include - + __android_log_print(ANDROID_LOG_INFO, "foo", "Something happened! x = %d", x); If you need to build without optimization turned on, you can create a file called @@ -437,7 +437,7 @@ where you only update a portion of the screen on each frame, you may notice a variety of visual glitches on Android, that are not present on other platforms. This is caused by SDL's use of EGL as the support system to handle OpenGL ES/ES2 contexts, in particular the use of the eglSwapBuffers function. As stated in the -documentation for the function "The contents of ancillary buffers are always +documentation for the function "The contents of ancillary buffers are always undefined after calling eglSwapBuffers". Setting the EGL_SWAP_BEHAVIOR attribute of the surface to EGL_BUFFER_PRESERVED is not possible for SDL as it requires EGL 1.4, available only on the API level @@ -456,7 +456,7 @@ Two legitimate ways: Activity by calling Activity.finish(). - Android OS can decide to terminate your application by calling onDestroy() -(see Activity life cycle). Your application will receive an SDL_EVENT_QUIT you +(see Activity life cycle). Your application will receive an SDL_EVENT_QUIT you can handle to save things and quit. Don't call exit() as it stops the activity badly. diff --git a/docs/README-cmake.md b/docs/README-cmake.md index 39787b5f9..8e368386f 100644 --- a/docs/README-cmake.md +++ b/docs/README-cmake.md @@ -18,7 +18,7 @@ The CMake build system is supported on the following platforms: ## Building SDL -Assuming the source for SDL is located at `~/sdl`. +Assuming the source for SDL is located at `~/sdl`. ```sh cmake -S ~/sdl -B ~/build cmake --build ~/build @@ -55,7 +55,7 @@ else() find_package(SDL3 REQUIRED CONFIG REQUIRED COMPONENTS SDL3) endif() -# Create your game executable target as usual +# Create your game executable target as usual add_executable(mygame WIN32 mygame.c) # Link to the actual SDL3 library. SDL3::SDL3 is the shared SDL library, SDL3::SDL3-static is the static SDL libarary. diff --git a/docs/README-dynapi.md b/docs/README-dynapi.md index 6fcf9fea1..a0f341244 100644 --- a/docs/README-dynapi.md +++ b/docs/README-dynapi.md @@ -4,29 +4,29 @@ Originally posted on Ryan's Google+ account. Background: -- The Steam Runtime has (at least in theory) a really kick-ass build of SDL, - but developers are shipping their own SDL with individual Steam games. - These games might stop getting updates, but a newer SDL might be needed later. - Certainly we'll always be fixing bugs in SDL, even if a new video target isn't +- The Steam Runtime has (at least in theory) a really kick-ass build of SDL, + but developers are shipping their own SDL with individual Steam games. + These games might stop getting updates, but a newer SDL might be needed later. + Certainly we'll always be fixing bugs in SDL, even if a new video target isn't ever needed, and these fixes won't make it to a game shipping its own SDL. -- Even if we replace the SDL in those games with a compatible one, that is to - say, edit a developer's Steam depot (yuck!), there are developers that are - statically linking SDL that we can't do this for. We can't even force the +- Even if we replace the SDL in those games with a compatible one, that is to + say, edit a developer's Steam depot (yuck!), there are developers that are + statically linking SDL that we can't do this for. We can't even force the dynamic loader to ignore their SDL in this case, of course. - If you don't ship an SDL with the game in some form, people that disabled the - Steam Runtime, or just tried to run the game from the command line instead of + Steam Runtime, or just tried to run the game from the command line instead of Steam might find themselves unable to run the game, due to a missing dependency. - If you want to ship on non-Steam platforms like GOG or Humble Bundle, or target - generic Linux boxes that may or may not have SDL installed, you have to ship - the library or risk a total failure to launch. So now, you might have to have - a non-Steam build plus a Steam build (that is, one with and one without SDL - included), which is inconvenient if you could have had one universal build + generic Linux boxes that may or may not have SDL installed, you have to ship + the library or risk a total failure to launch. So now, you might have to have + a non-Steam build plus a Steam build (that is, one with and one without SDL + included), which is inconvenient if you could have had one universal build that works everywhere. -- We like the zlib license, but the biggest complaint from the open source - community about the license change is the static linking. The LGPL forced this +- We like the zlib license, but the biggest complaint from the open source + community about the license change is the static linking. The LGPL forced this as a legal, not technical issue, but zlib doesn't care. Even those that aren't - concerned about the GNU freedoms found themselves solving the same problems: - swapping in a newer SDL to an older game often times can save the day. + concerned about the GNU freedoms found themselves solving the same problems: + swapping in a newer SDL to an older game often times can save the day. Static linking stops this dead. So here's what we did: @@ -45,7 +45,7 @@ Except that is all done with a bunch of macro magic so we don't have to maintain every one of these. What is jump_table.SDL_init()? Eventually, that's a function pointer of the real -SDL_Init() that you've been calling all this time. But at startup, it looks more +SDL_Init() that you've been calling all this time. But at startup, it looks more like this: ```c @@ -56,12 +56,12 @@ Uint32 SDL_Init_DEFAULT(Uint32 flags) } ``` -SDL_InitDynamicAPI() fills in jump_table with all the actual SDL function -pointers, which means that this `_DEFAULT` function never gets called again. +SDL_InitDynamicAPI() fills in jump_table with all the actual SDL function +pointers, which means that this `_DEFAULT` function never gets called again. First call to any SDL function sets the whole thing up. So you might be asking, what was the value in that? Isn't this what the operating -system's dynamic loader was supposed to do for us? Yes, but now we've got this +system's dynamic loader was supposed to do for us? Yes, but now we've got this level of indirection, we can do things like this: ```bash @@ -69,34 +69,34 @@ export SDL3_DYNAMIC_API=/my/actual/libSDL3.so.0 ./MyGameThatIsStaticallyLinkedToSDL ``` -And now, this game that is statically linked to SDL, can still be overridden -with a newer, or better, SDL. The statically linked one will only be used as +And now, this game that is statically linked to SDL, can still be overridden +with a newer, or better, SDL. The statically linked one will only be used as far as calling into the jump table in this case. But in cases where no override -is desired, the statically linked version will provide its own jump table, +is desired, the statically linked version will provide its own jump table, and everyone is happy. So now: -- Developers can statically link SDL, and users can still replace it. +- Developers can statically link SDL, and users can still replace it. (We'd still rather you ship a shared library, though!) -- Developers can ship an SDL with their game, Valve can override it for, say, - new features on SteamOS, or distros can override it for their own needs, +- Developers can ship an SDL with their game, Valve can override it for, say, + new features on SteamOS, or distros can override it for their own needs, but it'll also just work in the default case. -- Developers can ship the same package to everyone (Humble Bundle, GOG, etc), +- Developers can ship the same package to everyone (Humble Bundle, GOG, etc), and it'll do the right thing. -- End users (and Valve) can update a game's SDL in almost any case, +- End users (and Valve) can update a game's SDL in almost any case, to keep abandoned games running on newer platforms. -- Everyone develops with SDL exactly as they have been doing all along. +- Everyone develops with SDL exactly as they have been doing all along. Same headers, same ABI. Just get the latest version to enable this magic. A little more about SDL_InitDynamicAPI(): -Internally, InitAPI does some locking to make sure everything waits until a -single thread initializes everything (although even SDL_CreateThread() goes +Internally, InitAPI does some locking to make sure everything waits until a +single thread initializes everything (although even SDL_CreateThread() goes through here before spinning a thread, too), and then decides if it should use -an external SDL library. If not, it sets up the jump table using the current +an external SDL library. If not, it sets up the jump table using the current SDL's function pointers (which might be statically linked into a program, or in -a shared library of its own). If so, it loads that library and looks for and +a shared library of its own). If so, it loads that library and looks for and calls a single function: ```c @@ -104,35 +104,35 @@ SInt32 SDL_DYNAPI_entry(Uint32 version, void *table, Uint32 tablesize); ``` That function takes a version number (more on that in a moment), the address of -the jump table, and the size, in bytes, of the table. -Now, we've got policy here: this table's layout never changes; new stuff gets -added to the end. Therefore SDL_DYNAPI_entry() knows that it can provide all +the jump table, and the size, in bytes, of the table. +Now, we've got policy here: this table's layout never changes; new stuff gets +added to the end. Therefore SDL_DYNAPI_entry() knows that it can provide all the needed functions if tablesize <= sizeof its own jump table. If tablesize is bigger (say, SDL 3.0.4 is trying to load SDL 3.0.3), then we know to abort, but if it's smaller, we know we can provide the entire API that the caller needs. -The version variable is a failsafe switch. -Right now it's always 1. This number changes when there are major API changes -(so we know if the tablesize might be smaller, or entries in it have changed). -Right now SDL_DYNAPI_entry gives up if the version doesn't match, but it's not -inconceivable to have a small dispatch library that only supplies this one +The version variable is a failsafe switch. +Right now it's always 1. This number changes when there are major API changes +(so we know if the tablesize might be smaller, or entries in it have changed). +Right now SDL_DYNAPI_entry gives up if the version doesn't match, but it's not +inconceivable to have a small dispatch library that only supplies this one function and loads different, otherwise-incompatible SDL libraries and has the -right one initialize the jump table based on the version. For something that -must generically catch lots of different versions of SDL over time, like the +right one initialize the jump table based on the version. For something that +must generically catch lots of different versions of SDL over time, like the Steam Client, this isn't a bad option. Finally, I'm sure some people are reading this and thinking, -"I don't want that overhead in my project!" +"I don't want that overhead in my project!" -To which I would point out that the extra function call through the jump table -probably wouldn't even show up in a profile, but lucky you: this can all be -disabled. You can build SDL without this if you absolutely must, but we would -encourage you not to do that. However, on heavily locked down platforms like +To which I would point out that the extra function call through the jump table +probably wouldn't even show up in a profile, but lucky you: this can all be +disabled. You can build SDL without this if you absolutely must, but we would +encourage you not to do that. However, on heavily locked down platforms like iOS, or maybe when debugging, it makes sense to disable it. The way this is -designed in SDL, you just have to change one #define, and the entire system -vaporizes out, and SDL functions exactly like it always did. Most of it is -macro magic, so the system is contained to one C file and a few headers. -However, this is on by default and you have to edit a header file to turn it -off. Our hopes is that if we make it easy to disable, but not too easy, -everyone will ultimately be able to get what they want, but we've gently +designed in SDL, you just have to change one #define, and the entire system +vaporizes out, and SDL functions exactly like it always did. Most of it is +macro magic, so the system is contained to one C file and a few headers. +However, this is on by default and you have to edit a header file to turn it +off. Our hopes is that if we make it easy to disable, but not too easy, +everyone will ultimately be able to get what they want, but we've gently nudged everyone towards what we think is the best solution. diff --git a/docs/README-gdk.md b/docs/README-gdk.md index d6ce856fc..a785e6530 100644 --- a/docs/README-gdk.md +++ b/docs/README-gdk.md @@ -1,153 +1,153 @@ -GDK -===== - -This port allows SDL applications to run via Microsoft's Game Development Kit (GDK). - -Windows (GDK) and Xbox One/Xbox Series (GDKX) are supported. Although most of the Xbox code is included in the public SDL source code, NDA access is required for a small number of source files. If you have access to GDKX, these required Xbox files are posted on the GDK forums [here](https://forums.xboxlive.com/questions/130003/). - - -Requirements ------------- - -* Microsoft Visual Studio 2022 (in theory, it should also work in 2017 or 2019, but this has not been tested) -* Microsoft GDK June 2022 or newer (public release [here](https://github.com/microsoft/GDK/releases/tag/June_2022)) -* 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 identifiers used by the GDK test programs in the included solution will work. - - -Windows GDK Status ------- - -The Windows GDK port supports the full set of Win32 APIs, renderers, controllers, input devices, etc., as the normal Windows x64 build of SDL. - -* Additionally, the GDK port adds the following: - * Compile-time platform detection for SDL programs. The `__GDK__` is `#define`d on every GDK platform, and the `__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.) - * GDK-specific setup: - * Initializing/uninitializing the game runtime, and initializing Xbox Live services - * 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. - - * 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 `. - * Global task queue callbacks are dispatched during `SDL_PumpEvents` (which is also called internally if using `SDL_PollEvent`). - * You can get the handle of the global task queue through `SDL_GDKGetTaskQueue`, if needed. When done with the queue, be sure to use `XTaskQueueCloseHandle` to decrement the reference count (otherwise it will cause a resource leak). - -* What doesn't work: - * Compilation with anything other than through the included Visual C++ solution file - -## VisualC-GDK Solution - -The included `VisualC-GDK/SDL.sln` solution includes the following targets for the Gaming.Desktop.x64 configuration: - -* SDL3 (DLL) - This is the typical SDL3.dll, but for Gaming.Desktop.x64. -* tests/testgamecontroller - Standard SDL test program demonstrating controller functionality. -* tests/testgdk - GDK-specific test program that demonstrates using the global task queue to login a user into Xbox Live. - *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. -* tests/testsprite - Standard SDL test program demonstrating sprite drawing functionality. - -If you set one of the test programs as a startup project, you can run it directly from Visual Studio. - -Windows GDK Setup, Detailed Steps ---------------------- - -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. - -### 1. Add a Gaming.Desktop.x64 Configuration ### - -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. - -### 2. Build SDL3 for GDK ### - -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. - -*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. - -### 3. Configuring Project Settings ### - -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: - -* Under C/C++ > General > Additional Include Directories, make sure the `SDL/include` path is referenced -* Under Linker > General > Additional Library Directories, make sure to reference the path where the newly-built SDL3.lib are -* Under Linker > Input > Additional Dependencies, you need the following: - * `SDL3.lib` - * `xgameruntime.lib` - * `../Microsoft.Xbox.Services.141.GDK.C.Thunks.lib` -* 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. - -### 4. Setting up SDL_main ### - -Rather than using your own implementation of `WinMain`, it's recommended that you instead `#include ` 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 - -### 5. Required DLLs ### - -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: - -* Your SDL3.dll -* "$(Console_GRDKExtLibRoot)Xbox.Services.API.C\DesignTime\CommonConfiguration\Neutral\Lib\Release\Microsoft.Xbox.Services.141.GDK.C.Thunks.dll" -* XCurl.dll - -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. - -### 6. Setting up MicrosoftGame.config ### - -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. - -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. - -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. - -Then, you need to set the following values to the values from Partner Center: - -* Identity tag - Name and Publisher attributes -* TitleId -* MSAAppId - -### 7. Adding Required Logos - -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. - - -### 8. Copying any Data Files ### - -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. - - -### 9. Build and Run from Visual Studio ### - -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. - -If you are testing Xbox Live functionality, it's likely you will need to change to the Sandbox for your title. To do this: - -1. Run "Desktop VS 2022 Gaming Command Prompt" from the Start Menu -2. Switch the sandbox name with: - `XblPCSandbox SANDBOX.#` -3. (To switch back to the retail sandbox): - `XblPCSandbox RETAIL` - -### 10. Packaging and Installing Locally - -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. - -To create the package: - -1. Run "Desktop VS 2022 Gaming Command Prompt" from the Start Menu -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) -3. `mkdir Package` to create an output directory -4. To package the file into the `Package` directory, use: - `makepkg pack /f PackageLayout.xml /lt /d . /nogameos /pc /pd Package` -5. To install the package, use: - `wdapp install PACKAGENAME.msixvc` -6. Once the package is installed, you can run it from the start menu. -7. As with when running from Visual Studio, if you need to test any Xbox Live functionality you must switch to the correct sandbox. - - -Troubleshooting ---------------- - -#### Xbox Live Login does not work - -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. - -Furthermore, confirm that your PC is set to the correct sandbox. - - -#### "The current user has already installed an unpackaged version of this app. A packaged version cannot replace this." error when installing - -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). +GDK +===== + +This port allows SDL applications to run via Microsoft's Game Development Kit (GDK). + +Windows (GDK) and Xbox One/Xbox Series (GDKX) are supported. Although most of the Xbox code is included in the public SDL source code, NDA access is required for a small number of source files. If you have access to GDKX, these required Xbox files are posted on the GDK forums [here](https://forums.xboxlive.com/questions/130003/). + + +Requirements +------------ + +* Microsoft Visual Studio 2022 (in theory, it should also work in 2017 or 2019, but this has not been tested) +* Microsoft GDK June 2022 or newer (public release [here](https://github.com/microsoft/GDK/releases/tag/June_2022)) +* 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 identifiers used by the GDK test programs in the included solution will work. + + +Windows GDK Status +------ + +The Windows GDK port supports the full set of Win32 APIs, renderers, controllers, input devices, etc., as the normal Windows x64 build of SDL. + +* Additionally, the GDK port adds the following: + * Compile-time platform detection for SDL programs. The `__GDK__` is `#define`d on every GDK platform, and the `__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.) + * GDK-specific setup: + * Initializing/uninitializing the game runtime, and initializing Xbox Live services + * 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. + + * 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 `. + * Global task queue callbacks are dispatched during `SDL_PumpEvents` (which is also called internally if using `SDL_PollEvent`). + * You can get the handle of the global task queue through `SDL_GDKGetTaskQueue`, if needed. When done with the queue, be sure to use `XTaskQueueCloseHandle` to decrement the reference count (otherwise it will cause a resource leak). + +* What doesn't work: + * Compilation with anything other than through the included Visual C++ solution file + +## VisualC-GDK Solution + +The included `VisualC-GDK/SDL.sln` solution includes the following targets for the Gaming.Desktop.x64 configuration: + +* SDL3 (DLL) - This is the typical SDL3.dll, but for Gaming.Desktop.x64. +* tests/testgamecontroller - Standard SDL test program demonstrating controller functionality. +* tests/testgdk - GDK-specific test program that demonstrates using the global task queue to login a user into Xbox Live. + *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. +* tests/testsprite - Standard SDL test program demonstrating sprite drawing functionality. + +If you set one of the test programs as a startup project, you can run it directly from Visual Studio. + +Windows GDK Setup, Detailed Steps +--------------------- + +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. + +### 1. Add a Gaming.Desktop.x64 Configuration ### + +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. + +### 2. Build SDL3 for GDK ### + +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. + +*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. + +### 3. Configuring Project Settings ### + +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: + +* Under C/C++ > General > Additional Include Directories, make sure the `SDL/include` path is referenced +* Under Linker > General > Additional Library Directories, make sure to reference the path where the newly-built SDL3.lib are +* Under Linker > Input > Additional Dependencies, you need the following: + * `SDL3.lib` + * `xgameruntime.lib` + * `../Microsoft.Xbox.Services.141.GDK.C.Thunks.lib` +* 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. + +### 4. Setting up SDL_main ### + +Rather than using your own implementation of `WinMain`, it's recommended that you instead `#include ` 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 + +### 5. Required DLLs ### + +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: + +* Your SDL3.dll +* "$(Console_GRDKExtLibRoot)Xbox.Services.API.C\DesignTime\CommonConfiguration\Neutral\Lib\Release\Microsoft.Xbox.Services.141.GDK.C.Thunks.dll" +* XCurl.dll + +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. + +### 6. Setting up MicrosoftGame.config ### + +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. + +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. + +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. + +Then, you need to set the following values to the values from Partner Center: + +* Identity tag - Name and Publisher attributes +* TitleId +* MSAAppId + +### 7. Adding Required Logos + +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. + + +### 8. Copying any Data Files ### + +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. + + +### 9. Build and Run from Visual Studio ### + +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. + +If you are testing Xbox Live functionality, it's likely you will need to change to the Sandbox for your title. To do this: + +1. Run "Desktop VS 2022 Gaming Command Prompt" from the Start Menu +2. Switch the sandbox name with: + `XblPCSandbox SANDBOX.#` +3. (To switch back to the retail sandbox): + `XblPCSandbox RETAIL` + +### 10. Packaging and Installing Locally + +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. + +To create the package: + +1. Run "Desktop VS 2022 Gaming Command Prompt" from the Start Menu +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) +3. `mkdir Package` to create an output directory +4. To package the file into the `Package` directory, use: + `makepkg pack /f PackageLayout.xml /lt /d . /nogameos /pc /pd Package` +5. To install the package, use: + `wdapp install PACKAGENAME.msixvc` +6. Once the package is installed, you can run it from the start menu. +7. As with when running from Visual Studio, if you need to test any Xbox Live functionality you must switch to the correct sandbox. + + +Troubleshooting +--------------- + +#### Xbox Live Login does not work + +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. + +Furthermore, confirm that your PC is set to the correct sandbox. + + +#### "The current user has already installed an unpackaged version of this app. A packaged version cannot replace this." error when installing + +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/docs/README-git.md b/docs/README-git.md index 3f03488ae..fd12fd9f6 100644 --- a/docs/README-git.md +++ b/docs/README-git.md @@ -1,19 +1,19 @@ -git -========= - -The latest development version of SDL is available via git. -Git allows you to get up-to-the-minute fixes and enhancements; -as a developer works on a source tree, you can use "git" to mirror that -source tree instead of waiting for an official release. Please look -at the Git website ( https://git-scm.com/ ) for more -information on using git, where you can also download software for -macOS, Windows, and Unix systems. - - git clone https://github.com/libsdl-org/SDL - -If you are building SDL via configure, you will need to run autogen.sh -before running configure. - -There is a web interface to the Git repository at: - http://github.com/libsdl-org/SDL/ - +git +========= + +The latest development version of SDL is available via git. +Git allows you to get up-to-the-minute fixes and enhancements; +as a developer works on a source tree, you can use "git" to mirror that +source tree instead of waiting for an official release. Please look +at the Git website ( https://git-scm.com/ ) for more +information on using git, where you can also download software for +macOS, Windows, and Unix systems. + + git clone https://github.com/libsdl-org/SDL + +If you are building SDL via configure, you will need to run autogen.sh +before running configure. + +There is a web interface to the Git repository at: + http://github.com/libsdl-org/SDL/ + diff --git a/docs/README-hg.md b/docs/README-hg.md index b42aaa5b2..bd4e67263 100644 --- a/docs/README-hg.md +++ b/docs/README-hg.md @@ -1,7 +1,7 @@ -Mercurial -====== - -We are no longer hosted in Mercurial. Please see README-git.md for details. - -Thanks! - +Mercurial +====== + +We are no longer hosted in Mercurial. Please see README-git.md for details. + +Thanks! + diff --git a/docs/README-ios.md b/docs/README-ios.md index 3cdb81e81..715d337ea 100644 --- a/docs/README-ios.md +++ b/docs/README-ios.md @@ -109,17 +109,17 @@ e.g. return 1; } } - + int main(int argc, char *argv[]) { SDL_SetEventFilter(HandleAppEvents, NULL); - + ... run your main loop - + return 0; } - + Notes -- Accelerometer as Joystick ============================================================================== @@ -183,7 +183,7 @@ Once your application is installed its directory tree looks like: Preferences/ tmp/ -When your SDL based iPhone application starts up, it sets the working directory to the main bundle (MySDLApp Home/MySDLApp.app), where your application resources are stored. You cannot write to this directory. Instead, I advise you to write document files to "../Documents/" and preferences to "../Library/Preferences". +When your SDL based iPhone application starts up, it sets the working directory to the main bundle (MySDLApp Home/MySDLApp.app), where your application resources are stored. You cannot write to this directory. Instead, I advise you to write document files to "../Documents/" and preferences to "../Library/Preferences". More information on this subject is available here: http://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Introduction/Introduction.html @@ -192,7 +192,7 @@ http://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOS Notes -- xcFramework ============================================================================== -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. +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. 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. @@ -204,7 +204,7 @@ In addition, on Apple platforms, main() cannot be in a dynamically loaded librar 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. This means that iOS apps which used the statically-linked libSDL3.lib and now link with the xcframwork can just `#include ` 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. -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: +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: #include "SDL_main.h" #include @@ -240,7 +240,7 @@ to your Info.plist: MyApp would like to remain connected to nearby bluetooth Game Controllers and Game Pads even when you're not using the app. -Game Center +Game Center ============================================================================== 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: @@ -256,15 +256,15 @@ e.g. { ... do event handling, frame logic and rendering ... } - + int main(int argc, char *argv[]) { ... initialize game ... - + #ifdef __IOS__ // Initialize the Game Center for scoring and matchmaking InitGameCenter(); - + // Set up the game to run in the window animation callback on iOS // so that Game Center and so forth works correctly. SDL_iPhoneSetAnimationCallback(window, 1, ShowFrame, NULL); diff --git a/docs/README-kmsbsd.md b/docs/README-kmsbsd.md index 760481707..1bd6d0fdb 100644 --- a/docs/README-kmsbsd.md +++ b/docs/README-kmsbsd.md @@ -1,27 +1,27 @@ -KMSDRM on *BSD -================================================== - -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. - -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. - -OpenBSD note: Note that the video backend assumes that the user has read/write permissions to the /dev/drm* devices. - - -SDL WSCONS input backend features -=================================================== -1. It is keymap-aware; it will work properly with different keymaps. -2. It has mouse support. -3. Accent input is supported. -4. Compose keys are supported. -5. AltGr and Meta Shift keys work as intended. - -Partially working or no input on OpenBSD/NetBSD. -================================================== - -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. - -Partially working or no input on FreeBSD. -================================================== - -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. +KMSDRM on *BSD +================================================== + +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. + +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. + +OpenBSD note: Note that the video backend assumes that the user has read/write permissions to the /dev/drm* devices. + + +SDL WSCONS input backend features +=================================================== +1. It is keymap-aware; it will work properly with different keymaps. +2. It has mouse support. +3. Accent input is supported. +4. Compose keys are supported. +5. AltGr and Meta Shift keys work as intended. + +Partially working or no input on OpenBSD/NetBSD. +================================================== + +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. + +Partially working or no input on FreeBSD. +================================================== + +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/docs/README-linux.md b/docs/README-linux.md index e162478b8..ea354e95f 100644 --- a/docs/README-linux.md +++ b/docs/README-linux.md @@ -1,92 +1,92 @@ -Linux -================================================================================ - -By default SDL will only link against glibc, the rest of the features will be -enabled dynamically at runtime depending on the available features on the target -system. So, for example if you built SDL with XRandR support and the target -system does not have the XRandR libraries installed, it will be disabled -at runtime, and you won't get a missing library error, at least with the -default configuration parameters. - - -Build Dependencies --------------------------------------------------------------------------------- - -Ubuntu 18.04, all available features enabled: - - sudo apt-get install build-essential git make \ - pkg-config cmake ninja-build gnome-desktop-testing libasound2-dev libpulse-dev \ - libaudio-dev libjack-dev libsndio-dev libsamplerate0-dev libx11-dev libxext-dev \ - libxrandr-dev libxcursor-dev libxfixes-dev libxi-dev libxss-dev \ - libxkbcommon-dev libdrm-dev libgbm-dev libgl1-mesa-dev libgles2-mesa-dev \ - libegl1-mesa-dev libdbus-1-dev libibus-1.0-dev libudev-dev fcitx-libs-dev - -Ubuntu 22.04+ can also add `libpipewire-0.3-dev libwayland-dev libdecor-0-dev` to that command line. - -Fedora 35, all available features enabled: - - sudo yum install gcc git-core make cmake \ - alsa-lib-devel pulseaudio-libs-devel nas-devel pipewire-devel \ - libX11-devel libXext-devel libXrandr-devel libXcursor-devel libXfixes-devel \ - libXi-devel libXScrnSaver-devel dbus-devel ibus-devel fcitx-devel \ - systemd-devel mesa-libGL-devel libxkbcommon-devel mesa-libGLES-devel \ - mesa-libEGL-devel vulkan-devel wayland-devel wayland-protocols-devel \ - libdrm-devel mesa-libgbm-devel libusb-devel libdecor-devel \ - libsamplerate-devel pipewire-jack-audio-connection-kit-devel \ - -NOTES: -- The sndio audio target is unavailable on Fedora (but probably not what you - should want to use anyhow). -- libsamplerate0-dev lets SDL optionally link to libresamplerate at runtime - for higher-quality audio resampling. SDL will work without it if the library - is missing, so it's safe to build in support even if the end user doesn't - have this library installed. - - -Joystick does not work --------------------------------------------------------------------------------- - -If you compiled or are using a version of SDL with udev support (and you should!) -there's a few issues that may cause SDL to fail to detect your joystick. To -debug this, start by installing the evtest utility. On Ubuntu/Debian: - - sudo apt-get install evtest - -Then run: - - sudo evtest - -You'll hopefully see your joystick listed along with a name like "/dev/input/eventXX" -Now run: - - cat /dev/input/event/XX - -If you get a permission error, you need to set a udev rule to change the mode of -your device (see below) - -Also, try: - - sudo udevadm info --query=all --name=input/eventXX - -If you see a line stating ID_INPUT_JOYSTICK=1, great, if you don't see it, -you need to set up an udev rule to force this variable. - -A combined rule for the Saitek Pro Flight Rudder Pedals to fix both issues looks -like: - - SUBSYSTEM=="input", ATTRS{idProduct}=="0763", ATTRS{idVendor}=="06a3", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1" - SUBSYSTEM=="input", ATTRS{idProduct}=="0764", ATTRS{idVendor}=="06a3", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1" - -You can set up similar rules for your device by changing the values listed in -idProduct and idVendor. To obtain these values, try: - - sudo udevadm info -a --name=input/eventXX | grep idVendor - sudo udevadm info -a --name=input/eventXX | grep idProduct - -If multiple values come up for each of these, the one you want is the first one of each. - -On other systems which ship with an older udev (such as CentOS), you may need -to set up a rule such as: - - SUBSYSTEM=="input", ENV{ID_CLASS}=="joystick", ENV{ID_INPUT_JOYSTICK}="1" - +Linux +================================================================================ + +By default SDL will only link against glibc, the rest of the features will be +enabled dynamically at runtime depending on the available features on the target +system. So, for example if you built SDL with XRandR support and the target +system does not have the XRandR libraries installed, it will be disabled +at runtime, and you won't get a missing library error, at least with the +default configuration parameters. + + +Build Dependencies +-------------------------------------------------------------------------------- + +Ubuntu 18.04, all available features enabled: + + sudo apt-get install build-essential git make \ + pkg-config cmake ninja-build gnome-desktop-testing libasound2-dev libpulse-dev \ + libaudio-dev libjack-dev libsndio-dev libsamplerate0-dev libx11-dev libxext-dev \ + libxrandr-dev libxcursor-dev libxfixes-dev libxi-dev libxss-dev \ + libxkbcommon-dev libdrm-dev libgbm-dev libgl1-mesa-dev libgles2-mesa-dev \ + libegl1-mesa-dev libdbus-1-dev libibus-1.0-dev libudev-dev fcitx-libs-dev + +Ubuntu 22.04+ can also add `libpipewire-0.3-dev libwayland-dev libdecor-0-dev` to that command line. + +Fedora 35, all available features enabled: + + sudo yum install gcc git-core make cmake \ + alsa-lib-devel pulseaudio-libs-devel nas-devel pipewire-devel \ + libX11-devel libXext-devel libXrandr-devel libXcursor-devel libXfixes-devel \ + libXi-devel libXScrnSaver-devel dbus-devel ibus-devel fcitx-devel \ + systemd-devel mesa-libGL-devel libxkbcommon-devel mesa-libGLES-devel \ + mesa-libEGL-devel vulkan-devel wayland-devel wayland-protocols-devel \ + libdrm-devel mesa-libgbm-devel libusb-devel libdecor-devel \ + libsamplerate-devel pipewire-jack-audio-connection-kit-devel \ + +NOTES: +- The sndio audio target is unavailable on Fedora (but probably not what you + should want to use anyhow). +- libsamplerate0-dev lets SDL optionally link to libresamplerate at runtime + for higher-quality audio resampling. SDL will work without it if the library + is missing, so it's safe to build in support even if the end user doesn't + have this library installed. + + +Joystick does not work +-------------------------------------------------------------------------------- + +If you compiled or are using a version of SDL with udev support (and you should!) +there's a few issues that may cause SDL to fail to detect your joystick. To +debug this, start by installing the evtest utility. On Ubuntu/Debian: + + sudo apt-get install evtest + +Then run: + + sudo evtest + +You'll hopefully see your joystick listed along with a name like "/dev/input/eventXX" +Now run: + + cat /dev/input/event/XX + +If you get a permission error, you need to set a udev rule to change the mode of +your device (see below) + +Also, try: + + sudo udevadm info --query=all --name=input/eventXX + +If you see a line stating ID_INPUT_JOYSTICK=1, great, if you don't see it, +you need to set up an udev rule to force this variable. + +A combined rule for the Saitek Pro Flight Rudder Pedals to fix both issues looks +like: + + SUBSYSTEM=="input", ATTRS{idProduct}=="0763", ATTRS{idVendor}=="06a3", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1" + SUBSYSTEM=="input", ATTRS{idProduct}=="0764", ATTRS{idVendor}=="06a3", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1" + +You can set up similar rules for your device by changing the values listed in +idProduct and idVendor. To obtain these values, try: + + sudo udevadm info -a --name=input/eventXX | grep idVendor + sudo udevadm info -a --name=input/eventXX | grep idProduct + +If multiple values come up for each of these, the one you want is the first one of each. + +On other systems which ship with an older udev (such as CentOS), you may need +to set up a rule such as: + + SUBSYSTEM=="input", ENV{ID_CLASS}=="joystick", ENV{ID_INPUT_JOYSTICK}="1" + diff --git a/docs/README-macos.md b/docs/README-macos.md index 4f2db5c85..d66aa4284 100644 --- a/docs/README-macos.md +++ b/docs/README-macos.md @@ -57,10 +57,10 @@ NSApplicationDelegate implementation: event.type = SDL_EVENT_QUIT; SDL_PushEvent(&event); } - + return NSTerminateCancel; } - + - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename { if (SDL_GetEventState(SDL_EVENT_DROP_FILE) == SDL_ENABLE) { @@ -69,7 +69,7 @@ NSApplicationDelegate implementation: event.drop.file = SDL_strdup([filename UTF8String]); return (SDL_PushEvent(&event) > 0); } - + return NO; } ``` @@ -163,12 +163,12 @@ normally from the Finder. The SDL Library is packaged as a framework bundle, an organized relocatable folder hierarchy of executable code, interface headers, -and additional resources. For practical purposes, you can think of a +and additional resources. For practical purposes, you can think of a framework as a more user and system-friendly shared library, whose library file behaves more or less like a standard UNIX shared library. -To build the framework, simply open the framework project and build it. -By default, the framework bundle "SDL.framework" is installed in +To build the framework, simply open the framework project and build it. +By default, the framework bundle "SDL.framework" is installed in /Library/Frameworks. Therefore, the testers and project stationary expect it to be located there. However, it will function the same in any of the following locations: @@ -220,7 +220,7 @@ Use `xcode-build` in the same directory as your .pbxproj file You can send command line args to your app by either invoking it from the command line (in *.app/Contents/MacOS) or by entering them in the Executables" panel of the target settings. - + # Implementation Notes Some things that may be of interest about how it all works... diff --git a/docs/README-migration.md b/docs/README-migration.md index acb6ca9fc..2c1e3e91e 100644 --- a/docs/README-migration.md +++ b/docs/README-migration.md @@ -1,1085 +1,1085 @@ -# Migrating to SDL 3.0 - -This guide provides useful information for migrating applications from SDL 2.0 to SDL 3.0. - -Details on API changes are organized by SDL 2.0 header below. - -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: -```sh -rename_symbols.py --all-symbols source_code_path -``` - -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) - - -SDL headers should now be included as `#include `. Typically that's the only header you'll need in your application unless you are using OpenGL or Vulkan functionality. 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: -```sh -rename_headers.py source_code_path -``` - -The file with your main() function should also include , see below in the SDL_main.h section. - -CMake users should use this snippet to include SDL support in their project: -``` -find_package(SDL3 REQUIRED CONFIG REQUIRED COMPONENTS SDL3) -target_link_libraries(mygame PRIVATE SDL3::SDL3) -``` - -Autotools users should use this snippet to include SDL support in their project: -``` -PKG_CHECK_MODULES([SDL3], [sdl3]) -``` -and then add $SDL3_CFLAGS to their project CFLAGS and $SDL3_LIBS to their project LDFLAGS - -Makefile users can use this snippet to include SDL support in their project: -``` -CFLAGS += $(shell pkg-config sdl3 --cflags) -LDFLAGS += $(shell pkg-config sdl3 --libs) -``` - -The SDL3test library has been renamed SDL3_test. - -There is no SDLmain library anymore, it's now header-only, see below in the SDL_main.h section. - - -begin_code.h and close_code.h in the public headers have been renamed to SDL_begin_code.h and SDL_close_code.h. These aren't meant to be included directly by applications, but if your application did, please update your `#include` lines. - -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. - -## SDL_audio.h - -SDL_AudioInit() and SDL_AudioQuit() have been removed. Instead you can call SDL_InitSubSytem() and SDL_QuitSubSytem() with SDL_INIT_AUDIO, which will properly refcount the subsystems. You can choose a specific audio driver using SDL_AUDIO_DRIVER hint. - -SDL_PauseAudioDevice() is only used to pause audio playback. Use SDL_PlayAudioDevice() to start playing audio. - -SDL_FreeWAV has been removed and calls can be replaced with SDL_free. - -SDL_AudioCVT interface is removed, SDL_AudioStream interface or SDL_ConvertAudioSamples() helper function can be used. - -Code that used to look like this: -```c - SDL_AudioCVT cvt; - SDL_BuildAudioCVT(&cvt, src_format, src_channels, src_rate, dst_format, dst_channels, dst_rate); - cvt.len = src_len; - cvt.buf = (Uint8 *) SDL_malloc(src_len * cvt.len_mult); - SDL_memcpy(cvt.buf, src_data, src_len); - SDL_ConvertAudio(&cvt); - do_something(cvt.buf, cvt.len_cvt); -``` -should be changed to: -```c - Uint8 *dst_data = NULL; - int dst_len = 0; - if (SDL_ConvertAudioSamples(src_format, src_channels, src_rate, src_data, src_len - dst_format, dst_channels, dst_rate, &dst_data, &dst_len) < 0) { - /* error */ - } - do_something(dst_data, dst_len); - SDL_free(dst_data); -``` - - -The following functions have been renamed: -* SDL_AudioStreamAvailable() => SDL_GetAudioStreamAvailable() -* SDL_AudioStreamClear() => SDL_ClearAudioStream() -* SDL_AudioStreamFlush() => SDL_FlushAudioStream() -* SDL_AudioStreamGet() => SDL_GetAudioStreamData() -* SDL_AudioStreamPut() => SDL_PutAudioStreamData() -* SDL_FreeAudioStream() => SDL_DestroyAudioStream() -* SDL_NewAudioStream() => SDL_CreateAudioStream() - - -The following functions have been removed: -* SDL_ConvertAudio() -* SDL_BuildAudioCVT() -* SDL_OpenAudio() -* SDL_CloseAudio() -* SDL_PauseAudio() -* SDL_GetAudioStatus() -* SDL_LockAudio() -* SDL_UnlockAudio() -* SDL_MixAudio() - -Use the SDL_AudioDevice functions instead. - -## SDL_cpuinfo.h - -The intrinsics headers (mmintrin.h, etc.) have been moved to `` and are no longer automatically included in SDL.h. - -SDL_Has3DNow() has been removed; there is no replacement. - -SDL_SIMDAlloc(), SDL_SIMDRealloc(), and SDL_SIMDFree() have been removed. You can use SDL_aligned_alloc() and SDL_aligned_free() with SDL_SIMDGetAlignment() to get the same functionality. - -## SDL_events.h - -The timestamp member of the SDL_Event structure now represents nanoseconds, and is populated with SDL_GetTicksNS() - -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(). - -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(). - -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. - -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. - -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. - -The SDL_EVENT_WINDOW_RESIZED event is always sent, even in response to SDL_SetWindowSize(). - -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. - -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. - -The following symbols have been renamed: -* SDL_APP_DIDENTERBACKGROUND => SDL_EVENT_DID_ENTER_BACKGROUND -* SDL_APP_DIDENTERFOREGROUND => SDL_EVENT_DID_ENTER_FOREGROUND -* SDL_APP_LOWMEMORY => SDL_EVENT_LOW_MEMORY -* SDL_APP_TERMINATING => SDL_EVENT_TERMINATING -* SDL_APP_WILLENTERBACKGROUND => SDL_EVENT_WILL_ENTER_BACKGROUND -* SDL_APP_WILLENTERFOREGROUND => SDL_EVENT_WILL_ENTER_FOREGROUND -* SDL_AUDIODEVICEADDED => SDL_EVENT_AUDIO_DEVICE_ADDED -* SDL_AUDIODEVICEREMOVED => SDL_EVENT_AUDIO_DEVICE_REMOVED -* SDL_CLIPBOARDUPDATE => SDL_EVENT_CLIPBOARD_UPDATE -* SDL_CONTROLLERAXISMOTION => SDL_EVENT_GAMEPAD_AXIS_MOTION -* SDL_CONTROLLERBUTTONDOWN => SDL_EVENT_GAMEPAD_BUTTON_DOWN -* SDL_CONTROLLERBUTTONUP => SDL_EVENT_GAMEPAD_BUTTON_UP -* SDL_CONTROLLERDEVICEADDED => SDL_EVENT_GAMEPAD_ADDED -* SDL_CONTROLLERDEVICEREMAPPED => SDL_EVENT_GAMEPAD_REMAPPED -* SDL_CONTROLLERDEVICEREMOVED => SDL_EVENT_GAMEPAD_REMOVED -* SDL_CONTROLLERSENSORUPDATE => SDL_EVENT_GAMEPAD_SENSOR_UPDATE -* SDL_CONTROLLERTOUCHPADDOWN => SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN -* SDL_CONTROLLERTOUCHPADMOTION => SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION -* SDL_CONTROLLERTOUCHPADUP => SDL_EVENT_GAMEPAD_TOUCHPAD_UP -* SDL_DROPBEGIN => SDL_EVENT_DROP_BEGIN -* SDL_DROPCOMPLETE => SDL_EVENT_DROP_COMPLETE -* SDL_DROPFILE => SDL_EVENT_DROP_FILE -* SDL_DROPTEXT => SDL_EVENT_DROP_TEXT -* SDL_FINGERDOWN => SDL_EVENT_FINGER_DOWN -* SDL_FINGERMOTION => SDL_EVENT_FINGER_MOTION -* SDL_FINGERUP => SDL_EVENT_FINGER_UP -* SDL_FIRSTEVENT => SDL_EVENT_FIRST -* SDL_JOYAXISMOTION => SDL_EVENT_JOYSTICK_AXIS_MOTION -* SDL_JOYBATTERYUPDATED => SDL_EVENT_JOYSTICK_BATTERY_UPDATED -* SDL_JOYBUTTONDOWN => SDL_EVENT_JOYSTICK_BUTTON_DOWN -* SDL_JOYBUTTONUP => SDL_EVENT_JOYSTICK_BUTTON_UP -* SDL_JOYDEVICEADDED => SDL_EVENT_JOYSTICK_ADDED -* SDL_JOYDEVICEREMOVED => SDL_EVENT_JOYSTICK_REMOVED -* SDL_JOYHATMOTION => SDL_EVENT_JOYSTICK_HAT_MOTION -* SDL_KEYDOWN => SDL_EVENT_KEY_DOWN -* SDL_KEYMAPCHANGED => SDL_EVENT_KEYMAP_CHANGED -* SDL_KEYUP => SDL_EVENT_KEY_UP -* SDL_LASTEVENT => SDL_EVENT_LAST -* SDL_LOCALECHANGED => SDL_EVENT_LOCALE_CHANGED -* SDL_MOUSEBUTTONDOWN => SDL_EVENT_MOUSE_BUTTON_DOWN -* SDL_MOUSEBUTTONUP => SDL_EVENT_MOUSE_BUTTON_UP -* SDL_MOUSEMOTION => SDL_EVENT_MOUSE_MOTION -* SDL_MOUSEWHEEL => SDL_EVENT_MOUSE_WHEEL -* SDL_POLLSENTINEL => SDL_EVENT_POLL_SENTINEL -* SDL_QUIT => SDL_EVENT_QUIT -* SDL_RENDER_DEVICE_RESET => SDL_EVENT_RENDER_DEVICE_RESET -* SDL_RENDER_TARGETS_RESET => SDL_EVENT_RENDER_TARGETS_RESET -* SDL_SENSORUPDATE => SDL_EVENT_SENSOR_UPDATE -* SDL_SYSWMEVENT => SDL_EVENT_SYSWM -* SDL_TEXTEDITING => SDL_EVENT_TEXT_EDITING -* SDL_TEXTEDITING_EXT => SDL_EVENT_TEXT_EDITING_EXT -* SDL_TEXTINPUT => SDL_EVENT_TEXT_INPUT -* SDL_USEREVENT => SDL_EVENT_USER - -The following structures have been renamed: -* SDL_ControllerAxisEvent => SDL_GamepadAxisEvent -* SDL_ControllerButtonEvent => SDL_GamepadButtonEvent -* SDL_ControllerDeviceEvent => SDL_GamepadDeviceEvent -* SDL_ControllerSensorEvent => SDL_GamepadSensorEvent -* SDL_ControllerTouchpadEvent => SDL_GamepadTouchpadEvent - -The following functions have been removed: -* SDL_EventState() - replaced with SDL_SetEventEnabled() -* SDL_GetEventState() - replaced with SDL_EventEnabled() - -## SDL_gamecontroller.h - -SDL_gamecontroller.h has been renamed SDL_gamepad.h, and all APIs have been renamed to match. - -The SDL_EVENT_GAMEPAD_ADDED event now provides the joystick instance ID in the which member of the cdevice event structure. - -The functions SDL_GetGamepads(), SDL_GetGamepadInstanceName(), SDL_GetGamepadInstancePath(), SDL_GetGamepadInstancePlayerIndex(), SDL_GetGamepadInstanceGUID(), SDL_GetGamepadInstanceVendor(), SDL_GetGamepadInstanceProduct(), SDL_GetGamepadInstanceProductVersion(), and SDL_GetGamepadInstanceType() have been added to directly query the list of available gamepads. - -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. - -The following enums have been renamed: -* SDL_GameControllerAxis => SDL_GamepadAxis -* SDL_GameControllerBindType => SDL_GamepadBindingType -* SDL_GameControllerButton => SDL_GamepadButton -* SDL_GameControllerType => SDL_GamepadType - -The following structures have been renamed: -* SDL_GameController => SDL_Gamepad -* SDL_GameControllerButtonBind => SDL_GamepadBinding - -The following functions have been renamed: -* SDL_GameControllerAddMapping() => SDL_AddGamepadMapping() -* SDL_GameControllerAddMappingsFromFile() => SDL_AddGamepadMappingsFromFile() -* SDL_GameControllerAddMappingsFromRW() => SDL_AddGamepadMappingsFromRW() -* SDL_GameControllerClose() => SDL_CloseGamepad() -* SDL_GameControllerFromInstanceID() => SDL_GetGamepadFromInstanceID() -* SDL_GameControllerFromPlayerIndex() => SDL_GetGamepadFromPlayerIndex() -* SDL_GameControllerGetAppleSFSymbolsNameForAxis() => SDL_GetGamepadAppleSFSymbolsNameForAxis() -* SDL_GameControllerGetAppleSFSymbolsNameForButton() => SDL_GetGamepadAppleSFSymbolsNameForButton() -* SDL_GameControllerGetAttached() => SDL_GamepadConnected() -* SDL_GameControllerGetAxis() => SDL_GetGamepadAxis() -* SDL_GameControllerGetAxisFromString() => SDL_GetGamepadAxisFromString() -* SDL_GameControllerGetBindForAxis() => SDL_GetGamepadBindForAxis() -* SDL_GameControllerGetBindForButton() => SDL_GetGamepadBindForButton() -* SDL_GameControllerGetButton() => SDL_GetGamepadButton() -* SDL_GameControllerGetButtonFromString() => SDL_GetGamepadButtonFromString() -* SDL_GameControllerGetFirmwareVersion() => SDL_GetGamepadFirmwareVersion() -* SDL_GameControllerGetJoystick() => SDL_GetGamepadJoystick() -* SDL_GameControllerGetNumTouchpadFingers() => SDL_GetNumGamepadTouchpadFingers() -* SDL_GameControllerGetNumTouchpads() => SDL_GetNumGamepadTouchpads() -* SDL_GameControllerGetPlayerIndex() => SDL_GetGamepadPlayerIndex() -* SDL_GameControllerGetProduct() => SDL_GetGamepadProduct() -* SDL_GameControllerGetProductVersion() => SDL_GetGamepadProductVersion() -* SDL_GameControllerGetSensorData() => SDL_GetGamepadSensorData() -* SDL_GameControllerGetSensorDataRate() => SDL_GetGamepadSensorDataRate() -* SDL_GameControllerGetSerial() => SDL_GetGamepadSerial() -* SDL_GameControllerGetStringForAxis() => SDL_GetGamepadStringForAxis() -* SDL_GameControllerGetStringForButton() => SDL_GetGamepadStringForButton() -* SDL_GameControllerGetTouchpadFinger() => SDL_GetGamepadTouchpadFinger() -* SDL_GameControllerGetType() => SDL_GetGamepadType() -* SDL_GameControllerGetVendor() => SDL_GetGamepadVendor() -* SDL_GameControllerHasAxis() => SDL_GamepadHasAxis() -* SDL_GameControllerHasButton() => SDL_GamepadHasButton() -* SDL_GameControllerHasLED() => SDL_GamepadHasLED() -* SDL_GameControllerHasRumble() => SDL_GamepadHasRumble() -* SDL_GameControllerHasRumbleTriggers() => SDL_GamepadHasRumbleTriggers() -* SDL_GameControllerHasSensor() => SDL_GamepadHasSensor() -* SDL_GameControllerIsSensorEnabled() => SDL_GamepadSensorEnabled() -* SDL_GameControllerMapping() => SDL_GetGamepadMapping() -* SDL_GameControllerMappingForGUID() => SDL_GetGamepadMappingForGUID() -* SDL_GameControllerMappingForIndex() => SDL_GetGamepadMappingForIndex() -* SDL_GameControllerName() => SDL_GetGamepadName() -* SDL_GameControllerNumMappings() => SDL_GetNumGamepadMappings() -* SDL_GameControllerOpen() => SDL_OpenGamepad() -* SDL_GameControllerPath() => SDL_GetGamepadPath() -* SDL_GameControllerRumble() => SDL_RumbleGamepad() -* SDL_GameControllerRumbleTriggers() => SDL_RumbleGamepadTriggers() -* SDL_GameControllerSendEffect() => SDL_SendGamepadEffect() -* SDL_GameControllerSetLED() => SDL_SetGamepadLED() -* SDL_GameControllerSetPlayerIndex() => SDL_SetGamepadPlayerIndex() -* SDL_GameControllerSetSensorEnabled() => SDL_SetGamepadSensorEnabled() -* SDL_GameControllerUpdate() => SDL_UpdateGamepads() -* SDL_IsGameController() => SDL_IsGamepad() - -The following functions have been removed: -* SDL_GameControllerEventState() - replaced with SDL_SetGamepadEventsEnabled() and SDL_GamepadEventsEnabled() -* SDL_GameControllerMappingForDeviceIndex() - replaced with SDL_GetGamepadInstanceMapping() -* SDL_GameControllerNameForIndex() - replaced with SDL_GetGamepadInstanceName() -* SDL_GameControllerPathForIndex() - replaced with SDL_GetGamepadInstancePath() -* SDL_GameControllerTypeForIndex() - replaced with SDL_GetGamepadInstanceType() - -The following symbols have been renamed: -* SDL_CONTROLLER_AXIS_INVALID => SDL_GAMEPAD_AXIS_INVALID -* SDL_CONTROLLER_AXIS_LEFTX => SDL_GAMEPAD_AXIS_LEFTX -* SDL_CONTROLLER_AXIS_LEFTY => SDL_GAMEPAD_AXIS_LEFTY -* SDL_CONTROLLER_AXIS_MAX => SDL_GAMEPAD_AXIS_MAX -* SDL_CONTROLLER_AXIS_RIGHTX => SDL_GAMEPAD_AXIS_RIGHTX -* SDL_CONTROLLER_AXIS_RIGHTY => SDL_GAMEPAD_AXIS_RIGHTY -* SDL_CONTROLLER_AXIS_TRIGGERLEFT => SDL_GAMEPAD_AXIS_LEFT_TRIGGER -* SDL_CONTROLLER_AXIS_TRIGGERRIGHT => SDL_GAMEPAD_AXIS_RIGHT_TRIGGER -* SDL_CONTROLLER_BINDTYPE_AXIS => SDL_GAMEPAD_BINDTYPE_AXIS -* SDL_CONTROLLER_BINDTYPE_BUTTON => SDL_GAMEPAD_BINDTYPE_BUTTON -* SDL_CONTROLLER_BINDTYPE_HAT => SDL_GAMEPAD_BINDTYPE_HAT -* SDL_CONTROLLER_BINDTYPE_NONE => SDL_GAMEPAD_BINDTYPE_NONE -* SDL_CONTROLLER_BUTTON_A => SDL_GAMEPAD_BUTTON_A -* SDL_CONTROLLER_BUTTON_B => SDL_GAMEPAD_BUTTON_B -* SDL_CONTROLLER_BUTTON_BACK => SDL_GAMEPAD_BUTTON_BACK -* SDL_CONTROLLER_BUTTON_DPAD_DOWN => SDL_GAMEPAD_BUTTON_DPAD_DOWN -* SDL_CONTROLLER_BUTTON_DPAD_LEFT => SDL_GAMEPAD_BUTTON_DPAD_LEFT -* SDL_CONTROLLER_BUTTON_DPAD_RIGHT => SDL_GAMEPAD_BUTTON_DPAD_RIGHT -* SDL_CONTROLLER_BUTTON_DPAD_UP => SDL_GAMEPAD_BUTTON_DPAD_UP -* SDL_CONTROLLER_BUTTON_GUIDE => SDL_GAMEPAD_BUTTON_GUIDE -* SDL_CONTROLLER_BUTTON_INVALID => SDL_GAMEPAD_BUTTON_INVALID -* SDL_CONTROLLER_BUTTON_LEFTSHOULDER => SDL_GAMEPAD_BUTTON_LEFT_SHOULDER -* SDL_CONTROLLER_BUTTON_LEFTSTICK => SDL_GAMEPAD_BUTTON_LEFT_STICK -* SDL_CONTROLLER_BUTTON_MAX => SDL_GAMEPAD_BUTTON_MAX -* SDL_CONTROLLER_BUTTON_MISC1 => SDL_GAMEPAD_BUTTON_MISC1 -* SDL_CONTROLLER_BUTTON_PADDLE1 => SDL_GAMEPAD_BUTTON_PADDLE1 -* SDL_CONTROLLER_BUTTON_PADDLE2 => SDL_GAMEPAD_BUTTON_PADDLE2 -* SDL_CONTROLLER_BUTTON_PADDLE3 => SDL_GAMEPAD_BUTTON_PADDLE3 -* SDL_CONTROLLER_BUTTON_PADDLE4 => SDL_GAMEPAD_BUTTON_PADDLE4 -* SDL_CONTROLLER_BUTTON_RIGHTSHOULDER => SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER -* SDL_CONTROLLER_BUTTON_RIGHTSTICK => SDL_GAMEPAD_BUTTON_RIGHT_STICK -* SDL_CONTROLLER_BUTTON_START => SDL_GAMEPAD_BUTTON_START -* SDL_CONTROLLER_BUTTON_TOUCHPAD => SDL_GAMEPAD_BUTTON_TOUCHPAD -* SDL_CONTROLLER_BUTTON_X => SDL_GAMEPAD_BUTTON_X -* SDL_CONTROLLER_BUTTON_Y => SDL_GAMEPAD_BUTTON_Y -* SDL_CONTROLLER_TYPE_AMAZON_LUNA => SDL_GAMEPAD_TYPE_AMAZON_LUNA -* SDL_CONTROLLER_TYPE_GOOGLE_STADIA => SDL_GAMEPAD_TYPE_GOOGLE_STADIA -* SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT => SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT -* SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR => SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR -* SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT => SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT -* SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO => SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO -* SDL_CONTROLLER_TYPE_NVIDIA_SHIELD => SDL_GAMEPAD_TYPE_NVIDIA_SHIELD -* SDL_CONTROLLER_TYPE_PS3 => SDL_GAMEPAD_TYPE_PS3 -* SDL_CONTROLLER_TYPE_PS4 => SDL_GAMEPAD_TYPE_PS4 -* SDL_CONTROLLER_TYPE_PS5 => SDL_GAMEPAD_TYPE_PS5 -* SDL_CONTROLLER_TYPE_UNKNOWN => SDL_GAMEPAD_TYPE_UNKNOWN -* SDL_CONTROLLER_TYPE_VIRTUAL => SDL_GAMEPAD_TYPE_VIRTUAL -* SDL_CONTROLLER_TYPE_XBOX360 => SDL_GAMEPAD_TYPE_XBOX360 -* SDL_CONTROLLER_TYPE_XBOXONE => SDL_GAMEPAD_TYPE_XBOXONE - -## SDL_gesture.h - -The gesture API has been removed. There is no replacement planned in SDL3. -However, the SDL2 code has been moved to a single-header library that can -be dropped into an SDL3 or SDL2 program, to continue to provide this -functionality to your app and aid migration. That is located in the -[SDL_gesture GitHub repository](https://github.com/libsdl-org/SDL_gesture). - -## SDL_hints.h - -SDL_AddHintCallback() now returns a standard int result instead of void, returning 0 if the function succeeds or a negative error code if there was an error. - -The following hints have been removed: -* SDL_HINT_IDLE_TIMER_DISABLED - use SDL_DisableScreenSaver instead -* SDL_HINT_MOUSE_RELATIVE_SCALING - mouse coordinates are no longer automatically scaled by the SDL renderer -* SDL_HINT_RENDER_LOGICAL_SIZE_MODE - the logical size mode is explicitly set with SDL_SetRenderLogicalPresentation() -* SDL_HINT_VIDEO_X11_FORCE_EGL - use SDL_HINT_VIDEO_FORCE_EGL instead -* SDL_HINT_VIDEO_X11_XINERAMA - Xinerama no longer supported by the X11 backend -* SDL_HINT_VIDEO_X11_XVIDMODE - Xvidmode no longer supported by the X11 backend - -* Renamed hints SDL_HINT_VIDEODRIVER and SDL_HINT_AUDIODRIVER to SDL_HINT_VIDEO_DRIVER and SDL_HINT_AUDIO_DRIVER -* Renamed environment variables SDL_VIDEODRIVER and SDL_AUDIODRIVER to SDL_VIDEO_DRIVER and SDL_AUDIO_DRIVER - -## SDL_init.h - -The following symbols have been renamed: -* SDL_INIT_GAMECONTROLLER => SDL_INIT_GAMEPAD - -The following symbols have been removed: -* SDL_INIT_NOPARACHUTE - -## SDL_joystick.h - -SDL_JoystickID has changed from Sint32 to Uint32, with an invalid ID being 0. - -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: -```c -{ - if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == 0) { - int i, num_joysticks; - SDL_JoystickID *joysticks = SDL_GetJoysticks(&num_joysticks); - if (joysticks) { - for (i = 0; i < num_joysticks; ++i) { - SDL_JoystickID instance_id = joysticks[i]; - const char *name = SDL_GetJoystickInstanceName(instance_id); - const char *path = SDL_GetJoystickInstancePath(instance_id); - - SDL_Log("Joystick %" SDL_PRIu32 ": %s%s%s VID 0x%.4x, PID 0x%.4x\n", - instance_id, name ? name : "Unknown", path ? ", " : "", path ? path : "", SDL_GetJoystickInstanceVendor(instance_id), SDL_GetJoystickInstanceProduct(instance_id)); - } - SDL_free(joysticks); - } - SDL_QuitSubSystem(SDL_INIT_JOYSTICK); - } -} -``` - -The SDL_EVENT_JOYSTICK_ADDED event now provides the joystick instance ID in the `which` member of the jdevice event structure. - -The functions SDL_GetJoysticks(), SDL_GetJoystickInstanceName(), SDL_GetJoystickInstancePath(), SDL_GetJoystickInstancePlayerIndex(), SDL_GetJoystickInstanceGUID(), SDL_GetJoystickInstanceVendor(), SDL_GetJoystickInstanceProduct(), SDL_GetJoystickInstanceProductVersion(), and SDL_GetJoystickInstanceType() have been added to directly query the list of available joysticks. - -SDL_AttachVirtualJoystick() and SDL_AttachVirtualJoystickEx() now return the joystick instance ID instead of a device index, and return 0 if there was an error. - -The following functions have been renamed: -* SDL_JoystickAttachVirtual() => SDL_AttachVirtualJoystick() -* SDL_JoystickAttachVirtualEx() => SDL_AttachVirtualJoystickEx() -* SDL_JoystickClose() => SDL_CloseJoystick() -* SDL_JoystickCurrentPowerLevel() => SDL_GetJoystickPowerLevel() -* SDL_JoystickDetachVirtual() => SDL_DetachVirtualJoystick() -* SDL_JoystickFromInstanceID() => SDL_GetJoystickFromInstanceID() -* SDL_JoystickFromPlayerIndex() => SDL_GetJoystickFromPlayerIndex() -* SDL_JoystickGetAttached() => SDL_JoystickConnected() -* SDL_JoystickGetAxis() => SDL_GetJoystickAxis() -* SDL_JoystickGetAxisInitialState() => SDL_GetJoystickAxisInitialState() -* SDL_JoystickGetButton() => SDL_GetJoystickButton() -* SDL_JoystickGetFirmwareVersion() => SDL_GetJoystickFirmwareVersion() -* SDL_JoystickGetGUID() => SDL_GetJoystickGUID() -* SDL_JoystickGetGUIDFromString() => SDL_GetJoystickGUIDFromString() -* SDL_JoystickGetGUIDString() => SDL_GetJoystickGUIDString() -* SDL_JoystickGetHat() => SDL_GetJoystickHat() -* SDL_JoystickGetPlayerIndex() => SDL_GetJoystickPlayerIndex() -* SDL_JoystickGetProduct() => SDL_GetJoystickProduct() -* SDL_JoystickGetProductVersion() => SDL_GetJoystickProductVersion() -* SDL_JoystickGetSerial() => SDL_GetJoystickSerial() -* SDL_JoystickGetType() => SDL_GetJoystickType() -* SDL_JoystickGetVendor() => SDL_GetJoystickVendor() -* SDL_JoystickInstanceID() => SDL_GetJoystickInstanceID() -* SDL_JoystickIsVirtual() => SDL_IsJoystickVirtual() -* SDL_JoystickName() => SDL_GetJoystickName() -* SDL_JoystickNumAxes() => SDL_GetNumJoystickAxes() -* SDL_JoystickNumButtons() => SDL_GetNumJoystickButtons() -* SDL_JoystickNumHats() => SDL_GetNumJoystickHats() -* SDL_JoystickOpen() => SDL_OpenJoystick() -* SDL_JoystickPath() => SDL_GetJoystickPath() -* SDL_JoystickRumble() => SDL_RumbleJoystick() -* SDL_JoystickRumbleTriggers() => SDL_RumbleJoystickTriggers() -* SDL_JoystickSendEffect() => SDL_SendJoystickEffect() -* SDL_JoystickSetLED() => SDL_SetJoystickLED() -* SDL_JoystickSetPlayerIndex() => SDL_SetJoystickPlayerIndex() -* SDL_JoystickSetVirtualAxis() => SDL_SetJoystickVirtualAxis() -* SDL_JoystickSetVirtualButton() => SDL_SetJoystickVirtualButton() -* SDL_JoystickSetVirtualHat() => SDL_SetJoystickVirtualHat() -* SDL_JoystickUpdate() => SDL_UpdateJoysticks() - -The following symbols have been renamed: -* SDL_JOYSTICK_TYPE_GAMECONTROLLER => SDL_JOYSTICK_TYPE_GAMEPAD - -The following functions have been removed: -* SDL_JoystickEventState() - replaced with SDL_SetJoystickEventsEnabled() and SDL_JoystickEventsEnabled() -* SDL_JoystickGetDeviceGUID() - replaced with SDL_GetJoystickInstanceGUID() -* SDL_JoystickGetDeviceInstanceID() -* SDL_JoystickGetDevicePlayerIndex() - replaced with SDL_GetJoystickInstancePlayerIndex() -* SDL_JoystickGetDeviceProduct() - replaced with SDL_GetJoystickInstanceProduct() -* SDL_JoystickGetDeviceProductVersion() - replaced with SDL_GetJoystickInstanceProductVersion() -* SDL_JoystickGetDeviceType() - replaced with SDL_GetJoystickInstanceType() -* SDL_JoystickGetDeviceVendor() - replaced with SDL_GetJoystickInstanceVendor() -* SDL_JoystickNameForIndex() - replaced with SDL_GetJoystickInstanceName() -* SDL_JoystickPathForIndex() - replaced with SDL_GetJoystickInstancePath() -* SDL_NumJoysticks() - replaced with SDL_GetJoysticks() - -## SDL_keyboard.h - -The following functions have been renamed: -* SDL_IsScreenKeyboardShown() => SDL_ScreenKeyboardShown() -* SDL_IsTextInputActive() => SDL_TextInputActive() -* SDL_IsTextInputShown() => SDL_TextInputShown() - -## SDL_keycode.h - -The following symbols have been renamed: -* KMOD_ALT => SDL_KMOD_ALT -* KMOD_CAPS => SDL_KMOD_CAPS -* KMOD_CTRL => SDL_KMOD_CTRL -* KMOD_GUI => SDL_KMOD_GUI -* KMOD_LALT => SDL_KMOD_LALT -* KMOD_LCTRL => SDL_KMOD_LCTRL -* KMOD_LGUI => SDL_KMOD_LGUI -* KMOD_LSHIFT => SDL_KMOD_LSHIFT -* KMOD_MODE => SDL_KMOD_MODE -* KMOD_NONE => SDL_KMOD_NONE -* KMOD_NUM => SDL_KMOD_NUM -* KMOD_RALT => SDL_KMOD_RALT -* KMOD_RCTRL => SDL_KMOD_RCTRL -* KMOD_RESERVED => SDL_KMOD_RESERVED -* KMOD_RGUI => SDL_KMOD_RGUI -* KMOD_RSHIFT => SDL_KMOD_RSHIFT -* KMOD_SCROLL => SDL_KMOD_SCROLL -* KMOD_SHIFT => SDL_KMOD_SHIFT - -## SDL_loadso.h - -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. - -## SDL_main.h - -SDL3 doesn't have a static libSDLmain to link against anymore. -Instead SDL_main.h is now a header-only library **and not included by SDL.h anymore**. - -Using it is really simple: Just `#include ` in the source file with your standard -`int main(int argc, char* argv[])` function. - -The rest happens automatically: If your target platform needs the SDL_main functionality, -your main function will be renamed to SDL_main (with a macro, just like in SDL2), -and the real main-function will be implemented by inline code from SDL_main.h - and if your target -platform doesn't need it, nothing happens. -Like in SDL2, if you want to handle the platform-specific main yourself instead of using the SDL_main magic, -you can `#define SDL_MAIN_HANDLED` before `#include ` - don't forget to call SDL_SetMainReady() - -If you need SDL_main.h in another source file (that doesn't implement main()), you also need to -`#define SDL_MAIN_HANDLED` there, to avoid that multiple main functions are generated by SDL_main.h - -There is currently one platform where this approach doesn't always work: WinRT. -It requires WinMain to be implemented in a C++ source file that's compiled with `/ZW`. If your main -is implemented in plain C, or you can't use `/ZW` on that file, you can add another .cpp -source file that just contains `#include ` and compile that with `/ZW` - but keep -in mind that the source file with your standard main also needs that include! -See [README-winrt.md](./README-winrt.md) for more details. - -Furthermore, the different SDL_*RunApp() functions (SDL_WinRtRunApp, SDL_GDKRunApp, SDL_UIKitRunApp) -have been unified into just `int SDL_RunApp(int argc, char* argv[], void * reserved)` (which is also -used by additional platforms that didn't have a SDL_RunApp-like function before). - -## SDL_metal.h - -SDL_Metal_GetDrawableSize() has been removed. SDL_GetWindowSizeInPixels() can be used in its place. - -## SDL_mouse.h - -SDL_ShowCursor() has been split into three functions: SDL_ShowCursor(), SDL_HideCursor(), and SDL_CursorVisible() - -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. - -The following functions have been renamed: -* SDL_FreeCursor() => SDL_DestroyCursor() - -## SDL_pixels.h - -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)). - -The following functions have been renamed: -* SDL_AllocFormat() => SDL_CreatePixelFormat() -* SDL_AllocPalette() => SDL_CreatePalette() -* SDL_FreeFormat() => SDL_DestroyPixelFormat() -* SDL_FreePalette() => SDL_DestroyPalette() -* SDL_MasksToPixelFormatEnum() => SDL_GetPixelFormatEnumForMasks() -* SDL_PixelFormatEnumToMasks() => SDL_GetMasksForPixelFormatEnum() - -The following symbols have been renamed: -* SDL_DISPLAYEVENT_DISCONNECTED => SDL_EVENT_DISPLAY_DISCONNECTED -* SDL_DISPLAYEVENT_MOVED => SDL_EVENT_DISPLAY_MOVED -* SDL_DISPLAYEVENT_ORIENTATION => SDL_EVENT_DISPLAY_ORIENTATION -* SDL_WINDOWEVENT_CLOSE => SDL_EVENT_WINDOW_CLOSE_REQUESTED -* SDL_WINDOWEVENT_DISPLAY_CHANGED => SDL_EVENT_WINDOW_DISPLAY_CHANGED -* SDL_WINDOWEVENT_ENTER => SDL_EVENT_WINDOW_ENTER -* SDL_WINDOWEVENT_EXPOSED => SDL_EVENT_WINDOW_EXPOSED -* SDL_WINDOWEVENT_FOCUS_GAINED => SDL_EVENT_WINDOW_FOCUS_GAINED -* SDL_WINDOWEVENT_FOCUS_LOST => SDL_EVENT_WINDOW_FOCUS_LOST -* SDL_WINDOWEVENT_HIDDEN => SDL_EVENT_WINDOW_HIDDEN -* SDL_WINDOWEVENT_HIT_TEST => SDL_EVENT_WINDOW_HIT_TEST -* SDL_WINDOWEVENT_ICCPROF_CHANGED => SDL_EVENT_WINDOW_ICCPROF_CHANGED -* SDL_WINDOWEVENT_LEAVE => SDL_EVENT_WINDOW_LEAVE -* SDL_WINDOWEVENT_MAXIMIZED => SDL_EVENT_WINDOW_MAXIMIZED -* SDL_WINDOWEVENT_MINIMIZED => SDL_EVENT_WINDOW_MINIMIZED -* SDL_WINDOWEVENT_MOVED => SDL_EVENT_WINDOW_MOVED -* SDL_WINDOWEVENT_RESIZED => SDL_EVENT_WINDOW_RESIZED -* SDL_WINDOWEVENT_RESTORED => SDL_EVENT_WINDOW_RESTORED -* SDL_WINDOWEVENT_SHOWN => SDL_EVENT_WINDOW_SHOWN -* SDL_WINDOWEVENT_SIZE_CHANGED => SDL_EVENT_WINDOW_SIZE_CHANGED -* SDL_WINDOWEVENT_TAKE_FOCUS => SDL_EVENT_WINDOW_TAKE_FOCUS - - -## SDL_platform.h - -The preprocessor symbol `__MACOSX__` has been renamed `__MACOS__`, and `__IPHONEOS__` has been renamed `__IOS__` - -## SDL_rect.h - -The following functions have been renamed: -* SDL_EncloseFPoints() => SDL_GetRectEnclosingPointsFloat() -* SDL_EnclosePoints() => SDL_GetRectEnclosingPoints() -* SDL_FRectEmpty() => SDL_RectEmptyFloat() -* SDL_FRectEquals() => SDL_RectsEqualFloat() -* SDL_FRectEqualsEpsilon() => SDL_RectsEqualEpsilon() -* SDL_HasIntersection() => SDL_HasRectIntersection() -* SDL_HasIntersectionF() => SDL_HasRectIntersectionFloat() -* SDL_IntersectFRect() => SDL_GetRectIntersectionFloat() -* SDL_IntersectFRectAndLine() => SDL_GetRectAndLineIntersectionFloat() -* SDL_IntersectRect() => SDL_GetRectIntersection() -* SDL_IntersectRectAndLine() => SDL_GetRectAndLineIntersection() -* SDL_PointInFRect() => SDL_PointInRectFloat() -* SDL_RectEquals() => SDL_RectsEqual() -* SDL_UnionFRect() => SDL_GetRectUnionFloat() -* SDL_UnionRect() => SDL_GetRectUnion() - -## SDL_render.h - -SDL_GetRenderDriverInfo() has been removed, since most of the information it reported were -estimates and could not be accurate before creating a renderer. Often times this function -was used to figure out the index of a driver, so one would call it in a for-loop, looking -for the driver named "opengl" or whatnot. SDL_GetRenderDriver() has been added for this -functionality, which returns only the name of the driver. - -Additionally, SDL_CreateRenderer()'s second argument is no longer an integer index, but a -`const char *` representing a renderer's name; if you were just using a for-loop to find -which index is the "opengl" or whatnot driver, you can just pass that string directly -here, now. Passing NULL is the same as passing -1 here in SDL2, to signify you want SDL -to decide for you. - -When a renderer is created, it will automatically set the logical size to the size of -the window in screen coordinates. For high DPI displays, this will set up scaling from -window coordinates to pixels. You can disable this scaling with: -```c - SDL_SetRenderLogicalPresentation(renderer, 0, 0, SDL_LOGICAL_PRESENTATION_DISABLED, SDL_SCALEMODE_NEAREST); -``` - -Mouse and touch events are no longer filtered to change their coordinates, instead you -can call SDL_ConvertEventToRenderCoordinates() to explicitly map event coordinates into -the rendering viewport. - -SDL_RenderWindowToLogical() and SDL_RenderLogicalToWindow() have been renamed SDL_RenderCoordinatesFromWindow() and SDL_RenderCoordinatesToWindow() and take floating point coordinates in both directions. - -The viewport, clipping state, and scale for render targets are now persistent and will remain set whenever they are active. - -The following functions have been renamed: -* SDL_GetRendererOutputSize() => SDL_GetCurrentRenderOutputSize() -* SDL_RenderCopy() => SDL_RenderTexture() -* SDL_RenderCopyEx() => SDL_RenderTextureRotated() -* SDL_RenderCopyExF() => SDL_RenderTextureRotated() -* SDL_RenderCopyF() => SDL_RenderTexture() -* SDL_RenderDrawLine() => SDL_RenderLine() -* SDL_RenderDrawLineF() => SDL_RenderLine() -* SDL_RenderDrawLines() => SDL_RenderLines() -* SDL_RenderDrawLinesF() => SDL_RenderLines() -* SDL_RenderDrawPoint() => SDL_RenderPoint() -* SDL_RenderDrawPointF() => SDL_RenderPoint() -* SDL_RenderDrawPoints() => SDL_RenderPoints() -* SDL_RenderDrawPointsF() => SDL_RenderPoints() -* SDL_RenderDrawRect() => SDL_RenderRect() -* SDL_RenderDrawRectF() => SDL_RenderRect() -* SDL_RenderDrawRects() => SDL_RenderRects() -* SDL_RenderDrawRectsF() => SDL_RenderRects() -* SDL_RenderFillRectF() => SDL_RenderFillRect() -* SDL_RenderFillRectsF() => SDL_RenderFillRects() -* SDL_RenderGetClipRect() => SDL_GetRenderClipRect() -* SDL_RenderGetIntegerScale() => SDL_GetRenderIntegerScale() -* SDL_RenderGetLogicalSize() => SDL_GetRenderLogicalPresentation() -* SDL_RenderGetMetalCommandEncoder() => SDL_GetRenderMetalCommandEncoder() -* SDL_RenderGetMetalLayer() => SDL_GetRenderMetalLayer() -* SDL_RenderGetScale() => SDL_GetRenderScale() -* SDL_RenderGetViewport() => SDL_GetRenderViewport() -* SDL_RenderGetWindow() => SDL_GetRenderWindow() -* SDL_RenderIsClipEnabled() => SDL_RenderClipEnabled() -* SDL_RenderLogicalToWindow() => SDL_RenderCoordinatesToWindow() -* SDL_RenderSetClipRect() => SDL_SetRenderClipRect() -* SDL_RenderSetIntegerScale() => SDL_SetRenderIntegerScale() -* SDL_RenderSetLogicalSize() => SDL_SetRenderLogicalPresentation() -* SDL_RenderSetScale() => SDL_SetRenderScale() -* SDL_RenderSetVSync() => SDL_SetRenderVSync() -* SDL_RenderSetViewport() => SDL_SetRenderViewport() -* SDL_RenderWindowToLogical() => SDL_RenderCoordinatesFromWindow() - -The following functions have been removed: -* SDL_RenderGetIntegerScale() -* SDL_RenderSetIntegerScale() - this is now explicit with SDL_LOGICAL_PRESENTATION_INTEGER_SCALE -* SDL_RenderTargetSupported() - render targets are always supported - -The following symbols have been renamed: -* SDL_ScaleModeBest => SDL_SCALEMODE_BEST -* SDL_ScaleModeLinear => SDL_SCALEMODE_LINEAR -* SDL_ScaleModeNearest => SDL_SCALEMODE_NEAREST - -## SDL_rwops.h - -The following symbols have been renamed: -* RW_SEEK_CUR => SDL_RW_SEEK_CUR -* RW_SEEK_END => SDL_RW_SEEK_END -* RW_SEEK_SET => SDL_RW_SEEK_SET - -SDL_RWread and SDL_RWwrite (and SDL_RWops::read, SDL_RWops::write) have a different function signature in SDL3. - -Previously they looked more like stdio: - -```c -size_t SDL_RWread(SDL_RWops *context, void *ptr, size_t size, size_t maxnum); -size_t SDL_RWwrite(SDL_RWops *context, const void *ptr, size_t size, size_t maxnum); -``` - -But now they look more like POSIX: - -```c -Sint64 SDL_RWread(SDL_RWops *context, void *ptr, Sint64 size); -Sint64 SDL_RWwrite(SDL_RWops *context, const void *ptr, Sint64 size); -``` - -SDL_RWread() previously returned 0 at end of file or other error. Now it returns the number of bytes read, 0 for end of file, -1 for another error, or -2 for data not ready (in the case of a non-blocking context). - -Code that used to look like this: -``` -size_t custom_read(void *ptr, size_t size, size_t nitems, SDL_RWops *stream) -{ - return (size_t)SDL_RWread(stream, ptr, size, nitems); -} -``` -should be changed to: -``` -size_t custom_read(void *ptr, size_t size, size_t nitems, SDL_RWops *stream) -{ - Sint64 amount = SDL_RWread(stream, ptr, size * nitems); - if (amount <= 0) { - return 0; - } - return (size_t)(amount / size); -} -``` - -Similarly, SDL_RWwrite() can return -2 for data not ready in the case of a non-blocking context. There is currently no way to create a non-blocking context, we have simply defined the semantic for your own custom SDL_RWops object. - -SDL_RWFromFP has been removed from the API, due to issues when the SDL library uses a different C runtime from the application. - -You can implement this in your own code easily: -```c -#include - - -static Sint64 SDLCALL -stdio_size(SDL_RWops * context) -{ - Sint64 pos, size; - - pos = SDL_RWseek(context, 0, SDL_RW_SEEK_CUR); - if (pos < 0) { - return -1; - } - size = SDL_RWseek(context, 0, SDL_RW_SEEK_END); - - SDL_RWseek(context, pos, SDL_RW_SEEK_SET); - return size; -} - -static Sint64 SDLCALL -stdio_seek(SDL_RWops * context, Sint64 offset, int whence) -{ - int stdiowhence; - - switch (whence) { - case SDL_RW_SEEK_SET: - stdiowhence = SEEK_SET; - break; - case SDL_RW_SEEK_CUR: - stdiowhence = SEEK_CUR; - break; - case SDL_RW_SEEK_END: - stdiowhence = SEEK_END; - break; - default: - return SDL_SetError("Unknown value for 'whence'"); - } - - if (fseek((FILE *)context->hidden.stdio.fp, (fseek_off_t)offset, stdiowhence) == 0) { - Sint64 pos = ftell((FILE *)context->hidden.stdio.fp); - if (pos < 0) { - return SDL_SetError("Couldn't get stream offset"); - } - return pos; - } - return SDL_Error(SDL_EFSEEK); -} - -static Sint64 SDLCALL -stdio_read(SDL_RWops * context, void *ptr, Sint64 size) -{ - size_t nread; - - nread = fread(ptr, 1, (size_t) size, (FILE *)context->hidden.stdio.fp); - if (nread == 0 && ferror((FILE *)context->hidden.stdio.fp)) { - return SDL_Error(SDL_EFREAD); - } - return (Sint64) nread; -} - -static Sint64 SDLCALL -stdio_write(SDL_RWops * context, const void *ptr, Sint64 size) -{ - size_t nwrote; - - nwrote = fwrite(ptr, 1, (size_t) size, (FILE *)context->hidden.stdio.fp); - if (nwrote == 0 && ferror((FILE *)context->hidden.stdio.fp)) { - return SDL_Error(SDL_EFWRITE); - } - return (Sint64) nwrote; -} - -static int SDLCALL -stdio_close(SDL_RWops * context) -{ - int status = 0; - if (context) { - if (context->hidden.stdio.autoclose) { - /* WARNING: Check the return value here! */ - if (fclose((FILE *)context->hidden.stdio.fp) != 0) { - status = SDL_Error(SDL_EFWRITE); - } - } - SDL_DestroyRW(context); - } - return status; -} - -SDL_RWops * -SDL_RWFromFP(void *fp, SDL_bool autoclose) -{ - SDL_RWops *rwops = NULL; - - rwops = SDL_CreateRW(); - if (rwops != NULL) { - rwops->size = stdio_size; - rwops->seek = stdio_seek; - rwops->read = stdio_read; - rwops->write = stdio_write; - rwops->close = stdio_close; - rwops->hidden.stdio.fp = fp; - rwops->hidden.stdio.autoclose = autoclose; - rwops->type = SDL_RWOPS_STDFILE; - } - return rwops; -} -``` - - -The following functions have been renamed: -* SDL_AllocRW() => SDL_CreateRW() -* SDL_FreeRW() => SDL_DestroyRW() - -## SDL_sensor.h - -SDL_SensorID has changed from Sint32 to Uint32, with an invalid ID being 0. - -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: -```c -{ - if (SDL_InitSubSystem(SDL_INIT_SENSOR) == 0) { - int i, num_sensors; - SDL_SensorID *sensors = SDL_GetSensors(&num_sensors); - if (sensors) { - for (i = 0; i < num_sensors; ++i) { - SDL_Log("Sensor %" SDL_PRIu32 ": %s, type %d, platform type %d\n", - sensors[i], - SDL_GetSensorInstanceName(sensors[i]), - SDL_GetSensorInstanceType(sensors[i]), - SDL_GetSensorInstanceNonPortableType(sensors[i])); - } - SDL_free(sensors); - } - SDL_QuitSubSystem(SDL_INIT_SENSOR); - } -} -``` - -Removed SDL_SensorGetDataWithTimestamp(), if you want timestamps for the sensor data, you should use the sensor_timestamp member of SDL_EVENT_SENSOR_UPDATE events. - - -The following functions have been renamed: -* SDL_SensorClose() => SDL_CloseSensor() -* SDL_SensorFromInstanceID() => SDL_GetSensorFromInstanceID() -* SDL_SensorGetData() => SDL_GetSensorData() -* SDL_SensorGetInstanceID() => SDL_GetSensorInstanceID() -* SDL_SensorGetName() => SDL_GetSensorName() -* SDL_SensorGetNonPortableType() => SDL_GetSensorNonPortableType() -* SDL_SensorGetType() => SDL_GetSensorType() -* SDL_SensorOpen() => SDL_OpenSensor() -* SDL_SensorUpdate() => SDL_UpdateSensors() - -The following functions have been removed: -* SDL_LockSensors() -* SDL_NumSensors() - replaced with SDL_GetSensors() -* SDL_SensorGetDeviceInstanceID() -* SDL_SensorGetDeviceName() - replaced with SDL_GetSensorInstanceName() -* SDL_SensorGetDeviceNonPortableType() - replaced with SDL_GetSensorInstanceNonPortableType() -* SDL_SensorGetDeviceType() - replaced with SDL_GetSensorInstanceType() -* SDL_UnlockSensors() - -## SDL_stdinc.h - -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. -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. - - -## SDL_surface.h - -Removed unused 'flags' parameter from SDL_ConvertSurface and SDL_ConvertSurfaceFormat. - -SDL_CreateRGBSurface() and SDL_CreateRGBSurfaceWithFormat() have been combined into a new function SDL_CreateSurface(). -SDL_CreateRGBSurfaceFrom() and SDL_CreateRGBSurfaceWithFormatFrom() have been combined into a new function SDL_CreateSurfaceFrom(). - -You can implement the old functions in your own code easily: -```c -SDL_Surface *SDL_CreateRGBSurface(Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) -{ - return SDL_CreateSurface(width, height, - SDL_GetPixelFormatEnumForMasks(depth, Rmask, Gmask, Bmask, Amask)); -} - -SDL_Surface *SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int width, int height, int depth, Uint32 format) -{ - return SDL_CreateSurface(width, height, format); -} - -SDL_Surface *SDL_CreateRGBSurfaceFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) -{ - return SDL_CreateSurfaceFrom(pixels, width, height, pitch, - SDL_GetPixelFormatEnumForMasks(depth, Rmask, Gmask, Bmask, Amask)); -} - -SDL_Surface *SDL_CreateRGBSurfaceWithFormatFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 format) -{ - return SDL_CreateSurfaceFrom(pixels, width, height, pitch, format); -} - -``` - -But if you're migrating your code which uses masks, you probably have a format in mind, possibly one of these: -```c -// Various mask (R, G, B, A) and their corresponding format: -0xFF000000 0x00FF0000 0x0000FF00 0x000000FF => SDL_PIXELFORMAT_RGBA8888 -0x00FF0000 0x0000FF00 0x000000FF 0xFF000000 => SDL_PIXELFORMAT_ARGB8888 -0x0000FF00 0x00FF0000 0xFF000000 0x000000FF => SDL_PIXELFORMAT_BGRA8888 -0x000000FF 0x0000FF00 0x00FF0000 0xFF000000 => SDL_PIXELFORMAT_ABGR8888 -0x0000F800 0x000007E0 0x0000001F 0x00000000 => SDL_PIXELFORMAT_RGB565 -``` - - -The following functions have been renamed: -* SDL_FillRect() => SDL_FillSurfaceRect() -* SDL_FillRects() => SDL_FillSurfaceRects() -* SDL_FreeSurface() => SDL_DestroySurface() -* SDL_GetClipRect() => SDL_GetSurfaceClipRect() -* SDL_GetColorKey() => SDL_GetSurfaceColorKey() -* SDL_HasColorKey() => SDL_SurfaceHasColorKey() -* SDL_HasSurfaceRLE() => SDL_SurfaceHasRLE() -* SDL_LowerBlit() => SDL_BlitSurfaceUnchecked() -* SDL_LowerBlitScaled() => SDL_BlitSurfaceUncheckedScaled() -* SDL_SetClipRect() => SDL_SetSurfaceClipRect() -* SDL_SetColorKey() => SDL_SetSurfaceColorKey() -* SDL_UpperBlit() => SDL_BlitSurface() -* SDL_UpperBlitScaled() => SDL_BlitSurfaceScaled() - -## SDL_system.h - -SDL_AndroidGetExternalStorageState() takes the state as an output parameter and returns 0 if the function succeeds or a negative error code if there was an error. - -The following functions have been renamed: -* SDL_RenderGetD3D11Device() => SDL_GetRenderD3D11Device() -* SDL_RenderGetD3D9Device() => SDL_GetRenderD3D9Device() - -## SDL_syswm.h - -The structures in this file are versioned separately from the rest of SDL, allowing better backwards compatibility and limited forwards compatibility with your application. Instead of calling `SDL_VERSION(&info.version)` before calling SDL_GetWindowWMInfo(), you pass the version in explicitly as SDL_SYSWM_CURRENT_VERSION so SDL knows what fields you expect to be filled out. - -### SDL_GetWindowWMInfo - -This function now returns a standard int result instead of SDL_bool, returning 0 if the function succeeds or a negative error code if there was an error. You should also pass SDL_SYSWM_CURRENT_VERSION as the new third version parameter. The version member of the info structure will be filled in with the version of data that is returned, the minimum of the version you requested and the version supported by the runtime SDL library. - - -## SDL_timer.h - -SDL_GetTicks() now returns a 64-bit value. Instead of using the SDL_TICKS_PASSED macro, you can directly compare tick values, e.g. -```c -Uint32 deadline = SDL_GetTicks() + 1000; -... -if (SDL_TICKS_PASSED(SDL_GetTicks(), deadline)) { - ... -} -``` -becomes: -```c -Uint64 deadline = SDL_GetTicks() + 1000 -... -if (SDL_GetTicks() >= deadline) { - ... -} -``` - -If you were using this macro for other things besides SDL ticks values, you can define it in your own code as: -```c -#define SDL_TICKS_PASSED(A, B) ((Sint32)((B) - (A)) <= 0) -``` - -## SDL_touch.h - -SDL_GetNumTouchFingers() returns a negative error code if there was an error. - -## SDL_version.h - -SDL_GetRevisionNumber() has been removed from the API, it always returned 0 in SDL 2.0. - - -## SDL_video.h - -SDL_VideoInit() and SDL_VideoQuit() have been removed. Instead you can call SDL_InitSubSytem() and SDL_QuitSubSytem() with SDL_INIT_VIDEO, which will properly refcount the subsystems. You can choose a specific video driver using SDL_VIDEO_DRIVER hint. - -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. -```c -{ - if (SDL_InitSubSystem(SDL_INIT_VIDEO) == 0) { - int i, num_displays = 0; - SDL_DisplayID *displays = SDL_GetDisplays(&num_displays); - if (displays) { - for (i = 0; i < num_displays; ++i) { - SDL_DisplayID instance_id = displays[i]; - const char *name = SDL_GetDisplayName(instance_id); - - SDL_Log("Display %" SDL_PRIu32 ": %s\n", instance_id, name ? name : "Unknown"); - } - SDL_free(displays); - } - SDL_QuitSubSystem(SDL_INIT_VIDEO); - } -} -``` - -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. - -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. - -The SDL_WINDOW_ALLOW_HIGHDPI flag has been removed. Windows are automatically high DPI aware and their coordinates are in screen space, which may differ from physical pixels on displays using display scaling. - -SDL_DisplayMode now includes the pixel size, the screen size and the relationship between the two. For example, a 4K display at 200% scale could have a pixel size of 3840x2160, a screen size of 1920x1080, and a display scale of 2.0. - -The refresh rate in SDL_DisplayMode is now a float. - -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. -```c -{ - SDL_DisplayID display = SDL_GetPrimaryDisplay(); - int num_modes = 0; - SDL_DisplayMode **modes = SDL_GetFullscreenDisplayModes(display, &num_modes); - if (modes) { - for (i = 0; i < num_modes; ++i) { - SDL_DisplayMode *mode = modes[i]; - SDL_Log("Display %" SDL_PRIu32 " mode %d: %dx%d@%gHz, %d%% scale\n", - display, i, mode->pixel_w, mode->pixel_h, mode->refresh_rate, (int)(mode->display_scale * 100.0f)); - } - SDL_free(modes); - } -} -``` - -SDL_GetDesktopDisplayMode() and SDL_GetCurrentDisplayMode() return pointers to display modes rather than filling in application memory. - -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. - -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 fullscreen desktop mode will be used when the window is fullscreen. - -SDL_SetWindowBrightness and SDL_SetWindowGammaRamp 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. - -Programs which have access to shaders can implement more robust versions of those functions using custom shader code rendered as a post-process effect. - -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);` - -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. - -SDL_GL_SwapWindow() returns 0 if the function succeeds or a negative error code if there was an error. - -SDL_GL_GetSwapInterval() takes the interval as an output parameter and returns 0 if the function succeeds or a negative error code if there was an error. - -SDL_GL_GetDrawableSize() has been removed. SDL_GetWindowSizeInPixels() can be used in its place. - -The following functions have been renamed: -* SDL_GetClosestDisplayMode() => SDL_GetClosestFullscreenDisplayMode() -* SDL_GetPointDisplayIndex() => SDL_GetDisplayForPoint() -* SDL_GetRectDisplayIndex() => SDL_GetDisplayForRect() -* SDL_GetWindowDisplayIndex() => SDL_GetDisplayForWindow() -* SDL_GetWindowDisplayMode() => SDL_GetWindowFullscreenMode() -* SDL_SetWindowDisplayMode() => SDL_SetWindowFullscreenMode() - -The following functions have been removed: -* SDL_GetClosestFullscreenDisplayMode() -* SDL_GetDisplayDPI() - not reliable across platforms, approximately replaced by multiplying `display_scale` in the structure returned by SDL_GetDesktopDisplayMode() times 160 on iPhone and Android, and 96 on other platforms. -* SDL_GetDisplayMode() -* SDL_GetNumDisplayModes() - replaced with SDL_GetFullscreenDisplayModes() -* SDL_GetNumVideoDisplays() - replaced with SDL_GetDisplays() - -SDL_Window id type is named SDL_WindowID - -The following symbols have been renamed: -* SDL_WINDOW_INPUT_GRABBED => SDL_WINDOW_MOUSE_GRABBED - -## SDL_vulkan.h - -SDL_Vulkan_GetInstanceExtensions() no longer takes a window parameter. - -SDL_Vulkan_GetVkGetInstanceProcAddr() now returns `SDL_FunctionPointer` instead of `void *`, and should be cast to PFN_vkGetInstanceProcAddr. - -SDL_Vulkan_GetDrawableSize() has been removed. SDL_GetWindowSizeInPixels() can be used in its place. - +# Migrating to SDL 3.0 + +This guide provides useful information for migrating applications from SDL 2.0 to SDL 3.0. + +Details on API changes are organized by SDL 2.0 header below. + +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: +```sh +rename_symbols.py --all-symbols source_code_path +``` + +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) + + +SDL headers should now be included as `#include `. Typically that's the only header you'll need in your application unless you are using OpenGL or Vulkan functionality. 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: +```sh +rename_headers.py source_code_path +``` + +The file with your main() function should also include , see below in the SDL_main.h section. + +CMake users should use this snippet to include SDL support in their project: +``` +find_package(SDL3 REQUIRED CONFIG REQUIRED COMPONENTS SDL3) +target_link_libraries(mygame PRIVATE SDL3::SDL3) +``` + +Autotools users should use this snippet to include SDL support in their project: +``` +PKG_CHECK_MODULES([SDL3], [sdl3]) +``` +and then add $SDL3_CFLAGS to their project CFLAGS and $SDL3_LIBS to their project LDFLAGS + +Makefile users can use this snippet to include SDL support in their project: +``` +CFLAGS += $(shell pkg-config sdl3 --cflags) +LDFLAGS += $(shell pkg-config sdl3 --libs) +``` + +The SDL3test library has been renamed SDL3_test. + +There is no SDLmain library anymore, it's now header-only, see below in the SDL_main.h section. + + +begin_code.h and close_code.h in the public headers have been renamed to SDL_begin_code.h and SDL_close_code.h. These aren't meant to be included directly by applications, but if your application did, please update your `#include` lines. + +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. + +## SDL_audio.h + +SDL_AudioInit() and SDL_AudioQuit() have been removed. Instead you can call SDL_InitSubSytem() and SDL_QuitSubSytem() with SDL_INIT_AUDIO, which will properly refcount the subsystems. You can choose a specific audio driver using SDL_AUDIO_DRIVER hint. + +SDL_PauseAudioDevice() is only used to pause audio playback. Use SDL_PlayAudioDevice() to start playing audio. + +SDL_FreeWAV has been removed and calls can be replaced with SDL_free. + +SDL_AudioCVT interface is removed, SDL_AudioStream interface or SDL_ConvertAudioSamples() helper function can be used. + +Code that used to look like this: +```c + SDL_AudioCVT cvt; + SDL_BuildAudioCVT(&cvt, src_format, src_channels, src_rate, dst_format, dst_channels, dst_rate); + cvt.len = src_len; + cvt.buf = (Uint8 *) SDL_malloc(src_len * cvt.len_mult); + SDL_memcpy(cvt.buf, src_data, src_len); + SDL_ConvertAudio(&cvt); + do_something(cvt.buf, cvt.len_cvt); +``` +should be changed to: +```c + Uint8 *dst_data = NULL; + int dst_len = 0; + if (SDL_ConvertAudioSamples(src_format, src_channels, src_rate, src_data, src_len + dst_format, dst_channels, dst_rate, &dst_data, &dst_len) < 0) { + /* error */ + } + do_something(dst_data, dst_len); + SDL_free(dst_data); +``` + + +The following functions have been renamed: +* SDL_AudioStreamAvailable() => SDL_GetAudioStreamAvailable() +* SDL_AudioStreamClear() => SDL_ClearAudioStream() +* SDL_AudioStreamFlush() => SDL_FlushAudioStream() +* SDL_AudioStreamGet() => SDL_GetAudioStreamData() +* SDL_AudioStreamPut() => SDL_PutAudioStreamData() +* SDL_FreeAudioStream() => SDL_DestroyAudioStream() +* SDL_NewAudioStream() => SDL_CreateAudioStream() + + +The following functions have been removed: +* SDL_ConvertAudio() +* SDL_BuildAudioCVT() +* SDL_OpenAudio() +* SDL_CloseAudio() +* SDL_PauseAudio() +* SDL_GetAudioStatus() +* SDL_LockAudio() +* SDL_UnlockAudio() +* SDL_MixAudio() + +Use the SDL_AudioDevice functions instead. + +## SDL_cpuinfo.h + +The intrinsics headers (mmintrin.h, etc.) have been moved to `` and are no longer automatically included in SDL.h. + +SDL_Has3DNow() has been removed; there is no replacement. + +SDL_SIMDAlloc(), SDL_SIMDRealloc(), and SDL_SIMDFree() have been removed. You can use SDL_aligned_alloc() and SDL_aligned_free() with SDL_SIMDGetAlignment() to get the same functionality. + +## SDL_events.h + +The timestamp member of the SDL_Event structure now represents nanoseconds, and is populated with SDL_GetTicksNS() + +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(). + +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(). + +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. + +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. + +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. + +The SDL_EVENT_WINDOW_RESIZED event is always sent, even in response to SDL_SetWindowSize(). + +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. + +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. + +The following symbols have been renamed: +* SDL_APP_DIDENTERBACKGROUND => SDL_EVENT_DID_ENTER_BACKGROUND +* SDL_APP_DIDENTERFOREGROUND => SDL_EVENT_DID_ENTER_FOREGROUND +* SDL_APP_LOWMEMORY => SDL_EVENT_LOW_MEMORY +* SDL_APP_TERMINATING => SDL_EVENT_TERMINATING +* SDL_APP_WILLENTERBACKGROUND => SDL_EVENT_WILL_ENTER_BACKGROUND +* SDL_APP_WILLENTERFOREGROUND => SDL_EVENT_WILL_ENTER_FOREGROUND +* SDL_AUDIODEVICEADDED => SDL_EVENT_AUDIO_DEVICE_ADDED +* SDL_AUDIODEVICEREMOVED => SDL_EVENT_AUDIO_DEVICE_REMOVED +* SDL_CLIPBOARDUPDATE => SDL_EVENT_CLIPBOARD_UPDATE +* SDL_CONTROLLERAXISMOTION => SDL_EVENT_GAMEPAD_AXIS_MOTION +* SDL_CONTROLLERBUTTONDOWN => SDL_EVENT_GAMEPAD_BUTTON_DOWN +* SDL_CONTROLLERBUTTONUP => SDL_EVENT_GAMEPAD_BUTTON_UP +* SDL_CONTROLLERDEVICEADDED => SDL_EVENT_GAMEPAD_ADDED +* SDL_CONTROLLERDEVICEREMAPPED => SDL_EVENT_GAMEPAD_REMAPPED +* SDL_CONTROLLERDEVICEREMOVED => SDL_EVENT_GAMEPAD_REMOVED +* SDL_CONTROLLERSENSORUPDATE => SDL_EVENT_GAMEPAD_SENSOR_UPDATE +* SDL_CONTROLLERTOUCHPADDOWN => SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN +* SDL_CONTROLLERTOUCHPADMOTION => SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION +* SDL_CONTROLLERTOUCHPADUP => SDL_EVENT_GAMEPAD_TOUCHPAD_UP +* SDL_DROPBEGIN => SDL_EVENT_DROP_BEGIN +* SDL_DROPCOMPLETE => SDL_EVENT_DROP_COMPLETE +* SDL_DROPFILE => SDL_EVENT_DROP_FILE +* SDL_DROPTEXT => SDL_EVENT_DROP_TEXT +* SDL_FINGERDOWN => SDL_EVENT_FINGER_DOWN +* SDL_FINGERMOTION => SDL_EVENT_FINGER_MOTION +* SDL_FINGERUP => SDL_EVENT_FINGER_UP +* SDL_FIRSTEVENT => SDL_EVENT_FIRST +* SDL_JOYAXISMOTION => SDL_EVENT_JOYSTICK_AXIS_MOTION +* SDL_JOYBATTERYUPDATED => SDL_EVENT_JOYSTICK_BATTERY_UPDATED +* SDL_JOYBUTTONDOWN => SDL_EVENT_JOYSTICK_BUTTON_DOWN +* SDL_JOYBUTTONUP => SDL_EVENT_JOYSTICK_BUTTON_UP +* SDL_JOYDEVICEADDED => SDL_EVENT_JOYSTICK_ADDED +* SDL_JOYDEVICEREMOVED => SDL_EVENT_JOYSTICK_REMOVED +* SDL_JOYHATMOTION => SDL_EVENT_JOYSTICK_HAT_MOTION +* SDL_KEYDOWN => SDL_EVENT_KEY_DOWN +* SDL_KEYMAPCHANGED => SDL_EVENT_KEYMAP_CHANGED +* SDL_KEYUP => SDL_EVENT_KEY_UP +* SDL_LASTEVENT => SDL_EVENT_LAST +* SDL_LOCALECHANGED => SDL_EVENT_LOCALE_CHANGED +* SDL_MOUSEBUTTONDOWN => SDL_EVENT_MOUSE_BUTTON_DOWN +* SDL_MOUSEBUTTONUP => SDL_EVENT_MOUSE_BUTTON_UP +* SDL_MOUSEMOTION => SDL_EVENT_MOUSE_MOTION +* SDL_MOUSEWHEEL => SDL_EVENT_MOUSE_WHEEL +* SDL_POLLSENTINEL => SDL_EVENT_POLL_SENTINEL +* SDL_QUIT => SDL_EVENT_QUIT +* SDL_RENDER_DEVICE_RESET => SDL_EVENT_RENDER_DEVICE_RESET +* SDL_RENDER_TARGETS_RESET => SDL_EVENT_RENDER_TARGETS_RESET +* SDL_SENSORUPDATE => SDL_EVENT_SENSOR_UPDATE +* SDL_SYSWMEVENT => SDL_EVENT_SYSWM +* SDL_TEXTEDITING => SDL_EVENT_TEXT_EDITING +* SDL_TEXTEDITING_EXT => SDL_EVENT_TEXT_EDITING_EXT +* SDL_TEXTINPUT => SDL_EVENT_TEXT_INPUT +* SDL_USEREVENT => SDL_EVENT_USER + +The following structures have been renamed: +* SDL_ControllerAxisEvent => SDL_GamepadAxisEvent +* SDL_ControllerButtonEvent => SDL_GamepadButtonEvent +* SDL_ControllerDeviceEvent => SDL_GamepadDeviceEvent +* SDL_ControllerSensorEvent => SDL_GamepadSensorEvent +* SDL_ControllerTouchpadEvent => SDL_GamepadTouchpadEvent + +The following functions have been removed: +* SDL_EventState() - replaced with SDL_SetEventEnabled() +* SDL_GetEventState() - replaced with SDL_EventEnabled() + +## SDL_gamecontroller.h + +SDL_gamecontroller.h has been renamed SDL_gamepad.h, and all APIs have been renamed to match. + +The SDL_EVENT_GAMEPAD_ADDED event now provides the joystick instance ID in the which member of the cdevice event structure. + +The functions SDL_GetGamepads(), SDL_GetGamepadInstanceName(), SDL_GetGamepadInstancePath(), SDL_GetGamepadInstancePlayerIndex(), SDL_GetGamepadInstanceGUID(), SDL_GetGamepadInstanceVendor(), SDL_GetGamepadInstanceProduct(), SDL_GetGamepadInstanceProductVersion(), and SDL_GetGamepadInstanceType() have been added to directly query the list of available gamepads. + +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. + +The following enums have been renamed: +* SDL_GameControllerAxis => SDL_GamepadAxis +* SDL_GameControllerBindType => SDL_GamepadBindingType +* SDL_GameControllerButton => SDL_GamepadButton +* SDL_GameControllerType => SDL_GamepadType + +The following structures have been renamed: +* SDL_GameController => SDL_Gamepad +* SDL_GameControllerButtonBind => SDL_GamepadBinding + +The following functions have been renamed: +* SDL_GameControllerAddMapping() => SDL_AddGamepadMapping() +* SDL_GameControllerAddMappingsFromFile() => SDL_AddGamepadMappingsFromFile() +* SDL_GameControllerAddMappingsFromRW() => SDL_AddGamepadMappingsFromRW() +* SDL_GameControllerClose() => SDL_CloseGamepad() +* SDL_GameControllerFromInstanceID() => SDL_GetGamepadFromInstanceID() +* SDL_GameControllerFromPlayerIndex() => SDL_GetGamepadFromPlayerIndex() +* SDL_GameControllerGetAppleSFSymbolsNameForAxis() => SDL_GetGamepadAppleSFSymbolsNameForAxis() +* SDL_GameControllerGetAppleSFSymbolsNameForButton() => SDL_GetGamepadAppleSFSymbolsNameForButton() +* SDL_GameControllerGetAttached() => SDL_GamepadConnected() +* SDL_GameControllerGetAxis() => SDL_GetGamepadAxis() +* SDL_GameControllerGetAxisFromString() => SDL_GetGamepadAxisFromString() +* SDL_GameControllerGetBindForAxis() => SDL_GetGamepadBindForAxis() +* SDL_GameControllerGetBindForButton() => SDL_GetGamepadBindForButton() +* SDL_GameControllerGetButton() => SDL_GetGamepadButton() +* SDL_GameControllerGetButtonFromString() => SDL_GetGamepadButtonFromString() +* SDL_GameControllerGetFirmwareVersion() => SDL_GetGamepadFirmwareVersion() +* SDL_GameControllerGetJoystick() => SDL_GetGamepadJoystick() +* SDL_GameControllerGetNumTouchpadFingers() => SDL_GetNumGamepadTouchpadFingers() +* SDL_GameControllerGetNumTouchpads() => SDL_GetNumGamepadTouchpads() +* SDL_GameControllerGetPlayerIndex() => SDL_GetGamepadPlayerIndex() +* SDL_GameControllerGetProduct() => SDL_GetGamepadProduct() +* SDL_GameControllerGetProductVersion() => SDL_GetGamepadProductVersion() +* SDL_GameControllerGetSensorData() => SDL_GetGamepadSensorData() +* SDL_GameControllerGetSensorDataRate() => SDL_GetGamepadSensorDataRate() +* SDL_GameControllerGetSerial() => SDL_GetGamepadSerial() +* SDL_GameControllerGetStringForAxis() => SDL_GetGamepadStringForAxis() +* SDL_GameControllerGetStringForButton() => SDL_GetGamepadStringForButton() +* SDL_GameControllerGetTouchpadFinger() => SDL_GetGamepadTouchpadFinger() +* SDL_GameControllerGetType() => SDL_GetGamepadType() +* SDL_GameControllerGetVendor() => SDL_GetGamepadVendor() +* SDL_GameControllerHasAxis() => SDL_GamepadHasAxis() +* SDL_GameControllerHasButton() => SDL_GamepadHasButton() +* SDL_GameControllerHasLED() => SDL_GamepadHasLED() +* SDL_GameControllerHasRumble() => SDL_GamepadHasRumble() +* SDL_GameControllerHasRumbleTriggers() => SDL_GamepadHasRumbleTriggers() +* SDL_GameControllerHasSensor() => SDL_GamepadHasSensor() +* SDL_GameControllerIsSensorEnabled() => SDL_GamepadSensorEnabled() +* SDL_GameControllerMapping() => SDL_GetGamepadMapping() +* SDL_GameControllerMappingForGUID() => SDL_GetGamepadMappingForGUID() +* SDL_GameControllerMappingForIndex() => SDL_GetGamepadMappingForIndex() +* SDL_GameControllerName() => SDL_GetGamepadName() +* SDL_GameControllerNumMappings() => SDL_GetNumGamepadMappings() +* SDL_GameControllerOpen() => SDL_OpenGamepad() +* SDL_GameControllerPath() => SDL_GetGamepadPath() +* SDL_GameControllerRumble() => SDL_RumbleGamepad() +* SDL_GameControllerRumbleTriggers() => SDL_RumbleGamepadTriggers() +* SDL_GameControllerSendEffect() => SDL_SendGamepadEffect() +* SDL_GameControllerSetLED() => SDL_SetGamepadLED() +* SDL_GameControllerSetPlayerIndex() => SDL_SetGamepadPlayerIndex() +* SDL_GameControllerSetSensorEnabled() => SDL_SetGamepadSensorEnabled() +* SDL_GameControllerUpdate() => SDL_UpdateGamepads() +* SDL_IsGameController() => SDL_IsGamepad() + +The following functions have been removed: +* SDL_GameControllerEventState() - replaced with SDL_SetGamepadEventsEnabled() and SDL_GamepadEventsEnabled() +* SDL_GameControllerMappingForDeviceIndex() - replaced with SDL_GetGamepadInstanceMapping() +* SDL_GameControllerNameForIndex() - replaced with SDL_GetGamepadInstanceName() +* SDL_GameControllerPathForIndex() - replaced with SDL_GetGamepadInstancePath() +* SDL_GameControllerTypeForIndex() - replaced with SDL_GetGamepadInstanceType() + +The following symbols have been renamed: +* SDL_CONTROLLER_AXIS_INVALID => SDL_GAMEPAD_AXIS_INVALID +* SDL_CONTROLLER_AXIS_LEFTX => SDL_GAMEPAD_AXIS_LEFTX +* SDL_CONTROLLER_AXIS_LEFTY => SDL_GAMEPAD_AXIS_LEFTY +* SDL_CONTROLLER_AXIS_MAX => SDL_GAMEPAD_AXIS_MAX +* SDL_CONTROLLER_AXIS_RIGHTX => SDL_GAMEPAD_AXIS_RIGHTX +* SDL_CONTROLLER_AXIS_RIGHTY => SDL_GAMEPAD_AXIS_RIGHTY +* SDL_CONTROLLER_AXIS_TRIGGERLEFT => SDL_GAMEPAD_AXIS_LEFT_TRIGGER +* SDL_CONTROLLER_AXIS_TRIGGERRIGHT => SDL_GAMEPAD_AXIS_RIGHT_TRIGGER +* SDL_CONTROLLER_BINDTYPE_AXIS => SDL_GAMEPAD_BINDTYPE_AXIS +* SDL_CONTROLLER_BINDTYPE_BUTTON => SDL_GAMEPAD_BINDTYPE_BUTTON +* SDL_CONTROLLER_BINDTYPE_HAT => SDL_GAMEPAD_BINDTYPE_HAT +* SDL_CONTROLLER_BINDTYPE_NONE => SDL_GAMEPAD_BINDTYPE_NONE +* SDL_CONTROLLER_BUTTON_A => SDL_GAMEPAD_BUTTON_A +* SDL_CONTROLLER_BUTTON_B => SDL_GAMEPAD_BUTTON_B +* SDL_CONTROLLER_BUTTON_BACK => SDL_GAMEPAD_BUTTON_BACK +* SDL_CONTROLLER_BUTTON_DPAD_DOWN => SDL_GAMEPAD_BUTTON_DPAD_DOWN +* SDL_CONTROLLER_BUTTON_DPAD_LEFT => SDL_GAMEPAD_BUTTON_DPAD_LEFT +* SDL_CONTROLLER_BUTTON_DPAD_RIGHT => SDL_GAMEPAD_BUTTON_DPAD_RIGHT +* SDL_CONTROLLER_BUTTON_DPAD_UP => SDL_GAMEPAD_BUTTON_DPAD_UP +* SDL_CONTROLLER_BUTTON_GUIDE => SDL_GAMEPAD_BUTTON_GUIDE +* SDL_CONTROLLER_BUTTON_INVALID => SDL_GAMEPAD_BUTTON_INVALID +* SDL_CONTROLLER_BUTTON_LEFTSHOULDER => SDL_GAMEPAD_BUTTON_LEFT_SHOULDER +* SDL_CONTROLLER_BUTTON_LEFTSTICK => SDL_GAMEPAD_BUTTON_LEFT_STICK +* SDL_CONTROLLER_BUTTON_MAX => SDL_GAMEPAD_BUTTON_MAX +* SDL_CONTROLLER_BUTTON_MISC1 => SDL_GAMEPAD_BUTTON_MISC1 +* SDL_CONTROLLER_BUTTON_PADDLE1 => SDL_GAMEPAD_BUTTON_PADDLE1 +* SDL_CONTROLLER_BUTTON_PADDLE2 => SDL_GAMEPAD_BUTTON_PADDLE2 +* SDL_CONTROLLER_BUTTON_PADDLE3 => SDL_GAMEPAD_BUTTON_PADDLE3 +* SDL_CONTROLLER_BUTTON_PADDLE4 => SDL_GAMEPAD_BUTTON_PADDLE4 +* SDL_CONTROLLER_BUTTON_RIGHTSHOULDER => SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER +* SDL_CONTROLLER_BUTTON_RIGHTSTICK => SDL_GAMEPAD_BUTTON_RIGHT_STICK +* SDL_CONTROLLER_BUTTON_START => SDL_GAMEPAD_BUTTON_START +* SDL_CONTROLLER_BUTTON_TOUCHPAD => SDL_GAMEPAD_BUTTON_TOUCHPAD +* SDL_CONTROLLER_BUTTON_X => SDL_GAMEPAD_BUTTON_X +* SDL_CONTROLLER_BUTTON_Y => SDL_GAMEPAD_BUTTON_Y +* SDL_CONTROLLER_TYPE_AMAZON_LUNA => SDL_GAMEPAD_TYPE_AMAZON_LUNA +* SDL_CONTROLLER_TYPE_GOOGLE_STADIA => SDL_GAMEPAD_TYPE_GOOGLE_STADIA +* SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT => SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT +* SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR => SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR +* SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT => SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT +* SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO => SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO +* SDL_CONTROLLER_TYPE_NVIDIA_SHIELD => SDL_GAMEPAD_TYPE_NVIDIA_SHIELD +* SDL_CONTROLLER_TYPE_PS3 => SDL_GAMEPAD_TYPE_PS3 +* SDL_CONTROLLER_TYPE_PS4 => SDL_GAMEPAD_TYPE_PS4 +* SDL_CONTROLLER_TYPE_PS5 => SDL_GAMEPAD_TYPE_PS5 +* SDL_CONTROLLER_TYPE_UNKNOWN => SDL_GAMEPAD_TYPE_UNKNOWN +* SDL_CONTROLLER_TYPE_VIRTUAL => SDL_GAMEPAD_TYPE_VIRTUAL +* SDL_CONTROLLER_TYPE_XBOX360 => SDL_GAMEPAD_TYPE_XBOX360 +* SDL_CONTROLLER_TYPE_XBOXONE => SDL_GAMEPAD_TYPE_XBOXONE + +## SDL_gesture.h + +The gesture API has been removed. There is no replacement planned in SDL3. +However, the SDL2 code has been moved to a single-header library that can +be dropped into an SDL3 or SDL2 program, to continue to provide this +functionality to your app and aid migration. That is located in the +[SDL_gesture GitHub repository](https://github.com/libsdl-org/SDL_gesture). + +## SDL_hints.h + +SDL_AddHintCallback() now returns a standard int result instead of void, returning 0 if the function succeeds or a negative error code if there was an error. + +The following hints have been removed: +* SDL_HINT_IDLE_TIMER_DISABLED - use SDL_DisableScreenSaver instead +* SDL_HINT_MOUSE_RELATIVE_SCALING - mouse coordinates are no longer automatically scaled by the SDL renderer +* SDL_HINT_RENDER_LOGICAL_SIZE_MODE - the logical size mode is explicitly set with SDL_SetRenderLogicalPresentation() +* SDL_HINT_VIDEO_X11_FORCE_EGL - use SDL_HINT_VIDEO_FORCE_EGL instead +* SDL_HINT_VIDEO_X11_XINERAMA - Xinerama no longer supported by the X11 backend +* SDL_HINT_VIDEO_X11_XVIDMODE - Xvidmode no longer supported by the X11 backend + +* Renamed hints SDL_HINT_VIDEODRIVER and SDL_HINT_AUDIODRIVER to SDL_HINT_VIDEO_DRIVER and SDL_HINT_AUDIO_DRIVER +* Renamed environment variables SDL_VIDEODRIVER and SDL_AUDIODRIVER to SDL_VIDEO_DRIVER and SDL_AUDIO_DRIVER + +## SDL_init.h + +The following symbols have been renamed: +* SDL_INIT_GAMECONTROLLER => SDL_INIT_GAMEPAD + +The following symbols have been removed: +* SDL_INIT_NOPARACHUTE + +## SDL_joystick.h + +SDL_JoystickID has changed from Sint32 to Uint32, with an invalid ID being 0. + +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: +```c +{ + if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == 0) { + int i, num_joysticks; + SDL_JoystickID *joysticks = SDL_GetJoysticks(&num_joysticks); + if (joysticks) { + for (i = 0; i < num_joysticks; ++i) { + SDL_JoystickID instance_id = joysticks[i]; + const char *name = SDL_GetJoystickInstanceName(instance_id); + const char *path = SDL_GetJoystickInstancePath(instance_id); + + SDL_Log("Joystick %" SDL_PRIu32 ": %s%s%s VID 0x%.4x, PID 0x%.4x\n", + instance_id, name ? name : "Unknown", path ? ", " : "", path ? path : "", SDL_GetJoystickInstanceVendor(instance_id), SDL_GetJoystickInstanceProduct(instance_id)); + } + SDL_free(joysticks); + } + SDL_QuitSubSystem(SDL_INIT_JOYSTICK); + } +} +``` + +The SDL_EVENT_JOYSTICK_ADDED event now provides the joystick instance ID in the `which` member of the jdevice event structure. + +The functions SDL_GetJoysticks(), SDL_GetJoystickInstanceName(), SDL_GetJoystickInstancePath(), SDL_GetJoystickInstancePlayerIndex(), SDL_GetJoystickInstanceGUID(), SDL_GetJoystickInstanceVendor(), SDL_GetJoystickInstanceProduct(), SDL_GetJoystickInstanceProductVersion(), and SDL_GetJoystickInstanceType() have been added to directly query the list of available joysticks. + +SDL_AttachVirtualJoystick() and SDL_AttachVirtualJoystickEx() now return the joystick instance ID instead of a device index, and return 0 if there was an error. + +The following functions have been renamed: +* SDL_JoystickAttachVirtual() => SDL_AttachVirtualJoystick() +* SDL_JoystickAttachVirtualEx() => SDL_AttachVirtualJoystickEx() +* SDL_JoystickClose() => SDL_CloseJoystick() +* SDL_JoystickCurrentPowerLevel() => SDL_GetJoystickPowerLevel() +* SDL_JoystickDetachVirtual() => SDL_DetachVirtualJoystick() +* SDL_JoystickFromInstanceID() => SDL_GetJoystickFromInstanceID() +* SDL_JoystickFromPlayerIndex() => SDL_GetJoystickFromPlayerIndex() +* SDL_JoystickGetAttached() => SDL_JoystickConnected() +* SDL_JoystickGetAxis() => SDL_GetJoystickAxis() +* SDL_JoystickGetAxisInitialState() => SDL_GetJoystickAxisInitialState() +* SDL_JoystickGetButton() => SDL_GetJoystickButton() +* SDL_JoystickGetFirmwareVersion() => SDL_GetJoystickFirmwareVersion() +* SDL_JoystickGetGUID() => SDL_GetJoystickGUID() +* SDL_JoystickGetGUIDFromString() => SDL_GetJoystickGUIDFromString() +* SDL_JoystickGetGUIDString() => SDL_GetJoystickGUIDString() +* SDL_JoystickGetHat() => SDL_GetJoystickHat() +* SDL_JoystickGetPlayerIndex() => SDL_GetJoystickPlayerIndex() +* SDL_JoystickGetProduct() => SDL_GetJoystickProduct() +* SDL_JoystickGetProductVersion() => SDL_GetJoystickProductVersion() +* SDL_JoystickGetSerial() => SDL_GetJoystickSerial() +* SDL_JoystickGetType() => SDL_GetJoystickType() +* SDL_JoystickGetVendor() => SDL_GetJoystickVendor() +* SDL_JoystickInstanceID() => SDL_GetJoystickInstanceID() +* SDL_JoystickIsVirtual() => SDL_IsJoystickVirtual() +* SDL_JoystickName() => SDL_GetJoystickName() +* SDL_JoystickNumAxes() => SDL_GetNumJoystickAxes() +* SDL_JoystickNumButtons() => SDL_GetNumJoystickButtons() +* SDL_JoystickNumHats() => SDL_GetNumJoystickHats() +* SDL_JoystickOpen() => SDL_OpenJoystick() +* SDL_JoystickPath() => SDL_GetJoystickPath() +* SDL_JoystickRumble() => SDL_RumbleJoystick() +* SDL_JoystickRumbleTriggers() => SDL_RumbleJoystickTriggers() +* SDL_JoystickSendEffect() => SDL_SendJoystickEffect() +* SDL_JoystickSetLED() => SDL_SetJoystickLED() +* SDL_JoystickSetPlayerIndex() => SDL_SetJoystickPlayerIndex() +* SDL_JoystickSetVirtualAxis() => SDL_SetJoystickVirtualAxis() +* SDL_JoystickSetVirtualButton() => SDL_SetJoystickVirtualButton() +* SDL_JoystickSetVirtualHat() => SDL_SetJoystickVirtualHat() +* SDL_JoystickUpdate() => SDL_UpdateJoysticks() + +The following symbols have been renamed: +* SDL_JOYSTICK_TYPE_GAMECONTROLLER => SDL_JOYSTICK_TYPE_GAMEPAD + +The following functions have been removed: +* SDL_JoystickEventState() - replaced with SDL_SetJoystickEventsEnabled() and SDL_JoystickEventsEnabled() +* SDL_JoystickGetDeviceGUID() - replaced with SDL_GetJoystickInstanceGUID() +* SDL_JoystickGetDeviceInstanceID() +* SDL_JoystickGetDevicePlayerIndex() - replaced with SDL_GetJoystickInstancePlayerIndex() +* SDL_JoystickGetDeviceProduct() - replaced with SDL_GetJoystickInstanceProduct() +* SDL_JoystickGetDeviceProductVersion() - replaced with SDL_GetJoystickInstanceProductVersion() +* SDL_JoystickGetDeviceType() - replaced with SDL_GetJoystickInstanceType() +* SDL_JoystickGetDeviceVendor() - replaced with SDL_GetJoystickInstanceVendor() +* SDL_JoystickNameForIndex() - replaced with SDL_GetJoystickInstanceName() +* SDL_JoystickPathForIndex() - replaced with SDL_GetJoystickInstancePath() +* SDL_NumJoysticks() - replaced with SDL_GetJoysticks() + +## SDL_keyboard.h + +The following functions have been renamed: +* SDL_IsScreenKeyboardShown() => SDL_ScreenKeyboardShown() +* SDL_IsTextInputActive() => SDL_TextInputActive() +* SDL_IsTextInputShown() => SDL_TextInputShown() + +## SDL_keycode.h + +The following symbols have been renamed: +* KMOD_ALT => SDL_KMOD_ALT +* KMOD_CAPS => SDL_KMOD_CAPS +* KMOD_CTRL => SDL_KMOD_CTRL +* KMOD_GUI => SDL_KMOD_GUI +* KMOD_LALT => SDL_KMOD_LALT +* KMOD_LCTRL => SDL_KMOD_LCTRL +* KMOD_LGUI => SDL_KMOD_LGUI +* KMOD_LSHIFT => SDL_KMOD_LSHIFT +* KMOD_MODE => SDL_KMOD_MODE +* KMOD_NONE => SDL_KMOD_NONE +* KMOD_NUM => SDL_KMOD_NUM +* KMOD_RALT => SDL_KMOD_RALT +* KMOD_RCTRL => SDL_KMOD_RCTRL +* KMOD_RESERVED => SDL_KMOD_RESERVED +* KMOD_RGUI => SDL_KMOD_RGUI +* KMOD_RSHIFT => SDL_KMOD_RSHIFT +* KMOD_SCROLL => SDL_KMOD_SCROLL +* KMOD_SHIFT => SDL_KMOD_SHIFT + +## SDL_loadso.h + +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. + +## SDL_main.h + +SDL3 doesn't have a static libSDLmain to link against anymore. +Instead SDL_main.h is now a header-only library **and not included by SDL.h anymore**. + +Using it is really simple: Just `#include ` in the source file with your standard +`int main(int argc, char* argv[])` function. + +The rest happens automatically: If your target platform needs the SDL_main functionality, +your main function will be renamed to SDL_main (with a macro, just like in SDL2), +and the real main-function will be implemented by inline code from SDL_main.h - and if your target +platform doesn't need it, nothing happens. +Like in SDL2, if you want to handle the platform-specific main yourself instead of using the SDL_main magic, +you can `#define SDL_MAIN_HANDLED` before `#include ` - don't forget to call SDL_SetMainReady() + +If you need SDL_main.h in another source file (that doesn't implement main()), you also need to +`#define SDL_MAIN_HANDLED` there, to avoid that multiple main functions are generated by SDL_main.h + +There is currently one platform where this approach doesn't always work: WinRT. +It requires WinMain to be implemented in a C++ source file that's compiled with `/ZW`. If your main +is implemented in plain C, or you can't use `/ZW` on that file, you can add another .cpp +source file that just contains `#include ` and compile that with `/ZW` - but keep +in mind that the source file with your standard main also needs that include! +See [README-winrt.md](./README-winrt.md) for more details. + +Furthermore, the different SDL_*RunApp() functions (SDL_WinRtRunApp, SDL_GDKRunApp, SDL_UIKitRunApp) +have been unified into just `int SDL_RunApp(int argc, char* argv[], void * reserved)` (which is also +used by additional platforms that didn't have a SDL_RunApp-like function before). + +## SDL_metal.h + +SDL_Metal_GetDrawableSize() has been removed. SDL_GetWindowSizeInPixels() can be used in its place. + +## SDL_mouse.h + +SDL_ShowCursor() has been split into three functions: SDL_ShowCursor(), SDL_HideCursor(), and SDL_CursorVisible() + +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. + +The following functions have been renamed: +* SDL_FreeCursor() => SDL_DestroyCursor() + +## SDL_pixels.h + +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)). + +The following functions have been renamed: +* SDL_AllocFormat() => SDL_CreatePixelFormat() +* SDL_AllocPalette() => SDL_CreatePalette() +* SDL_FreeFormat() => SDL_DestroyPixelFormat() +* SDL_FreePalette() => SDL_DestroyPalette() +* SDL_MasksToPixelFormatEnum() => SDL_GetPixelFormatEnumForMasks() +* SDL_PixelFormatEnumToMasks() => SDL_GetMasksForPixelFormatEnum() + +The following symbols have been renamed: +* SDL_DISPLAYEVENT_DISCONNECTED => SDL_EVENT_DISPLAY_DISCONNECTED +* SDL_DISPLAYEVENT_MOVED => SDL_EVENT_DISPLAY_MOVED +* SDL_DISPLAYEVENT_ORIENTATION => SDL_EVENT_DISPLAY_ORIENTATION +* SDL_WINDOWEVENT_CLOSE => SDL_EVENT_WINDOW_CLOSE_REQUESTED +* SDL_WINDOWEVENT_DISPLAY_CHANGED => SDL_EVENT_WINDOW_DISPLAY_CHANGED +* SDL_WINDOWEVENT_ENTER => SDL_EVENT_WINDOW_ENTER +* SDL_WINDOWEVENT_EXPOSED => SDL_EVENT_WINDOW_EXPOSED +* SDL_WINDOWEVENT_FOCUS_GAINED => SDL_EVENT_WINDOW_FOCUS_GAINED +* SDL_WINDOWEVENT_FOCUS_LOST => SDL_EVENT_WINDOW_FOCUS_LOST +* SDL_WINDOWEVENT_HIDDEN => SDL_EVENT_WINDOW_HIDDEN +* SDL_WINDOWEVENT_HIT_TEST => SDL_EVENT_WINDOW_HIT_TEST +* SDL_WINDOWEVENT_ICCPROF_CHANGED => SDL_EVENT_WINDOW_ICCPROF_CHANGED +* SDL_WINDOWEVENT_LEAVE => SDL_EVENT_WINDOW_LEAVE +* SDL_WINDOWEVENT_MAXIMIZED => SDL_EVENT_WINDOW_MAXIMIZED +* SDL_WINDOWEVENT_MINIMIZED => SDL_EVENT_WINDOW_MINIMIZED +* SDL_WINDOWEVENT_MOVED => SDL_EVENT_WINDOW_MOVED +* SDL_WINDOWEVENT_RESIZED => SDL_EVENT_WINDOW_RESIZED +* SDL_WINDOWEVENT_RESTORED => SDL_EVENT_WINDOW_RESTORED +* SDL_WINDOWEVENT_SHOWN => SDL_EVENT_WINDOW_SHOWN +* SDL_WINDOWEVENT_SIZE_CHANGED => SDL_EVENT_WINDOW_SIZE_CHANGED +* SDL_WINDOWEVENT_TAKE_FOCUS => SDL_EVENT_WINDOW_TAKE_FOCUS + + +## SDL_platform.h + +The preprocessor symbol `__MACOSX__` has been renamed `__MACOS__`, and `__IPHONEOS__` has been renamed `__IOS__` + +## SDL_rect.h + +The following functions have been renamed: +* SDL_EncloseFPoints() => SDL_GetRectEnclosingPointsFloat() +* SDL_EnclosePoints() => SDL_GetRectEnclosingPoints() +* SDL_FRectEmpty() => SDL_RectEmptyFloat() +* SDL_FRectEquals() => SDL_RectsEqualFloat() +* SDL_FRectEqualsEpsilon() => SDL_RectsEqualEpsilon() +* SDL_HasIntersection() => SDL_HasRectIntersection() +* SDL_HasIntersectionF() => SDL_HasRectIntersectionFloat() +* SDL_IntersectFRect() => SDL_GetRectIntersectionFloat() +* SDL_IntersectFRectAndLine() => SDL_GetRectAndLineIntersectionFloat() +* SDL_IntersectRect() => SDL_GetRectIntersection() +* SDL_IntersectRectAndLine() => SDL_GetRectAndLineIntersection() +* SDL_PointInFRect() => SDL_PointInRectFloat() +* SDL_RectEquals() => SDL_RectsEqual() +* SDL_UnionFRect() => SDL_GetRectUnionFloat() +* SDL_UnionRect() => SDL_GetRectUnion() + +## SDL_render.h + +SDL_GetRenderDriverInfo() has been removed, since most of the information it reported were +estimates and could not be accurate before creating a renderer. Often times this function +was used to figure out the index of a driver, so one would call it in a for-loop, looking +for the driver named "opengl" or whatnot. SDL_GetRenderDriver() has been added for this +functionality, which returns only the name of the driver. + +Additionally, SDL_CreateRenderer()'s second argument is no longer an integer index, but a +`const char *` representing a renderer's name; if you were just using a for-loop to find +which index is the "opengl" or whatnot driver, you can just pass that string directly +here, now. Passing NULL is the same as passing -1 here in SDL2, to signify you want SDL +to decide for you. + +When a renderer is created, it will automatically set the logical size to the size of +the window in screen coordinates. For high DPI displays, this will set up scaling from +window coordinates to pixels. You can disable this scaling with: +```c + SDL_SetRenderLogicalPresentation(renderer, 0, 0, SDL_LOGICAL_PRESENTATION_DISABLED, SDL_SCALEMODE_NEAREST); +``` + +Mouse and touch events are no longer filtered to change their coordinates, instead you +can call SDL_ConvertEventToRenderCoordinates() to explicitly map event coordinates into +the rendering viewport. + +SDL_RenderWindowToLogical() and SDL_RenderLogicalToWindow() have been renamed SDL_RenderCoordinatesFromWindow() and SDL_RenderCoordinatesToWindow() and take floating point coordinates in both directions. + +The viewport, clipping state, and scale for render targets are now persistent and will remain set whenever they are active. + +The following functions have been renamed: +* SDL_GetRendererOutputSize() => SDL_GetCurrentRenderOutputSize() +* SDL_RenderCopy() => SDL_RenderTexture() +* SDL_RenderCopyEx() => SDL_RenderTextureRotated() +* SDL_RenderCopyExF() => SDL_RenderTextureRotated() +* SDL_RenderCopyF() => SDL_RenderTexture() +* SDL_RenderDrawLine() => SDL_RenderLine() +* SDL_RenderDrawLineF() => SDL_RenderLine() +* SDL_RenderDrawLines() => SDL_RenderLines() +* SDL_RenderDrawLinesF() => SDL_RenderLines() +* SDL_RenderDrawPoint() => SDL_RenderPoint() +* SDL_RenderDrawPointF() => SDL_RenderPoint() +* SDL_RenderDrawPoints() => SDL_RenderPoints() +* SDL_RenderDrawPointsF() => SDL_RenderPoints() +* SDL_RenderDrawRect() => SDL_RenderRect() +* SDL_RenderDrawRectF() => SDL_RenderRect() +* SDL_RenderDrawRects() => SDL_RenderRects() +* SDL_RenderDrawRectsF() => SDL_RenderRects() +* SDL_RenderFillRectF() => SDL_RenderFillRect() +* SDL_RenderFillRectsF() => SDL_RenderFillRects() +* SDL_RenderGetClipRect() => SDL_GetRenderClipRect() +* SDL_RenderGetIntegerScale() => SDL_GetRenderIntegerScale() +* SDL_RenderGetLogicalSize() => SDL_GetRenderLogicalPresentation() +* SDL_RenderGetMetalCommandEncoder() => SDL_GetRenderMetalCommandEncoder() +* SDL_RenderGetMetalLayer() => SDL_GetRenderMetalLayer() +* SDL_RenderGetScale() => SDL_GetRenderScale() +* SDL_RenderGetViewport() => SDL_GetRenderViewport() +* SDL_RenderGetWindow() => SDL_GetRenderWindow() +* SDL_RenderIsClipEnabled() => SDL_RenderClipEnabled() +* SDL_RenderLogicalToWindow() => SDL_RenderCoordinatesToWindow() +* SDL_RenderSetClipRect() => SDL_SetRenderClipRect() +* SDL_RenderSetIntegerScale() => SDL_SetRenderIntegerScale() +* SDL_RenderSetLogicalSize() => SDL_SetRenderLogicalPresentation() +* SDL_RenderSetScale() => SDL_SetRenderScale() +* SDL_RenderSetVSync() => SDL_SetRenderVSync() +* SDL_RenderSetViewport() => SDL_SetRenderViewport() +* SDL_RenderWindowToLogical() => SDL_RenderCoordinatesFromWindow() + +The following functions have been removed: +* SDL_RenderGetIntegerScale() +* SDL_RenderSetIntegerScale() - this is now explicit with SDL_LOGICAL_PRESENTATION_INTEGER_SCALE +* SDL_RenderTargetSupported() - render targets are always supported + +The following symbols have been renamed: +* SDL_ScaleModeBest => SDL_SCALEMODE_BEST +* SDL_ScaleModeLinear => SDL_SCALEMODE_LINEAR +* SDL_ScaleModeNearest => SDL_SCALEMODE_NEAREST + +## SDL_rwops.h + +The following symbols have been renamed: +* RW_SEEK_CUR => SDL_RW_SEEK_CUR +* RW_SEEK_END => SDL_RW_SEEK_END +* RW_SEEK_SET => SDL_RW_SEEK_SET + +SDL_RWread and SDL_RWwrite (and SDL_RWops::read, SDL_RWops::write) have a different function signature in SDL3. + +Previously they looked more like stdio: + +```c +size_t SDL_RWread(SDL_RWops *context, void *ptr, size_t size, size_t maxnum); +size_t SDL_RWwrite(SDL_RWops *context, const void *ptr, size_t size, size_t maxnum); +``` + +But now they look more like POSIX: + +```c +Sint64 SDL_RWread(SDL_RWops *context, void *ptr, Sint64 size); +Sint64 SDL_RWwrite(SDL_RWops *context, const void *ptr, Sint64 size); +``` + +SDL_RWread() previously returned 0 at end of file or other error. Now it returns the number of bytes read, 0 for end of file, -1 for another error, or -2 for data not ready (in the case of a non-blocking context). + +Code that used to look like this: +``` +size_t custom_read(void *ptr, size_t size, size_t nitems, SDL_RWops *stream) +{ + return (size_t)SDL_RWread(stream, ptr, size, nitems); +} +``` +should be changed to: +``` +size_t custom_read(void *ptr, size_t size, size_t nitems, SDL_RWops *stream) +{ + Sint64 amount = SDL_RWread(stream, ptr, size * nitems); + if (amount <= 0) { + return 0; + } + return (size_t)(amount / size); +} +``` + +Similarly, SDL_RWwrite() can return -2 for data not ready in the case of a non-blocking context. There is currently no way to create a non-blocking context, we have simply defined the semantic for your own custom SDL_RWops object. + +SDL_RWFromFP has been removed from the API, due to issues when the SDL library uses a different C runtime from the application. + +You can implement this in your own code easily: +```c +#include + + +static Sint64 SDLCALL +stdio_size(SDL_RWops * context) +{ + Sint64 pos, size; + + pos = SDL_RWseek(context, 0, SDL_RW_SEEK_CUR); + if (pos < 0) { + return -1; + } + size = SDL_RWseek(context, 0, SDL_RW_SEEK_END); + + SDL_RWseek(context, pos, SDL_RW_SEEK_SET); + return size; +} + +static Sint64 SDLCALL +stdio_seek(SDL_RWops * context, Sint64 offset, int whence) +{ + int stdiowhence; + + switch (whence) { + case SDL_RW_SEEK_SET: + stdiowhence = SEEK_SET; + break; + case SDL_RW_SEEK_CUR: + stdiowhence = SEEK_CUR; + break; + case SDL_RW_SEEK_END: + stdiowhence = SEEK_END; + break; + default: + return SDL_SetError("Unknown value for 'whence'"); + } + + if (fseek((FILE *)context->hidden.stdio.fp, (fseek_off_t)offset, stdiowhence) == 0) { + Sint64 pos = ftell((FILE *)context->hidden.stdio.fp); + if (pos < 0) { + return SDL_SetError("Couldn't get stream offset"); + } + return pos; + } + return SDL_Error(SDL_EFSEEK); +} + +static Sint64 SDLCALL +stdio_read(SDL_RWops * context, void *ptr, Sint64 size) +{ + size_t nread; + + nread = fread(ptr, 1, (size_t) size, (FILE *)context->hidden.stdio.fp); + if (nread == 0 && ferror((FILE *)context->hidden.stdio.fp)) { + return SDL_Error(SDL_EFREAD); + } + return (Sint64) nread; +} + +static Sint64 SDLCALL +stdio_write(SDL_RWops * context, const void *ptr, Sint64 size) +{ + size_t nwrote; + + nwrote = fwrite(ptr, 1, (size_t) size, (FILE *)context->hidden.stdio.fp); + if (nwrote == 0 && ferror((FILE *)context->hidden.stdio.fp)) { + return SDL_Error(SDL_EFWRITE); + } + return (Sint64) nwrote; +} + +static int SDLCALL +stdio_close(SDL_RWops * context) +{ + int status = 0; + if (context) { + if (context->hidden.stdio.autoclose) { + /* WARNING: Check the return value here! */ + if (fclose((FILE *)context->hidden.stdio.fp) != 0) { + status = SDL_Error(SDL_EFWRITE); + } + } + SDL_DestroyRW(context); + } + return status; +} + +SDL_RWops * +SDL_RWFromFP(void *fp, SDL_bool autoclose) +{ + SDL_RWops *rwops = NULL; + + rwops = SDL_CreateRW(); + if (rwops != NULL) { + rwops->size = stdio_size; + rwops->seek = stdio_seek; + rwops->read = stdio_read; + rwops->write = stdio_write; + rwops->close = stdio_close; + rwops->hidden.stdio.fp = fp; + rwops->hidden.stdio.autoclose = autoclose; + rwops->type = SDL_RWOPS_STDFILE; + } + return rwops; +} +``` + + +The following functions have been renamed: +* SDL_AllocRW() => SDL_CreateRW() +* SDL_FreeRW() => SDL_DestroyRW() + +## SDL_sensor.h + +SDL_SensorID has changed from Sint32 to Uint32, with an invalid ID being 0. + +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: +```c +{ + if (SDL_InitSubSystem(SDL_INIT_SENSOR) == 0) { + int i, num_sensors; + SDL_SensorID *sensors = SDL_GetSensors(&num_sensors); + if (sensors) { + for (i = 0; i < num_sensors; ++i) { + SDL_Log("Sensor %" SDL_PRIu32 ": %s, type %d, platform type %d\n", + sensors[i], + SDL_GetSensorInstanceName(sensors[i]), + SDL_GetSensorInstanceType(sensors[i]), + SDL_GetSensorInstanceNonPortableType(sensors[i])); + } + SDL_free(sensors); + } + SDL_QuitSubSystem(SDL_INIT_SENSOR); + } +} +``` + +Removed SDL_SensorGetDataWithTimestamp(), if you want timestamps for the sensor data, you should use the sensor_timestamp member of SDL_EVENT_SENSOR_UPDATE events. + + +The following functions have been renamed: +* SDL_SensorClose() => SDL_CloseSensor() +* SDL_SensorFromInstanceID() => SDL_GetSensorFromInstanceID() +* SDL_SensorGetData() => SDL_GetSensorData() +* SDL_SensorGetInstanceID() => SDL_GetSensorInstanceID() +* SDL_SensorGetName() => SDL_GetSensorName() +* SDL_SensorGetNonPortableType() => SDL_GetSensorNonPortableType() +* SDL_SensorGetType() => SDL_GetSensorType() +* SDL_SensorOpen() => SDL_OpenSensor() +* SDL_SensorUpdate() => SDL_UpdateSensors() + +The following functions have been removed: +* SDL_LockSensors() +* SDL_NumSensors() - replaced with SDL_GetSensors() +* SDL_SensorGetDeviceInstanceID() +* SDL_SensorGetDeviceName() - replaced with SDL_GetSensorInstanceName() +* SDL_SensorGetDeviceNonPortableType() - replaced with SDL_GetSensorInstanceNonPortableType() +* SDL_SensorGetDeviceType() - replaced with SDL_GetSensorInstanceType() +* SDL_UnlockSensors() + +## SDL_stdinc.h + +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. +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. + + +## SDL_surface.h + +Removed unused 'flags' parameter from SDL_ConvertSurface and SDL_ConvertSurfaceFormat. + +SDL_CreateRGBSurface() and SDL_CreateRGBSurfaceWithFormat() have been combined into a new function SDL_CreateSurface(). +SDL_CreateRGBSurfaceFrom() and SDL_CreateRGBSurfaceWithFormatFrom() have been combined into a new function SDL_CreateSurfaceFrom(). + +You can implement the old functions in your own code easily: +```c +SDL_Surface *SDL_CreateRGBSurface(Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) +{ + return SDL_CreateSurface(width, height, + SDL_GetPixelFormatEnumForMasks(depth, Rmask, Gmask, Bmask, Amask)); +} + +SDL_Surface *SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int width, int height, int depth, Uint32 format) +{ + return SDL_CreateSurface(width, height, format); +} + +SDL_Surface *SDL_CreateRGBSurfaceFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) +{ + return SDL_CreateSurfaceFrom(pixels, width, height, pitch, + SDL_GetPixelFormatEnumForMasks(depth, Rmask, Gmask, Bmask, Amask)); +} + +SDL_Surface *SDL_CreateRGBSurfaceWithFormatFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 format) +{ + return SDL_CreateSurfaceFrom(pixels, width, height, pitch, format); +} + +``` + +But if you're migrating your code which uses masks, you probably have a format in mind, possibly one of these: +```c +// Various mask (R, G, B, A) and their corresponding format: +0xFF000000 0x00FF0000 0x0000FF00 0x000000FF => SDL_PIXELFORMAT_RGBA8888 +0x00FF0000 0x0000FF00 0x000000FF 0xFF000000 => SDL_PIXELFORMAT_ARGB8888 +0x0000FF00 0x00FF0000 0xFF000000 0x000000FF => SDL_PIXELFORMAT_BGRA8888 +0x000000FF 0x0000FF00 0x00FF0000 0xFF000000 => SDL_PIXELFORMAT_ABGR8888 +0x0000F800 0x000007E0 0x0000001F 0x00000000 => SDL_PIXELFORMAT_RGB565 +``` + + +The following functions have been renamed: +* SDL_FillRect() => SDL_FillSurfaceRect() +* SDL_FillRects() => SDL_FillSurfaceRects() +* SDL_FreeSurface() => SDL_DestroySurface() +* SDL_GetClipRect() => SDL_GetSurfaceClipRect() +* SDL_GetColorKey() => SDL_GetSurfaceColorKey() +* SDL_HasColorKey() => SDL_SurfaceHasColorKey() +* SDL_HasSurfaceRLE() => SDL_SurfaceHasRLE() +* SDL_LowerBlit() => SDL_BlitSurfaceUnchecked() +* SDL_LowerBlitScaled() => SDL_BlitSurfaceUncheckedScaled() +* SDL_SetClipRect() => SDL_SetSurfaceClipRect() +* SDL_SetColorKey() => SDL_SetSurfaceColorKey() +* SDL_UpperBlit() => SDL_BlitSurface() +* SDL_UpperBlitScaled() => SDL_BlitSurfaceScaled() + +## SDL_system.h + +SDL_AndroidGetExternalStorageState() takes the state as an output parameter and returns 0 if the function succeeds or a negative error code if there was an error. + +The following functions have been renamed: +* SDL_RenderGetD3D11Device() => SDL_GetRenderD3D11Device() +* SDL_RenderGetD3D9Device() => SDL_GetRenderD3D9Device() + +## SDL_syswm.h + +The structures in this file are versioned separately from the rest of SDL, allowing better backwards compatibility and limited forwards compatibility with your application. Instead of calling `SDL_VERSION(&info.version)` before calling SDL_GetWindowWMInfo(), you pass the version in explicitly as SDL_SYSWM_CURRENT_VERSION so SDL knows what fields you expect to be filled out. + +### SDL_GetWindowWMInfo + +This function now returns a standard int result instead of SDL_bool, returning 0 if the function succeeds or a negative error code if there was an error. You should also pass SDL_SYSWM_CURRENT_VERSION as the new third version parameter. The version member of the info structure will be filled in with the version of data that is returned, the minimum of the version you requested and the version supported by the runtime SDL library. + + +## SDL_timer.h + +SDL_GetTicks() now returns a 64-bit value. Instead of using the SDL_TICKS_PASSED macro, you can directly compare tick values, e.g. +```c +Uint32 deadline = SDL_GetTicks() + 1000; +... +if (SDL_TICKS_PASSED(SDL_GetTicks(), deadline)) { + ... +} +``` +becomes: +```c +Uint64 deadline = SDL_GetTicks() + 1000 +... +if (SDL_GetTicks() >= deadline) { + ... +} +``` + +If you were using this macro for other things besides SDL ticks values, you can define it in your own code as: +```c +#define SDL_TICKS_PASSED(A, B) ((Sint32)((B) - (A)) <= 0) +``` + +## SDL_touch.h + +SDL_GetNumTouchFingers() returns a negative error code if there was an error. + +## SDL_version.h + +SDL_GetRevisionNumber() has been removed from the API, it always returned 0 in SDL 2.0. + + +## SDL_video.h + +SDL_VideoInit() and SDL_VideoQuit() have been removed. Instead you can call SDL_InitSubSytem() and SDL_QuitSubSytem() with SDL_INIT_VIDEO, which will properly refcount the subsystems. You can choose a specific video driver using SDL_VIDEO_DRIVER hint. + +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. +```c +{ + if (SDL_InitSubSystem(SDL_INIT_VIDEO) == 0) { + int i, num_displays = 0; + SDL_DisplayID *displays = SDL_GetDisplays(&num_displays); + if (displays) { + for (i = 0; i < num_displays; ++i) { + SDL_DisplayID instance_id = displays[i]; + const char *name = SDL_GetDisplayName(instance_id); + + SDL_Log("Display %" SDL_PRIu32 ": %s\n", instance_id, name ? name : "Unknown"); + } + SDL_free(displays); + } + SDL_QuitSubSystem(SDL_INIT_VIDEO); + } +} +``` + +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. + +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. + +The SDL_WINDOW_ALLOW_HIGHDPI flag has been removed. Windows are automatically high DPI aware and their coordinates are in screen space, which may differ from physical pixels on displays using display scaling. + +SDL_DisplayMode now includes the pixel size, the screen size and the relationship between the two. For example, a 4K display at 200% scale could have a pixel size of 3840x2160, a screen size of 1920x1080, and a display scale of 2.0. + +The refresh rate in SDL_DisplayMode is now a float. + +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. +```c +{ + SDL_DisplayID display = SDL_GetPrimaryDisplay(); + int num_modes = 0; + SDL_DisplayMode **modes = SDL_GetFullscreenDisplayModes(display, &num_modes); + if (modes) { + for (i = 0; i < num_modes; ++i) { + SDL_DisplayMode *mode = modes[i]; + SDL_Log("Display %" SDL_PRIu32 " mode %d: %dx%d@%gHz, %d%% scale\n", + display, i, mode->pixel_w, mode->pixel_h, mode->refresh_rate, (int)(mode->display_scale * 100.0f)); + } + SDL_free(modes); + } +} +``` + +SDL_GetDesktopDisplayMode() and SDL_GetCurrentDisplayMode() return pointers to display modes rather than filling in application memory. + +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. + +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 fullscreen desktop mode will be used when the window is fullscreen. + +SDL_SetWindowBrightness and SDL_SetWindowGammaRamp 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. + +Programs which have access to shaders can implement more robust versions of those functions using custom shader code rendered as a post-process effect. + +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);` + +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. + +SDL_GL_SwapWindow() returns 0 if the function succeeds or a negative error code if there was an error. + +SDL_GL_GetSwapInterval() takes the interval as an output parameter and returns 0 if the function succeeds or a negative error code if there was an error. + +SDL_GL_GetDrawableSize() has been removed. SDL_GetWindowSizeInPixels() can be used in its place. + +The following functions have been renamed: +* SDL_GetClosestDisplayMode() => SDL_GetClosestFullscreenDisplayMode() +* SDL_GetPointDisplayIndex() => SDL_GetDisplayForPoint() +* SDL_GetRectDisplayIndex() => SDL_GetDisplayForRect() +* SDL_GetWindowDisplayIndex() => SDL_GetDisplayForWindow() +* SDL_GetWindowDisplayMode() => SDL_GetWindowFullscreenMode() +* SDL_SetWindowDisplayMode() => SDL_SetWindowFullscreenMode() + +The following functions have been removed: +* SDL_GetClosestFullscreenDisplayMode() +* SDL_GetDisplayDPI() - not reliable across platforms, approximately replaced by multiplying `display_scale` in the structure returned by SDL_GetDesktopDisplayMode() times 160 on iPhone and Android, and 96 on other platforms. +* SDL_GetDisplayMode() +* SDL_GetNumDisplayModes() - replaced with SDL_GetFullscreenDisplayModes() +* SDL_GetNumVideoDisplays() - replaced with SDL_GetDisplays() + +SDL_Window id type is named SDL_WindowID + +The following symbols have been renamed: +* SDL_WINDOW_INPUT_GRABBED => SDL_WINDOW_MOUSE_GRABBED + +## SDL_vulkan.h + +SDL_Vulkan_GetInstanceExtensions() no longer takes a window parameter. + +SDL_Vulkan_GetVkGetInstanceProcAddr() now returns `SDL_FunctionPointer` instead of `void *`, and should be cast to PFN_vkGetInstanceProcAddr. + +SDL_Vulkan_GetDrawableSize() has been removed. SDL_GetWindowSizeInPixels() can be used in its place. + diff --git a/docs/README-ngage.md b/docs/README-ngage.md index 363760b99..ec4a7121a 100644 --- a/docs/README-ngage.md +++ b/docs/README-ngage.md @@ -1,44 +1,44 @@ -Nokia N-Gage -============ - -SDL port for Symbian S60v1 and v2 with a main focus on the Nokia N-Gage -(Classic and QD) by [Michael Fitzmayer](https://github.com/mupfdev). - -Compiling ---------- - -SDL is part of the [N-Gage SDK.](https://github.com/ngagesdk) project. -The library is included in the -[toolchain](https://github.com/ngagesdk/ngage-toolchain) as a -sub-module. - -A complete example project based on SDL can be found in the GitHub -account of the SDK: [Wordle](https://github.com/ngagesdk/wordle). - -Current level of implementation -------------------------------- - -The video driver currently provides full screen video support with -keyboard input. - -At the moment only the software renderer works. - -Audio is not yet implemented. - -Acknowledgements ----------------- - -Thanks to Hannu Viitala, Kimmo Kinnunen and Markus Mertama for the -valuable insight into Symbian programming. Without the SDL 1.2 port -which was specially developed for CDoom (Doom for the Nokia 9210), this -adaptation would not have been possible. - -I would like to thank my friends -[Razvan](https://twitter.com/bewarerazvan) and [Dan -Whelan](https://danwhelan.ie/), for their continuous support. Without -you and the [N-Gage community](https://discord.gg/dbUzqJ26vs), I would -have lost my patience long ago. - -Last but not least, I would like to thank the development team of -[EKA2L1](https://12z1.com/) (an experimental Symbian OS emulator). Your -patience and support in troubleshooting helped me a lot. +Nokia N-Gage +============ + +SDL port for Symbian S60v1 and v2 with a main focus on the Nokia N-Gage +(Classic and QD) by [Michael Fitzmayer](https://github.com/mupfdev). + +Compiling +--------- + +SDL is part of the [N-Gage SDK.](https://github.com/ngagesdk) project. +The library is included in the +[toolchain](https://github.com/ngagesdk/ngage-toolchain) as a +sub-module. + +A complete example project based on SDL can be found in the GitHub +account of the SDK: [Wordle](https://github.com/ngagesdk/wordle). + +Current level of implementation +------------------------------- + +The video driver currently provides full screen video support with +keyboard input. + +At the moment only the software renderer works. + +Audio is not yet implemented. + +Acknowledgements +---------------- + +Thanks to Hannu Viitala, Kimmo Kinnunen and Markus Mertama for the +valuable insight into Symbian programming. Without the SDL 1.2 port +which was specially developed for CDoom (Doom for the Nokia 9210), this +adaptation would not have been possible. + +I would like to thank my friends +[Razvan](https://twitter.com/bewarerazvan) and [Dan +Whelan](https://danwhelan.ie/), for their continuous support. Without +you and the [N-Gage community](https://discord.gg/dbUzqJ26vs), I would +have lost my patience long ago. + +Last but not least, I would like to thank the development team of +[EKA2L1](https://12z1.com/) (an experimental Symbian OS emulator). Your +patience and support in troubleshooting helped me a lot. diff --git a/docs/README-ps2.md b/docs/README-ps2.md index 095e5685b..6283b9f5f 100644 --- a/docs/README-ps2.md +++ b/docs/README-ps2.md @@ -33,7 +33,7 @@ int main(int argc, char *argv[]) { ..... ``` -For a release binary is recommendable to reset the IOP always. +For a release binary is recommendable to reset the IOP always. Remember to do a clean compilation everytime you enable or disable the `SDL_PS2_SKIP_IOP_RESET` otherwise the change won't be reflected. diff --git a/docs/README-psp.md b/docs/README-psp.md index 5d9b34f8d..e10f5c2dd 100644 --- a/docs/README-psp.md +++ b/docs/README-psp.md @@ -1,7 +1,7 @@ PSP ====== SDL port for the Sony PSP contributed by: -- Captian Lex +- Captian Lex - Francisco Javier Trujillo Mata - Wouter Wijsman diff --git a/docs/README-raspberrypi.md b/docs/README-raspberrypi.md index e8cdf40df..94093f023 100644 --- a/docs/README-raspberrypi.md +++ b/docs/README-raspberrypi.md @@ -20,9 +20,9 @@ Raspbian Build Dependencies sudo apt-get install libudev-dev libasound2-dev libdbus-1-dev -You also need the VideoCore binary stuff that ships in /opt/vc for EGL and +You also need the VideoCore binary stuff that ships in /opt/vc for EGL and OpenGL ES 2.x, it usually comes pre-installed, but in any case: - + sudo apt-get install libraspberrypi0 libraspberrypi-bin libraspberrypi-dev @@ -45,7 +45,7 @@ will be placed in /opt/rpi-tools sudo git clone --depth 1 https://github.com/raspberrypi/tools /opt/rpi-tools You'll also need a Raspbian binary image. -Get it from: http://downloads.raspberrypi.org/raspbian_latest +Get it from: http://downloads.raspberrypi.org/raspbian_latest After unzipping, you'll get file with a name like: "-wheezy-raspbian.img" Let's assume the sysroot will be built in /opt/rpi-sysroot. @@ -69,8 +69,8 @@ edit $SYSROOT/etc/ld.so.preload and comment out all lines in it. sudo umount $SYSROOT/proc sudo umount $SYSROOT/sys sudo umount /mnt - -There's one more fix required, as the libdl.so symlink uses an absolute path + +There's one more fix required, as the libdl.so symlink uses an absolute path which doesn't quite work in our setup. sudo rm -rf $SYSROOT/usr/lib/arm-linux-gnueabihf/libdl.so @@ -86,13 +86,13 @@ The final step is compiling SDL itself. make install To be able to deploy this to /usr/local in the Raspbian system you need to fix up a few paths: - + perl -w -pi -e "s#$PWD/rpi-sdl3-installed#/usr/local#g;" ./rpi-sdl3-installed/lib/libSDL3.la ./rpi-sdl3-installed/lib/pkgconfig/sdl3.pc - + Apps don't work or poor video/audio performance ----------------------------------------------- -If you get sound problems, buffer underruns, etc, run "sudo rpi-update" to +If you get sound problems, buffer underruns, etc, run "sudo rpi-update" to update the RPi's firmware. Note that doing so will fix these problems, but it will also render the CMA - Dynamic Memory Split functionality useless. @@ -101,7 +101,7 @@ low in general, specially if a 1080p TV is hooked up. See here how to configure this setting: http://elinux.org/RPiconfig -Using a fixed gpu_mem=128 is the best option (specially if you updated the +Using a fixed gpu_mem=128 is the best option (specially if you updated the firmware, using CMA probably won't work, at least it's the current case). No input @@ -115,9 +115,9 @@ No HDMI Audio ------------- If you notice that ALSA works but there's no audio over HDMI, try adding: - + hdmi_drive=2 - + to your config.txt file and reboot. Reference: http://www.raspberrypi.org/phpBB3/viewtopic.php?t=5062 @@ -129,7 +129,7 @@ The Text Input API is supported, with translation of scan codes done via the kernel symbol tables. For this to work, SDL needs access to a valid console. If you notice there's no SDL_EVENT_TEXT_INPUT message being emitted, double check that your app has read access to one of the following: - + * /proc/self/fd/0 * /dev/tty * /dev/tty[0...6] @@ -137,17 +137,17 @@ your app has read access to one of the following: * /dev/console This is usually not a problem if you run from the physical terminal (as opposed -to running from a pseudo terminal, such as via SSH). If running from a PTS, a +to running from a pseudo terminal, such as via SSH). If running from a PTS, a quick workaround is to run your app as root or add yourself to the tty group, then re-login to the system. sudo usermod -aG tty `whoami` - + The keyboard layout used by SDL is the same as the one the kernel uses. To configure the layout on Raspbian: - + sudo dpkg-reconfigure keyboard-configuration - + To configure the locale, which controls which keys are interpreted as letters, this determining the CAPS LOCK behavior: @@ -157,9 +157,9 @@ this determining the CAPS LOCK behavior: OpenGL problems --------------- -If you have desktop OpenGL headers installed at build time in your RPi or cross -compilation environment, support for it will be built in. However, the chipset -does not actually have support for it, which causes issues in certain SDL apps +If you have desktop OpenGL headers installed at build time in your RPi or cross +compilation environment, support for it will be built in. However, the chipset +does not actually have support for it, which causes issues in certain SDL apps since the presence of OpenGL support supersedes the ES/ES2 variants. The workaround is to disable OpenGL at configuration time: @@ -176,5 +176,5 @@ Notes * When launching apps remotely (via SSH), SDL can prevent local keystrokes from leaking into the console only if it has root privileges. Launching apps locally does not suffer from this issue. - + diff --git a/docs/README-riscos.md b/docs/README-riscos.md index 5af80a7f3..483042206 100644 --- a/docs/README-riscos.md +++ b/docs/README-riscos.md @@ -1,35 +1,35 @@ -RISC OS -======= - -Requirements: - -* RISC OS 3.5 or later. -* [SharedUnixLibrary](http://www.riscos.info/packages/LibraryDetails.html#SharedUnixLibraryarm). -* [DigitalRenderer](http://www.riscos.info/packages/LibraryDetails.html#DRendererarm), for audio support. -* [Iconv](http://www.netsurf-browser.org/projects/iconv/), for `SDL_iconv` and related functions. - - -Compiling: ----------- - -Currently, SDL for RISC OS only supports compiling with GCCSDK under Linux. - -The following commands can be used to build SDL for RISC OS using CMake: - - cmake -Bbuild-riscos -DCMAKE_TOOLCHAIN_FILE=$GCCSDK_INSTALL_ENV/toolchain-riscos.cmake -DRISCOS=ON -DCMAKE_INSTALL_PREFIX=$GCCSDK_INSTALL_ENV -DCMAKE_BUILD_TYPE=Release - cmake --build build-riscos - cmake --install build-riscos - -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. - - -Current level of implementation -------------------------------- - -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. - -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. - -The audio, loadso, thread and timer APIs are currently provided by UnixLib. - -The joystick, locale and power APIs are not yet implemented. +RISC OS +======= + +Requirements: + +* RISC OS 3.5 or later. +* [SharedUnixLibrary](http://www.riscos.info/packages/LibraryDetails.html#SharedUnixLibraryarm). +* [DigitalRenderer](http://www.riscos.info/packages/LibraryDetails.html#DRendererarm), for audio support. +* [Iconv](http://www.netsurf-browser.org/projects/iconv/), for `SDL_iconv` and related functions. + + +Compiling: +---------- + +Currently, SDL for RISC OS only supports compiling with GCCSDK under Linux. + +The following commands can be used to build SDL for RISC OS using CMake: + + cmake -Bbuild-riscos -DCMAKE_TOOLCHAIN_FILE=$GCCSDK_INSTALL_ENV/toolchain-riscos.cmake -DRISCOS=ON -DCMAKE_INSTALL_PREFIX=$GCCSDK_INSTALL_ENV -DCMAKE_BUILD_TYPE=Release + cmake --build build-riscos + cmake --install build-riscos + +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. + + +Current level of implementation +------------------------------- + +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. + +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. + +The audio, loadso, thread and timer APIs are currently provided by UnixLib. + +The joystick, locale and power APIs are not yet implemented. diff --git a/docs/README-touch.md b/docs/README-touch.md index 489e34061..94d4e7233 100644 --- a/docs/README-touch.md +++ b/docs/README-touch.md @@ -8,7 +8,7 @@ The linux touch system is currently based off event streams, and proc/bus/device Mac: 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. -iPhone: +iPhone: Works out of box. Windows: diff --git a/docs/README-versions.md b/docs/README-versions.md index 097dba1c7..d54bf40c1 100644 --- a/docs/README-versions.md +++ b/docs/README-versions.md @@ -1,60 +1,60 @@ -# Versioning - -## Since 2.23.0 - -SDL follows an "odd/even" versioning policy, similar to GLib, GTK, Flatpak -and older versions of the Linux kernel: - -* The major version (first part) increases when backwards compatibility - is broken, which will happen infrequently. - -* If the minor version (second part) is divisible by 2 - (for example 2.24.x, 2.26.x), this indicates a version of SDL that - is believed to be stable and suitable for production use. - - * In stable releases, the patchlevel or micro version (third part) - indicates bugfix releases. Bugfix releases should not add or - remove ABI, so the ".0" release (for example 2.24.0) should be - forwards-compatible with all the bugfix releases from the - same cycle (for example 2.24.1). - - * The minor version increases when new API or ABI is added, or when - other significant changes are made. Newer minor versions are - backwards-compatible, but not fully forwards-compatible. - For example, programs built against SDL 2.24.x should work fine - with SDL 2.26.x, but programs built against SDL 2.26.x will not - necessarily work with 2.24.x. - -* If the minor version (second part) is not divisible by 2 - (for example 2.23.x, 2.25.x), this indicates a development prerelease - of SDL that is not suitable for stable software distributions. - Use with caution. - - * The patchlevel or micro version (third part) increases with - each prerelease. - - * Each prerelease might add new API and/or ABI. - - * Prereleases are backwards-compatible with older stable branches. - For example, 2.25.x will be backwards-compatible with 2.24.x. - - * Prereleases are not guaranteed to be backwards-compatible with - each other. For example, new API or ABI added in 2.25.1 - might be removed or changed in 2.25.2. - If this would be a problem for you, please do not use prereleases. - - * Only upgrade to a prerelease if you can guarantee that you will - promptly upgrade to the stable release that follows it. - For example, do not upgrade to 2.23.x unless you will be able to - upgrade to 2.24.0 when it becomes available. - - * Software distributions that have a freeze policy (in particular Linux - distributions with a release cycle, such as Debian and Fedora) - should usually only package stable releases, and not prereleases. - -## Before 2.23.0 - -Older versions of SDL followed a similar policy, but instead of the -odd/even rule applying to the minor version, it applied to the patchlevel -(micro version, third part). For example, 2.0.22 was a stable release -and 2.0.21 was a prerelease. +# Versioning + +## Since 2.23.0 + +SDL follows an "odd/even" versioning policy, similar to GLib, GTK, Flatpak +and older versions of the Linux kernel: + +* The major version (first part) increases when backwards compatibility + is broken, which will happen infrequently. + +* If the minor version (second part) is divisible by 2 + (for example 2.24.x, 2.26.x), this indicates a version of SDL that + is believed to be stable and suitable for production use. + + * In stable releases, the patchlevel or micro version (third part) + indicates bugfix releases. Bugfix releases should not add or + remove ABI, so the ".0" release (for example 2.24.0) should be + forwards-compatible with all the bugfix releases from the + same cycle (for example 2.24.1). + + * The minor version increases when new API or ABI is added, or when + other significant changes are made. Newer minor versions are + backwards-compatible, but not fully forwards-compatible. + For example, programs built against SDL 2.24.x should work fine + with SDL 2.26.x, but programs built against SDL 2.26.x will not + necessarily work with 2.24.x. + +* If the minor version (second part) is not divisible by 2 + (for example 2.23.x, 2.25.x), this indicates a development prerelease + of SDL that is not suitable for stable software distributions. + Use with caution. + + * The patchlevel or micro version (third part) increases with + each prerelease. + + * Each prerelease might add new API and/or ABI. + + * Prereleases are backwards-compatible with older stable branches. + For example, 2.25.x will be backwards-compatible with 2.24.x. + + * Prereleases are not guaranteed to be backwards-compatible with + each other. For example, new API or ABI added in 2.25.1 + might be removed or changed in 2.25.2. + If this would be a problem for you, please do not use prereleases. + + * Only upgrade to a prerelease if you can guarantee that you will + promptly upgrade to the stable release that follows it. + For example, do not upgrade to 2.23.x unless you will be able to + upgrade to 2.24.0 when it becomes available. + + * Software distributions that have a freeze policy (in particular Linux + distributions with a release cycle, such as Debian and Fedora) + should usually only package stable releases, and not prereleases. + +## Before 2.23.0 + +Older versions of SDL followed a similar policy, but instead of the +odd/even rule applying to the minor version, it applied to the patchlevel +(micro version, third part). For example, 2.0.22 was a stable release +and 2.0.21 was a prerelease. diff --git a/docs/README-visualc.md b/docs/README-visualc.md index 43f426f42..4864548a7 100644 --- a/docs/README-visualc.md +++ b/docs/README-visualc.md @@ -1,113 +1,113 @@ -Using SDL with Microsoft Visual C++ -=================================== - -### by Lion Kimbro with additions by James Turk - -You can either use the precompiled libraries from the [SDL](https://www.libsdl.org/download.php) web site, or you can build SDL -yourself. - -### Building SDL - -0. To build SDL, your machine must, at a minimum, have the DirectX9.0c SDK installed. It may or may not be retrievable from -the [Microsoft](https://www.microsoft.com) website, so you might need to locate it [online](https://duckduckgo.com/?q=directx9.0c+sdk+download&t=h_&ia=web). -_Editor's note: I've been able to successfully build SDL using Visual Studio 2019 **without** the DX9.0c SDK_ - -1. Open the Visual Studio solution file at `./VisualC/SDL.sln`. - -2. Your IDE will likely prompt you to upgrade this solution file to whatever later version of the IDE you're using. In the `Retarget Projects` dialog, -all of the affected project files should be checked allowing you to use the latest `Windows SDK Version` you have installed, along with -the `Platform Toolset`. - -If you choose *NOT* to upgrade to use the latest `Windows SDK Version` or `Platform Toolset`, then you'll need the `Visual Studio 2010 Platform Toolset`. - -3. Build the `.dll` and `.lib` files by right clicking on each project in turn (Projects are listed in the _Workspace_ -panel in the _FileView_ tab), and selecting `Build`. - -You may get a few warnings, but you should not get any errors. - -Later, we will refer to the following `.lib` and `.dll` files that have just been generated: - -- `./VisualC/Win32/Debug/SDL3.dll` or `./VisualC/Win32/Release/SDL3.dll` -- `./VisualC/Win32/Debug/SDL3.lib` or `./VisualC/Win32/Release/SDL3.lib` - -_Note for the `x64` versions, just replace `Win32` in the path with `x64`_ - -### Creating a Project with SDL - -- Create a project as a `Win32 Application`. - -- Create a C++ file for your project. - -- Set the C runtime to `Multi-threaded DLL` in the menu: -`Project|Settings|C/C++ tab|Code Generation|Runtime Library `. - -- Add the SDL `include` directory to your list of includes in the menu: -`Project|Settings|C/C++ tab|Preprocessor|Additional include directories ` - -*VC7 Specific: Instead of doing this, I find it easier to add the -include and library directories to the list that VC7 keeps. Do this by -selecting Tools|Options|Projects|VC++ Directories and under the "Show -Directories For:" dropbox select "Include Files", and click the "New -Directory Icon" and add the [SDLROOT]\\include directory (e.g. If you -installed to c:\\SDL\\ add c:\\SDL\\include). Proceed to change the -dropbox selection to "Library Files" and add [SDLROOT]\\lib.* - -The "include directory" I am referring to is the `./include` folder. - -Now we're going to use the files that we had created earlier in the *Build SDL* step. - -Copy the following file into your Project directory: - -- `SDL3.dll` - -Add the following file to your project (It is not necessary to copy it to your project directory): - -- `SDL3.lib` - -To add them to your project, right click on your project, and select -`Add files to project`. - -**Instead of adding the files to your project, it is more desirable to add them to the linker options: Project|Properties|Linker|Command Line -and type the names of the libraries to link with in the "Additional Options:" box. Note: This must be done for each build configuration -(e.g. Release,Debug).** - -### Hello SDL - -Here's a sample SDL snippet to verify everything is setup in your IDE: - -``` - #include - #include // only include this one in the source file with main()! - - int main( int argc, char* argv[] ) - { - const int WIDTH = 640; - const int HEIGHT = 480; - SDL_Window* window = NULL; - SDL_Renderer* renderer = NULL; - - SDL_Init(SDL_INIT_VIDEO); - window = SDL_CreateWindow("Hello SDL", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, 0); - renderer = SDL_CreateRenderer(window, NULL, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); - - SDL_DestroyRenderer(renderer); - SDL_DestroyWindow(window); - SDL_Quit(); - return 0; - } - ``` - -### That's it! - -I hope that this document has helped you get through the most difficult part of using the SDL: installing it. -Suggestions for improvements should be posted to the [Github Issues](https://github.com/libsdl-org/SDL/issues). - -### Credits - -Thanks to [Paulus Esterhazy](mailto:pesterhazy@gmx.net), for the work on VC++ port. - -This document was originally called "VisualC.txt", and was written by [Sam Lantinga](mailto:slouken@libsdl.org). - -Later, it was converted to HTML and expanded into the document that you see today by [Lion Kimbro](mailto:snowlion@sprynet.com). - -Minor Fixes and Visual C++ 7 Information (In Green) was added by [James Turk](mailto:james@conceptofzero.net) +Using SDL with Microsoft Visual C++ +=================================== + +### by Lion Kimbro with additions by James Turk + +You can either use the precompiled libraries from the [SDL](https://www.libsdl.org/download.php) web site, or you can build SDL +yourself. + +### Building SDL + +0. To build SDL, your machine must, at a minimum, have the DirectX9.0c SDK installed. It may or may not be retrievable from +the [Microsoft](https://www.microsoft.com) website, so you might need to locate it [online](https://duckduckgo.com/?q=directx9.0c+sdk+download&t=h_&ia=web). +_Editor's note: I've been able to successfully build SDL using Visual Studio 2019 **without** the DX9.0c SDK_ + +1. Open the Visual Studio solution file at `./VisualC/SDL.sln`. + +2. Your IDE will likely prompt you to upgrade this solution file to whatever later version of the IDE you're using. In the `Retarget Projects` dialog, +all of the affected project files should be checked allowing you to use the latest `Windows SDK Version` you have installed, along with +the `Platform Toolset`. + +If you choose *NOT* to upgrade to use the latest `Windows SDK Version` or `Platform Toolset`, then you'll need the `Visual Studio 2010 Platform Toolset`. + +3. Build the `.dll` and `.lib` files by right clicking on each project in turn (Projects are listed in the _Workspace_ +panel in the _FileView_ tab), and selecting `Build`. + +You may get a few warnings, but you should not get any errors. + +Later, we will refer to the following `.lib` and `.dll` files that have just been generated: + +- `./VisualC/Win32/Debug/SDL3.dll` or `./VisualC/Win32/Release/SDL3.dll` +- `./VisualC/Win32/Debug/SDL3.lib` or `./VisualC/Win32/Release/SDL3.lib` + +_Note for the `x64` versions, just replace `Win32` in the path with `x64`_ + +### Creating a Project with SDL + +- Create a project as a `Win32 Application`. + +- Create a C++ file for your project. + +- Set the C runtime to `Multi-threaded DLL` in the menu: +`Project|Settings|C/C++ tab|Code Generation|Runtime Library `. + +- Add the SDL `include` directory to your list of includes in the menu: +`Project|Settings|C/C++ tab|Preprocessor|Additional include directories ` + +*VC7 Specific: Instead of doing this, I find it easier to add the +include and library directories to the list that VC7 keeps. Do this by +selecting Tools|Options|Projects|VC++ Directories and under the "Show +Directories For:" dropbox select "Include Files", and click the "New +Directory Icon" and add the [SDLROOT]\\include directory (e.g. If you +installed to c:\\SDL\\ add c:\\SDL\\include). Proceed to change the +dropbox selection to "Library Files" and add [SDLROOT]\\lib.* + +The "include directory" I am referring to is the `./include` folder. + +Now we're going to use the files that we had created earlier in the *Build SDL* step. + +Copy the following file into your Project directory: + +- `SDL3.dll` + +Add the following file to your project (It is not necessary to copy it to your project directory): + +- `SDL3.lib` + +To add them to your project, right click on your project, and select +`Add files to project`. + +**Instead of adding the files to your project, it is more desirable to add them to the linker options: Project|Properties|Linker|Command Line +and type the names of the libraries to link with in the "Additional Options:" box. Note: This must be done for each build configuration +(e.g. Release,Debug).** + +### Hello SDL + +Here's a sample SDL snippet to verify everything is setup in your IDE: + +``` + #include + #include // only include this one in the source file with main()! + + int main( int argc, char* argv[] ) + { + const int WIDTH = 640; + const int HEIGHT = 480; + SDL_Window* window = NULL; + SDL_Renderer* renderer = NULL; + + SDL_Init(SDL_INIT_VIDEO); + window = SDL_CreateWindow("Hello SDL", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, 0); + renderer = SDL_CreateRenderer(window, NULL, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); + + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); + SDL_Quit(); + return 0; + } + ``` + +### That's it! + +I hope that this document has helped you get through the most difficult part of using the SDL: installing it. +Suggestions for improvements should be posted to the [Github Issues](https://github.com/libsdl-org/SDL/issues). + +### Credits + +Thanks to [Paulus Esterhazy](mailto:pesterhazy@gmx.net), for the work on VC++ port. + +This document was originally called "VisualC.txt", and was written by [Sam Lantinga](mailto:slouken@libsdl.org). + +Later, it was converted to HTML and expanded into the document that you see today by [Lion Kimbro](mailto:snowlion@sprynet.com). + +Minor Fixes and Visual C++ 7 Information (In Green) was added by [James Turk](mailto:james@conceptofzero.net) diff --git a/docs/README-vita.md b/docs/README-vita.md index 503fef7d5..3dbaf1cd4 100644 --- a/docs/README-vita.md +++ b/docs/README-vita.md @@ -1,33 +1,33 @@ -PS Vita -======= -SDL port for the Sony Playstation Vita and Sony Playstation TV - -Credit to -* xerpi, cpasjuste and rsn8887 for initial (vita2d) port -* vitasdk/dolcesdk devs -* CBPS discord (Namely Graphene and SonicMastr) - -Building --------- -To build for the PSVita, make sure you have vitasdk and cmake installed and run: -``` - cmake -S. -Bbuild -DCMAKE_TOOLCHAIN_FILE=${VITASDK}/share/vita.toolchain.cmake -DCMAKE_BUILD_TYPE=Release - cmake --build build - cmake --install build -``` - - -Notes ------ -* gles1/gles2 support and renderers are disabled by default and can be enabled by configuring with `-DVIDEO_VITA_PVR=ON` - These renderers support 720p and 1080i resolutions. These can be specified with: - `SDL_setenv("VITA_RESOLUTION", "720", 1);` and `SDL_setenv("VITA_RESOLUTION", "1080", 1);` -* 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. - They support the same resolutions as the gles1/gles2 backends and require specifying `SDL_setenv("VITA_PVR_OGL", "1", 1);` - anytime before video subsystem initialization. -* gles2 support via PIB is disabled by default and can be enabled by configuring with `-DVIDEO_VITA_PIB=ON` -* By default SDL emits mouse events for touch events on every touchscreen. - Vita has two touchscreens, so it's recommended to use `SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");` and handle touch events instead. - Individual touchscreens can be disabled with: - `SDL_setenv("VITA_DISABLE_TOUCH_FRONT", "1", 1);` and `SDL_setenv("VITA_DISABLE_TOUCH_BACK", "1", 1);` -* Support for L2/R2/R3/R3 buttons, haptic feedback and gamepad led only available on PSTV, or when using external ds4 gamepad on vita. +PS Vita +======= +SDL port for the Sony Playstation Vita and Sony Playstation TV + +Credit to +* xerpi, cpasjuste and rsn8887 for initial (vita2d) port +* vitasdk/dolcesdk devs +* CBPS discord (Namely Graphene and SonicMastr) + +Building +-------- +To build for the PSVita, make sure you have vitasdk and cmake installed and run: +``` + cmake -S. -Bbuild -DCMAKE_TOOLCHAIN_FILE=${VITASDK}/share/vita.toolchain.cmake -DCMAKE_BUILD_TYPE=Release + cmake --build build + cmake --install build +``` + + +Notes +----- +* gles1/gles2 support and renderers are disabled by default and can be enabled by configuring with `-DVIDEO_VITA_PVR=ON` + These renderers support 720p and 1080i resolutions. These can be specified with: + `SDL_setenv("VITA_RESOLUTION", "720", 1);` and `SDL_setenv("VITA_RESOLUTION", "1080", 1);` +* 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. + They support the same resolutions as the gles1/gles2 backends and require specifying `SDL_setenv("VITA_PVR_OGL", "1", 1);` + anytime before video subsystem initialization. +* gles2 support via PIB is disabled by default and can be enabled by configuring with `-DVIDEO_VITA_PIB=ON` +* By default SDL emits mouse events for touch events on every touchscreen. + Vita has two touchscreens, so it's recommended to use `SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");` and handle touch events instead. + Individual touchscreens can be disabled with: + `SDL_setenv("VITA_DISABLE_TOUCH_FRONT", "1", 1);` and `SDL_setenv("VITA_DISABLE_TOUCH_BACK", "1", 1);` +* 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/docs/README-windows.md b/docs/README-windows.md index ed0c93e2c..cd29c1f92 100644 --- a/docs/README-windows.md +++ b/docs/README-windows.md @@ -1,58 +1,58 @@ -# Windows - -## LLVM and Intel C++ compiler support - -SDL will build with the Visual Studio project files with LLVM-based compilers, such as the Intel oneAPI C++ -compiler, but you'll have to manually add the "-msse3" command line option -to at least the SDL_audiocvt.c source file, and possibly others. This may -not be necessary if you build SDL with CMake instead of the included Visual -Studio solution. - -Details are here: https://github.com/libsdl-org/SDL/issues/5186 - - -## OpenGL ES 2.x support - -SDL has support for OpenGL ES 2.x under Windows via two alternative -implementations. - -The most straightforward method consists in running your app in a system with -a graphic card paired with a relatively recent (as of November of 2013) driver -which supports the WGL_EXT_create_context_es2_profile extension. Vendors known -to ship said extension on Windows currently include nVidia and Intel. - -The other method involves using the -[ANGLE library](https://code.google.com/p/angleproject/). If an OpenGL ES 2.x -context is requested and no WGL_EXT_create_context_es2_profile extension is -found, SDL will try to load the libEGL.dll library provided by ANGLE. - -To obtain the ANGLE binaries, you can either compile from source from -https://chromium.googlesource.com/angle/angle or copy the relevant binaries -from a recent Chrome/Chromium install for Windows. The files you need are: - -- libEGL.dll -- libGLESv2.dll -- d3dcompiler_46.dll (supports Windows Vista or later, better shader - compiler) *or* d3dcompiler_43.dll (supports Windows XP or later) - -If you compile ANGLE from source, you can configure it so it does not need the -d3dcompiler_* DLL at all (for details on this, see their documentation). -However, by default SDL will try to preload the d3dcompiler_46.dll to -comply with ANGLE's requirements. If you wish SDL to preload -d3dcompiler_43.dll (to support Windows XP) or to skip this step at all, you -can use the SDL_HINT_VIDEO_WIN_D3DCOMPILER hint (see SDL_hints.h for more -details). - -Known Bugs: - -- SDL_GL_SetSwapInterval is currently a no op when using ANGLE. It appears - that there's a bug in the library which prevents the window contents from - refreshing if this is set to anything other than the default value. - -## Vulkan Surface Support - -Support for creating Vulkan surfaces is configured on by default. To disable -it change the value of `SDL_VIDEO_VULKAN` to 0 in `SDL_config_windows.h`. You -must install the [Vulkan SDK](https://www.lunarg.com/vulkan-sdk/) in order to -use Vulkan graphics in your application. - +# Windows + +## LLVM and Intel C++ compiler support + +SDL will build with the Visual Studio project files with LLVM-based compilers, such as the Intel oneAPI C++ +compiler, but you'll have to manually add the "-msse3" command line option +to at least the SDL_audiocvt.c source file, and possibly others. This may +not be necessary if you build SDL with CMake instead of the included Visual +Studio solution. + +Details are here: https://github.com/libsdl-org/SDL/issues/5186 + + +## OpenGL ES 2.x support + +SDL has support for OpenGL ES 2.x under Windows via two alternative +implementations. + +The most straightforward method consists in running your app in a system with +a graphic card paired with a relatively recent (as of November of 2013) driver +which supports the WGL_EXT_create_context_es2_profile extension. Vendors known +to ship said extension on Windows currently include nVidia and Intel. + +The other method involves using the +[ANGLE library](https://code.google.com/p/angleproject/). If an OpenGL ES 2.x +context is requested and no WGL_EXT_create_context_es2_profile extension is +found, SDL will try to load the libEGL.dll library provided by ANGLE. + +To obtain the ANGLE binaries, you can either compile from source from +https://chromium.googlesource.com/angle/angle or copy the relevant binaries +from a recent Chrome/Chromium install for Windows. The files you need are: + +- libEGL.dll +- libGLESv2.dll +- d3dcompiler_46.dll (supports Windows Vista or later, better shader + compiler) *or* d3dcompiler_43.dll (supports Windows XP or later) + +If you compile ANGLE from source, you can configure it so it does not need the +d3dcompiler_* DLL at all (for details on this, see their documentation). +However, by default SDL will try to preload the d3dcompiler_46.dll to +comply with ANGLE's requirements. If you wish SDL to preload +d3dcompiler_43.dll (to support Windows XP) or to skip this step at all, you +can use the SDL_HINT_VIDEO_WIN_D3DCOMPILER hint (see SDL_hints.h for more +details). + +Known Bugs: + +- SDL_GL_SetSwapInterval is currently a no op when using ANGLE. It appears + that there's a bug in the library which prevents the window contents from + refreshing if this is set to anything other than the default value. + +## Vulkan Surface Support + +Support for creating Vulkan surfaces is configured on by default. To disable +it change the value of `SDL_VIDEO_VULKAN` to 0 in `SDL_config_windows.h`. You +must install the [Vulkan SDK](https://www.lunarg.com/vulkan-sdk/) in order to +use Vulkan graphics in your application. + diff --git a/docs/README-winrt.md b/docs/README-winrt.md index c65aa7d63..3530f673e 100644 --- a/docs/README-winrt.md +++ b/docs/README-winrt.md @@ -21,7 +21,7 @@ Requirements (The "Community" editions of Visual C++ do, however, support both desktop/Win32 and WinRT development). * A valid Microsoft account - This requirement is not imposed by SDL, but - rather by Microsoft's Visual C++ toolchain. This is required to launch or + rather by Microsoft's Visual C++ toolchain. This is required to launch or debug apps. @@ -44,8 +44,8 @@ Here is a rough list of what works, and what doesn't: SDL_GetPerformanceFrequency(), etc.) * file I/O via SDL_RWops * mouse input (unsupported on Windows Phone) - * audio, via SDL's WASAPI backend (if you want to record, your app must - have "Microphone" capabilities enabled in its manifest, and the user must + * audio, via SDL's WASAPI backend (if you want to record, your app must + have "Microphone" capabilities enabled in its manifest, and the user must not have blocked access. Otherwise, capture devices will fail to work, presenting as a device disconnect shortly after opening it.) * .DLL file loading. Libraries *MUST* be packaged inside applications. Loading @@ -55,7 +55,7 @@ Here is a rough list of what works, and what doesn't: SDL_Gamepad APIs, and is backed by Microsoft's XInput API. Please note, however, that Windows limits game-controller support in UWP apps to, "Xbox compatible controllers" (many controllers that work in Win32 apps, - do not work in UWP, due to restrictions in UWP itself.) + do not work in UWP, due to restrictions in UWP itself.) * multi-touch input * app events. SDL_APP_WILLENTER* and SDL_APP_DIDENTER* events get sent out as appropriate. @@ -198,7 +198,7 @@ libraries such that, when the app is built: 1. each library gets built for the appropriate CPU architecture(s) and WinRT platform(s). -2. each library's output, such as .dll files, get copied to the app's build +2. each library's output, such as .dll files, get copied to the app's build output. To set this up for SDL/WinRT, you'll need to run through the following steps: @@ -239,19 +239,19 @@ To change these settings: 2. choose "Properties" 3. in the drop-down box next to "Configuration", choose, "All Configurations" 4. in the drop-down box next to "Platform", choose, "All Platforms" -5. in the left-hand list, expand the "C/C++" section +5. in the left-hand list, expand the "C/C++" section **Note:** If you don't see this section, you may have to add a .c or .cpp Source file to the Project first. 6. select "General" 7. edit the "Additional Include Directories" setting, and add a path to SDL's "include" directory 8. **Optional: to enable compilation of C code:** change the setting for - "Consume Windows Runtime Extension" from "Yes (/ZW)" to "No". If you're - working with a completely C++ based project, this step can usually be + "Consume Windows Runtime Extension" from "Yes (/ZW)" to "No". If you're + working with a completely C++ based project, this step can usually be omitted. -9. **Optional: to disable precompiled headers (which can produce - 'stdafx.h'-related build errors, if setup incorrectly:** in the left-hand - list, select "Precompiled Headers", then change the setting for "Precompiled +9. **Optional: to disable precompiled headers (which can produce + 'stdafx.h'-related build errors, if setup incorrectly:** in the left-hand + list, select "Precompiled Headers", then change the setting for "Precompiled Header" from "Use (/Yu)" to "Not Using Precompiled Headers". 10. close the dialog, saving settings, by clicking the "OK" button @@ -268,7 +268,7 @@ A few files should be included directly in your app's MSVC project, specifically To include these files for C/C++ projects: -1. right-click on your project (again, in Visual C++'s Solution Explorer), +1. right-click on your project (again, in Visual C++'s Solution Explorer), navigate to "Add", then choose "Existing Item...". 2. navigate to the directory containing SDL's source code, then into its subdirectory, 'src/main/winrt/'. Select, then add, the following files: @@ -288,8 +288,8 @@ To include these files for C/C++ projects: 8. change the setting for "Consume Windows Runtime Extension" to "Yes (/ZW)". 9. click the OK button. This will close the dialog. -**NOTE: C++/CX compilation is currently required in at least one file of your -app's project. This is to make sure that Visual C++'s linker builds a 'Windows +**NOTE: C++/CX compilation is currently required in at least one file of your +app's project. This is to make sure that Visual C++'s linker builds a 'Windows Metadata' file (.winmd) for your app. Not doing so can lead to build errors.** For non-C++ projects, you will need to call SDL_RunApp from your language's @@ -299,58 +299,58 @@ first block in your Visual Studio project file. ### 6. Add app code and assets ### -At this point, you can add in SDL-specific source code. Be sure to include a -C-style main function (ie: `int main(int argc, char *argv[])`). From there you -should be able to create a single `SDL_Window` (WinRT apps can only have one -window, at present), as well as an `SDL_Renderer`. Direct3D will be used to -draw content. Events are received via SDL's usual event functions -(`SDL_PollEvent`, etc.) If you have a set of existing source files and assets, -you can start adding them to the project now. If not, or if you would like to -make sure that you're setup correctly, some short and simple sample code is +At this point, you can add in SDL-specific source code. Be sure to include a +C-style main function (ie: `int main(int argc, char *argv[])`). From there you +should be able to create a single `SDL_Window` (WinRT apps can only have one +window, at present), as well as an `SDL_Renderer`. Direct3D will be used to +draw content. Events are received via SDL's usual event functions +(`SDL_PollEvent`, etc.) If you have a set of existing source files and assets, +you can start adding them to the project now. If not, or if you would like to +make sure that you're setup correctly, some short and simple sample code is provided below. #### 6.A. ... when creating a new app #### -If you are creating a new app (rather than porting an existing SDL-based app), -or if you would just like a simple app to test SDL/WinRT with before trying to -get existing code working, some working SDL/WinRT code is provided below. To +If you are creating a new app (rather than porting an existing SDL-based app), +or if you would just like a simple app to test SDL/WinRT with before trying to +get existing code working, some working SDL/WinRT code is provided below. To set this up: 1. right click on your app's project 2. select Add, then New Item. An "Add New Item" dialog will show up. 3. from the left-hand list, choose "Visual C++" 4. from the middle/main list, choose "C++ File (.cpp)" -5. near the bottom of the dialog, next to "Name:", type in a name for your +5. near the bottom of the dialog, next to "Name:", type in a name for your source file, such as, "main.cpp". -6. click on the Add button. This will close the dialog, add the new file to +6. click on the Add button. This will close the dialog, add the new file to your project, and open the file in Visual C++'s text editor. 7. Copy and paste the following code into the new file, then save it. ```c #include #include - + int main(int argc, char **argv) { SDL_Window *window = NULL; SDL_Renderer *renderer = NULL; SDL_Event evt; SDL_bool keep_going = SDL_TRUE; - + if (SDL_Init(SDL_INIT_VIDEO) != 0) { return 1; } else if (SDL_CreateWindowAndRenderer(0, 0, SDL_WINDOW_FULLSCREEN, &window, &renderer) != 0) { return 1; } - + while (keep_going) { while (SDL_PollEvent(&evt)) { if ((evt.type == SDL_EVENT_KEY_DOWN) && (evt.key.keysym.sym == SDLK_ESCAPE)) { keep_going = SDL_FALSE; - } + } } - + SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255); SDL_RenderClear(renderer); SDL_RenderPresent(renderer); @@ -363,41 +363,41 @@ int main(int argc, char **argv) #### 6.B. Adding code and assets #### -If you have existing code and assets that you'd like to add, you should be able +If you have existing code and assets that you'd like to add, you should be able to add them now. The process for adding a set of files is as such. 1. right click on the app's project 2. select Add, then click on "New Item..." -3. open any source, header, or asset files as appropriate. Support for C and +3. open any source, header, or asset files as appropriate. Support for C and C++ is available. -Do note that WinRT only supports a subset of the APIs that are available to -Win32-based apps. Many portions of the Win32 API and the C runtime are not +Do note that WinRT only supports a subset of the APIs that are available to +Win32-based apps. Many portions of the Win32 API and the C runtime are not available. -A list of unsupported C APIs can be found at +A list of unsupported C APIs can be found at -General information on using the C runtime in WinRT can be found at +General information on using the C runtime in WinRT can be found at -A list of supported Win32 APIs for WinRT apps can be found at -. To note, -the list of supported Win32 APIs for Windows Phone 8.0 is different. -That list can be found at +A list of supported Win32 APIs for WinRT apps can be found at +. To note, +the list of supported Win32 APIs for Windows Phone 8.0 is different. +That list can be found at ### 7. Build and run your app ### -Your app project should now be setup, and you should be ready to build your app. -To run it on the local machine, open the Debug menu and choose "Start -Debugging". This will build your app, then run your app full-screen. To switch -out of your app, press the Windows key. Alternatively, you can choose to run -your app in a window. To do this, before building and running your app, find -the drop-down menu in Visual C++'s toolbar that says, "Local Machine". Expand -this by clicking on the arrow on the right side of the list, then click on -Simulator. Once you do that, any time you build and run the app, the app will +Your app project should now be setup, and you should be ready to build your app. +To run it on the local machine, open the Debug menu and choose "Start +Debugging". This will build your app, then run your app full-screen. To switch +out of your app, press the Windows key. Alternatively, you can choose to run +your app in a window. To do this, before building and running your app, find +the drop-down menu in Visual C++'s toolbar that says, "Local Machine". Expand +this by clicking on the arrow on the right side of the list, then click on +Simulator. Once you do that, any time you build and run the app, the app will launch in window, rather than full-screen. @@ -410,37 +410,37 @@ Windows 8.x that ran primarily on ARM-based tablet computers. To build and run the app on ARM-based, "Windows RT" devices, you'll need to: -- install Microsoft's "Remote Debugger" on the device. Visual C++ installs and +- install Microsoft's "Remote Debugger" on the device. Visual C++ installs and debugs ARM-based apps via IP networks. -- change a few options on the development machine, both to make sure it builds - for ARM (rather than x86 or x64), and to make sure it knows how to find the +- change a few options on the development machine, both to make sure it builds + for ARM (rather than x86 or x64), and to make sure it knows how to find the Windows RT device (on the network). -Microsoft's Remote Debugger can be found at -. Please note -that separate versions of this debugger exist for different versions of Visual +Microsoft's Remote Debugger can be found at +. Please note +that separate versions of this debugger exist for different versions of Visual C++, one each for MSVC 2015, 2013, and 2012. To setup Visual C++ to launch your app on an ARM device: -1. make sure the Remote Debugger is running on your ARM device, and that it's on +1. make sure the Remote Debugger is running on your ARM device, and that it's on the same IP network as your development machine. -2. from Visual C++'s toolbar, find a drop-down menu that says, "Win32". Click +2. from Visual C++'s toolbar, find a drop-down menu that says, "Win32". Click it, then change the value to "ARM". -3. make sure Visual C++ knows the hostname or IP address of the ARM device. To +3. make sure Visual C++ knows the hostname or IP address of the ARM device. To do this: 1. open the app project's properties 2. select "Debugging" - 3. next to "Machine Name", enter the hostname or IP address of the ARM + 3. next to "Machine Name", enter the hostname or IP address of the ARM device 4. if, and only if, you've turned off authentication in the Remote Debugger, then change the setting for "Require Authentication" to No 5. click "OK" -4. build and run the app (from Visual C++). The first time you do this, a - prompt will show up on the ARM device, asking for a Microsoft Account. You - do, unfortunately, need to log in here, and will need to follow the - subsequent registration steps in order to launch the app. After you do so, - if the app didn't already launch, try relaunching it again from within Visual +4. build and run the app (from Visual C++). The first time you do this, a + prompt will show up on the ARM device, asking for a Microsoft Account. You + do, unfortunately, need to log in here, and will need to follow the + subsequent registration steps in order to launch the app. After you do so, + if the app didn't already launch, try relaunching it again from within Visual C++.