quakequest/Projects/Android/jni/darkplaces/cl_dyntexture.c
2021-02-02 22:53:37 +00:00

93 lines
2.7 KiB
C

// Andreas Kirsch 07
#include "quakedef.h"
#include "cl_dyntexture.h"
typedef struct dyntexture_s {
// everything after DYNAMIC_TEXTURE_PATH_PREFIX
char name[ MAX_QPATH + 32 ];
// texture pointer (points to r_texture_white at first)
rtexture_t *texture;
} dyntexture_t;
static dyntexture_t dyntextures[ MAX_DYNAMIC_TEXTURE_COUNT ];
static unsigned dyntexturecount;
#define DEFAULT_DYNTEXTURE r_texture_grey128
static dyntexture_t * cl_finddyntexture( const char *name, qboolean warnonfailure ) {
unsigned i;
dyntexture_t *dyntexture = NULL;
// sanity checks - make sure its actually a dynamic texture path
if( !name || !*name || strncmp( name, CLDYNTEXTUREPREFIX, sizeof( CLDYNTEXTUREPREFIX ) - 1 ) != 0 ) {
// TODO: print a warning or something
if (warnonfailure)
Con_Printf( "cl_finddyntexture: Bad dynamic texture name '%s'\n", name );
return NULL;
}
for( i = 0 ; i < dyntexturecount ; i++ ) {
dyntexture = &dyntextures[ i ];
if( dyntexture->name && strcmp( dyntexture->name, name ) == 0 ) {
return dyntexture;
}
}
if( dyntexturecount == MAX_DYNAMIC_TEXTURE_COUNT ) {
// TODO: warn or expand the array, etc.
return NULL;
}
dyntexture = &dyntextures[ dyntexturecount++ ];
strlcpy( dyntexture->name, name, sizeof( dyntexture->name ) );
dyntexture->texture = DEFAULT_DYNTEXTURE;
return dyntexture;
}
rtexture_t * CL_GetDynTexture( const char *name ) {
dyntexture_t *dyntexture = cl_finddyntexture( name, false );
if( dyntexture ) {
return dyntexture->texture;
} else {
return NULL;
}
}
void CL_LinkDynTexture( const char *name, rtexture_t *texture ) {
dyntexture_t *dyntexture;
cachepic_t *cachepic;
skinframe_t *skinframe;
dyntexture = cl_finddyntexture( name, true );
if( !dyntexture ) {
Con_Printf( "CL_LinkDynTexture: internal error in cl_finddyntexture!\n" );
return;
}
// TODO: assert dyntexture != NULL!
if( dyntexture->texture != texture ) {
dyntexture->texture = texture;
cachepic = Draw_CachePic_Flags( name, CACHEPICFLAG_NOTPERSISTENT );
// TODO: assert cachepic and skinframe should be valid pointers...
// TODO: assert cachepic->tex = dyntexture->texture
cachepic->tex = texture;
// update cachepic's size, too
cachepic->width = R_TextureWidth( texture );
cachepic->height = R_TextureHeight( texture );
// update skinframes
skinframe = NULL;
while( (skinframe = R_SkinFrame_FindNextByName( skinframe, name )) != NULL ) {
skinframe->base = texture;
// simply reset the compare* attributes of skinframe
skinframe->comparecrc = 0;
skinframe->comparewidth = skinframe->compareheight = 0;
// this is kind of hacky
}
}
}
void CL_UnlinkDynTexture( const char *name ) {
CL_LinkDynTexture( name, DEFAULT_DYNTEXTURE );
}