From 5a079a2d114f96d4847d1ee305d5b7c16eeec50e Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Sat, 27 Dec 2025 12:03:39 -0800 Subject: Initial commit --- contrib/SDL-3.2.8/src/main/SDL_main_callbacks.c | 149 +++++++++++++++++++++ contrib/SDL-3.2.8/src/main/SDL_main_callbacks.h | 32 +++++ contrib/SDL-3.2.8/src/main/SDL_runapp.c | 43 ++++++ .../src/main/emscripten/SDL_sysmain_callbacks.c | 47 +++++++ .../src/main/emscripten/SDL_sysmain_runapp.c | 56 ++++++++ .../SDL-3.2.8/src/main/gdk/SDL_sysmain_runapp.cpp | 148 ++++++++++++++++++++ .../src/main/generic/SDL_sysmain_callbacks.c | 96 +++++++++++++ .../SDL-3.2.8/src/main/ios/SDL_sysmain_callbacks.m | 88 ++++++++++++ .../SDL-3.2.8/src/main/n3ds/SDL_sysmain_runapp.c | 48 +++++++ .../SDL-3.2.8/src/main/ps2/SDL_sysmain_runapp.c | 84 ++++++++++++ .../SDL-3.2.8/src/main/psp/SDL_sysmain_runapp.c | 82 ++++++++++++ .../src/main/windows/SDL_sysmain_runapp.c | 99 ++++++++++++++ 12 files changed, 972 insertions(+) create mode 100644 contrib/SDL-3.2.8/src/main/SDL_main_callbacks.c create mode 100644 contrib/SDL-3.2.8/src/main/SDL_main_callbacks.h create mode 100644 contrib/SDL-3.2.8/src/main/SDL_runapp.c create mode 100644 contrib/SDL-3.2.8/src/main/emscripten/SDL_sysmain_callbacks.c create mode 100644 contrib/SDL-3.2.8/src/main/emscripten/SDL_sysmain_runapp.c create mode 100644 contrib/SDL-3.2.8/src/main/gdk/SDL_sysmain_runapp.cpp create mode 100644 contrib/SDL-3.2.8/src/main/generic/SDL_sysmain_callbacks.c create mode 100644 contrib/SDL-3.2.8/src/main/ios/SDL_sysmain_callbacks.m create mode 100644 contrib/SDL-3.2.8/src/main/n3ds/SDL_sysmain_runapp.c create mode 100644 contrib/SDL-3.2.8/src/main/ps2/SDL_sysmain_runapp.c create mode 100644 contrib/SDL-3.2.8/src/main/psp/SDL_sysmain_runapp.c create mode 100644 contrib/SDL-3.2.8/src/main/windows/SDL_sysmain_runapp.c (limited to 'contrib/SDL-3.2.8/src/main') diff --git a/contrib/SDL-3.2.8/src/main/SDL_main_callbacks.c b/contrib/SDL-3.2.8/src/main/SDL_main_callbacks.c new file mode 100644 index 0000000..9f3d9c1 --- /dev/null +++ b/contrib/SDL-3.2.8/src/main/SDL_main_callbacks.c @@ -0,0 +1,149 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SDL_internal.h" +#include "SDL_main_callbacks.h" + +static SDL_AppEvent_func SDL_main_event_callback; +static SDL_AppIterate_func SDL_main_iteration_callback; +static SDL_AppQuit_func SDL_main_quit_callback; +static SDL_AtomicInt apprc; // use an atomic, since events might land from any thread and we don't want to wrap this all in a mutex. A CAS makes sure we only move from zero once. +static void *SDL_main_appstate = NULL; + +// Return true if this event needs to be processed before returning from the event watcher +static bool ShouldDispatchImmediately(SDL_Event *event) +{ + switch (event->type) { + case SDL_EVENT_TERMINATING: + case SDL_EVENT_LOW_MEMORY: + case SDL_EVENT_WILL_ENTER_BACKGROUND: + case SDL_EVENT_DID_ENTER_BACKGROUND: + case SDL_EVENT_WILL_ENTER_FOREGROUND: + case SDL_EVENT_DID_ENTER_FOREGROUND: + return true; + default: + return false; + } +} + +static void SDL_DispatchMainCallbackEvent(SDL_Event *event) +{ + if (SDL_GetAtomicInt(&apprc) == SDL_APP_CONTINUE) { // if already quitting, don't send the event to the app. + SDL_CompareAndSwapAtomicInt(&apprc, SDL_APP_CONTINUE, SDL_main_event_callback(SDL_main_appstate, event)); + } +} + +static void SDL_DispatchMainCallbackEvents(void) +{ + SDL_Event events[16]; + + for (;;) { + int count = SDL_PeepEvents(events, SDL_arraysize(events), SDL_GETEVENT, SDL_EVENT_FIRST, SDL_EVENT_LAST); + if (count <= 0) { + break; + } + for (int i = 0; i < count; ++i) { + SDL_Event *event = &events[i]; + if (!ShouldDispatchImmediately(event)) { + SDL_DispatchMainCallbackEvent(event); + } + } + } +} + +static bool SDLCALL SDL_MainCallbackEventWatcher(void *userdata, SDL_Event *event) +{ + if (ShouldDispatchImmediately(event)) { + // Make sure any currently queued events are processed then dispatch this before continuing + SDL_DispatchMainCallbackEvents(); + SDL_DispatchMainCallbackEvent(event); + + // Make sure that we quit if we get a terminating event + if (event->type == SDL_EVENT_TERMINATING) { + SDL_CompareAndSwapAtomicInt(&apprc, SDL_APP_CONTINUE, SDL_APP_SUCCESS); + } + } else { + // We'll process this event later from the main event queue + } + return true; +} + +bool SDL_HasMainCallbacks(void) +{ + if (SDL_main_iteration_callback) { + return true; + } + return false; +} + +SDL_AppResult SDL_InitMainCallbacks(int argc, char* argv[], SDL_AppInit_func appinit, SDL_AppIterate_func appiter, SDL_AppEvent_func appevent, SDL_AppQuit_func appquit) +{ + SDL_main_iteration_callback = appiter; + SDL_main_event_callback = appevent; + SDL_main_quit_callback = appquit; + SDL_SetAtomicInt(&apprc, SDL_APP_CONTINUE); + + const SDL_AppResult rc = appinit(&SDL_main_appstate, argc, argv); + if (SDL_CompareAndSwapAtomicInt(&apprc, SDL_APP_CONTINUE, rc) && (rc == SDL_APP_CONTINUE)) { // bounce if SDL_AppInit already said abort, otherwise... + // make sure we definitely have events initialized, even if the app didn't do it. + if (!SDL_InitSubSystem(SDL_INIT_EVENTS)) { + SDL_SetAtomicInt(&apprc, SDL_APP_FAILURE); + return SDL_APP_FAILURE; + } + + if (!SDL_AddEventWatch(SDL_MainCallbackEventWatcher, NULL)) { + SDL_SetAtomicInt(&apprc, SDL_APP_FAILURE); + return SDL_APP_FAILURE; + } + } + + return (SDL_AppResult)SDL_GetAtomicInt(&apprc); +} + +SDL_AppResult SDL_IterateMainCallbacks(bool pump_events) +{ + if (pump_events) { + SDL_PumpEvents(); + } + SDL_DispatchMainCallbackEvents(); + + SDL_AppResult rc = (SDL_AppResult)SDL_GetAtomicInt(&apprc); + if (rc == SDL_APP_CONTINUE) { + rc = SDL_main_iteration_callback(SDL_main_appstate); + if (!SDL_CompareAndSwapAtomicInt(&apprc, SDL_APP_CONTINUE, rc)) { + rc = (SDL_AppResult)SDL_GetAtomicInt(&apprc); // something else already set a quit result, keep that. + } + } + return rc; +} + +void SDL_QuitMainCallbacks(SDL_AppResult result) +{ + SDL_RemoveEventWatch(SDL_MainCallbackEventWatcher, NULL); + SDL_main_quit_callback(SDL_main_appstate, result); + SDL_main_appstate = NULL; // just in case. + + // for symmetry, you should explicitly Quit what you Init, but we might come through here uninitialized and SDL_Quit() will clear everything anyhow. + //SDL_QuitSubSystem(SDL_INIT_EVENTS); + + SDL_Quit(); +} + diff --git a/contrib/SDL-3.2.8/src/main/SDL_main_callbacks.h b/contrib/SDL-3.2.8/src/main/SDL_main_callbacks.h new file mode 100644 index 0000000..1fd3725 --- /dev/null +++ b/contrib/SDL-3.2.8/src/main/SDL_main_callbacks.h @@ -0,0 +1,32 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_main_callbacks_h_ +#define SDL_main_callbacks_h_ + +bool SDL_HasMainCallbacks(void); +SDL_AppResult SDL_InitMainCallbacks(int argc, char *argv[], SDL_AppInit_func appinit, SDL_AppIterate_func _appiter, SDL_AppEvent_func _appevent, SDL_AppQuit_func _appquit); +SDL_AppResult SDL_IterateMainCallbacks(bool pump_events); +void SDL_QuitMainCallbacks(SDL_AppResult result); + +#endif // SDL_main_callbacks_h_ + + diff --git a/contrib/SDL-3.2.8/src/main/SDL_runapp.c b/contrib/SDL-3.2.8/src/main/SDL_runapp.c new file mode 100644 index 0000000..ddda4a6 --- /dev/null +++ b/contrib/SDL-3.2.8/src/main/SDL_runapp.c @@ -0,0 +1,43 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + +/* Most platforms that use/need SDL_main have their own SDL_RunApp() implementation. + * If not, you can special case it here by appending || defined(__YOUR_PLATFORM__) */ +#if ( !defined(SDL_MAIN_NEEDED) && !defined(SDL_MAIN_AVAILABLE) ) || defined(SDL_PLATFORM_ANDROID) + +int SDL_RunApp(int argc, char* argv[], SDL_main_func mainFunction, void * reserved) +{ + (void)reserved; + + if(!argv) + { + // make sure argv isn't NULL, in case some user code doesn't like that + static char dummyargv0[] = { 'S', 'D', 'L', '_', 'a', 'p', 'p', '\0' }; + static char* argvdummy[2] = { dummyargv0, NULL }; + argc = 1; + argv = argvdummy; + } + + return mainFunction(argc, argv); +} + +#endif diff --git a/contrib/SDL-3.2.8/src/main/emscripten/SDL_sysmain_callbacks.c b/contrib/SDL-3.2.8/src/main/emscripten/SDL_sysmain_callbacks.c new file mode 100644 index 0000000..d3b2f95 --- /dev/null +++ b/contrib/SDL-3.2.8/src/main/emscripten/SDL_sysmain_callbacks.c @@ -0,0 +1,47 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SDL_internal.h" +#include "../SDL_main_callbacks.h" + +#include + +static void EmscriptenInternalMainloop(void) +{ + const SDL_AppResult rc = SDL_IterateMainCallbacks(true); + if (rc != SDL_APP_CONTINUE) { + SDL_QuitMainCallbacks(rc); + emscripten_cancel_main_loop(); // kill" the mainloop, so it stops calling back into it. + exit((rc == SDL_APP_FAILURE) ? 1 : 0); // hopefully this takes down everything else, too. + } +} + +int SDL_EnterAppMainCallbacks(int argc, char* argv[], SDL_AppInit_func appinit, SDL_AppIterate_func appiter, SDL_AppEvent_func appevent, SDL_AppQuit_func appquit) +{ + const SDL_AppResult rc = SDL_InitMainCallbacks(argc, argv, appinit, appiter, appevent, appquit); + if (rc == SDL_APP_CONTINUE) { + emscripten_set_main_loop(EmscriptenInternalMainloop, 0, 0); // run at refresh rate, don't throw an exception since we do an orderly return. + } else { + SDL_QuitMainCallbacks(rc); + } + return (rc == SDL_APP_FAILURE) ? 1 : 0; +} + diff --git a/contrib/SDL-3.2.8/src/main/emscripten/SDL_sysmain_runapp.c b/contrib/SDL-3.2.8/src/main/emscripten/SDL_sysmain_runapp.c new file mode 100644 index 0000000..20dd6eb --- /dev/null +++ b/contrib/SDL-3.2.8/src/main/emscripten/SDL_sysmain_runapp.c @@ -0,0 +1,56 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + +#ifdef SDL_PLATFORM_EMSCRIPTEN + +#include + +EM_JS_DEPS(sdlrunapp, "$dynCall,$stringToNewUTF8"); + +int SDL_RunApp(int argc, char* argv[], SDL_main_func mainFunction, void * reserved) +{ + (void)reserved; + + // Move any URL params that start with "SDL_" over to environment + // variables, so the hint system can pick them up, etc, much like a user + // can set them from a shell prompt on a desktop machine. Ignore all + // other params, in case the app wants to use them for something. + MAIN_THREAD_EM_ASM({ + var parms = new URLSearchParams(window.location.search); + for (const [key, value] of parms) { + if (key.startsWith("SDL_")) { + var ckey = stringToNewUTF8(key); + var cvalue = stringToNewUTF8(value); + if ((ckey != 0) && (cvalue != 0)) { + //console.log("Setting SDL env var '" + key + "' to '" + value + "' ..."); + dynCall('iiii', $0, [ckey, cvalue, 1]); + } + _free(ckey); // these must use free(), not SDL_free()! + _free(cvalue); + } + } + }, SDL_setenv_unsafe); + + return mainFunction(argc, argv); +} + +#endif diff --git a/contrib/SDL-3.2.8/src/main/gdk/SDL_sysmain_runapp.cpp b/contrib/SDL-3.2.8/src/main/gdk/SDL_sysmain_runapp.cpp new file mode 100644 index 0000000..d7bdea0 --- /dev/null +++ b/contrib/SDL-3.2.8/src/main/gdk/SDL_sysmain_runapp.cpp @@ -0,0 +1,148 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + +extern "C" { +#include "../../core/gdk/SDL_gdk.h" +#include "../../core/windows/SDL_windows.h" +#include "../../events/SDL_events_c.h" +} +#include +#include +#include // CommandLineToArgvW() +#include + +// Pop up an out of memory message, returns to Windows +static BOOL OutOfMemory(void) +{ + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "Out of memory - aborting", NULL); + return FALSE; +} + +/* Gets the arguments with GetCommandLine, converts them to argc and argv + and calls SDL_main */ +extern "C" +int SDL_RunApp(int, char**, SDL_main_func mainFunction, void *reserved) +{ + LPWSTR *argvw; + char **argv; + int i, argc, result; + HRESULT hr; + XTaskQueueHandle taskQueue; + + argvw = CommandLineToArgvW(GetCommandLineW(), &argc); + if (argvw == NULL) { + return OutOfMemory(); + } + + /* Note that we need to be careful about how we allocate/free memory here. + * If the application calls SDL_SetMemoryFunctions(), we can't rely on + * SDL_free() to use the same allocator after SDL_main() returns. + */ + + // Parse it into argv and argc + argv = (char **)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (argc + 1) * sizeof(*argv)); + if (argv == NULL) { + return OutOfMemory(); + } + for (i = 0; i < argc; ++i) { + const int utf8size = WideCharToMultiByte(CP_UTF8, 0, argvw[i], -1, NULL, 0, NULL, NULL); + if (!utf8size) { // uhoh? + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "Error processing command line arguments", NULL); + return -1; + } + + argv[i] = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, utf8size); // this size includes the null-terminator character. + if (!argv[i]) { + return OutOfMemory(); + } + + if (WideCharToMultiByte(CP_UTF8, 0, argvw[i], -1, argv[i], utf8size, NULL, NULL) == 0) { // failed? uhoh! + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "Error processing command line arguments", NULL); + return -1; + } + } + argv[i] = NULL; + LocalFree(argvw); + + hr = XGameRuntimeInitialize(); + + if (SUCCEEDED(hr) && SDL_GetGDKTaskQueue(&taskQueue)) { + Uint32 titleid = 0; + char scidBuffer[64]; + XblInitArgs xblArgs; + + XTaskQueueSetCurrentProcessTaskQueue(taskQueue); + + // Try to get the title ID and initialize Xbox Live + hr = XGameGetXboxTitleId(&titleid); + if (SUCCEEDED(hr)) { + SDL_zero(xblArgs); + xblArgs.queue = taskQueue; + SDL_snprintf(scidBuffer, 64, "00000000-0000-0000-0000-0000%08X", titleid); + xblArgs.scid = scidBuffer; + hr = XblInitialize(&xblArgs); + } else { + SDL_SetError("[GDK] Unable to get titleid. Will not call XblInitialize. Check MicrosoftGame.config!"); + } + + SDL_SetMainReady(); + + if (!GDK_RegisterChangeNotifications()) { + return -1; + } + + // Run the application main() code + result = mainFunction(argc, argv); + + GDK_UnregisterChangeNotifications(); + + // !!! FIXME: This follows the docs exactly, but for some reason still leaks handles on exit? + // Terminate the task queue and dispatch any pending tasks + XTaskQueueTerminate(taskQueue, false, nullptr, nullptr); + while (XTaskQueueDispatch(taskQueue, XTaskQueuePort::Completion, 0)) + ; + + XTaskQueueCloseHandle(taskQueue); + + XGameRuntimeUninitialize(); + } else { +#ifdef SDL_PLATFORM_WINGDK + if (hr == E_GAMERUNTIME_DLL_NOT_FOUND) { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "[GDK] Gaming Runtime library not found (xgameruntime.dll)", NULL); + } else { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "[GDK] Could not initialize - aborting", NULL); + } +#else + SDL_assert_always(0 && "[GDK] Could not initialize - aborting"); +#endif + result = -1; + } + + // Free argv, to avoid memory leak + for (i = 0; i < argc; ++i) { + HeapFree(GetProcessHeap(), 0, argv[i]); + } + HeapFree(GetProcessHeap(), 0, argv); + + return result; +} + diff --git a/contrib/SDL-3.2.8/src/main/generic/SDL_sysmain_callbacks.c b/contrib/SDL-3.2.8/src/main/generic/SDL_sysmain_callbacks.c new file mode 100644 index 0000000..716489f --- /dev/null +++ b/contrib/SDL-3.2.8/src/main/generic/SDL_sysmain_callbacks.c @@ -0,0 +1,96 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SDL_internal.h" +#include "../SDL_main_callbacks.h" +#include "../../video/SDL_sysvideo.h" + +#ifndef SDL_PLATFORM_IOS + +static int callback_rate_increment = 0; +static bool iterate_after_waitevent = false; + +static void SDLCALL MainCallbackRateHintChanged(void *userdata, const char *name, const char *oldValue, const char *newValue) +{ + iterate_after_waitevent = newValue && (SDL_strcmp(newValue, "waitevent") == 0); + if (iterate_after_waitevent) { + callback_rate_increment = 0; + } else { + const int callback_rate = newValue ? SDL_atoi(newValue) : 0; + if (callback_rate > 0) { + callback_rate_increment = ((Uint64) 1000000000) / ((Uint64) callback_rate); + } else { + callback_rate_increment = 0; + } + } +} + +static SDL_AppResult GenericIterateMainCallbacks(void) +{ + if (iterate_after_waitevent) { + SDL_WaitEvent(NULL); + } + return SDL_IterateMainCallbacks(!iterate_after_waitevent); +} + +int SDL_EnterAppMainCallbacks(int argc, char* argv[], SDL_AppInit_func appinit, SDL_AppIterate_func appiter, SDL_AppEvent_func appevent, SDL_AppQuit_func appquit) +{ + SDL_AppResult rc = SDL_InitMainCallbacks(argc, argv, appinit, appiter, appevent, appquit); + if (rc == 0) { + SDL_AddHintCallback(SDL_HINT_MAIN_CALLBACK_RATE, MainCallbackRateHintChanged, NULL); + + Uint64 next_iteration = callback_rate_increment ? (SDL_GetTicksNS() + callback_rate_increment) : 0; + + while ((rc = GenericIterateMainCallbacks()) == SDL_APP_CONTINUE) { + // !!! FIXME: this can be made more complicated if we decide to + // !!! FIXME: optionally hand off callback responsibility to the + // !!! FIXME: video subsystem (for example, if Wayland has a + // !!! FIXME: protocol to drive an animation loop, maybe we hand + // !!! FIXME: off to them here if/when the video subsystem becomes + // !!! FIXME: initialized). + + // Try to run at whatever rate the hint requested. This makes this + // not eat all the CPU in simple things like loopwave. By + // default, we run as fast as possible, which means we'll clamp to + // vsync in common cases, and won't be restrained to vsync if the + // app is doing a benchmark or doesn't want to be, based on how + // they've set up that window. + if (callback_rate_increment == 0) { + next_iteration = 0; // just clear the timer and run at the pace the video subsystem allows. + } else { + const Uint64 now = SDL_GetTicksNS(); + if (next_iteration > now) { // Running faster than the limit, sleep a little. + SDL_DelayPrecise(next_iteration - now); + } else { + next_iteration = now; // if running behind, reset the timer. If right on time, `next_iteration` already equals `now`. + } + next_iteration += callback_rate_increment; + } + } + + SDL_RemoveHintCallback(SDL_HINT_MAIN_CALLBACK_RATE, MainCallbackRateHintChanged, NULL); + } + SDL_QuitMainCallbacks(rc); + + return (rc == SDL_APP_FAILURE) ? 1 : 0; +} + +#endif // !SDL_PLATFORM_IOS diff --git a/contrib/SDL-3.2.8/src/main/ios/SDL_sysmain_callbacks.m b/contrib/SDL-3.2.8/src/main/ios/SDL_sysmain_callbacks.m new file mode 100644 index 0000000..becbda2 --- /dev/null +++ b/contrib/SDL-3.2.8/src/main/ios/SDL_sysmain_callbacks.m @@ -0,0 +1,88 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SDL_internal.h" +#include "../SDL_main_callbacks.h" + +#ifdef SDL_PLATFORM_IOS + +#import + +#include "../../video/uikit/SDL_uikitevents.h" // For SDL_UpdateLifecycleObserver() + + +@interface SDLIosMainCallbacksDisplayLink : NSObject +@property(nonatomic, retain) CADisplayLink *displayLink; +- (void)appIteration:(CADisplayLink *)sender; +- (instancetype)init:(SDL_AppIterate_func)_appiter quitfunc:(SDL_AppQuit_func)_appquit; +@end + +static SDLIosMainCallbacksDisplayLink *globalDisplayLink; + +@implementation SDLIosMainCallbacksDisplayLink + +- (instancetype)init:(SDL_AppIterate_func)_appiter quitfunc:(SDL_AppQuit_func)_appquit; +{ + if ((self = [super init])) { + self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(appIteration:)]; + [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + } + return self; +} + +- (void)appIteration:(CADisplayLink *)sender +{ + const SDL_AppResult rc = SDL_IterateMainCallbacks(true); + if (rc != SDL_APP_CONTINUE) { + [self.displayLink invalidate]; + self.displayLink = nil; + globalDisplayLink = nil; + SDL_QuitMainCallbacks(rc); + SDL_UpdateLifecycleObserver(); + exit((rc == SDL_APP_FAILURE) ? 1 : 0); + } +} +@end + +// SDL_RunApp will land in UIApplicationMain, which calls SDL_main from postFinishLaunch, which calls this. +// When we return from here, we're living in the RunLoop, and a CADisplayLink is firing regularly for us. +int SDL_EnterAppMainCallbacks(int argc, char* argv[], SDL_AppInit_func appinit, SDL_AppIterate_func appiter, SDL_AppEvent_func appevent, SDL_AppQuit_func appquit) +{ + SDL_AppResult rc = SDL_InitMainCallbacks(argc, argv, appinit, appiter, appevent, appquit); + if (rc == SDL_APP_CONTINUE) { + globalDisplayLink = [[SDLIosMainCallbacksDisplayLink alloc] init:appiter quitfunc:appquit]; + if (globalDisplayLink == nil) { + rc = SDL_APP_FAILURE; + } else { + return 0; // this will fall all the way out of SDL_main, where UIApplicationMain will keep running the RunLoop. + } + } + + // appinit requested quit, just bounce out now. + SDL_QuitMainCallbacks(rc); + exit((rc == SDL_APP_FAILURE) ? 1 : 0); + + return 1; // just in case. +} + +#endif + + diff --git a/contrib/SDL-3.2.8/src/main/n3ds/SDL_sysmain_runapp.c b/contrib/SDL-3.2.8/src/main/n3ds/SDL_sysmain_runapp.c new file mode 100644 index 0000000..74ead99 --- /dev/null +++ b/contrib/SDL-3.2.8/src/main/n3ds/SDL_sysmain_runapp.c @@ -0,0 +1,48 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SDL_internal.h" + +#ifdef SDL_PLATFORM_3DS + +#include <3ds.h> + +int SDL_RunApp(int argc, char* argv[], SDL_main_func mainFunction, void * reserved) +{ + int result; + // init + osSetSpeedupEnable(true); + romfsInit(); + + SDL_SetMainReady(); + result = mainFunction(argc, argv); + + // quit + romfsExit(); + + return result; +} + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/contrib/SDL-3.2.8/src/main/ps2/SDL_sysmain_runapp.c b/contrib/SDL-3.2.8/src/main/ps2/SDL_sysmain_runapp.c new file mode 100644 index 0000000..23443c5 --- /dev/null +++ b/contrib/SDL-3.2.8/src/main/ps2/SDL_sysmain_runapp.c @@ -0,0 +1,84 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SDL_internal.h" + +#ifdef SDL_PLATFORM_PS2 + +// SDL_RunApp() code for PS2 based on SDL_ps2_main.c, fjtrujy@gmail.com + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +__attribute__((weak)) void reset_IOP(void) +{ + SifInitRpc(0); + while (!SifIopReset(NULL, 0)) { + } + while (!SifIopSync()) { + } +} + +static void prepare_IOP(void) +{ + reset_IOP(); + SifInitRpc(0); + sbv_patch_enable_lmb(); + sbv_patch_disable_prefix_check(); + sbv_patch_fileio(); +} + +static void init_drivers(void) +{ + init_ps2_filesystem_driver(); +} + +static void deinit_drivers(void) +{ + deinit_ps2_filesystem_driver(); +} + +int SDL_RunApp(int argc, char* argv[], SDL_main_func mainFunction, void * reserved) +{ + int res; + (void)reserved; + + prepare_IOP(); + init_drivers(); + + SDL_SetMainReady(); + + res = mainFunction(argc, argv); + + deinit_drivers(); + + return res; +} + +#endif // SDL_PLATFORM_PS2 diff --git a/contrib/SDL-3.2.8/src/main/psp/SDL_sysmain_runapp.c b/contrib/SDL-3.2.8/src/main/psp/SDL_sysmain_runapp.c new file mode 100644 index 0000000..e89f5ff --- /dev/null +++ b/contrib/SDL-3.2.8/src/main/psp/SDL_sysmain_runapp.c @@ -0,0 +1,82 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SDL_internal.h" + +#ifdef SDL_PLATFORM_PSP + +// SDL_RunApp() for PSP based on SDL_psp_main.c, placed in the public domain by Sam Lantinga 3/13/14 + +#include +#include +#include "../../events/SDL_events_c.h" + +/* If application's main() is redefined as SDL_main, and libSDL_main is + linked, then this file will create the standard exit callback, + define the PSP_MODULE_INFO macro, and exit back to the browser when + the program is finished. + + You can still override other parameters in your own code if you + desire, such as PSP_HEAP_SIZE_KB, PSP_MAIN_THREAD_ATTR, + PSP_MAIN_THREAD_STACK_SIZE, etc. +*/ + +PSP_MODULE_INFO("SDL App", 0, 1, 0); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_VFPU | THREAD_ATTR_USER); + +int sdl_psp_exit_callback(int arg1, int arg2, void *common) +{ + SDL_SendQuit(); + return 0; +} + +int sdl_psp_callback_thread(SceSize args, void *argp) +{ + int cbid; + cbid = sceKernelCreateCallback("Exit Callback", + sdl_psp_exit_callback, NULL); + sceKernelRegisterExitCallback(cbid); + sceKernelSleepThreadCB(); + return 0; +} + +int sdl_psp_setup_callbacks(void) +{ + int thid; + thid = sceKernelCreateThread("update_thread", + sdl_psp_callback_thread, 0x11, 0xFA0, 0, 0); + if (thid >= 0) { + sceKernelStartThread(thid, 0, 0); + } + return thid; +} + +int SDL_RunApp(int argc, char* argv[], SDL_main_func mainFunction, void * reserved) +{ + (void)reserved; + sdl_psp_setup_callbacks(); + + SDL_SetMainReady(); + + return mainFunction(argc, argv); +} + +#endif // SDL_PLATFORM_PSP diff --git a/contrib/SDL-3.2.8/src/main/windows/SDL_sysmain_runapp.c b/contrib/SDL-3.2.8/src/main/windows/SDL_sysmain_runapp.c new file mode 100644 index 0000000..d8c3fac --- /dev/null +++ b/contrib/SDL-3.2.8/src/main/windows/SDL_sysmain_runapp.c @@ -0,0 +1,99 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + +#ifdef SDL_PLATFORM_WIN32 + +#include "../../core/windows/SDL_windows.h" + +/* Win32-specific SDL_RunApp(), which does most of the SDL_main work, + based on SDL_windows_main.c, placed in the public domain by Sam Lantinga 4/13/98 */ + +#include // CommandLineToArgvW() + +// Pop up an out of memory message, returns to Windows +static int OutOfMemory(void) +{ + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "Out of memory - aborting", NULL); + return -1; +} + +int MINGW32_FORCEALIGN SDL_RunApp(int _argc, char* _argv[], SDL_main_func mainFunction, void * reserved) +{ + /* Gets the arguments with GetCommandLine, converts them to argc and argv + and calls SDL_main */ + + LPWSTR *argvw; + char **argv; + int i, argc, result; + + (void)_argc; (void)_argv; (void)reserved; + + argvw = CommandLineToArgvW(GetCommandLineW(), &argc); + if (!argvw) { + return OutOfMemory(); + } + + /* Note that we need to be careful about how we allocate/free memory here. + * If the application calls SDL_SetMemoryFunctions(), we can't rely on + * SDL_free() to use the same allocator after SDL_main() returns. + */ + + // Parse it into argv and argc + argv = (char **)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (argc + 1) * sizeof(*argv)); + if (!argv) { + return OutOfMemory(); + } + for (i = 0; i < argc; ++i) { + const int utf8size = WideCharToMultiByte(CP_UTF8, 0, argvw[i], -1, NULL, 0, NULL, NULL); + if (!utf8size) { // uhoh? + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "Error processing command line arguments", NULL); + return -1; + } + + argv[i] = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, utf8size); // this size includes the null-terminator character. + if (!argv[i]) { + return OutOfMemory(); + } + + if (WideCharToMultiByte(CP_UTF8, 0, argvw[i], -1, argv[i], utf8size, NULL, NULL) == 0) { // failed? uhoh! + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "Error processing command line arguments", NULL); + return -1; + } + } + argv[i] = NULL; + LocalFree(argvw); + + SDL_SetMainReady(); + + // Run the application main() code + result = mainFunction(argc, argv); + + // Free argv, to avoid memory leak + for (i = 0; i < argc; ++i) { + HeapFree(GetProcessHeap(), 0, argv[i]); + } + HeapFree(GetProcessHeap(), 0, argv); + + return result; +} + +#endif // SDL_PLATFORM_WIN32 -- cgit v1.2.3