engine: mod_studio: more studio model swapping

This commit is contained in:
Alibek Omarov
2026-04-24 20:51:14 +05:00
parent e43ccee77f
commit 6ca7271006
2 changed files with 69 additions and 3 deletions

View File

@@ -162,7 +162,6 @@ le_struct_begin( mstudioattachment_swap )
le_struct_field( mstudioattachment_t, flags )
le_struct_field( mstudioattachment_t, bone )
le_struct_array( mstudioattachment_t, org, 3 )
le_struct_array( mstudioattachment_t, vectors, 3 * 3 )
le_struct_end();
le_struct_begin( mstudiobodyparts_swap )
@@ -977,6 +976,9 @@ static qboolean Mod_SwapStudioModel( const char *name, void *buffer, size_t buff
if( phdr->ident != IDSTUDIOHEADER || phdr->version != STUDIO_VERSION )
return false;
#if XASH_BIG_ENDIAN
if( phdr->studiohdr2index > 0 && phdr->studiohdr2index < phdr->length )
{
@@ -998,7 +1000,11 @@ static qboolean Mod_SwapStudioModel( const char *name, void *buffer, size_t buff
le_struct_swap( mstudioseqgroup_swap, (mstudioseqgroup_t *)( mod_base + phdr->seqgroupindex ) + i );
for( int i = 0; i < phdr->numattachments; i++ )
le_struct_swap( mstudioattachment_swap, (mstudioattachment_t *)( mod_base + phdr->attachmentindex ) + i );
{
mstudioattachment_t *pattach = (mstudioattachment_t *)( mod_base + phdr->attachmentindex ) + i;
le_struct_swap( mstudioattachment_swap, pattach );
le_array_swap((float *)pattach->vectors, 3 * 3 );
}
for( int i = 0; i < phdr->numtextures; i++ )
le_struct_swap( mstudiotexture_swap, (mstudiotexture_t *)( mod_base + phdr->textureindex ) + i );
@@ -1013,6 +1019,38 @@ static qboolean Mod_SwapStudioModel( const char *name, void *buffer, size_t buff
for( int j = 0; j < pseq->numevents; j++ )
le_struct_swap( mstudioevent_swap, (mstudioevent_t *)( mod_base + pseq->eventindex ) + j );
if( pseq->seqgroup != 0 )
continue;
mstudioanim_t *panim = (mstudioanim_t *)( mod_base + pseq->animindex );
int numanims = pseq->numblends * phdr->numbones;
for( int j = 0; j < numanims; j++, panim++ )
{
le_struct_swap( mstudioanim_swap, panim );
for( int k = 0; k < 6; k++ )
{
if( panim->offset[k] == 0 )
continue;
mstudioanimvalue_t *panimvalue = (mstudioanimvalue_t *)((byte *)panim + panim->offset[k] );
int frames = pseq->numframes;
while( frames > 0 )
{
int valid = panimvalue->num.valid;
int total = panimvalue->num.total;
for( int l = 1; l <= valid; l++ )
panimvalue[l].value = LittleShort( panimvalue[l].value );
panimvalue += valid + 1;
frames -= total;
}
}
}
}
for( int i = 0; i < phdr->numbodyparts; i++ )
@@ -1024,8 +1062,25 @@ static qboolean Mod_SwapStudioModel( const char *name, void *buffer, size_t buff
mstudiomodel_t *pmodel = (mstudiomodel_t *)( mod_base + pbodypart->modelindex ) + j;
le_struct_swap( mstudiomodel_swap, pmodel );
le_array_swap((float *)( mod_base + pmodel->vertindex ), pmodel->numverts * 3 );
le_array_swap((float *)( mod_base + pmodel->normindex ), pmodel->numnorms * 3 );
for( int k = 0; k < pmodel->nummesh; k++ )
le_struct_swap( mstudiomesh_swap, (mstudiomesh_t *)( mod_base + pmodel->meshindex ) + k );
{
mstudiomesh_t *pmesh = (mstudiomesh_t *)( mod_base + pmodel->meshindex ) + k;
le_struct_swap( mstudiomesh_swap, pmesh );
short *ptricmds = (short *)( mod_base + pmesh->triindex );
short n;
while(( n = LittleShort( *ptricmds )))
{
*ptricmds++ = n;
int count = abs( n ) * 4;
for( int l = 0; l < count; l++, ptricmds++ )
*ptricmds = LittleShort( *ptricmds );
}
*ptricmds = 0;
}
}
}

View File

@@ -82,9 +82,16 @@ static inline void swap_struct_( const swap_struct_def_t *def, size_t len, byte
}
}
static inline void swap_array_( byte *data, int32_t elem_size, uint32_t count )
{
for( uint32_t i = 0; i < count; i++ )
swap_field_( &data[i * elem_size], elem_size );
}
// do not use these macros, they will swap structs unconditionally
// you might want to use le_/be_ macros instead
#define swap_struct( swapdef, ptr ) swap_struct_(( swapdef ), sizeof( swapdef ) / sizeof( swapdef[0] ), (byte *)( ptr ))
#define swap_array( ptr, count ) swap_array_((byte *)( ptr ), sizeof( *( ptr )), ( count ))
#define swap_struct_begin( swapdef ) static swap_struct_def_t swapdef[] = {
#define swap_struct_end() }
@@ -112,6 +119,7 @@ static inline void swap_struct_( const swap_struct_def_t *def, size_t len, byte
#define be_struct_array_child( x, y, z, w ) swap_struct_array_child( x, y, z, w )
#define be_struct_end() swap_struct_end()
#define be_struct_swap( x, y ) swap_struct( x, y )
#define be_array_swap( x, y ) swap_array( x, y )
#define le_struct_begin( x )
#define le_struct_field( x, y )
#define le_struct_child( x, y, z )
@@ -119,6 +127,7 @@ static inline void swap_struct_( const swap_struct_def_t *def, size_t len, byte
#define le_struct_array_child( x, y, z, w )
#define le_struct_end() extern int _le_struct_end_dummy // define as extern variable, to let end() end with ;
#define le_struct_swap( x, y ) (void)(y)
#define le_array_swap( x, y ) (void)(x)
#else
#define be_struct_begin( x )
#define be_struct_field( x, y )
@@ -127,6 +136,7 @@ static inline void swap_struct_( const swap_struct_def_t *def, size_t len, byte
#define be_struct_array_child( x, y, z, w )
#define be_struct_end() extern int _le_struct_end_dummy
#define be_struct_swap( x, y ) (void)(y)
#define be_array_swap( x, y ) (void)(x)
#define le_struct_begin( x ) swap_struct_begin( x )
#define le_struct_field( x, y ) swap_struct_field( x, y )
#define le_struct_child( x, y, z ) swap_struct_child( x, y, z )
@@ -134,6 +144,7 @@ static inline void swap_struct_( const swap_struct_def_t *def, size_t len, byte
#define le_struct_array_child( x, y, z, w ) swap_struct_array_child( x, y, z, w )
#define le_struct_end() swap_struct_end()
#define le_struct_swap( x, y ) swap_struct( x, y )
#define le_array_swap( x, y ) swap_array( x, y )
#endif