Skip to content

Commit

Permalink
Fix secondary weapon models registering
Browse files Browse the repository at this point in the history
Several people have noticed a curious regression which cause some
secondary weapon models (such as machinegun's barrel) to not be
rendered.
For instance:
- OpenArena#316
- OpenArena/engine#85
- https://forum.manjaro.org/t/openarena-lightning-gun-beam-not-visible-with-glibc-2-37-x86-64-bug/135312

And some people have hypothesized that this could have something to
do with a recent change in glibc.

I'm also facing this issue since an upgrade from ubuntu 22.04 to
24.04 and I've found its cause, here is the patch.

As you can see the logic to add a suffix to the primary weapon
model was previously based on a call to COM_StripExtension() with
the same pointer for in & out.
However, this function passes in & out to Q_strncpyz() which itself
relies on strncpy() which does not specify the expected behavior
in case of aliasing/overlapping of src & dst.
So it was relying on an unspecified behavior, prone to change
at any time and without any communication.

This patch passes the build step but I've tested it in-game with the
legacy project https://github.com/OpenArena/legacy and a back-ported
version of it.
  • Loading branch information
NoiseByNorthwest committed Jun 21, 2024
1 parent d371ff1 commit d85fb74
Showing 1 changed file with 10 additions and 20 deletions.
30 changes: 10 additions & 20 deletions code/cgame/cg_weapons.c
Original file line number Diff line number Diff line change
Expand Up @@ -855,8 +855,7 @@ void CG_RegisterWeapon( int weaponNum )
weaponInfo->ammoModel = trap_R_RegisterModel( ammo->world_model[0] );
}

Q_strncpyz( path, item->world_model[0], MAX_QPATH );
COM_StripExtension(path, path, sizeof(path));
COM_StripExtension(item->world_model[0], path, sizeof(path));
Q_strcat( path, sizeof(path), "_flash.md3" );
weaponInfo->flashModel = trap_R_RegisterModel( path );

Expand All @@ -866,39 +865,32 @@ void CG_RegisterWeapon( int weaponNum )

// leilei - additional flash styles

Q_strncpyz( path, item->world_model[0], MAX_QPATH );
COM_StripExtension(path, path, sizeof(path));
COM_StripExtension(item->world_model[0], path, sizeof(path));
Q_strcat( path, sizeof(path), "_flash1.md3" );
weaponInfo->flashModel_type1 = trap_R_RegisterModel( path );

Q_strncpyz( path, item->world_model[0], MAX_QPATH );
COM_StripExtension(path, path, sizeof(path));
COM_StripExtension(item->world_model[0], path, sizeof(path));
Q_strcat( path, sizeof(path), "_flash2.md3" );
weaponInfo->flashModel_type2 = trap_R_RegisterModel( path );

Q_strncpyz( path, item->world_model[0], MAX_QPATH );
COM_StripExtension(path, path, sizeof(path));
COM_StripExtension(item->world_model[0], path, sizeof(path));
Q_strcat( path, sizeof(path), "_flash2a.md3" );
weaponInfo->flashModel_type2a = trap_R_RegisterModel( path );

Q_strncpyz( path, item->world_model[0], MAX_QPATH );
COM_StripExtension(path, path, sizeof(path));
COM_StripExtension(item->world_model[0], path, sizeof(path));
Q_strcat( path, sizeof(path), "_flash3.md3" );
weaponInfo->flashModel_type3 = trap_R_RegisterModel( path );

Q_strncpyz( path, item->world_model[0], MAX_QPATH );
COM_StripExtension(path, path, sizeof(path));
COM_StripExtension(item->world_model[0], path, sizeof(path));
Q_strcat( path, sizeof(path), "_flash4.md3" );
weaponInfo->flashModel_type4 = trap_R_RegisterModel( path );

Q_strncpyz( path, item->world_model[0], MAX_QPATH );
COM_StripExtension(path, path, sizeof(path));
COM_StripExtension(item->world_model[0], path, sizeof(path));
Q_strcat( path, sizeof(path), "_flash5.md3" );
weaponInfo->flashModel_type5 = trap_R_RegisterModel( path );


Q_strncpyz( path, item->world_model[0], MAX_QPATH );
COM_StripExtension(path, path, sizeof(path));
COM_StripExtension(item->world_model[0], path, sizeof(path));
Q_strcat( path, sizeof(path), "_flash5a.md3" );
weaponInfo->flashModel_type5a = trap_R_RegisterModel( path );

Expand All @@ -917,13 +909,11 @@ void CG_RegisterWeapon( int weaponNum )
if (!weaponInfo->flashModel_type5) weaponInfo->flashModel_type5 = trap_R_RegisterModel( "models/muzzle/flash5.md3" );
if (!weaponInfo->flashModel_type5a) weaponInfo->flashModel_type5a = trap_R_RegisterModel( "models/muzzle/flash5a.md3" );

Q_strncpyz( path, item->world_model[0], MAX_QPATH );
COM_StripExtension(path, path, sizeof(path));
COM_StripExtension(item->world_model[0], path, sizeof(path));
Q_strcat( path, sizeof(path), "_barrel.md3" );
weaponInfo->barrelModel = trap_R_RegisterModel( path );

Q_strncpyz( path, item->world_model[0], MAX_QPATH );
COM_StripExtension(path, path, sizeof(path));
COM_StripExtension(item->world_model[0], path, sizeof(path));
Q_strcat( path, sizeof(path), "_hand.md3" );
weaponInfo->handsModel = trap_R_RegisterModel( path );

Expand Down

0 comments on commit d85fb74

Please sign in to comment.