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

Reply via email to