Compare commits

...

14 Commits

Author SHA1 Message Date
Alibek Omarov
9cd456e414 ci: add wafcache to all targets that use Waf, except Android which uses generated CMakeLists instead 2025-01-13 20:24:45 +03:00
Alibek Omarov
4a7a5f0b8c wscript: add option to use wafcache 2025-01-13 20:02:59 +03:00
Alibek Omarov
201d9c8f80 public: split VCS info to separate file for slightly better compilation speeds 2025-01-13 20:02:59 +03:00
Alibek Omarov
69341e36a3 public: expose commit and branch as global variables instead of functions 2025-01-13 20:02:59 +03:00
Alibek Omarov
3532a77643 public: move git commit and branch private to libpublic 2025-01-13 20:02:59 +03:00
Alibek Omarov
35dc072b26 filesystem: on Android, assume all paths are case-sensitive because doing Linux-specific ioctl check crashes FUSE driver and kills our app 2025-01-13 13:56:15 +03:00
Alibek Omarov
f92a3695b3 filesystem: fix fd leak in Platform_GetDirectoryCaseSensitivity 2025-01-13 13:54:42 +03:00
Alibek Omarov
a7b776f3b9 Revert "wscript: disable /showIncludes based msvcdeps for now, it causes issues with non-English locales"
Add option --enable-msvcdeps that we only enable on CI.

This reverts commit e58007aab3.
2025-01-10 21:48:43 +03:00
Alibek Omarov
f2fb668c9e android: now run exit() from Java side, as the next engine run is expected to be clean 2025-01-09 21:29:01 +03:00
Alibek Omarov
90e493fa3a engine: common: add Host_ExitInMain function that will force engine return from Host_Main() function, essentially making engine gracefully exit on Android
In future, this might be used everywhere, so users would be able to add custom
cleanup in some advanced game_launch implementation, on any platform.
2025-01-09 20:31:26 +03:00
Alibek Omarov
692bcc4073 engine: client: cl_tent: rewrite fizz effect, fix incorrect positoning along the way 2025-01-09 19:23:40 +03:00
Alibek Omarov
823642b10d readme: add link to ipa-reader.com for Xash word pronounciation [skip ci] 2025-01-09 17:13:56 +03:00
Alibek Omarov
07189ca2f5 engine: client: remove spammy message about not precached model on client side
Recently, mods (Brutal Half-Life v3 and MMod) started to call this function
every frame as a hacky way to detect presence of some model on the level. I
don't know why they do that, but users (who co-incidentally run engine with
-dev) has been complaining about console spam.

This is why we can't have things.
2025-01-09 17:10:54 +03:00
Alibek Omarov
0d55441830 engine: properly pass shutdown reason down to close log, helps to finally get rid of global finalmsg 2025-01-09 08:04:18 +03:00
33 changed files with 236 additions and 162 deletions

View File

