diff --git a/misc/ios/CCIOS.xcodeproj/project.pbxproj b/misc/ios/CCIOS.xcodeproj/project.pbxproj index 364ab0a13..99841b95b 100644 --- a/misc/ios/CCIOS.xcodeproj/project.pbxproj +++ b/misc/ios/CCIOS.xcodeproj/project.pbxproj @@ -9,7 +9,6 @@ /* Begin PBXBuildFile section */ 9A4D0C642BDD168800E1695D /* TouchUI.c in Sources */ = {isa = PBXBuildFile; fileRef = 9A4D0C632BDD168800E1695D /* TouchUI.c */; }; 9A57ECEE2BCD1408006A89F0 /* Audio_OpenAL.c in Sources */ = {isa = PBXBuildFile; fileRef = 9A57ECED2BCD1408006A89F0 /* Audio_OpenAL.c */; }; - 9A57ECF02BCD1413006A89F0 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 9A57ECEF2BCD1412006A89F0 /* main.c */; }; 9A62ADF5286D906F00E5E3DE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9A62ADF4286D906F00E5E3DE /* Assets.xcassets */; }; 9A6C79652BFDDEF200676D27 /* FancyLighting.c in Sources */ = {isa = PBXBuildFile; fileRef = 9A6C79642BFDDEF100676D27 /* FancyLighting.c */; }; 9A6C79672BFDDF0700676D27 /* Queue.c in Sources */ = {isa = PBXBuildFile; fileRef = 9A6C79662BFDDF0600676D27 /* Queue.c */; }; @@ -101,7 +100,6 @@ /* Begin PBXFileReference section */ 9A4D0C632BDD168800E1695D /* TouchUI.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = TouchUI.c; sourceTree = ""; }; 9A57ECED2BCD1408006A89F0 /* Audio_OpenAL.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Audio_OpenAL.c; sourceTree = ""; }; - 9A57ECEF2BCD1412006A89F0 /* main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = ""; }; 9A62ADF4286D906F00E5E3DE /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = ClassiCube/Assets.xcassets; sourceTree = ""; }; 9A6C79642BFDDEF100676D27 /* FancyLighting.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = FancyLighting.c; sourceTree = ""; }; 9A6C79662BFDDF0600676D27 /* Queue.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Queue.c; sourceTree = ""; }; @@ -231,7 +229,6 @@ 9A6C79662BFDDF0600676D27 /* Queue.c */, 9A6C79642BFDDEF100676D27 /* FancyLighting.c */, 9A4D0C632BDD168800E1695D /* TouchUI.c */, - 9A57ECEF2BCD1412006A89F0 /* main.c */, 9A57ECED2BCD1408006A89F0 /* Audio_OpenAL.c */, 9A7401DA2B7384060040E575 /* SSL.c */, 9A7401D82B737D5B0040E575 /* Commands.c */, @@ -457,7 +454,6 @@ 9AC5433E2AE2649F0086C85F /* SystemFonts.c in Sources */, 9A89D57F27F802F600FF3F80 /* LWeb.c in Sources */, 9A89D56627F802F600FF3F80 /* Drawer2D.c in Sources */, - 9A57ECF02BCD1413006A89F0 /* main.c in Sources */, 9A89D57427F802F600FF3F80 /* MapRenderer.c in Sources */, 9A89D57627F802F600FF3F80 /* _pshinter.c in Sources */, 9A89D56A27F802F600FF3F80 /* Physics.c in Sources */, diff --git a/src/Platform_Amiga.c b/src/Platform_Amiga.c index 4cc33a583..f89e51b6c 100644 --- a/src/Platform_Amiga.c +++ b/src/Platform_Amiga.c @@ -31,6 +31,24 @@ cc_bool Platform_ReadonlyFilesystem; static const char __attribute__((used)) min_stack[] = "$STACK:102400"; +/*########################################################################################################################* +*-----------------------------------------------------Main entrypoint-----------------------------------------------------* +*#########################################################################################################################*/ +#include "main_impl.h" + +int main(int argc, char** argv) { + cc_result res; + SetupProgram(argc, argv); + + do { + res = RunProgram(argc, argv); + } while (Window_Main.Exists); + + Window_Free(); + Process_Exit(res); + return res; +} + /*########################################################################################################################* *---------------------------------------------------------Memory----------------------------------------------------------* *#########################################################################################################################*/ diff --git a/src/Platform_Android.c b/src/Platform_Android.c index df3f6838f..f2caf299e 100644 --- a/src/Platform_Android.c +++ b/src/Platform_Android.c @@ -10,6 +10,20 @@ #include #include +/*########################################################################################################################* +*-----------------------------------------------------Main entrypoint-----------------------------------------------------* +*#########################################################################################################################*/ +#include "main_impl.h" + +// ClassiCube is just a native library on android, +// unlike most other platforms where it is the executable. +// The activity java class is responsible for kickstarting the game +void android_main(void) { + Platform_LogConst("Main loop started!"); + SetupProgram(0, NULL); + for (;;) { RunProgram(0, NULL); } +} + /*########################################################################################################################* *------------------------------------------------------Logging/Time-------------------------------------------------------* @@ -214,7 +228,6 @@ void JavaCall_String_String(const char* name, const cc_string* arg, cc_string* d /*########################################################################################################################* *----------------------------------------------------Initialisation-------------------------------------------------------* *#########################################################################################################################*/ -extern void android_main(void); static void JNICALL java_updateInstance(JNIEnv* env, jobject instance) { Platform_LogConst("App instance updated!"); App_Instance = (*env)->NewGlobalRef(env, instance); diff --git a/src/Platform_MacClassic.c b/src/Platform_MacClassic.c index 592c9c595..8c1b2f3c7 100644 --- a/src/Platform_MacClassic.c +++ b/src/Platform_MacClassic.c @@ -38,6 +38,24 @@ const char* Platform_AppNameSuffix = " MAC PPC"; cc_uint8 Platform_Flags = PLAT_FLAG_SINGLE_PROCESS; cc_bool Platform_ReadonlyFilesystem; +/*########################################################################################################################* +*-----------------------------------------------------Main entrypoint-----------------------------------------------------* +*#########################################################################################################################*/ +#include "main_impl.h" + +int main(int argc, char** argv) { + cc_result res; + SetupProgram(argc, argv); + + do { + res = RunProgram(argc, argv); + } while (Window_Main.Exists); + + Window_Free(); + Process_Exit(res); + return res; +} + /*########################################################################################################################* *---------------------------------------------------Imported headers------------------------------------------------------* diff --git a/src/Platform_Posix.c b/src/Platform_Posix.c index 58beaf337..452dce619 100644 --- a/src/Platform_Posix.c +++ b/src/Platform_Posix.c @@ -88,6 +88,29 @@ cc_bool Platform_ReadonlyFilesystem; #include #endif +/*########################################################################################################################* +*-----------------------------------------------------Main entrypoint-----------------------------------------------------* +*#########################################################################################################################*/ +#if defined CC_BUILD_IOS || defined CC_BUILD_ANDROID +/* Implemented in interop_ios.m or Platform_Android.c */ +#else +#include "main_impl.h" + +int main(int argc, char** argv) { + cc_result res; + SetupProgram(argc, argv); + + /* If single process mode, then the loop is launcher -> game -> launcher etc */ + do { + res = RunProgram(argc, argv); + } while (Platform_IsSingleProcess() && Window_Main.Exists); + + Window_Free(); + Process_Exit(res); + return res; +} +#endif + /*########################################################################################################################* *---------------------------------------------------------Memory----------------------------------------------------------* diff --git a/src/Platform_Symbian.cpp b/src/Platform_Symbian.cpp index 62db0f8aa..9c71a1403 100644 --- a/src/Platform_Symbian.cpp +++ b/src/Platform_Symbian.cpp @@ -55,6 +55,24 @@ const char* Platform_AppNameSuffix = ""; cc_uint8 Platform_Flags = PLAT_FLAG_SINGLE_PROCESS | PLAT_FLAG_APP_EXIT; cc_bool Platform_ReadonlyFilesystem; +/*########################################################################################################################* +*-----------------------------------------------------Main entrypoint-----------------------------------------------------* +*#########################################################################################################################*/ +#include "main_impl.h" + +int main(int argc, char** argv) { + cc_result res; + SetupProgram(argc, argv); + + do { + res = RunProgram(argc, argv); + } while (Window_Main.Exists); + + Window_Free(); + Process_Exit(res); + return res; +} + /*########################################################################################################################* *---------------------------------------------------------Memory----------------------------------------------------------* diff --git a/src/Platform_Web.c b/src/Platform_Web.c index 76e8cfb55..3eaa4e002 100644 --- a/src/Platform_Web.c +++ b/src/Platform_Web.c @@ -403,6 +403,8 @@ void Platform_Init(void) { } void Platform_Free(void) { } +cc_result Platform_SetDefaultCurrentDirectory(int argc, char** argv) { return 0; } + /*########################################################################################################################* *-------------------------------------------------------Encryption--------------------------------------------------------* @@ -429,15 +431,18 @@ int Platform_GetCommandLineArgs(int argc, STRING_REF char** argv, cc_string* arg for (i = 0; i < count; i++) { args[i] = String_FromReadonly(argv[i]); } return count; } - - -cc_result Platform_SetDefaultCurrentDirectory(int argc, char** argv) { return 0; } -static int _argc; +static int _argc; static char** _argv; -extern void interop_FS_Init(void); -extern void interop_DirectorySetWorking(const char* path); -extern void interop_AsyncDownloadTexturePack(const char* path); +/* webclient does some asynchronous initialisation first, then kickstarts the game after that */ +static void web_main(int argc, char** argv) { + SetupProgram(_argc, _argv); + cc_result res = RunProgram(_argc, _argv); + + if (!res) return; + Window_Free(); + Process_Exit(res); +} int main(int argc, char** argv) { _argc = argc; _argv = argv; @@ -454,15 +459,13 @@ int main(int argc, char** argv) { extern void interop_LoadIndexedDB(void); extern void interop_AsyncLoadIndexedDB(void); + /* Asynchronous callback after texture pack is downloaded */ EMSCRIPTEN_KEEPALIVE void main_phase1(void) { interop_LoadIndexedDB(); /* legacy compatibility */ interop_AsyncLoadIndexedDB(); } -extern int web_main(int argc, char** argv); /* Asynchronous callback after IndexedDB is loaded */ -EMSCRIPTEN_KEEPALIVE void main_phase2(void) { - web_main(_argc, _argv); -} +EMSCRIPTEN_KEEPALIVE void main_phase2(void) { web_main(); } #endif diff --git a/src/Platform_Windows.c b/src/Platform_Windows.c index a7b29a286..160298225 100644 --- a/src/Platform_Windows.c +++ b/src/Platform_Windows.c @@ -41,6 +41,34 @@ const char* Platform_AppNameSuffix = ""; cc_bool Platform_ReadonlyFilesystem; cc_uint8 Platform_Flags; +/*########################################################################################################################* +*-----------------------------------------------------Main entrypoint-----------------------------------------------------* +*#########################################################################################################################*/ +#include "main_impl.h" + +/* NOTE: main_real is used for when compiling with MinGW without linking to startup files. */ +/* Normally, the final code produced for "main" is our "main" combined with crt's main */ +/* (mingw-w64-crt/crt/gccmain.c) - alas this immediately crashes the game on startup. */ +/* Using main_real instead and setting main_real as the entrypoint fixes the crash. */ +#if defined CC_NOMAIN +int main_real(int argc, char** argv) { +#else +int main(int argc, char** argv) { +#endif + cc_result res; + SetupProgram(argc, argv); + + /* If single process mode, then the loop is launcher -> game -> launcher etc */ + do { + res = RunProgram(argc, argv); + } while (Platform_IsSingleProcess() && Window_Main.Exists); + + Window_Free(); + Process_Exit(res); + return res; +} + + /*########################################################################################################################* *---------------------------------------------------------Memory----------------------------------------------------------* *#########################################################################################################################*/ diff --git a/src/_PlatformConsole.h b/src/_PlatformConsole.h index c2701a2ed..7877e42bb 100644 --- a/src/_PlatformConsole.h +++ b/src/_PlatformConsole.h @@ -1,5 +1,20 @@ cc_uint8 Platform_Flags = PLAT_FLAG_SINGLE_PROCESS | PLAT_FLAG_APP_EXIT; +/*########################################################################################################################* +*-----------------------------------------------------Main entrypoint-----------------------------------------------------* +*#########################################################################################################################*/ +#include "main_impl.h" + +int main(int argc, char** argv) { + SetupProgram(argc, argv); + while (Window_Main.Exists) { + RunProgram(argc, argv); + } + + Window_Free(); + return 0; +} + /*########################################################################################################################* *---------------------------------------------------------Memory----------------------------------------------------------* diff --git a/src/interop_ios.m b/src/interop_ios.m index 989ecd01d..4850bfa0e 100644 --- a/src/interop_ios.m +++ b/src/interop_ios.m @@ -46,9 +46,12 @@ void LogUnhandledNSErrors(NSException* ex); @implementation CCAppDelegate +#include "main_impl.h" - (void)runMainLoop { - extern int ios_main(int argc, char** argv); - ios_main(1, NULL); + /* ClassiCube is sort of and sort of not the executable */ + /* on iOS - UIKit is responsible for kickstarting the game. */ + SetupProgram(1, NULL); + for (;;) { RunProgram(1, NULL); } } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { diff --git a/src/main.c b/src/main_impl.h similarity index 77% rename from src/main.c rename to src/main_impl.h index e978de050..82ead7211 100644 --- a/src/main.c +++ b/src/main_impl.h @@ -1,3 +1,12 @@ +/* +NOTE: This file contains the common entrypoint code for ClassiCube. + +This file is included by platform backend files (e.g. see Platform_Windows.c, Platform_Posix.c) +This separation is necessary because some platforms require special 'main' functions. + +Eg. the webclient 'main' function loads IndexedDB, and when that has asynchronously finished, + then calls the 'web_main' callback - which actually runs ClassiCube +*/ #include "Logger.h" #include "String.h" #include "Platform.h" @@ -212,63 +221,3 @@ static int RunProgram(int argc, char** argv) { return 0; } -#if defined CC_BUILD_IOS -/* ClassiCube is sort of and sort of not the executable */ -/* on iOS - UIKit is responsible for kickstarting the game. */ -/* (this is handled in interop_ios.m as the code is Objective C) */ -int ios_main(int argc, char** argv) { - SetupProgram(argc, argv); - for (;;) { RunProgram(argc, argv); } - return 0; -} -#elif defined CC_BUILD_ANDROID -/* ClassiCube is just a native library on android, */ -/* unlike other platforms where it is the executable. */ -/* (activity java class is responsible for kickstarting the game, - see Platform_Android.c for the code that actually calls this) */ -void android_main(void) { - Platform_LogConst("Main loop started!"); - SetupProgram(0, NULL); - for (;;) { RunProgram(0, NULL); } -} -#elif defined CC_BUILD_CONSOLE -int main(int argc, char** argv) { - SetupProgram(argc, argv); - while (Window_Main.Exists) { - RunProgram(argc, argv); - } - - Window_Free(); - return 0; -} -#else -/* NOTE: main_real is used for when compiling with MinGW without linking to startup files. */ -/* Normally, the final code produced for "main" is our "main" combined with crt's main */ -/* (mingw-w64-crt/crt/gccmain.c) - alas this immediately crashes the game on startup. */ -/* Using main_real instead and setting main_real as the entrypoint fixes the crash. */ -#if defined CC_NOMAIN -int main_real(int argc, char** argv) { -#elif defined CC_BUILD_WEB -/* webclient does some asynchronous initialisation first, then kickstarts the game after that */ -int web_main(int argc, char** argv) { -#else -int main(int argc, char** argv) { -#endif - cc_result res; - SetupProgram(argc, argv); - - /* If single process mode, then the loop is launcher -> game -> launcher etc */ - do { - res = RunProgram(argc, argv); - } while (Platform_IsSingleProcess() && Window_Main.Exists); - -#ifdef CC_BUILD_WEB - if (res) Window_Free(); -#else - Window_Free(); -#endif - - Process_Exit(res); - return res; -} -#endif