chore(build): use SDL3

This commit is contained in:
phaneron 2025-04-12 04:38:19 -04:00
parent 9d04a35d87
commit b3c0734a9e
3286 changed files with 866354 additions and 554996 deletions

View file

@ -0,0 +1,149 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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();
}

View file

@ -0,0 +1,32 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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_

43
vendor/sdl-3.2.10/src/main/SDL_runapp.c vendored Normal file
View file

@ -0,0 +1,43 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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

View file

@ -0,0 +1,47 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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 <emscripten.h>
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;
}

View file

@ -0,0 +1,56 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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 <emscripten/emscripten.h>
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

View file

@ -0,0 +1,148 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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 <XGameRuntime.h>
#include <xsapi-c/services_c.h>
#include <shellapi.h> // CommandLineToArgvW()
#include <appnotify.h>
// 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;
}

View file

@ -0,0 +1,96 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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

View file

@ -0,0 +1,88 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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 <UIKit/UIKit.h>
#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

View file

@ -0,0 +1,48 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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

View file

@ -0,0 +1,84 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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 <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <kernel.h>
#include <sifrpc.h>
#include <iopcontrol.h>
#include <sbv_patches.h>
#include <ps2_filesystem_driver.h>
__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

View file

@ -0,0 +1,82 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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 <pspkernel.h>
#include <pspthreadman.h>
#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

View file

@ -0,0 +1,99 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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 <shellapi.h> // 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