@@ -6,8 +6,21 @@ jobs:
# steps: # steps:
# - name: Cleanup # - name: Cleanup
# run: rm -rf .* || true # run: rm -rf .* || true
get_prev_runid:
runs-on: ubuntu-latest
outputs:
value: ${{ steps.do.outputs.value }}
steps:
- id: do
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
value=$(gh run -R ${{ github.repository }} list -b${{ github.ref_name }} -ssuccess -L1 --json databaseId -q'.[0].databaseId')
echo "Last run ID is $value"
echo "value=$value" >> "$GITHUB_OUTPUT"
build: build:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
needs: get_prev_runid
continue-on-error: true continue-on-error: true
strategy: strategy:
fail-fast: false fail-fast: false
@@ -69,11 +82,19 @@ jobs:
SDL_VERSION: 2.30.11 SDL_VERSION: 2.30.11
GH_CPU_ARCH: ${{ matrix.targetarch }} GH_CPU_ARCH: ${{ matrix.targetarch }}
GH_CROSSCOMPILING: ${{ matrix.cross }} GH_CROSSCOMPILING: ${{ matrix.cross }}
WAFCACHE: ${{ github.workspace }}/wafcache/
WAFCACHE_EVICT_MAX_BYTES: 1000000 # github only gives 10gb for the whole repository
WAFCACHE_STATS: 1 # enable statistics in build log
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- name: Restore cache
uses: actions/cache/restore@v4
with:
key: ${{ runner.os }}-${{ matrix.targetos }}-${{ matrix.targetarch }}-${{ needs.get_prev_runid.outputs.value }}
path: ${{ github.workspace }}/wafcache/
- name: Install dependencies - name: Install dependencies
run: bash scripts/gha/deps_${{ matrix.targetos }}.sh run: bash scripts/gha/deps_${{ matrix.targetos }}.sh
- name: Build engine - name: Build engine
@@ -85,6 +106,12 @@ jobs:
with: with:
name: artifact-${{ matrix.targetos }}-${{ matrix.targetarch }} name: artifact-${{ matrix.targetos }}-${{ matrix.targetarch }}
path: artifacts/* path: artifacts/*
- name: Save cache
uses: actions/cache/save@v4
with:
path: ${{ github.workspace }}/wafcache/
key: ${{ runner.os }}-${{ matrix.targetos }}-${{ matrix.targetarch }}-${{ github.run_id }}
flatpak: flatpak:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:

View File

@@ -2,7 +2,7 @@
[![builds.sr.ht status](https://builds.sr.ht/~a1batross/xash3d-fwgs.svg)](https://builds.sr.ht/~a1batross/xash3d-fwgs?) [![GitHub Actions Status](https://github.com/FWGS/xash3d-fwgs/actions/workflows/c-cpp.yml/badge.svg)](https://github.com/FWGS/xash3d-fwgs/actions/workflows/c-cpp.yml) [![FreeBSD Build Status](https://img.shields.io/cirrus/github/FWGS/xash3d-fwgs?label=freebsd%20build)](https://cirrus-ci.com/github/FWGS/xash3d-fwgs) [![Discord Server](https://img.shields.io/discord/355697768582610945.svg)](http://fwgsdiscord.mentality.rip/) \ [![builds.sr.ht status](https://builds.sr.ht/~a1batross/xash3d-fwgs.svg)](https://builds.sr.ht/~a1batross/xash3d-fwgs?) [![GitHub Actions Status](https://github.com/FWGS/xash3d-fwgs/actions/workflows/c-cpp.yml/badge.svg)](https://github.com/FWGS/xash3d-fwgs/actions/workflows/c-cpp.yml) [![FreeBSD Build Status](https://img.shields.io/cirrus/github/FWGS/xash3d-fwgs?label=freebsd%20build)](https://cirrus-ci.com/github/FWGS/xash3d-fwgs) [![Discord Server](https://img.shields.io/discord/355697768582610945.svg)](http://fwgsdiscord.mentality.rip/) \
[![Download Stable](https://img.shields.io/badge/download-stable-yellow)](https://github.com/FWGS/xash3d-fwgs/releases/latest) [![Download Testing](https://img.shields.io/badge/downloads-testing-orange)](https://github.com/FWGS/xash3d-fwgs/releases/tag/continuous) [![Download Stable](https://img.shields.io/badge/download-stable-yellow)](https://github.com/FWGS/xash3d-fwgs/releases/latest) [![Download Testing](https://img.shields.io/badge/downloads-testing-orange)](https://github.com/FWGS/xash3d-fwgs/releases/tag/continuous)
Xash3D (pronounced `[ksɑʂ]`) FWGS is a game engine, aimed to provide compatibility with Half-Life Engine and extend it, as well as to give game developers well known workflow. Xash3D ([pronounced](https://ipa-reader.com/?text=ks%C9%91%CA%82) `[ksɑʂ]`) FWGS is a game engine, aimed to provide compatibility with Half-Life Engine and extend it, as well as to give game developers well known workflow.
Xash3D FWGS is a heavily modified fork of an original [Xash3D Engine](https://www.moddb.com/engines/xash3d-engine) by Unkle Mike. Xash3D FWGS is a heavily modified fork of an original [Xash3D Engine](https://www.moddb.com/engines/xash3d-engine) by Unkle Mike.

View File

@@ -30,6 +30,18 @@ public class XashActivity extends SDLActivity {
AndroidBug5497Workaround.assistActivity(this); AndroidBug5497Workaround.assistActivity(this);
} }
@Override
public void onDestroy()
{
super.onDestroy();
// Now that we don't exit from native code, we need to exit here, resetting
// application state (actually global variables that we don't cleanup on exit)
//
// When the issue with global variables will be resolved, remove that exit() call
System.exit(0);
}
@Override @Override
protected String[] getLibraries() { protected String[] getLibraries() {
return new String[]{"SDL2", "xash"}; return new String[]{"SDL2", "xash"};

View File

@@ -2409,7 +2409,6 @@ CL_FindModelIndex
static int GAME_EXPORT CL_FindModelIndex( const char *m ) static int GAME_EXPORT CL_FindModelIndex( const char *m )
{ {
char filepath[MAX_QPATH]; char filepath[MAX_QPATH];
static float lasttimewarn;
int i; int i;
if( !COM_CheckString( m )) if( !COM_CheckString( m ))
@@ -2427,13 +2426,6 @@ static int GAME_EXPORT CL_FindModelIndex( const char *m )
return i+1; return i+1;
} }
if( lasttimewarn < host.realtime )
{
// tell user about problem (but don't spam console)
Con_DPrintf( S_ERROR "Could not find index for model %s: not precached\n", filepath );
lasttimewarn = host.realtime + 1.0f;
}
return 0; return 0;
} }

View File

@@ -1761,8 +1761,8 @@ static size_t NONNULL CL_BuildMasterServerScanRequest( char *buf, size_t size, u
// let master know about client version // let master know about client version
Info_SetValueForKey( info, "clver", XASH_VERSION, remaining ); Info_SetValueForKey( info, "clver", XASH_VERSION, remaining );
Info_SetValueForKey( info, "nat", nat ? "1" : "0", remaining ); Info_SetValueForKey( info, "nat", nat ? "1" : "0", remaining );
Info_SetValueForKey( info, "commit", Q_buildcommit(), remaining ); Info_SetValueForKey( info, "commit", g_buildcommit, remaining );
Info_SetValueForKey( info, "branch", Q_buildbranch(), remaining ); Info_SetValueForKey( info, "branch", g_buildbranch, remaining );
Info_SetValueForKey( info, "os", Q_buildos(), remaining ); Info_SetValueForKey( info, "os", Q_buildos(), remaining );
Info_SetValueForKey( info, "arch", Q_buildarch(), remaining ); Info_SetValueForKey( info, "arch", Q_buildarch(), remaining );

View File

@@ -567,57 +567,54 @@ R_FizzEffect
Create a fizz effect Create a fizz effect
============== ==============
*/ */
void GAME_EXPORT R_FizzEffect( cl_entity_t *pent, int modelIndex, int density ) void GAME_EXPORT R_FizzEffect( cl_entity_t *ent, int modelIndex, int density )
{ {
TEMPENTITY *pTemp; const float base_time = cl.time - 0.1f;
int i, width, depth; model_t *mod = CL_ModelHandle( modelIndex );
float angle, maxHeight, speed; vec3_t volume, mins, maxs;
float xspeed, yspeed, zspeed; vec2_t speed;
vec3_t origin; int i;
model_t *mod;
if( !pent || !pent->model || !modelIndex ) if( !ent || !ent->model || !modelIndex || !mod )
return; return;
if(( mod = CL_ModelHandle( modelIndex )) == NULL ) VectorCopy( ent->model->mins, mins );
return; VectorCopy( ent->model->maxs, maxs );
maxHeight = pent->model->maxs[2] - pent->model->mins[2]; if( ent->angles[1] != 0.0f )
width = pent->model->maxs[0] - pent->model->mins[0]; {
depth = pent->model->maxs[1] - pent->model->mins[1]; const float base_speed = ( ent->curstate.rendercolor.b ? -1.0f : 1.0f ) * ( ent->curstate.rendercolor.r * 256.0f + ent->curstate.rendercolor.g );
SinCos( DEG2RAD( ent->angles[1] ), &speed[1], &speed[0] );
speed[0] *= base_speed;
speed[1] *= base_speed;
}
else speed[0] = speed[1] = 0.0f;
speed = ( pent->curstate.rendercolor.r<<8 | pent->curstate.rendercolor.g ); VectorSubtract( maxs, mins, volume );
if( pent->curstate.rendercolor.b )
speed = -speed;
angle = DEG2RAD( pent->angles[YAW] );
SinCos( angle, &yspeed, &xspeed );
xspeed *= speed;
yspeed *= speed;
for( i = 0; i <= density; i++ ) for( i = 0; i <= density; i++ )
{ {
origin[0] = mod->mins[0] + COM_RandomLong( 0, width - 1 ); TEMPENTITY *tent;
origin[1] = mod->mins[1] + COM_RandomLong( 0, depth - 1 ); vec3_t origin;
origin[2] = mod->mins[2];
pTemp = CL_TempEntAlloc( origin, mod );
if ( !pTemp ) return; VectorCopy( mins, origin );
origin[0] += COM_RandomLong( 0, (int)volume[0] - 1 );
origin[1] += COM_RandomLong( 0, (int)volume[1] - 1 );
pTemp->flags |= FTENT_SINEWAVE; if( !( tent = CL_TempEntAlloc( origin, mod )))
return;
pTemp->x = origin[0]; tent->x = origin[0];
pTemp->y = origin[1]; tent->y = origin[1];
tent->die = base_time;
tent->flags |= FTENT_SINEWAVE;
tent->entity.curstate.rendermode = kRenderTransAlpha;
Vector2Copy( speed, tent->entity.baseline.origin );
zspeed = COM_RandomLong( 80, 140 ); tent->entity.baseline.origin[2] = COM_RandomLong( 80, 140 );
VectorSet( pTemp->entity.baseline.origin, xspeed, yspeed, zspeed ); tent->die += volume[2] / tent->entity.baseline.origin[2];
pTemp->die = cl.time + ( maxHeight / zspeed ) - 0.1f; tent->entity.curstate.frame = COM_RandomLong( 0, tent->frameMax );
pTemp->entity.curstate.frame = COM_RandomLong( 0, pTemp->frameMax ); tent->entity.curstate.scale = 1.0f / COM_RandomFloat( 2.0f, 5.0f );
// Set sprite scale
pTemp->entity.curstate.scale = 1.0f / COM_RandomFloat( 2.0f, 5.0f );
pTemp->entity.curstate.rendermode = kRenderTransAlpha;
pTemp->entity.curstate.renderamt = 255;
} }
} }

