From d7b96ea8c216ff5755a546d1a913a9cd9e7fb3f0 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Tue, 13 Jan 2026 05:47:20 +0500 Subject: [PATCH] engine: pass arguments on engine restart on nswitch, add forgotten -changegame parameter, simplify code for other platforms --- engine/common/system.c | 63 ++++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/engine/common/system.c b/engine/common/system.c index 20de119e..b6cfda08 100644 --- a/engine/common/system.c +++ b/engine/common/system.c @@ -536,42 +536,63 @@ it explicitly doesn't use internal allocation or string copy utils */ qboolean Sys_NewInstance( const char *gamedir, const char *finalmsg ) { + qboolean replaced_arg = false; + int i; + #if XASH_NSWITCH char newargs[4096]; const char *exe = host.argv[0]; // arg 0 is always the full NRO path - // TODO: carry over the old args (assuming you can even pass any) - Q_snprintf( newargs, sizeof( newargs ), "%s -game %s", exe, gamedir ); + for( i = 0; i < host.argc; i++ ) + { + Q_strncat( newargs, host.argv[i], sizeof( newargs )); + Q_strncat( newargs, " ", sizeof( newargs )); + + if( !Q_stricmp( host.argv[i], "-game" )) + { + Q_strncat( newargs, gamedir, sizeof( newargs )); + Q_strncat( newargs, " ", sizeof( newargs )); + replaced_arg = true; + i++; + } + } + + if( !replaced_arg ) + { + Q_strncat( newargs, "-game ", sizeof( newargs )); + Q_strncat( newargs, gamedir, sizeof( newargs )); + } + + Q_strncat( newargs, " -changegame", sizeof( newargs )); + // just restart the entire thing printf( "envSetNextLoad exe: `%s`\n", exe ); printf( "envSetNextLoad argv:\n`%s`\n", newargs ); + Host_ShutdownWithReason( finalmsg ); envSetNextLoad( exe, newargs ); exit( 0 ); #else - int i = 0; - qboolean replacedArg = false; - size_t exelen; + int exelen; char *exe, **newargs; // don't use engine allocation utils here // they will be freed after Host_Shutdown newargs = calloc( host.argc + 4, sizeof( *newargs )); - while( i < host.argc ) + + for( i = 0; i < host.argc; i++ ) { newargs[i] = strdup( host.argv[i] ); - // replace existing -game argument if( !Q_stricmp( newargs[i], "-game" )) { newargs[i + 1] = strdup( gamedir ); - replacedArg = true; - i += 2; + replaced_arg = true; + i++; } - else i++; } - if( !replacedArg ) + if( !replaced_arg ) { newargs[i++] = strdup( "-game" ); newargs[i++] = strdup( gamedir ); @@ -580,25 +601,27 @@ qboolean Sys_NewInstance( const char *gamedir, const char *finalmsg ) newargs[i++] = strdup( "-changegame" ); newargs[i] = NULL; + Host_ShutdownWithReason( finalmsg ); + #if XASH_PSVITA // under normal circumstances it's always going to be the same path exe = strdup( "app0:/eboot.bin" ); - Host_ShutdownWithReason( finalmsg ); sceAppMgrLoadExec( exe, newargs, NULL ); #else exelen = wai_getExecutablePath( NULL, 0, NULL ); - exe = malloc( exelen + 1 ); - wai_getExecutablePath( exe, exelen, NULL ); - exe[exelen] = 0; + if( exelen >= 0 ) + { + exe = malloc( exelen + 1 ); + wai_getExecutablePath( exe, exelen, NULL ); + exe[exelen] = 0; - Host_ShutdownWithReason( finalmsg ); + execv( exe, newargs ); - execv( exe, newargs ); + // if execv returned, it's probably an error + printf( "execv failed: %s", strerror( errno )); + } #endif - // if execv returned, it's probably an error - printf( "execv failed: %s", strerror( errno )); - for( ; i >= 0; i-- ) free( newargs[i] ); free( newargs );