SDL: Update doc/README-* for header-only SDL_main

From ab554c8392491b9b6320ad7e8800685c37bfa700 Mon Sep 17 00:00:00 2001
From: Daniel Gibson <[EMAIL REDACTED]>
Date: Mon, 12 Dec 2022 23:27:58 +0100
Subject: [PATCH] Update doc/README-* for header-only SDL_main

---
 docs/README-android.md   |  4 ++--
 docs/README-cmake.md     | 10 ----------
 docs/README-gdk.md       |  4 ++--
 docs/README-ios.md       |  2 +-
 docs/README-migration.md | 36 +++++++++++++++++++++++++++++++-----
 docs/README-n3ds.md      |  2 +-
 docs/README-porting.md   |  1 -
 docs/README-winrt.md     |  2 +-
 8 files changed, 38 insertions(+), 23 deletions(-)

diff --git a/docs/README-android.md b/docs/README-android.md
index a232a3e9e51f..4980aec84377 100644
--- a/docs/README-android.md
+++ b/docs/README-android.md
@@ -83,8 +83,8 @@ If you already have a project that uses CMake, the instructions change somewhat:
 2. Edit "<project>/app/build.gradle" to comment out or remove sections containing ndk-build
    and uncomment the cmake sections. Add arguments to the CMake invocation as needed.
 3. Edit "<project>/app/jni/CMakeLists.txt" to include your project (it defaults to
-   adding the "src" subdirectory). Note that you'll have SDL3, SDL3_main and SDL3-static
-   as targets in your project, so you should have "target_link_libraries(yourgame SDL3 SDL3_main)"
+   adding the "src" subdirectory). Note that you'll have SDL3 and SDL3-static
+   as targets in your project, so you should have "target_link_libraries(yourgame SDL3)"
    in your CMakeLists.txt file. Also be aware that you should use add_library() instead of
    add_executable() for the target containing your "main" function.
 
diff --git a/docs/README-cmake.md b/docs/README-cmake.md
index b84345aadb3d..66b52e514a8d 100644
--- a/docs/README-cmake.md
+++ b/docs/README-cmake.md
@@ -59,20 +59,11 @@ if(MYGAME_VENDORED)
 else()
     # 1. Look for a SDL3 package, 2. look for the SDL3 component and 3. fail if none can be found
     find_package(SDL3 REQUIRED CONFIG REQUIRED COMPONENTS SDL3)
-    
-    # 1. Look for a SDL3 package, 2. Look for the SDL3_maincomponent and 3. DO NOT fail when SDL3_main is not available 
-    find_package(SDL3 REQUIRED CONFIG COMPONENTS SDL3_main)
 endif()
 
 # Create your game executable target as usual 
 add_executable(mygame WIN32 mygame.c)
 
-# SDL3::SDL3_main may or may not be available. It is e.g. required by Windows GUI applications  
-if(TARGET SDL3::SDL3_main)
-    # It has an implicit dependency on SDL3 functions, so it MUST be added before SDL3::SDL3 (or SDL3::SDL3-static)
-    target_link_libraries(mygame PRIVATE SDL3::SDL3_main)
-endif()
-
 # Link to the actual SDL3 library. SDL3::SDL3 is the shared SDL library, SDL3::SDL3-static is the static SDL libarary.
 target_link_libraries(mygame PRIVATE SDL3::SDL3)

