SDL: Port PSP SDL_main to header-only + SDL_RunApp()

From 989a8ca90ed8ae55c9df10999d57a091d0e56618 Mon Sep 17 00:00:00 2001
From: Daniel Gibson <[EMAIL REDACTED]>
Date: Mon, 12 Dec 2022 19:22:17 +0100
Subject: [PATCH] Port PSP SDL_main to header-only + SDL_RunApp()

---
 CMakeLists.txt              |  3 ++
 include/SDL3/SDL_main.h     |  2 +-
 src/core/psp/SDL_psp.c      | 83 +++++++++++++++++++++++++++++++++++++
 src/main/psp/SDL_psp_main.c | 64 +---------------------------
 4 files changed, 89 insertions(+), 63 deletions(-)
 create mode 100644 src/core/psp/SDL_psp.c

diff --git a/CMakeLists.txt b/CMakeLists.txt
index a4ddfdcd67cd..a67f210e6982 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2572,6 +2572,9 @@ elseif(PSP)
  file(GLOB PSP_MAIN_SOURCES ${SDL3_SOURCE_DIR}/src/main/psp/*.c)
  list(APPEND SDLMAIN_SOURCES ${PSP_MAIN_SOURCES})
 
+  file(GLOB PSP_CORE_SOURCES ${SDL3_SOURCE_DIR}/src/core/psp/*.c)
+  list(APPEND SOURCE_FILES ${PSP_CORE_SOURCES})
+
   if(SDL_AUDIO)
     set(SDL_AUDIO_DRIVER_PSP 1)
     file(GLOB PSP_AUDIO_SOURCES ${SDL3_SOURCE_DIR}/src/audio/psp/*.c)
diff --git a/include/SDL3/SDL_main.h b/include/SDL3/SDL_main.h
index 8a47091af630..193d44bfe927 100644
--- a/include/SDL3/SDL_main.h
+++ b/include/SDL3/SDL_main.h
@@ -280,7 +280,7 @@ extern DECLSPEC void SDLCALL SDL_GDKSuspendComplete(void);
 #if !defined(SDL_MAIN_HANDLED) && !defined(SDL_MAIN_NOIMPL)
 /* include header-only SDL_main implementations */
 #if defined(__WIN32__) || defined(__GDK__) || defined(__IOS__) || defined(__TVOS__) \
-    || defined(__3DS__) || defined(__NGAGE__) || defined(__PS2__)
+    || defined(__3DS__) || defined(__NGAGE__) || defined(__PS2__) || defined(__PSP__)
 
 /* platforms whichs main (-equivalent) can be implemented in plain C */
 #include <SDL3/SDL_main_impl.h>
diff --git a/src/core/psp/SDL_psp.c b/src/core/psp/SDL_psp.c
new file mode 100644
index 000000000000..b9877af8ed83
--- /dev/null
+++ b/src/core/psp/SDL_psp.c
@@ -0,0 +1,83 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2022 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 __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>
+
+/* 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)
+{
+    sceKernelExitGame();
+    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;
+}
+
+DECLSPEC int
+SDL_RunApp(int argc, char* argv[], SDL_main_func mainFunction, void * reserved)
+{
+    (void)reserved;
+    sdl_psp_setup_callbacks();
+
+    SDL_SetMainReady();
+
+    (void)SDL_main(argc, argv);
+    return 0;
+}
+
+#endif /* __PSP__ */
diff --git a/src/main/psp/SDL_psp_main.c b/src/main/psp/SDL_psp_main.c
index c05d3ec4f0be..2eb1cf84fad9 100644
--- a/src/main/psp/SDL_psp_main.c
+++ b/src/main/psp/SDL_psp_main.c
@@ -1,68 +1,8 @@
 /*
     SDL_psp_main.c, placed in the public domain by Sam Lantinga  3/13/14
-*/
-#include <SDL3/SDL.h>
-#include <SDL3/SDL_main.h> /* until this SDL_main impl is converted to header-only.. */
-
-#ifdef __PSP__
-
-#include <pspkernel.h>
-#include <pspthreadman.h>
-
-#ifdef main
-#undef main
-#endif
 
-/* 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.
+    empty, moved to SDL_RunApp() in src/core/psp/SDL_psp.c
+    TODO: remove
 */
 
-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)
-{
-    sceKernelExitGame();
-    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 main(int argc, char *argv[])
-{
-    sdl_psp_setup_callbacks();
-
-    SDL_SetMainReady();
-
-    (void)SDL_main(argc, argv);
-    return 0;
-}
-
-#endif /* __PSP__ */
-
 /* vi: set ts=4 sw=4 expandtab: */