Make GDK's SDL_main header-only

This commit is contained in:
Daniel Gibson 2022-12-11 04:45:38 +01:00 committed by Sam Lantinga
parent 2d0eaea1cc
commit 28ecbbf0b5
5 changed files with 29 additions and 35 deletions

View File

@ -18,9 +18,10 @@
#include <stdio.h> #include <stdio.h>
#include <time.h> #include <time.h>
#include "SDL_test.h" #include <SDL3/SDL_test.h>
#include "SDL_test_common.h" #include <SDL3/SDL_test_common.h>
#include "../src/core/windows/SDL_windows.h" #include "../src/core/windows/SDL_windows.h"
#include <SDL3/SDL_main.h>
extern "C" { extern "C" {
#include "../test/testutils.h" #include "../test/testutils.h"

View File

@ -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 * 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. * 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 (you should link against SDL3_main.lib, as in Windows x64). 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. * 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>`.
* Global task queue callbacks are dispatched during `SDL_PumpEvents` (which is also called internally if using `SDL_PollEvent`). * 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). * 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).
@ -37,7 +37,6 @@ The Windows GDK port supports the full set of Win32 APIs, renderers, controllers
The included `VisualC-GDK/SDL.sln` solution includes the following targets for the Gaming.Desktop.x64 configuration: 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. * SDL3 (DLL) - This is the typical SDL3.dll, but for Gaming.Desktop.x64.
* SDL3_main (lib) - This contains a drop-in implementation of `WinMain` that is used as the entry point for GDK programs.
* tests/testgamecontroller - Standard SDL test program demonstrating controller functionality. * 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. * 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. *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.
@ -56,26 +55,25 @@ In your game's existing Visual Studio Solution, go to Build > Configuration Mana
### 2. Build SDL3 and SDL3_main for GDK ### ### 2. Build SDL3 and SDL3_main for GDK ###
Open `VisualC-GDK/SDL.sln` in Visual Studio, you need to build the SDL3 and SDL3_main targets 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), `SDL3.lib`, and `SDL3_main.lib` output files for your game project. 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/SDL3_main project file targets from the SDL source, and add those projects as a dependency. This would mean that SDL3 and SDL3_main would both be built when your game is built. *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 ### ### 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: 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 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 and SDL3_main.lib are * 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: * Under Linker > Input > Additional Dependencies, you need the following:
* `SDL3.lib` * `SDL3.lib`
* `SDL3_main.lib` (unless not using)
* `xgameruntime.lib` * `xgameruntime.lib`
* `../Microsoft.Xbox.Services.141.GDK.C.Thunks.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. * 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 ### ### 4. Setting up SDL_main ###
Rather than using your own implementation of `WinMain`, it's recommended that you instead `#include "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. 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
### 5. Required DLLs ### ### 5. Required DLLs ###

View File

@ -54,9 +54,10 @@
#elif defined(__GDK__) #elif defined(__GDK__)
/* On GDK, SDL provides a main function that initializes the game runtime. /* On GDK, SDL provides a main function that initializes the game runtime.
Please note that #include'ing SDL_main.h is not enough to get a main() If you prefer to write your own WinMain-function instead of having SDL
function working. You must either link against SDL3_main or, if not possible, provide one that calls your main() function,
call the SDL_GDKRunApp function from your entry point. #define SDL_MAIN_HANDLED before #include'ing SDL_main.h
and call the SDL_GDKRunApp function from your entry point.
*/ */
#define SDL_MAIN_NEEDED #define SDL_MAIN_NEEDED

View File

@ -32,16 +32,13 @@
not definition of SDL_MAIN_AVAILABLE etc in SDL_main.h) */ not definition of SDL_MAIN_AVAILABLE etc in SDL_main.h) */
#if !defined(SDL_MAIN_HANDLED) && !defined(_SDL_MAIN_NOIMPL) #if !defined(SDL_MAIN_HANDLED) && !defined(_SDL_MAIN_NOIMPL)
#if defined(__WIN32__) #if defined(__WIN32__) || defined(__GDK__)
/* these defines/typedefs are needed for the WinMain() definition */ /* these defines/typedefs are needed for the WinMain() definition */
#ifndef WINAPI #ifndef WINAPI
#define WINAPI __stdcall #define WINAPI __stdcall
#endif #endif
typedef struct HINSTANCE__ * HINSTANCE;
typedef char* LPSTR;
#ifdef main #ifdef main
# undef main # undef main
#endif /* main */ #endif /* main */
@ -52,6 +49,10 @@ typedef char* LPSTR;
extern "C" { extern "C" {
#endif #endif
typedef struct HINSTANCE__ * HINSTANCE;
typedef char* LPSTR;
#ifndef __GDK__ /* this is only needed for Win32 */
#if defined(_MSC_VER) #if defined(_MSC_VER)
/* The VC++ compiler needs main/wmain defined */ /* The VC++ compiler needs main/wmain defined */
@ -79,11 +80,17 @@ console_ansi_main(int argc, char *argv[])
} }
#endif /* UNICODE/ANSI */ #endif /* UNICODE/ANSI */
/* This is where execution begins [windowed apps] */ #endif /* not __GDK__ */
/* This is where execution begins [windowed apps and GDK] */
int WINAPI int WINAPI
WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
{ {
#ifdef __GDK__
return SDL_GDKRunApp(SDL_main, NULL);
#else
return SDL_Win32RunApp(SDL_main, NULL); return SDL_Win32RunApp(SDL_main, NULL);
#endif
} }
#ifdef __cplusplus #ifdef __cplusplus
@ -95,8 +102,8 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
/* rename users main() function to SDL_main() so it can be called from the wrapper above */ /* rename users main() function to SDL_main() so it can be called from the wrapper above */
#define main SDL_main #define main SDL_main
/* end of __WIN32__ and __GDK__ impls */
#elif 1 /* end of __WIN32__ impl - TODO: other platforms */ #elif 1 /* TODO: next platform */
#endif /* __WIN32__ etc */ #endif /* __WIN32__ etc */

View File

@ -17,22 +17,9 @@
2. Altered source versions must be plainly marked as such, and must not be 2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software. misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution. 3. This notice may not be removed or altered from any source distribution.
Nothing to do here, the code moved into SDL_main_impl.h
TODO: remove this file
*/ */
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h> /* until this SDL_main impl is converted to header-only.. */
/* Include this so we define UNICODE properly */
#include "../../core/windows/SDL_windows.h"
#ifdef main
#undef main
#endif /* main */
/* This is where execution begins */
int WINAPI
WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
{
return SDL_GDKRunApp(SDL_main, NULL);
}
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */