mirror of
https://github.com/FWGS/xash3d-fwgs
synced 2024-11-29 05:20:23 +01:00
engine: client: reimplement Mod_LoadMapSprite on engine side
This commit is contained in:
parent
addd50467e
commit
4cb11861e4
@ -1165,6 +1165,126 @@ void CL_ClearSpriteTextures( void )
|
||||
clgame.sprites[i].needload = NL_UNREFERENCED;
|
||||
}
|
||||
|
||||
// it's a Valve default value for LoadMapSprite (probably must be power of two)
|
||||
#define MAPSPRITE_SIZE 128
|
||||
|
||||
/*
|
||||
====================
|
||||
Mod_LoadMapSprite
|
||||
|
||||
Loading a bitmap image as sprite with multiple frames
|
||||
as pieces of input image
|
||||
====================
|
||||
*/
|
||||
static void Mod_LoadMapSprite( model_t *mod, const void *buffer, size_t size, qboolean *loaded )
|
||||
{
|
||||
rgbdata_t *pix, temp = { 0 };
|
||||
char texname[128];
|
||||
int i, w, h;
|
||||
int xl, yl;
|
||||
int numframes;
|
||||
msprite_t *psprite;
|
||||
char poolname[MAX_VA_STRING];
|
||||
|
||||
if( loaded ) *loaded = false;
|
||||
Q_snprintf( texname, sizeof( texname ), "#%s", mod->name );
|
||||
Image_SetForceFlags( IL_OVERVIEW );
|
||||
pix = FS_LoadImage( texname, buffer, size );
|
||||
Image_ClearForceFlags();
|
||||
if( !pix ) return; // bad image or something else
|
||||
|
||||
mod->type = mod_sprite;
|
||||
|
||||
if( pix->width % MAPSPRITE_SIZE )
|
||||
w = pix->width - ( pix->width % MAPSPRITE_SIZE );
|
||||
else w = pix->width;
|
||||
|
||||
if( pix->height % MAPSPRITE_SIZE )
|
||||
h = pix->height - ( pix->height % MAPSPRITE_SIZE );
|
||||
else h = pix->height;
|
||||
|
||||
if( w < MAPSPRITE_SIZE ) w = MAPSPRITE_SIZE;
|
||||
if( h < MAPSPRITE_SIZE ) h = MAPSPRITE_SIZE;
|
||||
|
||||
// resample image if needed
|
||||
Image_Process( &pix, w, h, IMAGE_FORCE_RGBA|IMAGE_RESAMPLE, 0.0f );
|
||||
|
||||
w = h = MAPSPRITE_SIZE;
|
||||
|
||||
// check range
|
||||
if( w > pix->width ) w = pix->width;
|
||||
if( h > pix->height ) h = pix->height;
|
||||
|
||||
// determine how many frames we needs
|
||||
numframes = (pix->width * pix->height) / (w * h);
|
||||
Q_snprintf( poolname, sizeof( poolname ), "^2%s^7", mod->name );
|
||||
mod->mempool = Mem_AllocPool( poolname );
|
||||
psprite = Mem_Calloc( mod->mempool, sizeof( msprite_t ) + ( numframes - 1 ) * sizeof( psprite->frames ));
|
||||
mod->cache.data = psprite; // make link to extradata
|
||||
|
||||
psprite->type = SPR_FWD_PARALLEL_ORIENTED;
|
||||
psprite->texFormat = SPR_ALPHTEST;
|
||||
psprite->numframes = mod->numframes = numframes;
|
||||
psprite->radius = sqrt(((w >> 1) * (w >> 1)) + ((h >> 1) * (h >> 1)));
|
||||
|
||||
mod->mins[0] = mod->mins[1] = -w / 2;
|
||||
mod->maxs[0] = mod->maxs[1] = w / 2;
|
||||
mod->mins[2] = -h / 2;
|
||||
mod->maxs[2] = h / 2;
|
||||
|
||||
// create a temporary pic
|
||||
temp.width = w;
|
||||
temp.height = h;
|
||||
temp.type = pix->type;
|
||||
temp.flags = pix->flags;
|
||||
temp.size = w * h * PFDesc[temp.type].bpp;
|
||||
temp.buffer = Mem_Malloc( mod->mempool, temp.size );
|
||||
temp.palette = NULL;
|
||||
|
||||
// chop the image and upload into video memory
|
||||
for( i = xl = yl = 0; i < numframes; i++ )
|
||||
{
|
||||
mspriteframe_t *pspriteframe;
|
||||
int xh = xl + w, yh = yl + h, x, y, j;
|
||||
int linedelta = ( pix->width - w ) * 4;
|
||||
byte *src = pix->buffer + ( yl * pix->width + xl ) * 4;
|
||||
byte *dst = temp.buffer;
|
||||
|
||||
// cut block from source
|
||||
for( y = yl; y < yh; y++ )
|
||||
{
|
||||
for( x = xl; x < xh; x++ )
|
||||
for( j = 0; j < 4; j++ )
|
||||
*dst++ = *src++;
|
||||
src += linedelta;
|
||||
}
|
||||
|
||||
// build uinque frame name
|
||||
Q_snprintf( texname, sizeof( texname ), "#MAP/%s_%i%i.spr", mod->name, i / 10, i % 10 );
|
||||
|
||||
psprite->frames[i].frameptr = Mem_Calloc( mod->mempool, sizeof( mspriteframe_t ));
|
||||
pspriteframe = psprite->frames[i].frameptr;
|
||||
pspriteframe->width = w;
|
||||
pspriteframe->height = h;
|
||||
pspriteframe->up = ( h >> 1 );
|
||||
pspriteframe->left = -( w >> 1 );
|
||||
pspriteframe->down = ( h >> 1 ) - h;
|
||||
pspriteframe->right = w + -( w >> 1 );
|
||||
pspriteframe->gl_texturenum = GL_LoadTextureInternal( texname, &temp, TF_IMAGE );
|
||||
|
||||
xl += w;
|
||||
if( xl >= pix->width )
|
||||
{
|
||||
xl = 0;
|
||||
yl += h;
|
||||
}
|
||||
}
|
||||
|
||||
FS_FreeImage( pix );
|
||||
Mem_Free( temp.buffer );
|
||||
if( loaded ) *loaded = true;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
CL_LoadHudSprite
|
||||
@ -1210,7 +1330,7 @@ static qboolean CL_LoadHudSprite( const char *szSpriteName, model_t *m_pSprite,
|
||||
return false;
|
||||
|
||||
if( type == SPR_MAPSPRITE )
|
||||
ref.dllFuncs.Mod_LoadMapSprite( m_pSprite, buf, size, &loaded );
|
||||
Mod_LoadMapSprite( m_pSprite, buf, size, &loaded );
|
||||
else
|
||||
{
|
||||
Mod_LoadSpriteModel( m_pSprite, buf, &loaded );
|
||||
|
Loading…
Reference in New Issue
Block a user