@@ -87,7 +78,6 @@ The following components are available, to be used as an argument of find_packa |----------------|--------------------------------------------------------------------------------------------| | SDL3 | The SDL3 shared library, available through the SDL3::SDL3target [^SDL_TARGET_EXCEPTION] | | SDL3-static | The SDL3 static library, available through theSDL3::SDL3-statictarget | -| SDL3_main | The SDL3_main static library, available through theSDL3::SDL3_maintarget | | SDL3_test | The SDL3_test static library, available through theSDL3::SDL3_test` target |

diff --git a/docs/README-gdk.md b/docs/README-gdk.md
index e90b4e4891ff…ee049236d934 100644
— a/docs/README-gdk.md
+++ b/docs/README-gdk.md
@@ -25,7 +25,7 @@ The Windows GDK port supports the full set of Win32 APIs, renderers, controllers
* 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_GDKRunApp from your entry point, passing in your SDL_main function and NULL as the parameters. To use SDL_GDKRunApp, #define SDL_MAIN_HANDLED before #include <SDL3/SDL_main.h>.
    • An implementation on WinMain that performs the above GDK setup that you can use by #include’ing SDL_main.h in the source file that includes your standard main() function. If you are unable to do this, you can instead manually call SDL_RunApp from your entry point, passing in your SDL_main function and NULL as the parameters. To use SDL_RunApp, #define SDL_MAIN_HANDLED before #include <SDL3/SDL_main.h>.
    • 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).

@@ -73,7 +73,7 @@ While the Gaming.Desktop.x64 configuration sets most of the required settings, t

4. Setting up SDL_main

-Rather than using your own implementation of WinMain, it’s recommended that you instead #include <SDL3/SDL_main.h> and declare a standard main function. If you are unable to do this, you can instead manually call SDL_GDKRunApp 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
+Rather than using your own implementation of WinMain, it’s recommended that you instead #include <SDL3/SDL_main.h> and declare a standard main function. If you are unable to do this, you can instead manually call SDL_RunApp from your entry point, passing in your SDL_main function and NULL as the parameters; in that case #define SDL_MAIN_HANDLED before including SDL_main.h

5. Required DLLs

diff --git a/docs/README-ios.md b/docs/README-ios.md
index 1575888579fa…595058e5f901 100644
— a/docs/README-ios.md
+++ b/docs/README-ios.md
@@ -203,7 +203,7 @@ This target requires Xcode 11 or later. The target will simply fail to build if

In addition, on Apple platforms, main() cannot be in a dynamically loaded library.
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 <SDL3/SDL3_main.h> in the source file that contains their standard int main(int argc; char *argv[]) function to get a header-only SDL_main implementation that calls the SDL_UIKitRunApp() with your standard main function.
+This means that iOS apps which used the statically-linked libSDL3.lib and now link with the xcframwork can just #include <SDL3/SDL_main.h> in the source file that contains their standard int main(int argc; char *argv[]) function to get a header-only SDL_main implementation that calls the SDL_RunApp() with your standard main function.

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:

diff --git a/docs/README-migration.md b/docs/README-migration.md
index e654f8690b52…1891fee97d48 100644
— a/docs/README-migration.md
+++ b/docs/README-migration.md
@@ -9,10 +9,6 @@ SDL headers should now be included as #include <SDL3/SDL.h>. Typically that’s
CMake users should use this snippet to include SDL support in their project:

find_package(SDL3 REQUIRED CONFIG REQUIRED COMPONENTS SDL3)
-find_package(SDL3 REQUIRED CONFIG COMPONENTS SDL3_main)
-if(TARGET SDL3::SDL3_main)
-    target_link_libraries(mygame PRIVATE SDL3::SDL3_main)
-endif()
target_link_libraries(mygame PRIVATE SDL3::SDL3)

@@ -28,7 +24,9 @@ CFLAGS += $(shell pkg-config sdl3 --cflags)
LDFLAGS += $(shell pkg-config sdl3 --libs)


-The SDL3main and SDL3test libraries have been renamed SDL3_main and SDL3_test, respectively.
+The SDL3test library has been renamed SDL3_test.
+
+There is no static SDLmain library anymore, it's now header-only, see below in the SDL_main.h section.


## SDL_cpuinfo.h
@@ -63,6 +61,34 @@ SDL_GetEventState used to be a macro, now it's a real function, but otherwise fu

Removed SDL_GameControllerGetSensorDataWithTimestamp(), if you want timestamps for the sensor data, you should use the sensor_timestamp member of SDL_CONTROLLERSENSORUPDATE events.

+## 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 <SDL3/SDL_main.h>` 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 <SDL3/SDL_main.h>` - 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 <SDL3/SDL_main.h>` 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_platform.h

diff --git a/docs/README-n3ds.md b/docs/README-n3ds.md
index 933952bb1120..33ac084462d6 100644
--- a/docs/README-n3ds.md
+++ b/docs/README-n3ds.md
@@ -22,7 +22,7 @@ cmake --install build
## Notes

-   Currently only software rendering is supported.
--   SDL3_main should be used to ensure ROMFS is enabled.
+-   SDL3_main should be used to ensure ROMFS is enabled - this is done with `#include <SDL3/SDL_main.h>` in the source file that contains your main function.
-   By default, the extra L2 cache and higher clock speeds of the New 2/3DS lineup are enabled. If you wish to turn it off, use `osSetSpeedupEnable(false)` in your main function.
-   `SDL_GetBasePath` returns the romfs root instead of the executable's directory.
-   The Nintendo 3DS uses a cooperative threading model on a single core, meaning a thread will never yield unless done manually through the `SDL_Delay` functions, or blocking waits (`SDL_LockMutex`, `SDL_SemWait`, `SDL_CondWait`, `SDL_WaitThread`). To avoid starving other threads, `SDL_SemTryWait` and `SDL_SemWaitTimeout` will yield if they fail to acquire the semaphore, see https://github.com/libsdl-org/SDL/pull/6776 for more information.
diff --git a/docs/README-porting.md b/docs/README-porting.md
index a3c81e242cf8..9bd24568d33c 100644
--- a/docs/README-porting.md
+++ b/docs/README-porting.md
@@ -49,7 +49,6 @@ There are two basic ways of building SDL at the moment:
	src/video/dummy/*.c
	src/haptic/dummy/*.c
	src/joystick/dummy/*.c
-	src/main/dummy/*.c
	src/thread/generic/*.c
	src/timer/dummy/*.c
	src/loadso/dummy/*.c
diff --git a/docs/README-winrt.md b/docs/README-winrt.md
index 6f9d49d135d4..d2f778a712dc 100644
--- a/docs/README-winrt.md
+++ b/docs/README-winrt.md
@@ -292,7 +292,7 @@ To include these files for C/C++ projects:
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_WinRTRunApp from your language's
+For non-C++ projects, you will need to call SDL_RunApp from your language's
main function, and generate SDL3-WinRTResources.res manually by using `rc` via
the Developer Command Prompt and including it as a <Win32Resource> within the
first <PropertyGroup> block in your Visual Studio project file.