From b3dc772cd2e0d2fcc54a05cad073dad1b43489e6 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Fri, 31 Oct 2025 15:40:58 +0500 Subject: [PATCH] engine: add file size argument to sprite model loader --- engine/client/cl_game.c | 2 +- engine/common/mod_local.h | 2 +- engine/common/mod_sprite.c | 85 +++++++++++++++++++++++++++----------- engine/common/model.c | 2 +- 4 files changed, 64 insertions(+), 27 deletions(-) diff --git a/engine/client/cl_game.c b/engine/client/cl_game.c index 06b1f815..40d62c52 100644 --- a/engine/client/cl_game.c +++ b/engine/client/cl_game.c @@ -1281,7 +1281,7 @@ static qboolean CL_LoadHudSprite( const char *szSpriteName, model_t *m_pSprite, Mod_LoadMapSprite( m_pSprite, buf, size, &loaded ); else { - Mod_LoadSpriteModel( m_pSprite, buf, &loaded ); + Mod_LoadSpriteModel( m_pSprite, buf, size, &loaded ); ref.dllFuncs.Mod_ProcessRenderData( m_pSprite, true, buf ); } diff --git a/engine/common/mod_local.h b/engine/common/mod_local.h index 7dc1e989..9ee1ae18 100644 --- a/engine/common/mod_local.h +++ b/engine/common/mod_local.h @@ -207,7 +207,7 @@ void Mod_ClearStudioCache( void ); // // mod_sprite.c // -void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded ); +void Mod_LoadSpriteModel( model_t *mod, const void *buffer, size_t buffersize, qboolean *loaded ); #endif #endif//MOD_LOCAL_H diff --git a/engine/common/mod_sprite.c b/engine/common/mod_sprite.c index 880802d3..45c49d05 100644 --- a/engine/common/mod_sprite.c +++ b/engine/common/mod_sprite.c @@ -30,63 +30,98 @@ Mod_LoadSpriteModel load sprite model ==================== */ -void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded ) +void Mod_LoadSpriteModel( model_t *mod, const void *buffer, size_t buffersize, qboolean *loaded ) { - dsprite_q1_t *pinq1; - dsprite_hl_t *pinhl; - dsprite_t *pin; - msprite_t *psprite; - char poolname[MAX_VA_STRING]; - int i, size; + const dsprite_t *pin = buffer; + msprite_t *psprite; + char poolname[MAX_VA_STRING]; - if( loaded ) *loaded = false; - pin = (dsprite_t *)buffer; - mod->type = mod_sprite; - i = pin->version; + if( loaded ) + *loaded = false; + + if( buffersize < sizeof( dsprite_t )) + { + Con_DPrintf( S_ERROR "%s: %s have incorrect file size %zu should be greater than %zu (%s)\n", __func__, mod->name, buffersize, sizeof( dsprite_t ), "basic header" ); + return; + } if( pin->ident != IDSPRITEHEADER ) { - Con_DPrintf( S_ERROR "%s has wrong id (%x should be %x)\n", mod->name, pin->ident, IDSPRITEHEADER ); + Con_DPrintf( S_ERROR "%s: %s has wrong id (0x%x should be 0x%x)\n", __func__, mod->name, pin->ident, IDSPRITEHEADER ); return; } - if( i != SPRITE_VERSION_Q1 && i != SPRITE_VERSION_HL && i != SPRITE_VERSION_32 ) + switch( pin->version ) { - Con_DPrintf( S_ERROR "%s has wrong version number (%i should be %i or %i)\n", mod->name, i, SPRITE_VERSION_Q1, SPRITE_VERSION_HL ); + case SPRITE_VERSION_Q1: + case SPRITE_VERSION_32: + if( buffersize < sizeof( dsprite_q1_t )) + { + Con_DPrintf( S_ERROR "%s: %s have incorrect file size %zu should be greater than %zu (%s)\n", __func__, mod->name, buffersize, sizeof( dsprite_q1_t ), "q1 header" ); + return; + } + break; + case SPRITE_VERSION_HL: + if( buffersize < sizeof( dsprite_hl_t )) + { + Con_DPrintf( S_ERROR "%s: %s have incorrect file size %zu should be greater than %zu (%s)\n", __func__, mod->name, buffersize, sizeof( dsprite_hl_t ), "hl header" ); + return; + } + break; + default: + Con_DPrintf( S_ERROR "%s: %s has wrong version number (%i should be %i, %i or %i)\n", __func__, mod->name, pin->version, SPRITE_VERSION_Q1, SPRITE_VERSION_32, SPRITE_VERSION_HL ); return; } + mod->type = mod_sprite; Q_snprintf( poolname, sizeof( poolname ), "^2%s^7", mod->name ); mod->mempool = Mem_AllocPool( poolname ); - if( i == SPRITE_VERSION_Q1 || i == SPRITE_VERSION_32 ) + if( pin->version == SPRITE_VERSION_Q1 || pin->version == SPRITE_VERSION_32 ) { - pinq1 = (dsprite_q1_t *)buffer; + const dsprite_q1_t *pinq1 = buffer; + size_t size; + + if( pinq1->numframes == 0 ) + { + Con_DPrintf( S_ERROR "%s: %s has no frames\n", __func__, mod->name ); + return; + } + size = sizeof( msprite_t ) + ( pinq1->numframes - 1 ) * sizeof( psprite->frames ); + psprite = Mem_Calloc( mod->mempool, size ); mod->cache.data = psprite; // make link to extradata psprite->type = pinq1->type; - psprite->texFormat = SPR_ADDITIVE; //SPR_ALPHTEST; + psprite->texFormat = SPR_ADDITIVE; psprite->numframes = mod->numframes = pinq1->numframes; psprite->facecull = SPR_CULL_FRONT; psprite->radius = pinq1->boundingradius; psprite->synctype = pinq1->synctype; - // LordHavoc: hack to allow sprites to be non-fullbright - for( i = 0; i < MAX_QPATH && mod->name[i]; i++ ) - if( mod->name[i] == '!' ) - psprite->texFormat = SPR_ALPHTEST; + // LadyHavoc: hack to allow sprites to be non-fullbright + if( Q_strchr( mod->name, '!' )) + psprite->texFormat = SPR_ALPHTEST; mod->mins[0] = mod->mins[1] = -pinq1->bounds[0] * 0.5f; mod->maxs[0] = mod->maxs[1] = pinq1->bounds[0] * 0.5f; mod->mins[2] = -pinq1->bounds[1] * 0.5f; mod->maxs[2] = pinq1->bounds[1] * 0.5f; } - else // if( i == SPRITE_VERSION_HL ) + else // if( pin->version == SPRITE_VERSION_HL ) { - pinhl = (dsprite_hl_t *)buffer; + const dsprite_hl_t *pinhl = buffer; + size_t size; + + if( pinhl->numframes == 0 ) + { + Con_DPrintf( S_WARN "%s: %s has no frames\n", __func__, mod->name ); + return; + } + size = sizeof( msprite_t ) + ( pinhl->numframes - 1 ) * sizeof( psprite->frames ); + psprite = Mem_Calloc( mod->mempool, size ); mod->cache.data = psprite; // make link to extradata @@ -102,7 +137,9 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded ) mod->mins[2] = -pinhl->bounds[1] * 0.5f; mod->maxs[2] = pinhl->bounds[1] * 0.5f; } - if( loaded ) *loaded = true; // done + + if( loaded ) + *loaded = true; // done if( Host_IsDedicated() ) { diff --git a/engine/common/model.c b/engine/common/model.c index 9f5e3c1d..05686f43 100644 --- a/engine/common/model.c +++ b/engine/common/model.c @@ -300,7 +300,7 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash ) Mod_LoadStudioModel( mod, buf, &loaded ); break; case IDSPRITEHEADER: - Mod_LoadSpriteModel( mod, buf, &loaded ); + Mod_LoadSpriteModel( mod, buf, length, &loaded ); break; case IDALIASHEADER: Mod_LoadAliasModel( mod, buf, &loaded );