View File

@@ -266,7 +266,7 @@ static qboolean Touch_DumpConfig( const char *name, const char *profilename )
} }
FS_Printf( f, "//=======================================================================\n"); FS_Printf( f, "//=======================================================================\n");
FS_Printf( f, "//\tGenerated by "XASH_ENGINE_NAME" (%i, %s, %s, %s-%s)\n", Q_buildnum(), Q_buildcommit(), Q_buildbranch(), Q_buildos(), Q_buildarch()); FS_Printf( f, "//\tGenerated by "XASH_ENGINE_NAME" (%i, %s, %s, %s-%s)\n", Q_buildnum(), g_buildcommit, g_buildbranch, Q_buildos(), Q_buildarch());
FS_Printf( f, "//\t\t\ttouchscreen config\n" ); FS_Printf( f, "//\t\t\ttouchscreen config\n" );
FS_Printf( f, "//=======================================================================\n" ); FS_Printf( f, "//=======================================================================\n" );
FS_Printf( f, "\ntouch_config_file \"%s\"\n", profilename ); FS_Printf( f, "\ntouch_config_file \"%s\"\n", profilename );

View File

@@ -301,7 +301,6 @@ typedef struct host_parm_s
poolhandle_t mempool; // static mempool for misc allocations poolhandle_t mempool; // static mempool for misc allocations
poolhandle_t imagepool; // imagelib mempool poolhandle_t imagepool; // imagelib mempool
poolhandle_t soundpool; // soundlib mempool poolhandle_t soundpool; // soundlib mempool
string finalmsg; // server shutdown final message
string downloadfile; // filename to be downloading string downloadfile; // filename to be downloading
int downloadcount; // how many files remain to downloading int downloadcount; // how many files remain to downloading
char deferred_cmd[128];// deferred commands char deferred_cmd[128];// deferred commands
@@ -560,6 +559,7 @@ void Host_Error( const char *error, ... ) FORMAT_CHECK( 1 );
void Host_ValidateEngineFeatures( uint32_t mask, uint32_t features ); void Host_ValidateEngineFeatures( uint32_t mask, uint32_t features );
void Host_Frame( double time ); void Host_Frame( double time );
void Host_Credits( void ); void Host_Credits( void );
void Host_ExitInMain( void );
// //
// host_state.c // host_state.c

View File

