This is an automated email from the git hooks/post-receive script. smcv pushed a commit to tag 1.51b in repository iortcw.
commit f040cfb7f42ebb6a60f921f13f77c80c22187002 Author: MAN-AT-ARMS <m4n4t4...@gmail.com> Date: Thu Jul 20 10:53:36 2017 -0400 All: Allow more than 32 surfaces in skin files --- MP/code/rend2/tr_animation.c | 18 +++++++++++------- MP/code/rend2/tr_image.c | 23 ++++++++++++++--------- MP/code/rend2/tr_local.h | 16 +++++++++++----- MP/code/rend2/tr_mesh.c | 9 ++++----- MP/code/rend2/tr_model_iqm.c | 9 +++++++-- MP/code/renderer/tr_animation.c | 18 +++++++++++------- MP/code/renderer/tr_cmesh.c | 10 ++++------ MP/code/renderer/tr_image.c | 23 ++++++++++++++--------- MP/code/renderer/tr_local.h | 16 +++++++++++----- MP/code/renderer/tr_mesh.c | 12 ++++-------- MP/code/renderer/tr_model_iqm.c | 9 +++++++-- SP/code/rend2/tr_animation.c | 14 +++++++++----- SP/code/rend2/tr_image.c | 23 ++++++++++++++--------- SP/code/rend2/tr_local.h | 16 +++++++++++----- SP/code/rend2/tr_mesh.c | 4 ++-- SP/code/rend2/tr_model_iqm.c | 9 +++++++-- SP/code/renderer/tr_animation.c | 14 +++++++++----- SP/code/renderer/tr_cmesh.c | 25 +++++++++++-------------- SP/code/renderer/tr_image.c | 23 ++++++++++++++--------- SP/code/renderer/tr_local.h | 16 +++++++++++----- SP/code/renderer/tr_mesh.c | 24 +++++++++++------------- SP/code/renderer/tr_model_iqm.c | 9 +++++++-- 22 files changed, 204 insertions(+), 136 deletions(-) diff --git a/MP/code/rend2/tr_animation.c b/MP/code/rend2/tr_animation.c index 80b7679..7cfd936 100644 --- a/MP/code/rend2/tr_animation.c +++ b/MP/code/rend2/tr_animation.c @@ -355,8 +355,8 @@ void R_AddAnimSurfaces( trRefEntity_t *ent ) { if ( ent->e.renderfx & RF_BLINK ) { const char *s = va( "%s_b", surface->name ); // append '_b' for 'blink' for ( j = 0 ; j < skin->numSurfaces ; j++ ) { - if ( !strcmp( skin->surfaces[j]->name, s ) ) { - shader = skin->surfaces[j]->shader; + if ( !strcmp( skin->surfaces[j].name, s ) ) { + shader = skin->surfaces[j].shader; break; } } @@ -366,8 +366,8 @@ void R_AddAnimSurfaces( trRefEntity_t *ent ) { for ( j = 0 ; j < skin->numSurfaces ; j++ ) { // the names have both been lowercased - if ( !strcmp( skin->surfaces[j]->name, surface->name ) ) { - shader = skin->surfaces[j]->shader; + if ( !strcmp( skin->surfaces[j].name, surface->name ) ) { + shader = skin->surfaces[j].shader; break; } } @@ -1605,9 +1605,9 @@ void R_MDRAddAnimSurfaces( trRefEntity_t *ent ) { for(j = 0; j < skin->numSurfaces; j++) { - if (!strcmp(skin->surfaces[j]->name, surface->name)) + if (!strcmp(skin->surfaces[j].name, surface->name)) { - shader = skin->surfaces[j]->shader; + shader = skin->surfaces[j].shader; break; } } @@ -1638,7 +1638,11 @@ void R_MDRAddAnimSurfaces( trRefEntity_t *ent ) { R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, qfalse, qfalse, 0 ); } - if (!personalModel) + // for testing polygon shadows (on /all/ models) + if ( r_shadows->integer == 4 ) + R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, qfalse, qfalse, 0 ); + + if ( !personalModel ) R_AddDrawSurf( (void *)surface, shader, fogNum, qfalse, qfalse, cubemapIndex ); surface = (mdrSurface_t *)( (byte *)surface + surface->ofsEnd ); diff --git a/MP/code/rend2/tr_image.c b/MP/code/rend2/tr_image.c index dca835f..834dc2a 100644 --- a/MP/code/rend2/tr_image.c +++ b/MP/code/rend2/tr_image.c @@ -3223,6 +3223,7 @@ RE_RegisterSkin =============== */ qhandle_t RE_RegisterSkin( const char *name ) { + skinSurface_t parseSurfaces[MAX_SKIN_SURFACES]; qhandle_t hSkin; skin_t *skin; skinSurface_t *surf; @@ -3279,8 +3280,8 @@ qhandle_t RE_RegisterSkin( const char *name ) { skin->numSurfaces = 0; skin->numModels = 0; //----(SA) added skin->numSurfaces = 1; - skin->surfaces[0] = ri.Hunk_Alloc( sizeof( *skin->surfaces[0] ), h_low ); - skin->surfaces[0]->shader = R_FindShader( name, LIGHTMAP_NONE, qtrue ); + skin->surfaces = ri.Hunk_Alloc( sizeof( skinSurface_t ), h_low ); + skin->surfaces[0].shader = R_FindShader( name, LIGHTMAP_NONE, qtrue ); return hSkin; } @@ -3350,12 +3351,12 @@ qhandle_t RE_RegisterSkin( const char *name ) { // parse the shader name token = CommaParse( &text_p ); - if ( skin->numSurfaces >= MD3_MAX_SURFACES ) { - ri.Printf( PRINT_WARNING, "WARNING: Ignoring surfaces in '%s', the max is %d surfaces!\n", name, MD3_MAX_SURFACES ); + if ( skin->numSurfaces >= MAX_SKIN_SURFACES ) { + ri.Printf( PRINT_WARNING, "WARNING: Ignoring surfaces in '%s', the max is %d surfaces!\n", name, MAX_SKIN_SURFACES ); break; } - surf = skin->surfaces[ skin->numSurfaces ] = ri.Hunk_Alloc( sizeof( *skin->surfaces[0] ), h_low ); + surf = &parseSurfaces[skin->numSurfaces]; Q_strncpyz( surf->name, surfName, sizeof( surf->name ) ); surf->shader = R_FindShader( token, LIGHTMAP_NONE, qtrue ); skin->numSurfaces++; @@ -3374,6 +3375,10 @@ qhandle_t RE_RegisterSkin( const char *name ) { } } + // copy surfaces to skin + skin->surfaces = ri.Hunk_Alloc( skin->numSurfaces * sizeof( skinSurface_t ), h_low ); + memcpy( skin->surfaces, parseSurfaces, skin->numSurfaces * sizeof( skinSurface_t ) ); + return hSkin; } @@ -3392,8 +3397,8 @@ void R_InitSkins( void ) { skin = tr.skins[0] = ri.Hunk_Alloc( sizeof( skin_t ), h_low ); Q_strncpyz( skin->name, "<default skin>", sizeof( skin->name ) ); skin->numSurfaces = 1; - skin->surfaces[0] = ri.Hunk_Alloc( sizeof( *skin->surfaces[0] ), h_low ); - skin->surfaces[0]->shader = tr.defaultShader; + skin->surfaces = ri.Hunk_Alloc( sizeof( skinSurface_t ), h_low ); + skin->surfaces[0].shader = tr.defaultShader; } /* @@ -3422,10 +3427,10 @@ void R_SkinList_f( void ) { for ( i = 0 ; i < tr.numSkins ; i++ ) { skin = tr.skins[i]; - ri.Printf( PRINT_ALL, "%3i:%s\n", i, skin->name ); + ri.Printf( PRINT_ALL, "%3i:%s (%d surfaces)\n", i, skin->name, skin->numSurfaces ); for ( j = 0 ; j < skin->numSurfaces ; j++ ) { ri.Printf( PRINT_ALL, " %s = %s\n", - skin->surfaces[j]->name, skin->surfaces[j]->shader->name ); + skin->surfaces[j].name, skin->surfaces[j].shader->name ); } } ri.Printf( PRINT_ALL, "------------------\n" ); diff --git a/MP/code/rend2/tr_local.h b/MP/code/rend2/tr_local.h index 3895bfd..cc146d1 100644 --- a/MP/code/rend2/tr_local.h +++ b/MP/code/rend2/tr_local.h @@ -860,6 +860,12 @@ typedef struct { //================================================================================= +// max surfaces per-skin +// This is an arbitry limit. Vanilla Q3 only supported 32 surfaces in skins but failed to +// enforce the maximum limit when reading skin files. It was possile to use more than 32 +// surfaces which accessed out of bounds memory past end of skin->surfaces hunk block. +#define MAX_SKIN_SURFACES 256 + // skins allow models to be retextured without modifying the model file typedef struct { char name[MAX_QPATH]; @@ -870,17 +876,17 @@ typedef struct { #define MAX_PART_MODELS 5 typedef struct { - char type[MAX_QPATH]; // md3_lower, md3_lbelt, md3_rbelt, etc. - char model[MAX_QPATH]; // lower.md3, belt1.md3, etc. + char type[MAX_QPATH]; // md3_lower, md3_lbelt, md3_rbelt, etc. + char model[MAX_QPATH]; // lower.md3, belt1.md3, etc. } skinModel_t; typedef struct skin_s { - char name[MAX_QPATH]; // game path, including extension + char name[MAX_QPATH]; // game path, including extension int numSurfaces; int numModels; - skinSurface_t *surfaces[MD3_MAX_SURFACES]; + skinSurface_t *surfaces; // dynamically allocated array of surfaces skinModel_t *models[MAX_PART_MODELS]; - vec3_t scale; //----(SA) added + vec3_t scale; //----(SA) added } skin_t; //----(SA) end diff --git a/MP/code/rend2/tr_mesh.c b/MP/code/rend2/tr_mesh.c index 695491f..538fe1e 100644 --- a/MP/code/rend2/tr_mesh.c +++ b/MP/code/rend2/tr_mesh.c @@ -382,8 +382,8 @@ void R_AddMD3Surfaces( trRefEntity_t *ent ) { if ( ent->e.renderfx & RF_BLINK ) { const char *s = va( "%s_b", surface->name ); // append '_b' for 'blink' for ( j = 0 ; j < skin->numSurfaces ; j++ ) { - if ( !strcmp( skin->surfaces[j]->name, s ) ) { - shader = skin->surfaces[j]->shader; + if ( !strcmp( skin->surfaces[j].name, s ) ) { + shader = skin->surfaces[j].shader; break; } } @@ -392,9 +392,8 @@ void R_AddMD3Surfaces( trRefEntity_t *ent ) { if ( shader == tr.defaultShader ) { // blink reference in skin was not found for ( j = 0 ; j < skin->numSurfaces ; j++ ) { // the names have both been lowercased - - if ( !strcmp( skin->surfaces[j]->name, surface->name ) ) { - shader = skin->surfaces[j]->shader; + if ( !strcmp( skin->surfaces[j].name, surface->name ) ) { + shader = skin->surfaces[j].shader; break; } } diff --git a/MP/code/rend2/tr_model_iqm.c b/MP/code/rend2/tr_model_iqm.c index 5b528d0..507158c 100644 --- a/MP/code/rend2/tr_model_iqm.c +++ b/MP/code/rend2/tr_model_iqm.c @@ -907,9 +907,9 @@ void R_AddIQMSurfaces( trRefEntity_t *ent ) { for(j = 0; j < skin->numSurfaces; j++) { - if (!strcmp(skin->surfaces[j]->name, surface->name)) + if (!strcmp(skin->surfaces[j].name, surface->name)) { - shader = skin->surfaces[j]->shader; + shader = skin->surfaces[j].shader; break; } } @@ -936,6 +936,11 @@ void R_AddIQMSurfaces( trRefEntity_t *ent ) { R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, 0, 0, 0 ); } + // for testing polygon shadows (on /all/ models) + if ( r_shadows->integer == 4 ) { + R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, qfalse, qfalse, 0 ); + } + if( !personalModel ) { R_AddDrawSurf( (void *)surface, shader, fogNum, 0, 0, cubemapIndex ); } diff --git a/MP/code/renderer/tr_animation.c b/MP/code/renderer/tr_animation.c index ce92d56..2dc73b8 100644 --- a/MP/code/renderer/tr_animation.c +++ b/MP/code/renderer/tr_animation.c @@ -353,8 +353,8 @@ void R_AddAnimSurfaces( trRefEntity_t *ent ) { if ( ent->e.renderfx & RF_BLINK ) { const char *s = va( "%s_b", surface->name ); // append '_b' for 'blink' for ( j = 0 ; j < skin->numSurfaces ; j++ ) { - if ( !strcmp( skin->surfaces[j]->name, s ) ) { - shader = skin->surfaces[j]->shader; + if ( !strcmp( skin->surfaces[j].name, s ) ) { + shader = skin->surfaces[j].shader; break; } } @@ -364,8 +364,8 @@ void R_AddAnimSurfaces( trRefEntity_t *ent ) { for ( j = 0 ; j < skin->numSurfaces ; j++ ) { // the names have both been lowercased - if ( !strcmp( skin->surfaces[j]->name, surface->name ) ) { - shader = skin->surfaces[j]->shader; + if ( !strcmp( skin->surfaces[j].name, surface->name ) ) { + shader = skin->surfaces[j].shader; break; } } @@ -1603,9 +1603,9 @@ void R_MDRAddAnimSurfaces( trRefEntity_t *ent ) { for(j = 0; j < skin->numSurfaces; j++) { - if (!strcmp(skin->surfaces[j]->name, surface->name)) + if (!strcmp(skin->surfaces[j].name, surface->name)) { - shader = skin->surfaces[j]->shader; + shader = skin->surfaces[j].shader; break; } } @@ -1636,7 +1636,11 @@ void R_MDRAddAnimSurfaces( trRefEntity_t *ent ) { R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, qfalse ); } - if (!personalModel) + // for testing polygon shadows (on /all/ models) + if ( r_shadows->integer == 4 ) + R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, qfalse ); + + if ( !personalModel ) R_AddDrawSurf( (void *)surface, shader, fogNum, qfalse ); surface = (mdrSurface_t *)( (byte *)surface + surface->ofsEnd ); diff --git a/MP/code/renderer/tr_cmesh.c b/MP/code/renderer/tr_cmesh.c index aca1fea..365e461 100644 --- a/MP/code/renderer/tr_cmesh.c +++ b/MP/code/renderer/tr_cmesh.c @@ -376,8 +376,8 @@ void R_AddMDCSurfaces( trRefEntity_t *ent ) { if ( ent->e.renderfx & RF_BLINK ) { const char *s = va( "%s_b", surface->name ); // append '_b' for 'blink' for ( j = 0 ; j < skin->numSurfaces ; j++ ) { - if ( !strcmp( skin->surfaces[j]->name, s ) ) { - shader = skin->surfaces[j]->shader; + if ( !strcmp( skin->surfaces[j].name, s ) ) { + shader = skin->surfaces[j].shader; break; } } @@ -387,8 +387,8 @@ void R_AddMDCSurfaces( trRefEntity_t *ent ) { for ( j = 0 ; j < skin->numSurfaces ; j++ ) { // the names have both been lowercased - if ( !strcmp( skin->surfaces[j]->name, surface->name ) ) { - shader = skin->surfaces[j]->shader; + if ( !strcmp( skin->surfaces[j].name, surface->name ) ) { + shader = skin->surfaces[j].shader; break; } } @@ -426,7 +426,6 @@ void R_AddMDCSurfaces( trRefEntity_t *ent ) { if ( r_shadows->integer == 4 ) { R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, qfalse ); } - //----(SA) done testing // don't add third_person objects if not viewing through a portal @@ -436,6 +435,5 @@ void R_AddMDCSurfaces( trRefEntity_t *ent ) { surface = ( mdcSurface_t * )( (byte *)surface + surface->ofsEnd ); } - } diff --git a/MP/code/renderer/tr_image.c b/MP/code/renderer/tr_image.c index 6b3ce45..402f117 100644 --- a/MP/code/renderer/tr_image.c +++ b/MP/code/renderer/tr_image.c @@ -1879,6 +1879,7 @@ RE_RegisterSkin =============== */ qhandle_t RE_RegisterSkin( const char *name ) { + skinSurface_t parseSurfaces[MAX_SKIN_SURFACES]; qhandle_t hSkin; skin_t *skin; skinSurface_t *surf; @@ -1935,8 +1936,8 @@ qhandle_t RE_RegisterSkin( const char *name ) { skin->numSurfaces = 0; skin->numModels = 0; //----(SA) added skin->numSurfaces = 1; - skin->surfaces[0] = ri.Hunk_Alloc( sizeof( *skin->surfaces[0] ), h_low ); - skin->surfaces[0]->shader = R_FindShader( name, LIGHTMAP_NONE, qtrue ); + skin->surfaces = ri.Hunk_Alloc( sizeof( skinSurface_t ), h_low ); + skin->surfaces[0].shader = R_FindShader( name, LIGHTMAP_NONE, qtrue ); return hSkin; } @@ -2006,12 +2007,12 @@ qhandle_t RE_RegisterSkin( const char *name ) { // parse the shader name token = CommaParse( &text_p ); - if ( skin->numSurfaces >= MD3_MAX_SURFACES ) { - ri.Printf( PRINT_WARNING, "WARNING: Ignoring surfaces in '%s', the max is %d surfaces!\n", name, MD3_MAX_SURFACES ); + if ( skin->numSurfaces >= MAX_SKIN_SURFACES ) { + ri.Printf( PRINT_WARNING, "WARNING: Ignoring surfaces in '%s', the max is %d surfaces!\n", name, MAX_SKIN_SURFACES ); break; } - surf = skin->surfaces[ skin->numSurfaces ] = ri.Hunk_Alloc( sizeof( *skin->surfaces[0] ), h_low ); + surf = &parseSurfaces[skin->numSurfaces]; Q_strncpyz( surf->name, surfName, sizeof( surf->name ) ); surf->shader = R_FindShader( token, LIGHTMAP_NONE, qtrue ); skin->numSurfaces++; @@ -2030,6 +2031,10 @@ qhandle_t RE_RegisterSkin( const char *name ) { } } + // copy surfaces to skin + skin->surfaces = ri.Hunk_Alloc( skin->numSurfaces * sizeof( skinSurface_t ), h_low ); + memcpy( skin->surfaces, parseSurfaces, skin->numSurfaces * sizeof( skinSurface_t ) ); + return hSkin; } @@ -2048,8 +2053,8 @@ void R_InitSkins( void ) { skin = tr.skins[0] = ri.Hunk_Alloc( sizeof( skin_t ), h_low ); Q_strncpyz( skin->name, "<default skin>", sizeof( skin->name ) ); skin->numSurfaces = 1; - skin->surfaces[0] = ri.Hunk_Alloc( sizeof( *skin->surfaces[0] ), h_low ); - skin->surfaces[0]->shader = tr.defaultShader; + skin->surfaces = ri.Hunk_Alloc( sizeof( skinSurface_t ), h_low ); + skin->surfaces[0].shader = tr.defaultShader; } /* @@ -2078,10 +2083,10 @@ void R_SkinList_f( void ) { for ( i = 0 ; i < tr.numSkins ; i++ ) { skin = tr.skins[i]; - ri.Printf( PRINT_ALL, "%3i:%s\n", i, skin->name ); + ri.Printf( PRINT_ALL, "%3i:%s (%d surfaces)\n", i, skin->name, skin->numSurfaces ); for ( j = 0 ; j < skin->numSurfaces ; j++ ) { ri.Printf( PRINT_ALL, " %s = %s\n", - skin->surfaces[j]->name, skin->surfaces[j]->shader->name ); + skin->surfaces[j].name, skin->surfaces[j].shader->name ); } } ri.Printf( PRINT_ALL, "------------------\n" ); diff --git a/MP/code/renderer/tr_local.h b/MP/code/renderer/tr_local.h index c036572..e0722f6 100644 --- a/MP/code/renderer/tr_local.h +++ b/MP/code/renderer/tr_local.h @@ -502,6 +502,12 @@ typedef struct { //================================================================================= +// max surfaces per-skin +// This is an arbitry limit. Vanilla Q3 only supported 32 surfaces in skins but failed to +// enforce the maximum limit when reading skin files. It was possile to use more than 32 +// surfaces which accessed out of bounds memory past end of skin->surfaces hunk block. +#define MAX_SKIN_SURFACES 256 + // skins allow models to be retextured without modifying the model file typedef struct { char name[MAX_QPATH]; @@ -512,17 +518,17 @@ typedef struct { #define MAX_PART_MODELS 5 typedef struct { - char type[MAX_QPATH]; // md3_lower, md3_lbelt, md3_rbelt, etc. - char model[MAX_QPATH]; // lower.md3, belt1.md3, etc. + char type[MAX_QPATH]; // md3_lower, md3_lbelt, md3_rbelt, etc. + char model[MAX_QPATH]; // lower.md3, belt1.md3, etc. } skinModel_t; typedef struct skin_s { - char name[MAX_QPATH]; // game path, including extension + char name[MAX_QPATH]; // game path, including extension int numSurfaces; int numModels; - skinSurface_t *surfaces[MD3_MAX_SURFACES]; + skinSurface_t *surfaces; // dynamically allocated array of surfaces skinModel_t *models[MAX_PART_MODELS]; - vec3_t scale; //----(SA) added + vec3_t scale; //----(SA) added } skin_t; //----(SA) end diff --git a/MP/code/renderer/tr_mesh.c b/MP/code/renderer/tr_mesh.c index e3deb99..8cf262c 100644 --- a/MP/code/renderer/tr_mesh.c +++ b/MP/code/renderer/tr_mesh.c @@ -378,8 +378,8 @@ void R_AddMD3Surfaces( trRefEntity_t *ent ) { if ( ent->e.renderfx & RF_BLINK ) { const char *s = va( "%s_b", surface->name ); // append '_b' for 'blink' for ( j = 0 ; j < skin->numSurfaces ; j++ ) { - if ( !strcmp( skin->surfaces[j]->name, s ) ) { - shader = skin->surfaces[j]->shader; + if ( !strcmp( skin->surfaces[j].name, s ) ) { + shader = skin->surfaces[j].shader; break; } } @@ -388,9 +388,8 @@ void R_AddMD3Surfaces( trRefEntity_t *ent ) { if ( shader == tr.defaultShader ) { // blink reference in skin was not found for ( j = 0 ; j < skin->numSurfaces ; j++ ) { // the names have both been lowercased - - if ( !strcmp( skin->surfaces[j]->name, surface->name ) ) { - shader = skin->surfaces[j]->shader; + if ( !strcmp( skin->surfaces[j].name, surface->name ) ) { + shader = skin->surfaces[j].shader; break; } } @@ -430,13 +429,11 @@ void R_AddMD3Surfaces( trRefEntity_t *ent ) { R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, qfalse ); } - // for testing polygon shadows (on /all/ models) if ( r_shadows->integer == 4 ) { R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, qfalse ); } - // don't add third_person objects if not viewing through a portal if ( !personalModel ) { R_AddDrawSurf( (void *)surface, shader, fogNum, qfalse ); @@ -444,6 +441,5 @@ void R_AddMD3Surfaces( trRefEntity_t *ent ) { surface = ( md3Surface_t * )( (byte *)surface + surface->ofsEnd ); } - } diff --git a/MP/code/renderer/tr_model_iqm.c b/MP/code/renderer/tr_model_iqm.c index b6f570e..370fc45 100644 --- a/MP/code/renderer/tr_model_iqm.c +++ b/MP/code/renderer/tr_model_iqm.c @@ -903,9 +903,9 @@ void R_AddIQMSurfaces( trRefEntity_t *ent ) { for(j = 0; j < skin->numSurfaces; j++) { - if (!strcmp(skin->surfaces[j]->name, surface->name)) + if (!strcmp(skin->surfaces[j].name, surface->name)) { - shader = skin->surfaces[j]->shader; + shader = skin->surfaces[j].shader; break; } } @@ -932,6 +932,11 @@ void R_AddIQMSurfaces( trRefEntity_t *ent ) { R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, 0 ); } + // for testing polygon shadows (on /all/ models) + if ( r_shadows->integer == 4 ) { + R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, qfalse ); + } + if( !personalModel ) { R_AddDrawSurf( (void *)surface, shader, fogNum, 0 ); } diff --git a/SP/code/rend2/tr_animation.c b/SP/code/rend2/tr_animation.c index 5d24a33..d7c9d7c 100644 --- a/SP/code/rend2/tr_animation.c +++ b/SP/code/rend2/tr_animation.c @@ -387,8 +387,8 @@ void R_AddAnimSurfaces( trRefEntity_t *ent ) { shader = tr.defaultShader; for ( j = 0 ; j < skin->numSurfaces ; j++ ) { // the names have both been lowercased - if ( !strcmp( skin->surfaces[j]->name, surface->name ) ) { - shader = skin->surfaces[j]->shader; + if ( !strcmp( skin->surfaces[j].name, surface->name ) ) { + shader = skin->surfaces[j].shader; break; } } @@ -1598,9 +1598,9 @@ void R_MDRAddAnimSurfaces( trRefEntity_t *ent ) { for(j = 0; j < skin->numSurfaces; j++) { - if (!strcmp(skin->surfaces[j]->name, surface->name)) + if (!strcmp(skin->surfaces[j].name, surface->name)) { - shader = skin->surfaces[j]->shader; + shader = skin->surfaces[j].shader; break; } } @@ -1631,7 +1631,11 @@ void R_MDRAddAnimSurfaces( trRefEntity_t *ent ) { R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, qfalse, qfalse, 0, ATI_TESS_TRUFORM ); } - if (!personalModel) + // for testing polygon shadows (on /all/ models) + if ( r_shadows->integer == 4 ) + R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, qfalse, qfalse, 0, ATI_TESS_TRUFORM ); + + if ( !personalModel ) R_AddDrawSurf( (void *)surface, shader, fogNum, qfalse, qfalse, cubemapIndex, ATI_TESS_TRUFORM ); surface = (mdrSurface_t *)( (byte *)surface + surface->ofsEnd ); diff --git a/SP/code/rend2/tr_image.c b/SP/code/rend2/tr_image.c index 56e8ab4..32b9c83 100644 --- a/SP/code/rend2/tr_image.c +++ b/SP/code/rend2/tr_image.c @@ -3228,6 +3228,7 @@ RE_RegisterSkin =============== */ qhandle_t RE_RegisterSkin( const char *name ) { + skinSurface_t parseSurfaces[MAX_SKIN_SURFACES]; qhandle_t hSkin; skin_t *skin; skinSurface_t *surf; @@ -3284,8 +3285,8 @@ qhandle_t RE_RegisterSkin( const char *name ) { skin->numSurfaces = 0; skin->numModels = 0; //----(SA) added skin->numSurfaces = 1; - skin->surfaces[0] = ri.Hunk_Alloc( sizeof( *skin->surfaces[0] ), h_low ); - skin->surfaces[0]->shader = R_FindShader( name, LIGHTMAP_NONE, qtrue ); + skin->surfaces = ri.Hunk_Alloc( sizeof( skinSurface_t ), h_low ); + skin->surfaces[0].shader = R_FindShader( name, LIGHTMAP_NONE, qtrue ); return hSkin; } @@ -3355,12 +3356,12 @@ qhandle_t RE_RegisterSkin( const char *name ) { // parse the shader name token = CommaParse( &text_p ); - if ( skin->numSurfaces >= MD3_MAX_SURFACES ) { - ri.Printf( PRINT_WARNING, "WARNING: Ignoring surfaces in '%s', the max is %d surfaces!\n", name, MD3_MAX_SURFACES ); + if ( skin->numSurfaces >= MAX_SKIN_SURFACES ) { + ri.Printf( PRINT_WARNING, "WARNING: Ignoring surfaces in '%s', the max is %d surfaces!\n", name, MAX_SKIN_SURFACES ); break; } - surf = skin->surfaces[ skin->numSurfaces ] = ri.Hunk_Alloc( sizeof( *skin->surfaces[0] ), h_low ); + surf = &parseSurfaces[skin->numSurfaces]; Q_strncpyz( surf->name, surfName, sizeof( surf->name ) ); surf->shader = R_FindShader( token, LIGHTMAP_NONE, qtrue ); skin->numSurfaces++; @@ -3379,6 +3380,10 @@ qhandle_t RE_RegisterSkin( const char *name ) { } } + // copy surfaces to skin + skin->surfaces = ri.Hunk_Alloc( skin->numSurfaces * sizeof( skinSurface_t ), h_low ); + memcpy( skin->surfaces, parseSurfaces, skin->numSurfaces * sizeof( skinSurface_t ) ); + return hSkin; } @@ -3397,8 +3402,8 @@ void R_InitSkins( void ) { skin = tr.skins[0] = ri.Hunk_Alloc( sizeof( skin_t ), h_low ); Q_strncpyz( skin->name, "<default skin>", sizeof( skin->name ) ); skin->numSurfaces = 1; - skin->surfaces[0] = ri.Hunk_Alloc( sizeof( *skin->surfaces[0] ), h_low ); - skin->surfaces[0]->shader = tr.defaultShader; + skin->surfaces = ri.Hunk_Alloc( sizeof( skinSurface_t ), h_low ); + skin->surfaces[0].shader = tr.defaultShader; } /* @@ -3427,10 +3432,10 @@ void R_SkinList_f( void ) { for ( i = 0 ; i < tr.numSkins ; i++ ) { skin = tr.skins[i]; - ri.Printf( PRINT_ALL, "%3i:%s\n", i, skin->name ); + ri.Printf( PRINT_ALL, "%3i:%s (%d surfaces)\n", i, skin->name, skin->numSurfaces ); for ( j = 0 ; j < skin->numSurfaces ; j++ ) { ri.Printf( PRINT_ALL, " %s = %s\n", - skin->surfaces[j]->name, skin->surfaces[j]->shader->name ); + skin->surfaces[j].name, skin->surfaces[j].shader->name ); } } ri.Printf( PRINT_ALL, "------------------\n" ); diff --git a/SP/code/rend2/tr_local.h b/SP/code/rend2/tr_local.h index 73b22c1..cf78ef2 100644 --- a/SP/code/rend2/tr_local.h +++ b/SP/code/rend2/tr_local.h @@ -864,6 +864,12 @@ typedef struct { //================================================================================= +// max surfaces per-skin +// This is an arbitry limit. Vanilla Q3 only supported 32 surfaces in skins but failed to +// enforce the maximum limit when reading skin files. It was possile to use more than 32 +// surfaces which accessed out of bounds memory past end of skin->surfaces hunk block. +#define MAX_SKIN_SURFACES 256 + // skins allow models to be retextured without modifying the model file typedef struct { char name[MAX_QPATH]; @@ -874,17 +880,17 @@ typedef struct { #define MAX_PART_MODELS 5 typedef struct { - char type[MAX_QPATH]; // md3_lower, md3_lbelt, md3_rbelt, etc. - char model[MAX_QPATH]; // lower.md3, belt1.md3, etc. + char type[MAX_QPATH]; // md3_lower, md3_lbelt, md3_rbelt, etc. + char model[MAX_QPATH]; // lower.md3, belt1.md3, etc. } skinModel_t; typedef struct skin_s { - char name[MAX_QPATH]; // game path, including extension + char name[MAX_QPATH]; // game path, including extension int numSurfaces; int numModels; - skinSurface_t *surfaces[MD3_MAX_SURFACES]; + skinSurface_t *surfaces; // dynamically allocated array of surfaces skinModel_t *models[MAX_PART_MODELS]; - vec3_t scale; //----(SA) added + vec3_t scale; //----(SA) added } skin_t; //----(SA) end diff --git a/SP/code/rend2/tr_mesh.c b/SP/code/rend2/tr_mesh.c index 15902d6..bbfbc69 100644 --- a/SP/code/rend2/tr_mesh.c +++ b/SP/code/rend2/tr_mesh.c @@ -411,8 +411,8 @@ void R_AddMD3Surfaces( trRefEntity_t *ent ) { shader = tr.defaultShader; for ( j = 0 ; j < skin->numSurfaces ; j++ ) { // the names have both been lowercased - if ( !strcmp( skin->surfaces[j]->name, surface->name ) ) { - shader = skin->surfaces[j]->shader; + if ( !strcmp( skin->surfaces[j].name, surface->name ) ) { + shader = skin->surfaces[j].shader; break; } } diff --git a/SP/code/rend2/tr_model_iqm.c b/SP/code/rend2/tr_model_iqm.c index deabf42..5274c0e 100644 --- a/SP/code/rend2/tr_model_iqm.c +++ b/SP/code/rend2/tr_model_iqm.c @@ -907,9 +907,9 @@ void R_AddIQMSurfaces( trRefEntity_t *ent ) { for(j = 0; j < skin->numSurfaces; j++) { - if (!strcmp(skin->surfaces[j]->name, surface->name)) + if (!strcmp(skin->surfaces[j].name, surface->name)) { - shader = skin->surfaces[j]->shader; + shader = skin->surfaces[j].shader; break; } } @@ -936,6 +936,11 @@ void R_AddIQMSurfaces( trRefEntity_t *ent ) { R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, 0, 0, 0, ATI_TESS_TRUFORM ); } + // for testing polygon shadows (on /all/ models) + if ( r_shadows->integer == 4 ) { + R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, qfalse, qfalse, 0, ATI_TESS_TRUFORM ); + } + if( !personalModel ) { R_AddDrawSurf( (void *)surface, shader, fogNum, 0, 0, cubemapIndex, ATI_TESS_TRUFORM ); } diff --git a/SP/code/renderer/tr_animation.c b/SP/code/renderer/tr_animation.c index e0f4bc6..8b31d55 100644 --- a/SP/code/renderer/tr_animation.c +++ b/SP/code/renderer/tr_animation.c @@ -385,8 +385,8 @@ void R_AddAnimSurfaces( trRefEntity_t *ent ) { shader = tr.defaultShader; for ( j = 0 ; j < skin->numSurfaces ; j++ ) { // the names have both been lowercased - if ( !strcmp( skin->surfaces[j]->name, surface->name ) ) { - shader = skin->surfaces[j]->shader; + if ( !strcmp( skin->surfaces[j].name, surface->name ) ) { + shader = skin->surfaces[j].shader; break; } } @@ -1593,9 +1593,9 @@ void R_MDRAddAnimSurfaces( trRefEntity_t *ent ) { for(j = 0; j < skin->numSurfaces; j++) { - if (!strcmp(skin->surfaces[j]->name, surface->name)) + if (!strcmp(skin->surfaces[j].name, surface->name)) { - shader = skin->surfaces[j]->shader; + shader = skin->surfaces[j].shader; break; } } @@ -1626,7 +1626,11 @@ void R_MDRAddAnimSurfaces( trRefEntity_t *ent ) { R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, qfalse, ATI_TESS_TRUFORM ); } - if (!personalModel) + // for testing polygon shadows (on /all/ models) + if ( r_shadows->integer == 4 ) + R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, qfalse, ATI_TESS_TRUFORM ); + + if ( !personalModel ) R_AddDrawSurf( (void *)surface, shader, fogNum, qfalse, ATI_TESS_TRUFORM ); surface = (mdrSurface_t *)( (byte *)surface + surface->ofsEnd ); diff --git a/SP/code/renderer/tr_cmesh.c b/SP/code/renderer/tr_cmesh.c index 607251f..23550ad 100644 --- a/SP/code/renderer/tr_cmesh.c +++ b/SP/code/renderer/tr_cmesh.c @@ -407,8 +407,8 @@ void R_AddMDCSurfaces( trRefEntity_t *ent ) { shader = tr.defaultShader; for ( j = 0 ; j < skin->numSurfaces ; j++ ) { // the names have both been lowercased - if ( !strcmp( skin->surfaces[j]->name, surface->name ) ) { - shader = skin->surfaces[j]->shader; + if ( !strcmp( skin->surfaces[j].name, surface->name ) ) { + shader = skin->surfaces[j].shader; break; } } @@ -433,20 +433,18 @@ void R_AddMDCSurfaces( trRefEntity_t *ent ) { R_AddDrawSurf( (void *)surface, tr.shadowShader, 0, qfalse, tr.currentModel->ATI_tess ); } -//----(SA) - // projection shadows work fine with personal models -// if ( r_shadows->integer == 3 -// && fogNum == 0 -// && (ent->e.renderfx & RF_SHADOW_PLANE ) -// && shader->sort == SS_OPAQUE ) { -// R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, qfalse ); -// } + if ( r_shadows->integer == 3 + && fogNum == 0 + && (ent->e.renderfx & RF_SHADOW_PLANE ) + && shader->sort == SS_OPAQUE ) { + R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, qfalse, tr.currentModel->ATI_tess ); + } //----(SA) for testing polygon shadows (on /all/ models) -// if ( r_shadows->integer == 4) -// R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, qfalse ); - + if ( r_shadows->integer == 4 ) { + R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, qfalse, tr.currentModel->ATI_tess ); + } //----(SA) done testing // don't add third_person objects if not viewing through a portal @@ -457,6 +455,5 @@ void R_AddMDCSurfaces( trRefEntity_t *ent ) { surface = ( mdcSurface_t * )( (byte *)surface + surface->ofsEnd ); } - } diff --git a/SP/code/renderer/tr_image.c b/SP/code/renderer/tr_image.c index 2893b58..2ce4d6d 100644 --- a/SP/code/renderer/tr_image.c +++ b/SP/code/renderer/tr_image.c @@ -1950,6 +1950,7 @@ RE_RegisterSkin =============== */ qhandle_t RE_RegisterSkin( const char *name ) { + skinSurface_t parseSurfaces[MAX_SKIN_SURFACES]; qhandle_t hSkin; skin_t *skin; skinSurface_t *surf; @@ -2006,8 +2007,8 @@ qhandle_t RE_RegisterSkin( const char *name ) { skin->numSurfaces = 0; skin->numModels = 0; //----(SA) added skin->numSurfaces = 1; - skin->surfaces[0] = ri.Hunk_Alloc( sizeof( *skin->surfaces[0] ), h_low ); - skin->surfaces[0]->shader = R_FindShader( name, LIGHTMAP_NONE, qtrue ); + skin->surfaces = ri.Hunk_Alloc( sizeof( skinSurface_t ), h_low ); + skin->surfaces[0].shader = R_FindShader( name, LIGHTMAP_NONE, qtrue ); return hSkin; } @@ -2077,12 +2078,12 @@ qhandle_t RE_RegisterSkin( const char *name ) { // parse the shader name token = CommaParse( &text_p ); - if ( skin->numSurfaces >= MD3_MAX_SURFACES ) { - ri.Printf( PRINT_WARNING, "WARNING: Ignoring surfaces in '%s', the max is %d surfaces!\n", name, MD3_MAX_SURFACES ); + if ( skin->numSurfaces >= MAX_SKIN_SURFACES ) { + ri.Printf( PRINT_WARNING, "WARNING: Ignoring surfaces in '%s', the max is %d surfaces!\n", name, MAX_SKIN_SURFACES ); break; } - surf = skin->surfaces[ skin->numSurfaces ] = ri.Hunk_Alloc( sizeof( *skin->surfaces[0] ), h_low ); + surf = &parseSurfaces[skin->numSurfaces]; Q_strncpyz( surf->name, surfName, sizeof( surf->name ) ); surf->shader = R_FindShader( token, LIGHTMAP_NONE, qtrue ); skin->numSurfaces++; @@ -2101,6 +2102,10 @@ qhandle_t RE_RegisterSkin( const char *name ) { } } + // copy surfaces to skin + skin->surfaces = ri.Hunk_Alloc( skin->numSurfaces * sizeof( skinSurface_t ), h_low ); + memcpy( skin->surfaces, parseSurfaces, skin->numSurfaces * sizeof( skinSurface_t ) ); + return hSkin; } @@ -2119,8 +2124,8 @@ void R_InitSkins( void ) { skin = tr.skins[0] = ri.Hunk_Alloc( sizeof( skin_t ), h_low ); Q_strncpyz( skin->name, "<default skin>", sizeof( skin->name ) ); skin->numSurfaces = 1; - skin->surfaces[0] = ri.Hunk_Alloc( sizeof( *skin->surfaces[0] ), h_low ); - skin->surfaces[0]->shader = tr.defaultShader; + skin->surfaces = ri.Hunk_Alloc( sizeof( skinSurface_t ), h_low ); + skin->surfaces[0].shader = tr.defaultShader; } /* @@ -2149,10 +2154,10 @@ void R_SkinList_f( void ) { for ( i = 0 ; i < tr.numSkins ; i++ ) { skin = tr.skins[i]; - ri.Printf( PRINT_ALL, "%3i:%s\n", i, skin->name ); + ri.Printf( PRINT_ALL, "%3i:%s (%d surfaces)\n", i, skin->name, skin->numSurfaces ); for ( j = 0 ; j < skin->numSurfaces ; j++ ) { ri.Printf( PRINT_ALL, " %s = %s\n", - skin->surfaces[j]->name, skin->surfaces[j]->shader->name ); + skin->surfaces[j].name, skin->surfaces[j].shader->name ); } } ri.Printf( PRINT_ALL, "------------------\n" ); diff --git a/SP/code/renderer/tr_local.h b/SP/code/renderer/tr_local.h index a23037d..a53ee2f 100644 --- a/SP/code/renderer/tr_local.h +++ b/SP/code/renderer/tr_local.h @@ -506,6 +506,12 @@ typedef struct { //================================================================================= +// max surfaces per-skin +// This is an arbitry limit. Vanilla Q3 only supported 32 surfaces in skins but failed to +// enforce the maximum limit when reading skin files. It was possile to use more than 32 +// surfaces which accessed out of bounds memory past end of skin->surfaces hunk block. +#define MAX_SKIN_SURFACES 256 + // skins allow models to be retextured without modifying the model file typedef struct { char name[MAX_QPATH]; @@ -516,17 +522,17 @@ typedef struct { #define MAX_PART_MODELS 5 typedef struct { - char type[MAX_QPATH]; // md3_lower, md3_lbelt, md3_rbelt, etc. - char model[MAX_QPATH]; // lower.md3, belt1.md3, etc. + char type[MAX_QPATH]; // md3_lower, md3_lbelt, md3_rbelt, etc. + char model[MAX_QPATH]; // lower.md3, belt1.md3, etc. } skinModel_t; typedef struct skin_s { - char name[MAX_QPATH]; // game path, including extension + char name[MAX_QPATH]; // game path, including extension int numSurfaces; int numModels; - skinSurface_t *surfaces[MD3_MAX_SURFACES]; + skinSurface_t *surfaces; // dynamically allocated array of surfaces skinModel_t *models[MAX_PART_MODELS]; - vec3_t scale; //----(SA) added + vec3_t scale; //----(SA) added } skin_t; //----(SA) end diff --git a/SP/code/renderer/tr_mesh.c b/SP/code/renderer/tr_mesh.c index 5f016a4..5390c57 100644 --- a/SP/code/renderer/tr_mesh.c +++ b/SP/code/renderer/tr_mesh.c @@ -406,8 +406,8 @@ void R_AddMD3Surfaces( trRefEntity_t *ent ) { shader = tr.defaultShader; for ( j = 0 ; j < skin->numSurfaces ; j++ ) { // the names have both been lowercased - if ( !strcmp( skin->surfaces[j]->name, surface->name ) ) { - shader = skin->surfaces[j]->shader; + if ( !strcmp( skin->surfaces[j].name, surface->name ) ) { + shader = skin->surfaces[j].shader; break; } } @@ -439,18 +439,17 @@ void R_AddMD3Surfaces( trRefEntity_t *ent ) { } // projection shadows work fine with personal models -// if ( r_shadows->integer == 3 -// && fogNum == 0 -// && (ent->e.renderfx & RF_SHADOW_PLANE ) -// && shader->sort == SS_OPAQUE ) { -// R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, qfalse ); -// } - + if ( r_shadows->integer == 3 + && fogNum == 0 + && (ent->e.renderfx & RF_SHADOW_PLANE ) + && shader->sort == SS_OPAQUE ) { + R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, qfalse, tr.currentModel->ATI_tess ); + } // for testing polygon shadows (on /all/ models) -// if ( r_shadows->integer == 4) -// R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, qfalse ); - + if ( r_shadows->integer == 4 ) { + R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, qfalse, tr.currentModel->ATI_tess ); + } // don't add third_person objects if not viewing through a portal if ( !personalModel ) { @@ -460,6 +459,5 @@ void R_AddMD3Surfaces( trRefEntity_t *ent ) { surface = ( md3Surface_t * )( (byte *)surface + surface->ofsEnd ); } - } diff --git a/SP/code/renderer/tr_model_iqm.c b/SP/code/renderer/tr_model_iqm.c index 5ab41c2..b1ab522 100644 --- a/SP/code/renderer/tr_model_iqm.c +++ b/SP/code/renderer/tr_model_iqm.c @@ -903,9 +903,9 @@ void R_AddIQMSurfaces( trRefEntity_t *ent ) { for(j = 0; j < skin->numSurfaces; j++) { - if (!strcmp(skin->surfaces[j]->name, surface->name)) + if (!strcmp(skin->surfaces[j].name, surface->name)) { - shader = skin->surfaces[j]->shader; + shader = skin->surfaces[j].shader; break; } } @@ -932,6 +932,11 @@ void R_AddIQMSurfaces( trRefEntity_t *ent ) { R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, 0, ATI_TESS_TRUFORM ); } + // for testing polygon shadows (on /all/ models) + if ( r_shadows->integer == 4 ) { + R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, qfalse, ATI_TESS_TRUFORM ); + } + if( !personalModel ) { R_AddDrawSurf( (void *)surface, shader, fogNum, 0, ATI_TESS_TRUFORM ); } -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/iortcw.git _______________________________________________ Pkg-games-commits mailing list Pkg-games-commits@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-games-commits