diff --git a/engine/common/mod_local.h b/engine/common/mod_local.h index c114300c..e1c32351 100644 --- a/engine/common/mod_local.h +++ b/engine/common/mod_local.h @@ -191,6 +191,7 @@ void Mod_StudioGetAttachment( const edict_t *e, int iAttachment, float *org, flo void Mod_GetBonePosition( const edict_t *e, int iBone, float *org, float *ang ); hull_t *Mod_HullForStudio( model_t *m, float frame, int seq, vec3_t ang, vec3_t org, vec3_t size, byte *pcnt, byte *pbl, int *hitboxes, edict_t *ed ); void *R_StudioGetAnim( studiohdr_t *m_pStudioHeader, model_t *m_pSubModel, mstudioseqdesc_t *pseqdesc ); +void Mod_SwapStudioSeqGroupAnims( studiohdr_t *phdr, mstudioseqdesc_t *pseq, byte *buf ); int Mod_HitgroupForStudioHull( int index ); void Mod_ClearStudioCache( void ); diff --git a/engine/common/mod_studio.c b/engine/common/mod_studio.c index 51b16164..3c3d9d3f 100644 --- a/engine/common/mod_studio.c +++ b/engine/common/mod_studio.c @@ -550,7 +550,7 @@ static void Mod_StudioCalcRotations( int boneused[], int numbones, const byte *p } -static void Mod_SwapStudioSeqGroupAnims( studiohdr_t *phdr, mstudioseqdesc_t *pseq, byte *buf ) +void Mod_SwapStudioSeqGroupAnims( studiohdr_t *phdr, mstudioseqdesc_t *pseq, byte *buf ) { mstudioanim_t *panim = (mstudioanim_t *)( buf + pseq->animindex ); int numanims = pseq->numblends * phdr->numbones; diff --git a/engine/common/model.c b/engine/common/model.c index 7ef52838..6c557bee 100644 --- a/engine/common/model.c +++ b/engine/common/model.c @@ -608,6 +608,31 @@ void GAME_EXPORT Mod_LoadCacheFile( const char *filename, cache_user_t *cu ) cu->data = Mem_Malloc( com_studiocache, size ); memcpy( cu->data, buf, size ); Mem_Free( buf ); + + // this handles when studio model renderer tries to load sequence files on it's own + // which is what they always do in HLSDK +#if XASH_BIG_ENDIAN + if( size >= sizeof( int ) && LittleLong( IDSEQGRPHEADER ) == *(uint *)cu->data ) + { + studiohdr_t *phdr = (studiohdr_t *)(intptr_t)REF_GET_PARM( PARM_GET_STUDIO_HDR, 0 ); + if( !phdr ) + return; + + mstudioseqdesc_t *pseq = (mstudioseqdesc_t *)((byte *)phdr + phdr->seqindex ); + + for( int i = 0; i < phdr->numseq; i++ ) + { + if( pseq[i].seqgroup == 0 ) + continue; + + mstudioseqgroup_t *pgrp = (mstudioseqgroup_t *)((byte *)phdr + phdr->seqgroupindex ) + pseq[i].seqgroup; + + // assuming filename passes seqgroup's name + if( !Q_stricmp( pgrp->name, filename )) + Mod_SwapStudioSeqGroupAnims( phdr, &pseq[i], (byte *)cu->data ); + } + } +#endif } /* diff --git a/engine/ref_api.h b/engine/ref_api.h index 571946bf..d504faa9 100644 --- a/engine/ref_api.h +++ b/engine/ref_api.h @@ -342,6 +342,7 @@ typedef enum PARM_GET_LIGHTSTYLES_PTR = -20, PARM_GET_DLIGHTS_PTR = -21, PARM_GET_ELIGHTS_PTR = -22, + PARM_GET_STUDIO_HDR = -23, // current m_pStudioHeader in renderer // implemented by ref_dll diff --git a/ref/gl/gl_context.c b/ref/gl/gl_context.c index 96f6bc70..f436b0e7 100644 --- a/ref/gl/gl_context.c +++ b/ref/gl/gl_context.c @@ -230,6 +230,8 @@ static int GL_RefGetParm( int parm, int arg ) return gl_texture_nearest.value == 0.0f; return GL_TextureFilteringEnabled( R_GetTexture( arg )); + case PARM_GET_STUDIO_HDR: + return (intptr_t)R_StudioGetHeader(); default: return ENGINE_GET_PARM_( parm, arg ); } diff --git a/ref/gl/gl_local.h b/ref/gl/gl_local.h index 744bac86..f99a105b 100644 --- a/ref/gl/gl_local.h +++ b/ref/gl/gl_local.h @@ -403,6 +403,7 @@ void R_DrawSpriteModel( cl_entity_t *e ); // gl_studio.c // void R_StudioInit( void ); +studiohdr_t *R_StudioGetHeader( void ); void R_StudioLerpMovement( cl_entity_t *e, double time, vec3_t origin, vec3_t angles ); struct mstudiotex_s *R_StudioGetTexture( cl_entity_t *e ); int R_GetEntityRenderMode( cl_entity_t *ent ); diff --git a/ref/gl/gl_studio.c b/ref/gl/gl_studio.c index aa223470..1bed6a0e 100644 --- a/ref/gl/gl_studio.c +++ b/ref/gl/gl_studio.c @@ -2602,6 +2602,11 @@ static void R_StudioSetHeader( studiohdr_t *pheader ) m_fDoRemap = false; } +studiohdr_t *R_StudioGetHeader( void ) +{ + return m_pStudioHeader; +} + /* =============== R_StudioSetRenderModel diff --git a/ref/soft/r_context.c b/ref/soft/r_context.c index 5ee0c558..c9113d00 100644 --- a/ref/soft/r_context.c +++ b/ref/soft/r_context.c @@ -188,6 +188,8 @@ static int GL_RefGetParm( int parm, int arg ) return 0; // ref_soft doesn't support sky sphere case PARM_TEX_FILTERING: return 0; // ref_soft doesn't do filtering in general + case PARM_GET_STUDIO_HDR: + return (intptr_t)R_StudioGetHeader(); default: return ENGINE_GET_PARM_( parm, arg ); } diff --git a/ref/soft/r_local.h b/ref/soft/r_local.h index 3eab6695..a3a3f3ae 100644 --- a/ref/soft/r_local.h +++ b/ref/soft/r_local.h @@ -392,6 +392,7 @@ void R_DrawSpriteModel( cl_entity_t *e ); // gl_studio.c // void R_StudioInit( void ); +studiohdr_t *R_StudioGetHeader( void ); void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded ); void R_StudioLerpMovement( cl_entity_t *e, double time, vec3_t origin, vec3_t angles ); struct mstudiotex_s *R_StudioGetTexture( cl_entity_t *e ); diff --git a/ref/soft/r_studio.c b/ref/soft/r_studio.c index 87279ef7..a75b0a63 100644 --- a/ref/soft/r_studio.c +++ b/ref/soft/r_studio.c @@ -2267,6 +2267,11 @@ static void R_StudioSetHeader( studiohdr_t *pheader ) m_fDoRemap = false; } +studiohdr_t *R_StudioGetHeader( void ) +{ + return m_pStudioHeader; +} + /* =============== R_StudioSetRenderModel