@@ -1395,7 +1395,7 @@ void Host_WriteConfig( void )
{ {
Con_Reportf( "%s()\n", __func__ ); Con_Reportf( "%s()\n", __func__ );
FS_Printf( f, "//=======================================================================\n"); FS_Printf( f, "//=======================================================================\n");
FS_Printf( f, "//\tGenerated by "XASH_ENGINE_NAME" (%i, %s, %s, %s-%s)\n", Q_buildnum(), Q_buildcommit(), Q_buildbranch(), Q_buildos(), Q_buildarch()); FS_Printf( f, "//\tGenerated by "XASH_ENGINE_NAME" (%i, %s, %s, %s-%s)\n", Q_buildnum(), g_buildcommit, g_buildbranch, Q_buildos(), Q_buildarch());
FS_Printf( f, "//\t\tconfig.cfg - archive of cvars\n" ); FS_Printf( f, "//\t\tconfig.cfg - archive of cvars\n" );
FS_Printf( f, "//=======================================================================\n" ); FS_Printf( f, "//=======================================================================\n" );
Key_WriteBindings( f ); Key_WriteBindings( f );
@@ -1443,7 +1443,7 @@ void GAME_EXPORT Host_WriteServerConfig( const char *name )
if(( f = FS_Open( newconfigfile, "w", false )) != NULL ) if(( f = FS_Open( newconfigfile, "w", false )) != NULL )
{ {
FS_Printf( f, "//=======================================================================\n" ); FS_Printf( f, "//=======================================================================\n" );
FS_Printf( f, "//\tGenerated by "XASH_ENGINE_NAME" (%i, %s, %s, %s-%s)\n", Q_buildnum(), Q_buildcommit(), Q_buildbranch(), Q_buildos(), Q_buildarch()); FS_Printf( f, "//\tGenerated by "XASH_ENGINE_NAME" (%i, %s, %s, %s-%s)\n", Q_buildnum(), g_buildcommit, g_buildbranch, Q_buildos(), Q_buildarch());
FS_Printf( f, "//\t\tgame.cfg - multiplayer server temporare config\n" ); FS_Printf( f, "//\t\tgame.cfg - multiplayer server temporare config\n" );
FS_Printf( f, "//=======================================================================\n" ); FS_Printf( f, "//=======================================================================\n" );
@@ -1478,7 +1478,7 @@ void Host_WriteOpenGLConfig( void )
{ {
Con_Reportf( "%s()\n", __func__ ); Con_Reportf( "%s()\n", __func__ );
FS_Printf( f, "//=======================================================================\n" ); FS_Printf( f, "//=======================================================================\n" );
FS_Printf( f, "//\tGenerated by "XASH_ENGINE_NAME" (%i, %s, %s, %s-%s)\n", Q_buildnum(), Q_buildcommit(), Q_buildbranch(), Q_buildos(), Q_buildarch()); FS_Printf( f, "//\tGenerated by "XASH_ENGINE_NAME" (%i, %s, %s, %s-%s)\n", Q_buildnum(), g_buildcommit, g_buildbranch, Q_buildos(), Q_buildarch());
FS_Printf( f, "//\t\t%s - archive of renderer implementation cvars\n", name ); FS_Printf( f, "//\t\t%s - archive of renderer implementation cvars\n", name );
FS_Printf( f, "//=======================================================================\n" ); FS_Printf( f, "//=======================================================================\n" );
FS_Printf( f, "\n" ); FS_Printf( f, "\n" );
@@ -1508,7 +1508,7 @@ void Host_WriteVideoConfig( void )
{ {
Con_Reportf( "%s()\n", __func__ ); Con_Reportf( "%s()\n", __func__ );
FS_Printf( f, "//=======================================================================\n" ); FS_Printf( f, "//=======================================================================\n" );
FS_Printf( f, "//\tGenerated by "XASH_ENGINE_NAME" (%i, %s, %s, %s-%s)\n", Q_buildnum(), Q_buildcommit(), Q_buildbranch(), Q_buildos(), Q_buildarch()); FS_Printf( f, "//\tGenerated by "XASH_ENGINE_NAME" (%i, %s, %s, %s-%s)\n", Q_buildnum(), g_buildcommit, g_buildbranch, Q_buildos(), Q_buildarch());
FS_Printf( f, "//\t\tvideo.cfg - archive of renderer variables\n"); FS_Printf( f, "//\t\tvideo.cfg - archive of renderer variables\n");
FS_Printf( f, "//=======================================================================\n" ); FS_Printf( f, "//=======================================================================\n" );
Cvar_WriteVariables( f, FCVAR_RENDERINFO ); Cvar_WriteVariables( f, FCVAR_RENDERINFO );
@@ -1534,7 +1534,7 @@ void Key_EnumCmds_f( void )
if( f ) if( f )
{ {
FS_Printf( f, "//=======================================================================\n"); FS_Printf( f, "//=======================================================================\n");
FS_Printf( f, "//\tGenerated by "XASH_ENGINE_NAME" (%i, %s, %s, %s-%s)\n", Q_buildnum(), Q_buildcommit(), Q_buildbranch(), Q_buildos(), Q_buildarch()); FS_Printf( f, "//\tGenerated by "XASH_ENGINE_NAME" (%i, %s, %s, %s-%s)\n", Q_buildnum(), g_buildcommit, g_buildbranch, Q_buildos(), Q_buildarch());
FS_Printf( f, "//\t\thelp.txt - xash commands and console variables\n"); FS_Printf( f, "//\t\thelp.txt - xash commands and console variables\n");
FS_Printf( f, "//=======================================================================\n"); FS_Printf( f, "//=======================================================================\n");

View File

@@ -43,6 +43,27 @@ GNU General Public License for more details.
static pfnChangeGame pChangeGame = NULL; static pfnChangeGame pChangeGame = NULL;
host_parm_t host; // host parms host_parm_t host; // host parms
#if XASH_ANDROID
static jmp_buf return_from_main_buf;
/*
===============
Host_ExitInMain
On some platforms (e.g. Android) we can't exit with exit(3) as calling it would
kill wrapper process (e.g. app_process) too early, before all resources would
be freed, contexts released, files closed, etc, etc...
To fix this, we create jmp_buf in Host_Main function, when jumping into with
non-zero value will immediately return from it with `error_on_exit`.
===============
*/
void Host_ExitInMain( void )
{
longjmp( return_from_main_buf, 1 );
}
#endif // XASH_ANDROID
#ifdef XASH_ENGINE_TESTS #ifdef XASH_ENGINE_TESTS
struct tests_stats_s tests_stats; struct tests_stats_s tests_stats;
#endif #endif
@@ -362,9 +383,8 @@ static void Host_NewInstance( const char *name, const char *finalmsg )
if( !pChangeGame ) return; if( !pChangeGame ) return;
host.change_game = true; host.change_game = true;
Q_strncpy( host.finalmsg, finalmsg, sizeof( host.finalmsg ));
if( !Sys_NewInstance( name )) if( !Sys_NewInstance( name, finalmsg ))
pChangeGame( name ); // call from hl.exe pChangeGame( name ); // call from hl.exe
} }
@@ -838,7 +858,6 @@ void GAME_EXPORT Host_Error( const char *error, ... )
recursive = true; recursive = true;
Q_strncpy( hosterror2, hosterror1, sizeof( hosterror2 )); Q_strncpy( hosterror2, hosterror1, sizeof( hosterror2 ));
host.errorframe = host.framecount; // to avoid multply calls per frame host.errorframe = host.framecount; // to avoid multply calls per frame
Q_snprintf( host.finalmsg, sizeof( host.finalmsg ), "Server crashed: %s", hosterror1 );
// clearing cmd buffer to prevent execute any commands // clearing cmd buffer to prevent execute any commands
COM_InitHostState(); COM_InitHostState();
@@ -1214,7 +1233,7 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
Cvar_Getf( "buildnum", FCVAR_READ_ONLY, "returns a current build number", "%i", Q_buildnum_compat()); Cvar_Getf( "buildnum", FCVAR_READ_ONLY, "returns a current build number", "%i", Q_buildnum_compat());
Cvar_Getf( "ver", FCVAR_READ_ONLY, "shows an engine version", "%i/%s (hw build %i)", PROTOCOL_VERSION, XASH_COMPAT_VERSION, Q_buildnum_compat()); Cvar_Getf( "ver", FCVAR_READ_ONLY, "shows an engine version", "%i/%s (hw build %i)", PROTOCOL_VERSION, XASH_COMPAT_VERSION, Q_buildnum_compat());
Cvar_Getf( "host_ver", FCVAR_READ_ONLY, "detailed info about this build", "%i " XASH_VERSION " %s %s %s", Q_buildnum(), Q_buildos(), Q_buildarch(), Q_buildcommit()); Cvar_Getf( "host_ver", FCVAR_READ_ONLY, "detailed info about this build", "%i " XASH_VERSION " %s %s %s", Q_buildnum(), Q_buildos(), Q_buildarch(), g_buildcommit);
Cvar_Getf( "host_lowmemorymode", FCVAR_READ_ONLY, "indicates if engine compiled for low RAM consumption (0 - normal, 1 - low engine limits, 2 - low protocol limits)", "%i", XASH_LOW_MEMORY ); Cvar_Getf( "host_lowmemorymode", FCVAR_READ_ONLY, "indicates if engine compiled for low RAM consumption (0 - normal, 1 - low engine limits, 2 - low protocol limits)", "%i", XASH_LOW_MEMORY );
Mod_Init(); Mod_Init();
@@ -1321,6 +1340,11 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
// check after all configs were executed // check after all configs were executed
HPAK_CheckIntegrity( hpk_custom_file.string ); HPAK_CheckIntegrity( hpk_custom_file.string );
#if XASH_ANDROID
if( setjmp( return_from_main_buf ))
return error_on_exit;
#endif // XASH_ANDROID
// main window message loop // main window message loop
while( !host.crashed ) while( !host.crashed )
{ {
@@ -1359,9 +1383,6 @@ void Host_ShutdownWithReason( const char *reason )
if( host.status != HOST_ERR_FATAL ) if( host.status != HOST_ERR_FATAL )
host.status = HOST_SHUTDOWN; // prepare host to normal shutdown host.status = HOST_SHUTDOWN; // prepare host to normal shutdown
if( !host.change_game )
Q_strncpy( host.finalmsg, "Server shutdown", sizeof( host.finalmsg ));
#if !XASH_DEDICATED #if !XASH_DEDICATED
if( host.type == HOST_NORMAL && !error ) if( host.type == HOST_NORMAL && !error )
Host_WriteConfig(); Host_WriteConfig();
@@ -1384,5 +1405,5 @@ void Host_ShutdownWithReason( const char *reason )
// restore filter // restore filter
Sys_RestoreCrashHandler(); Sys_RestoreCrashHandler();
Sys_CloseLog(); Sys_CloseLog( reason );
} }

View File

@@ -326,7 +326,7 @@ static int HTTP_FileConnect( httpfile_t *file )
if( !COM_CheckStringEmpty( http_useragent.string ) || !Q_strcmp( http_useragent.string, "xash3d" )) if( !COM_CheckStringEmpty( http_useragent.string ) || !Q_strcmp( http_useragent.string, "xash3d" ))
{ {
Q_snprintf( useragent, sizeof( useragent ), "%s/%s (%s-%s; build %d; %s)", Q_snprintf( useragent, sizeof( useragent ), "%s/%s (%s-%s; build %d; %s)",
XASH_ENGINE_NAME, XASH_VERSION, Q_buildos( ), Q_buildarch( ), Q_buildnum( ), Q_buildcommit( )); XASH_ENGINE_NAME, XASH_VERSION, Q_buildos( ), Q_buildarch( ), Q_buildnum( ), g_buildcommit );
} }
else Q_strncpy( useragent, http_useragent.string, sizeof( useragent )); else Q_strncpy( useragent, http_useragent.string, sizeof( useragent ));

View File

@@ -109,44 +109,44 @@ void Sys_InitLog( void )
// fit to 80 columns for easier read on standard terminal // fit to 80 columns for easier read on standard terminal
fputs( "================================================================================\n", s_ld.logfile ); fputs( "================================================================================\n", s_ld.logfile );
fprintf( s_ld.logfile, "%s (%i, %s, %s, %s-%s)\n", s_ld.title, Q_buildnum(), Q_buildcommit(), Q_buildbranch(), Q_buildos(), Q_buildarch()); fprintf( s_ld.logfile, "%s (%i, %s, %s, %s-%s)\n", s_ld.title, Q_buildnum(), g_buildcommit, g_buildbranch, Q_buildos(), Q_buildarch());
fprintf( s_ld.logfile, "Game started at %s\n", Q_timestamp( TIME_FULL )); fprintf( s_ld.logfile, "Game started at %s\n", Q_timestamp( TIME_FULL ));
fputs( "================================================================================\n", s_ld.logfile ); fputs( "================================================================================\n", s_ld.logfile );
fflush( s_ld.logfile ); fflush( s_ld.logfile );
} }
} }
void Sys_CloseLog( void ) void Sys_CloseLog( const char *finalmsg )
{ {
char event_name[64]; Sys_FlushStdout(); // flush to stdout to ensure all data was written
if( !s_ld.logfile )
return;
// continue logged // continue logged
if( !finalmsg )
{
switch( host.status ) switch( host.status )
{ {
case HOST_CRASHED: case HOST_CRASHED:
Q_strncpy( event_name, "crashed", sizeof( event_name )); finalmsg = "crashed";
break; break;
case HOST_ERR_FATAL: case HOST_ERR_FATAL:
Q_strncpy( event_name, "stopped with error", sizeof( event_name )); finalmsg = "stopped with error";
break; break;
default: default:
if( !host.change_game ) Q_strncpy( event_name, "stopped", sizeof( event_name )); finalmsg = "stopped";
else Q_strncpy( event_name, host.finalmsg, sizeof( event_name ));
break; break;
} }
}
Sys_FlushStdout(); // flush to stdout to ensure all data was written
if( s_ld.logfile )
{
fputc( '\n', s_ld.logfile ); fputc( '\n', s_ld.logfile );
fputs( "================================================================================\n", s_ld.logfile ); fputs( "================================================================================\n", s_ld.logfile );
fprintf( s_ld.logfile, "%s (%i, %s, %s, %s-%s)\n", s_ld.title, Q_buildnum(), Q_buildcommit(), Q_buildbranch(), Q_buildos(), Q_buildarch()); fprintf( s_ld.logfile, "%s (%i, %s, %s, %s-%s)\n", s_ld.title, Q_buildnum(), g_buildcommit, g_buildbranch, Q_buildos(), Q_buildarch());
fprintf( s_ld.logfile, "Stopped with reason \"%s\" at %s\n", event_name, Q_timestamp( TIME_FULL )); fprintf( s_ld.logfile, "Stopped with reason \"%s\" at %s\n", finalmsg, Q_timestamp( TIME_FULL ));
fputs( "================================================================================\n", s_ld.logfile ); fputs( "================================================================================\n", s_ld.logfile );
fclose( s_ld.logfile ); fclose( s_ld.logfile );
s_ld.logfile = NULL; s_ld.logfile = NULL;
}
} }
#if XASH_COLORIZE_CONSOLE #if XASH_COLORIZE_CONSOLE

View File

@@ -420,6 +420,12 @@ void Sys_Error( const char *error, ... )
_exit->_Exit->asm._exit->_exit _exit->_Exit->asm._exit->_exit
As we do not need atexit(), just throw hidden exception As we do not need atexit(), just throw hidden exception
*/ */
// Hey, you, making an Emscripten port!
// What if we're not supposed to use exit() on Emscripten and instead we should
// exit from the main() function? Would this fix this bug? Test this case, pls.
#error "Read the comment above"
#include <emscripten.h> #include <emscripten.h>
#define exit my_exit #define exit my_exit
void my_exit(int ret) void my_exit(int ret)
@@ -438,7 +444,11 @@ Sys_Quit
void Sys_Quit( const char *reason ) void Sys_Quit( const char *reason )
{ {
Host_ShutdownWithReason( reason ); Host_ShutdownWithReason( reason );
#if XASH_ANDROID
Host_ExitInMain();
#else
exit( error_on_exit ); exit( error_on_exit );
#endif
} }
/* /*
@@ -529,7 +539,7 @@ but since engine will be unloaded during this call
it explicitly doesn't use internal allocation or string copy utils it explicitly doesn't use internal allocation or string copy utils
================== ==================
*/ */
qboolean Sys_NewInstance( const char *gamedir ) qboolean Sys_NewInstance( const char *gamedir, const char *finalmsg )
{ {
#if XASH_NSWITCH #if XASH_NSWITCH
char newargs[4096]; char newargs[4096];
@@ -540,7 +550,7 @@ qboolean Sys_NewInstance( const char *gamedir )
// just restart the entire thing // just restart the entire thing
printf( "envSetNextLoad exe: `%s`\n", exe ); printf( "envSetNextLoad exe: `%s`\n", exe );
printf( "envSetNextLoad argv:\n`%s`\n", newargs ); printf( "envSetNextLoad argv:\n`%s`\n", newargs );
Host_ShutdownWithReason( "changing game" ); Host_ShutdownWithReason( finalmsg );
envSetNextLoad( exe, newargs ); envSetNextLoad( exe, newargs );
exit( 0 ); exit( 0 );
#else #else
@@ -578,7 +588,7 @@ qboolean Sys_NewInstance( const char *gamedir )
#if XASH_PSVITA #if XASH_PSVITA
// under normal circumstances it's always going to be the same path // under normal circumstances it's always going to be the same path
exe = strdup( "app0:/eboot.bin" ); exe = strdup( "app0:/eboot.bin" );
Host_ShutdownWithReason( "changing game" ); Host_ShutdownWithReason( finalmsg );
sceAppMgrLoadExec( exe, newargs, NULL ); sceAppMgrLoadExec( exe, newargs, NULL );
#else #else
exelen = wai_getExecutablePath( NULL, 0, NULL ); exelen = wai_getExecutablePath( NULL, 0, NULL );
@@ -586,7 +596,7 @@ qboolean Sys_NewInstance( const char *gamedir )
wai_getExecutablePath( exe, exelen, NULL ); wai_getExecutablePath( exe, exelen, NULL );
exe[exelen] = 0; exe[exelen] = 0;
Host_ShutdownWithReason( "changing game" ); Host_ShutdownWithReason( finalmsg );
execv( exe, newargs ); execv( exe, newargs );
#endif #endif

View File

@@ -56,11 +56,8 @@ void Sys_DebugBreak( void );
qboolean _Sys_GetParmFromCmdLine( const char *parm, char *out, size_t size ); qboolean _Sys_GetParmFromCmdLine( const char *parm, char *out, size_t size );
qboolean Sys_GetIntFromCmdLine( const char *parm, int *out ); qboolean Sys_GetIntFromCmdLine( const char *parm, int *out );
void Sys_Print( const char *pMsg ); void Sys_Print( const char *pMsg );
void Sys_PrintLog( const char *pMsg );
void Sys_InitLog( void );
void Sys_CloseLog( void );
void Sys_Quit( const char *reason ) NORETURN; void Sys_Quit( const char *reason ) NORETURN;
qboolean Sys_NewInstance( const char *gamedir ); qboolean Sys_NewInstance( const char *gamedir, const char *finalmsg );
void *Sys_GetNativeObject( const char *obj ); void *Sys_GetNativeObject( const char *obj );
// //
@@ -68,7 +65,7 @@ void *Sys_GetNativeObject( const char *obj );
// //
char *Sys_Input( void ); char *Sys_Input( void );
void Sys_DestroyConsole( void ); void Sys_DestroyConsole( void );
void Sys_CloseLog( void ); void Sys_CloseLog( const char *finalmsg );
void Sys_InitLog( void ); void Sys_InitLog( void );
void Sys_PrintLog( const char *pMsg ); void Sys_PrintLog( const char *pMsg );
int Sys_LogFileNo( void ); int Sys_LogFileNo( void );

View File

@@ -113,7 +113,7 @@ static void Sys_Crash( int signal, siginfo_t *si, void *context)
// safe actions first, stack and memory may be corrupted // safe actions first, stack and memory may be corrupted
len = Q_snprintf( message, sizeof( message ), "Ver: " XASH_ENGINE_NAME " " XASH_VERSION " (build %i-%s, %s-%s)\n", len = Q_snprintf( message, sizeof( message ), "Ver: " XASH_ENGINE_NAME " " XASH_VERSION " (build %i-%s, %s-%s)\n",
Q_buildnum(), Q_buildcommit(), Q_buildos(), Q_buildarch() ); Q_buildnum(), g_buildcommit, Q_buildos(), Q_buildarch() );
#if !XASH_FREEBSD && !XASH_NETBSD && !XASH_OPENBSD #if !XASH_FREEBSD && !XASH_NETBSD && !XASH_OPENBSD
len += Q_snprintf( message + len, sizeof( message ) - len, "Crash: signal %d errno %d with code %d at %p %p\n", signal, si->si_errno, si->si_code, si->si_addr, si->si_ptr ); len += Q_snprintf( message + len, sizeof( message ) - len, "Crash: signal %d errno %d with code %d at %p %p\n", signal, si->si_errno, si->si_code, si->si_addr, si->si_ptr );

View File

@@ -588,7 +588,7 @@ void Wcon_DestroyConsole( void )
// last text message into console or log // last text message into console or log
Con_Reportf( "%s: Unloading xash.dll\n", __func__ ); Con_Reportf( "%s: Unloading xash.dll\n", __func__ );
Sys_CloseLog(); Sys_CloseLog( NULL );
if( !s_wcd.attached ) if( !s_wcd.attached )
{ {

View File

@@ -138,7 +138,7 @@ static void Sys_StackTrace( PEXCEPTION_POINTERS pInfo )
#endif #endif
len = Q_snprintf( message, sizeof( message ), "Ver: " XASH_ENGINE_NAME " " XASH_VERSION " (build %i-%s, %s-%s)\n", len = Q_snprintf( message, sizeof( message ), "Ver: " XASH_ENGINE_NAME " " XASH_VERSION " (build %i-%s, %s-%s)\n",
Q_buildnum(), Q_buildcommit(), Q_buildos(), Q_buildarch() ); Q_buildnum(), g_buildcommit, Q_buildos(), Q_buildarch() );
len += Q_snprintf( message + len, 1024 - len, "Sys_Crash: address %p, code %p\n", len += Q_snprintf( message + len, 1024 - len, "Sys_Crash: address %p, code %p\n",
pInfo->ExceptionRecord->ExceptionAddress, (void*)pInfo->ExceptionRecord->ExceptionCode ); pInfo->ExceptionRecord->ExceptionAddress, (void*)pInfo->ExceptionRecord->ExceptionCode );
@@ -214,13 +214,13 @@ static void Sys_GetMinidumpFileName( const char *processName, char *mdmpFileName
Q_snprintf( mdmpFileName, bufferSize, "%s_%s_crash_%d%.2d%.2d_%.2d%.2d%.2d.mdmp", Q_snprintf( mdmpFileName, bufferSize, "%s_%s_crash_%d%.2d%.2d_%.2d%.2d%.2d.mdmp",
processName, processName,
Q_buildcommit(), g_buildcommit,
currentLocalTime->tm_year + 1900, currentLocalTime->tm_year + 1900,
currentLocalTime->tm_mon + 1, currentLocalTime->tm_mon + 1,
currentLocalTime->tm_mday, currentLocalTime->tm_mday,
currentLocalTime->tm_hour, currentLocalTime->tm_hour,
currentLocalTime->tm_min, currentLocalTime->tm_min,
currentLocalTime->tm_sec); currentLocalTime->tm_sec );
} }
static qboolean Sys_WriteMinidump(PEXCEPTION_POINTERS exceptionInfo, MINIDUMP_TYPE minidumpType) static qboolean Sys_WriteMinidump(PEXCEPTION_POINTERS exceptionInfo, MINIDUMP_TYPE minidumpType)

View File

@@ -2226,7 +2226,7 @@ SV_SendBuildInfo_f
static qboolean SV_SendBuildInfo_f( sv_client_t *cl ) static qboolean SV_SendBuildInfo_f( sv_client_t *cl )
{ {
SV_ClientPrintf( cl, "Server running " XASH_ENGINE_NAME " " XASH_VERSION " (build %i-%s, %s-%s)\n", SV_ClientPrintf( cl, "Server running " XASH_ENGINE_NAME " " XASH_VERSION " (build %i-%s, %s-%s)\n",
Q_buildnum(), Q_buildcommit(), Q_buildos(), Q_buildarch() ); Q_buildnum(), g_buildcommit, Q_buildos(), Q_buildarch() );
return true; return true;
} }

View File

@@ -970,7 +970,7 @@ void SV_Init( void )
MSG_Init( &net_message, "NetMessage", net_message_buffer, sizeof( net_message_buffer )); MSG_Init( &net_message, "NetMessage", net_message_buffer, sizeof( net_message_buffer ));
Q_snprintf( versionString, sizeof( versionString ), XASH_ENGINE_NAME ": " XASH_VERSION "-%s(%s-%s),%i,%i", Q_snprintf( versionString, sizeof( versionString ), XASH_ENGINE_NAME ": " XASH_VERSION "-%s(%s-%s),%i,%i",
Q_buildcommit(), Q_buildos(), Q_buildarch(), PROTOCOL_VERSION, Q_buildnum() ); g_buildcommit, Q_buildos(), Q_buildarch(), PROTOCOL_VERSION, Q_buildnum() );
Cvar_FullSet( "sv_version", versionString, FCVAR_READ_ONLY ); Cvar_FullSet( "sv_version", versionString, FCVAR_READ_ONLY );

View File

@@ -57,6 +57,12 @@ static qboolean Platform_GetDirectoryCaseSensitivity( const char *dir )
{ {
#if XASH_WIN32 || XASH_PSVITA || XASH_NSWITCH #if XASH_WIN32 || XASH_PSVITA || XASH_NSWITCH
return false; return false;
#elif XASH_ANDROID
// on Android, doing code below causes crash in MediaProviderGoogle.apk!libfuse_jni.so
// which in turn makes vold (Android's Volume Daemon) to umount /storage/emulated/0
// and because you can't unmount a filesystem when there is file descriptors open
// it has no other choice but to terminate and then kill our program
return true;
#elif XASH_LINUX && defined( FS_IOC_GETFLAGS ) #elif XASH_LINUX && defined( FS_IOC_GETFLAGS )
int flags = 0; int flags = 0;
int fd; int fd;
@@ -66,7 +72,10 @@ static qboolean Platform_GetDirectoryCaseSensitivity( const char *dir )
return true; return true;
if( ioctl( fd, FS_IOC_GETFLAGS, &flags ) < 0 ) if( ioctl( fd, FS_IOC_GETFLAGS, &flags ) < 0 )
{
close( fd );
return true; return true;
}
close( fd ); close( fd );

View File

@@ -529,7 +529,7 @@ static qboolean FS_WriteGameInfo( const char *filepath, gameinfo_t *GameInfo )
if( !f ) if( !f )
return false; return false;
FS_Printf( f, "// generated by " XASH_ENGINE_NAME " " XASH_VERSION "-%s (%s-%s)\n\n\n", Q_buildcommit(), Q_buildos(), Q_buildarch() ); FS_Printf( f, "// generated by " XASH_ENGINE_NAME " " XASH_VERSION "-%s (%s-%s)\n\n\n", g_buildcommit, Q_buildos(), Q_buildarch() );
if( COM_CheckStringEmpty( GameInfo->basedir ) ) if( COM_CheckStringEmpty( GameInfo->basedir ) )
FS_Printf( f, "basedir\t\t\"%s\"\n", GameInfo->basedir ); FS_Printf( f, "basedir\t\t\"%s\"\n", GameInfo->basedir );

View File

@@ -239,29 +239,3 @@ const char *Q_buildarch( void )
); );
} }
/*
=============
Q_buildcommit
Returns a short hash of current commit in VCS as string
XASH_BUILD_COMMIT must be passed in quotes
=============
*/
const char *Q_buildcommit( void )
{
return XASH_BUILD_COMMIT;
}
/*
=============
Q_buildbranch
Returns current branch name in VCS as string
XASH_BUILD_BRANCH must be passed in quotes
=============
*/
const char *Q_buildbranch( void )
{
return XASH_BUILD_BRANCH;
}

18
public/build_vcs.c Normal file
View File

@@ -0,0 +1,18 @@
/*
build_vcs.c - info from VCS
Copyright (C) 2025 Alibek Omarov
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
const char *g_buildcommit = XASH_BUILD_COMMIT;
const char *g_buildbranch = XASH_BUILD_BRANCH;

View File

@@ -62,8 +62,8 @@ const char *Q_PlatformStringByID( const int platform );
const char *Q_buildos( void ); const char *Q_buildos( void );
const char *Q_ArchitectureStringByID( const int arch, const uint abi, const int endianness, const qboolean is64 ); const char *Q_ArchitectureStringByID( const int arch, const uint abi, const int endianness, const qboolean is64 );
const char *Q_buildarch( void ); const char *Q_buildarch( void );
const char *Q_buildcommit( void ); extern const char *g_buildcommit;
const char *Q_buildbranch( void ); extern const char *g_buildbranch;
// //
// crtlib.c // crtlib.c

View File

@@ -67,8 +67,6 @@ def options(opt):
def configure(conf): def configure(conf):
# private to libpublic # private to libpublic
conf.load('gitversion') conf.load('gitversion')
conf.define('XASH_BUILD_COMMIT', conf.env.GIT_VERSION if conf.env.GIT_VERSION else 'unknown-commit')
conf.define('XASH_BUILD_BRANCH', conf.env.GIT_BRANCH if conf.env.GIT_BRANCH else 'unknown-branch')
conf.env.VALIDATE_TARGET = conf.options.VALIDATE_TARGET conf.env.VALIDATE_TARGET = conf.options.VALIDATE_TARGET
# need to expose it for everyone using libpublic headers # need to expose it for everyone using libpublic headers
@@ -120,9 +118,14 @@ def build(bld):
export_includes = '. ../common ../pm_shared ../engine', export_includes = '. ../common ../pm_shared ../engine',
export_defines = bld.env.EXPORT_DEFINES_LIST) export_defines = bld.env.EXPORT_DEFINES_LIST)
bld.stlib(source = bld.path.ant_glob('*.c'), # build it separately to slightly improve rebuild times
bld.stlib(source = 'build_vcs.c',
target = 'build_vcs',
defines = ['XASH_BUILD_COMMIT=\"%s\"' % bld.env.GIT_VERSION, 'XASH_BUILD_BRANCH=\"%s\"' % bld.env.GIT_BRANCH])
bld.stlib(source = bld.path.ant_glob('*.c', excl='build_vcs.c'),
target = 'public', target = 'public',
use = 'sdk_includes werror') use = 'sdk_includes werror build_vcs')
if bld.env.TESTS: if bld.env.TESTS:
if bld.env.VALIDATE_TARGET: if bld.env.VALIDATE_TARGET:

View File

@@ -8,7 +8,7 @@ pushd hlsdk || die
./waf configure build install --destdir=../bin || die ./waf configure build install --destdir=../bin || die
popd popd
./waf configure --enable-utils --enable-tests --enable-lto build install --destdir=bin || die_configure ./waf configure --enable-utils --enable-tests --enable-lto --enable-wafcache build --zones=wafcache install --destdir=bin || die_configure
cp -vr /Library/Frameworks/SDL2.framework bin cp -vr /Library/Frameworks/SDL2.framework bin

View File

@@ -61,14 +61,14 @@ build_engine()
fi fi
if [ "$1" = "dedicated" ]; then if [ "$1" = "dedicated" ]; then
./waf configure $AMD64 $ENABLE_TESTS --enable-lto --enable-bundled-deps -d || die_configure ./waf configure $AMD64 $ENABLE_TESTS --enable-lto --enable-bundled-deps -d --enable-wafcache || die_configure
elif [ "$1" = "full" ]; then elif [ "$1" = "full" ]; then
./waf configure $AMD64 $ENABLE_TESTS --enable-lto --enable-bundled-deps -s SDL2_linux --enable-stb --enable-utils || die_configure ./waf configure $AMD64 $ENABLE_TESTS --enable-lto --enable-bundled-deps -s SDL2_linux --enable-stb --enable-utils --enable-wafcache || die_configure
else else
die die
fi fi
./waf build || die_configure ./waf build --zones=wafcache || die_configure
} }
deploy_engine() deploy_engine()

View File

@@ -12,7 +12,7 @@ pushd hlsdk || die
./waf configure -T fast --enable-magx --enable-simple-mod-hacks build install --destdir=../Xash || die ./waf configure -T fast --enable-magx --enable-simple-mod-hacks build install --destdir=../Xash || die
popd popd
./waf configure -T fast --enable-magx build install --destdir=Xash/ || die ./waf configure -T fast --enable-magx --enable-wafcache build install --destdir=Xash/ || die
cat > Xash/run.sh << 'EOF' cat > Xash/run.sh << 'EOF'
mypath=${0%/*} mypath=${0%/*}

View File

@@ -11,7 +11,7 @@ mkdir -p artifacts/ || die
echo "Running build script in Docker container..." echo "Running build script in Docker container..."
docker run --name xash-build --rm -v `pwd`:`pwd` -w `pwd` devkitpro/devkita64:latest bash ./scripts/gha/build_nswitch_docker.sh || die docker run --name xash-build --rm -v `pwd`:`pwd` -v $HOME/.cache:$HOME/.cache -w `pwd` devkitpro/devkita64:latest bash ./scripts/gha/build_nswitch_docker.sh || die
echo "Packaging artifacts..." echo "Packaging artifacts..."

View File

@@ -42,7 +42,7 @@ make -C libsolder install || die
echo "Building engine..." echo "Building engine..."
./waf configure -T release --nswitch || die_configure ./waf configure -T release --nswitch --enable-wafcache || die_configure
./waf build install --destdir=pkgtemp/xash3d -v || die ./waf build install --destdir=pkgtemp/xash3d -v || die
echo "Building HLSDK..." echo "Building HLSDK..."

View File

@@ -44,8 +44,8 @@ popd
echo "Building engine..." echo "Building engine..."
./waf configure -T release --psvita || die_configure ./waf configure -T release --psvita --enable-wafcache || die_configure
./waf build install --destdir=pkgtemp/data/xash3d -v || die ./waf build install --destdir=pkgtemp/data/xash3d || die
cp build/engine/xash.vpk pkgtemp/ cp build/engine/xash.vpk pkgtemp/
echo "Building HLSDK..." echo "Building HLSDK..."

View File

@@ -11,8 +11,9 @@ fi
# NOTE: to build with other version use --msvc_version during configuration # NOTE: to build with other version use --msvc_version during configuration
# NOTE: sometimes you may need to add WinSDK to %PATH% # NOTE: sometimes you may need to add WinSDK to %PATH%
./waf.bat configure -s "SDL2_VC" -T release --enable-utils --enable-tests --enable-lto $AMD64 || die_configure # NOTE: --enable-msvcdeps only used for CI builds, enabling it non-English versions of MSVC causes useless console spam
./waf.bat build || die ./waf.bat configure -s "SDL2_VC" -T release --enable-utils --enable-tests --enable-lto --enable-msvcdeps --enable-wafcache $AMD64 || die_configure
./waf.bat build --zones=wafcache || die
./waf.bat install --destdir=. || die ./waf.bat install --destdir=. || die
if [ "$ARCH" = "i386" ]; then if [ "$ARCH" = "i386" ]; then

15
wscript
View File

@@ -128,6 +128,9 @@ REFDLLS = [
def options(opt): def options(opt):
opt.load('reconfigure compiler_optimizations xshlib xcompile compiler_cxx compiler_c sdl2 clang_compilation_database strip_on_install waf_unit_test msdev msvs subproject cmake') opt.load('reconfigure compiler_optimizations xshlib xcompile compiler_cxx compiler_c sdl2 clang_compilation_database strip_on_install waf_unit_test msdev msvs subproject cmake')
opt.add_option('--enable-wafcache', action = 'store_false', dest = 'enable_gccdeps', default = True,
help = 'enable usage of wafcache tool, disables gccdeps')
grp = opt.add_option_group('Common options') grp = opt.add_option_group('Common options')
grp.add_option('-d', '--dedicated', action = 'store_true', dest = 'DEDICATED', default = False, grp.add_option('-d', '--dedicated', action = 'store_true', dest = 'DEDICATED', default = False,
@@ -162,6 +165,7 @@ def options(opt):
# a1ba: special option for me # a1ba: special option for me
grp.add_option('--debug-all-servers', action='store_true', dest='ALL_SERVERS', default=False, help='') grp.add_option('--debug-all-servers', action='store_true', dest='ALL_SERVERS', default=False, help='')
grp.add_option('--enable-msvcdeps', action='store_true', dest='MSVCDEPS', default=False, help='')
grp = opt.add_option_group('Renderers options') grp = opt.add_option_group('Renderers options')
@@ -200,6 +204,12 @@ def configure(conf):
# Load compilers early # Load compilers early
conf.load('xshlib xcompile compiler_c compiler_cxx gccdeps') conf.load('xshlib xcompile compiler_c compiler_cxx gccdeps')
if conf.options.MSVCDEPS:
conf.load('msvcdeps')
if not conf.options.enable_gccdeps:
conf.env.ENABLE_WAFCACHE = True
if conf.options.NSWITCH: if conf.options.NSWITCH:
conf.load('nswitch') conf.load('nswitch')
@@ -213,7 +223,7 @@ def configure(conf):
if conf.env.COMPILER_CC == 'msvc': if conf.env.COMPILER_CC == 'msvc':
conf.load('msvc_pdb') conf.load('msvc_pdb')
conf.load('msvs msdev subproject clang_compilation_database strip_on_install waf_unit_test enforce_pic cmake force_32bit') conf.load('msvs msdev subproject clang_compilation_database strip_on_install waf_unit_test enforce_pic force_32bit')
if conf.env.MSVC_TARGETS[0] == 'amd64_x86' or conf.env.MSVC_TARGETS[0] == 'x86': if conf.env.MSVC_TARGETS[0] == 'amd64_x86' or conf.env.MSVC_TARGETS[0] == 'x86':
conf.env.MSVC_SUBSYSTEM = 'WINDOWS,5.01' conf.env.MSVC_SUBSYSTEM = 'WINDOWS,5.01'
@@ -499,6 +509,9 @@ int main(void) { return (int)BZ2_bzlibVersion(); }'''
conf.add_subproject(i.name) conf.add_subproject(i.name)
def build(bld): def build(bld):
if bld.env.ENABLE_WAFCACHE:
bld.load('wafcache')
# guard rails to not let install to root # guard rails to not let install to root
if bld.is_install and not bld.options.PACKAGING and not bld.options.destdir: if bld.is_install and not bld.options.PACKAGING and not bld.options.destdir:
bld.fatal('Set the install destination directory using --destdir option') bld.fatal('Set the install destination directory using --destdir option')