]> icculus.org git repositories - divverent/darkplaces.git/blob - cl_dyntexture.c
Fixed user font initialization writing beyond fonts array bounds.
[divverent/darkplaces.git] / cl_dyntexture.c
1 // Andreas Kirsch 07\r
2 \r
3 #include "quakedef.h"\r
4 #include "cl_dyntexture.h"\r
5 \r
6 typedef struct dyntexture_s {\r
7         // everything after DYNAMIC_TEXTURE_PATH_PREFIX\r
8         char name[ MAX_QPATH + 32 ];\r
9         // texture pointer (points to r_texture_white at first)\r
10         rtexture_t *texture;\r
11 } dyntexture_t;\r
12 \r
13 static dyntexture_t dyntextures[ MAX_DYNAMIC_TEXTURE_COUNT ];\r
14 static unsigned dyntexturecount;\r
15 \r
16 #define DEFAULT_DYNTEXTURE r_texture_grey128\r
17 \r
18 static dyntexture_t * cl_finddyntexture( const char *name ) {\r
19         unsigned i;\r
20         dyntexture_t *dyntexture = NULL;\r
21 \r
22         // sanity checks - make sure its actually a dynamic texture path\r
23         if( !name || !*name || strncmp( name, CLDYNTEXTUREPREFIX, sizeof( CLDYNTEXTUREPREFIX ) - 1 ) != 0 ) {\r
24                 // TODO: print a warning or something\r
25                 if( developer.integer > 0 ) {\r
26                         Con_Printf( "cl_finddyntexture: Bad dynamic texture name '%s'\n", name );\r
27                 }\r
28                 return NULL;\r
29         }\r
30 \r
31         for( i = 0 ; i < dyntexturecount ; i++ ) {\r
32                 dyntexture = &dyntextures[ i ];\r
33                 if( dyntexture->name && strcmp( dyntexture->name, name ) == 0 ) {\r
34                         return dyntexture;\r
35                 }\r
36         }\r
37 \r
38         if( dyntexturecount == MAX_DYNAMIC_TEXTURE_COUNT ) {\r
39                 // TODO: warn or expand the array, etc.\r
40                 return NULL;\r
41         }\r
42         dyntexture = &dyntextures[ dyntexturecount++ ];\r
43         strlcpy( dyntexture->name, name, sizeof( dyntexture->name ) );\r
44         dyntexture->texture = DEFAULT_DYNTEXTURE;\r
45         return dyntexture;\r
46 }\r
47 \r
48 rtexture_t * CL_GetDynTexture( const char *name ) {\r
49         dyntexture_t *dyntexture = cl_finddyntexture( name );\r
50         if( dyntexture ) {\r
51                 return dyntexture->texture;\r
52         } else {\r
53                 return NULL;\r
54         }\r
55 }\r
56 \r
57 void CL_LinkDynTexture( const char *name, rtexture_t *texture ) {\r
58         dyntexture_t *dyntexture;\r
59         cachepic_t *cachepic;\r
60         skinframe_t *skinframe;\r
61 \r
62         dyntexture = cl_finddyntexture( name );\r
63         if( !dyntexture ) {\r
64                 Con_Printf( "CL_LinkDynTexture: internal error in cl_finddyntexture!\n" );\r
65                 return;\r
66         }\r
67         // TODO: assert dyntexture != NULL!\r
68         if( dyntexture->texture != texture ) {\r
69                 dyntexture->texture = texture;\r
70 \r
71                 cachepic = Draw_CachePic( name, false );\r
72                 // TODO: assert cachepic and skinframe should be valid pointers...\r
73                 // TODO: assert cachepic->tex = dyntexture->texture\r
74                 cachepic->tex = texture;\r
75                 // update cachepic's size, too\r
76                 cachepic->width = R_TextureWidth( texture );\r
77                 cachepic->height = R_TextureHeight( texture );\r
78 \r
79                 // update skinframes\r
80                 skinframe = NULL;\r
81                 while( (skinframe = R_SkinFrame_FindNextByName( skinframe, name )) != NULL ) {\r
82                         skinframe->base = texture;\r
83                         // simply reset the compare* attributes of skinframe\r
84                         skinframe->comparecrc = 0;\r
85                         skinframe->comparewidth = skinframe->compareheight = 0;\r
86                         // this is kind of hacky\r
87                 }\r
88         }\r
89 }\r
90 \r
91 void CL_UnlinkDynTexture( const char *name ) {\r
92         CL_LinkDynTexture( name, DEFAULT_DYNTEXTURE );\r
93 }\r
94 \r