]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - model_alias.c
fixed some dynamic lighting bugs related to glowing self
[xonotic/darkplaces.git] / model_alias.c
index 9debb5387a21283b131028c919c664bb4820761f..9adc1b7792763ff795fe4b46b1a1082838851bf3 100644 (file)
@@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
 
 #include "quakedef.h"
+#include "image.h"
 
 static cvar_t r_mipskins = {CVAR_SAVE, "r_mipskins", "0"};
 
@@ -155,92 +156,52 @@ static void Mod_MDL_LoadFrames (qbyte * datapointer, int inverts, int outverts,
        }
 }
 
-static rtexture_t *GL_SkinSplitShirt(qbyte *in, qbyte *out, int width, int height, int bits, char *name, int precache)
+static rtexture_t *GL_TextureForSkinLayer(const qbyte *in, int width, int height, const char *name, const unsigned int *palette, int precache)
 {
-       int i, pixels, passed;
-       qbyte pixeltest[16];
-       for (i = 0;i < 16;i++)
-               pixeltest[i] = (bits & (1 << i)) != 0;
-       pixels = width*height;
-       passed = 0;
-       while(pixels--)
-       {
-               if (pixeltest[*in >> 4] && *in != 0 && *in != 255)
-               {
-                       passed++;
-                       // turn to white while copying
-                       if (*in >= 128 && *in < 224) // backwards ranges
-                               *out = (*in & 15) ^ 15;
-                       else
-                               *out = *in & 15;
-               }
-               else
-                       *out = 0;
-               in++;
-               out++;
-       }
-       if (passed)
-               return R_LoadTexture (loadmodel->texturepool, name, width, height, out - width*height, TEXTYPE_QPALETTE, (r_mipskins.integer ? TEXF_MIPMAP : 0) | (precache ? TEXF_PRECACHE : 0));
-       else
-               return NULL;
-}
-
-static rtexture_t *GL_SkinSplit(qbyte *in, qbyte *out, int width, int height, int bits, char *name, int precache)
-{
-       int i, pixels, passed;
-       qbyte pixeltest[16];
-       for (i = 0;i < 16;i++)
-               pixeltest[i] = (bits & (1 << i)) != 0;
-       pixels = width*height;
-       passed = 0;
-       while(pixels--)
-       {
-               if (pixeltest[*in >> 4] && *in != 0 && *in != 255)
-               {
-                       passed++;
-                       *out = *in;
-               }
-               else
-                       *out = 0;
-               in++;
-               out++;
-       }
-       if (passed)
-               return R_LoadTexture (loadmodel->texturepool, name, width, height, out - width*height, TEXTYPE_QPALETTE, (r_mipskins.integer ? TEXF_MIPMAP : 0) | (precache ? TEXF_PRECACHE : 0));
-       else
-               return NULL;
+       int i;
+       for (i = 0;i < width*height;i++)
+               if (((qbyte *)&palette[in[i]])[3] > 0)
+                       return R_LoadTexture2D (loadmodel->texturepool, name, width, height, in, TEXTYPE_PALETTE, (r_mipskins.integer ? TEXF_MIPMAP : 0) | (precache ? TEXF_PRECACHE : 0), palette);
+       return NULL;
 }
 
 static int Mod_LoadExternalSkin (char *basename, skinframe_t *skinframe, int precache)
 {
-       skinframe->base   = loadtextureimagewithmask(loadmodel->texturepool, va("%s_normal", basename), 0, 0, false, r_mipskins.integer, precache);
-       skinframe->fog    = image_masktex;
+       skinframe->base   = loadtextureimagewithmaskandnmap(loadmodel->texturepool, va("%s_normal", basename), 0, 0, false, TEXF_ALPHA | (precache ? TEXF_PRECACHE : 0) | (r_mipskins.integer ? TEXF_MIPMAP : 0), 1);
        if (!skinframe->base)
-       {
-               skinframe->base   = loadtextureimagewithmask(loadmodel->texturepool, basename, 0, 0, false, r_mipskins.integer, precache);
-               skinframe->fog    = image_masktex;
-       }
-       skinframe->pants  = loadtextureimage(loadmodel->texturepool, va("%s_pants" , basename), 0, 0, false, r_mipskins.integer, precache);
-       skinframe->shirt  = loadtextureimage(loadmodel->texturepool, va("%s_shirt" , basename), 0, 0, false, r_mipskins.integer, precache);
-       skinframe->glow   = loadtextureimage(loadmodel->texturepool, va("%s_glow"  , basename), 0, 0, false, r_mipskins.integer, precache);
+               skinframe->base   = loadtextureimagewithmaskandnmap(loadmodel->texturepool, basename, 0, 0, false, TEXF_ALPHA | (precache ? TEXF_PRECACHE : 0) | (r_mipskins.integer ? TEXF_MIPMAP : 0), 1);
+       skinframe->fog    = image_masktex;
+       skinframe->nmap   = image_nmaptex;
+       skinframe->gloss  = loadtextureimage(loadmodel->texturepool, va("%s_gloss" , basename), 0, 0, false, TEXF_ALPHA | (precache ? TEXF_PRECACHE : 0) | (r_mipskins.integer ? TEXF_MIPMAP : 0));
+       skinframe->pants  = loadtextureimage(loadmodel->texturepool, va("%s_pants" , basename), 0, 0, false, TEXF_ALPHA | (precache ? TEXF_PRECACHE : 0) | (r_mipskins.integer ? TEXF_MIPMAP : 0));
+       skinframe->shirt  = loadtextureimage(loadmodel->texturepool, va("%s_shirt" , basename), 0, 0, false, TEXF_ALPHA | (precache ? TEXF_PRECACHE : 0) | (r_mipskins.integer ? TEXF_MIPMAP : 0));
+       skinframe->glow   = loadtextureimage(loadmodel->texturepool, va("%s_glow"  , basename), 0, 0, false, TEXF_ALPHA | (precache ? TEXF_PRECACHE : 0) | (r_mipskins.integer ? TEXF_MIPMAP : 0));
        skinframe->merged = NULL;
        return skinframe->base != NULL || skinframe->pants != NULL || skinframe->shirt != NULL || skinframe->glow != NULL;
 }
 
-static int Mod_LoadInternalSkin (char *basename, qbyte *skindata, qbyte *skintemp, int width, int height, skinframe_t *skinframe, int precache)
+static int Mod_LoadInternalSkin (char *basename, qbyte *skindata, int width, int height, skinframe_t *skinframe, int precache)
 {
-       if (!skindata || !skintemp)
+       qbyte *temp1, *temp2;
+       if (!skindata)
                return false;
-       skinframe->pants  = GL_SkinSplitShirt(skindata, skintemp, width, height, 0x0040, va("%s_pants", basename), false); // pants
-       skinframe->shirt  = GL_SkinSplitShirt(skindata, skintemp, width, height, 0x0002, va("%s_shirt", basename), false); // shirt
-       skinframe->glow   = GL_SkinSplit     (skindata, skintemp, width, height, 0xC000, va("%s_glow", basename), precache); // glow
+       temp1 = Mem_Alloc(loadmodel->mempool, width * height * 8);
+       temp2 = temp1 + width * height * 4;
+       Image_Copy8bitRGBA(skindata, temp1, width * height, palette_nofullbrights);
+       Image_HeightmapToNormalmap(temp1, temp2, width, height, false, 1);
+       skinframe->nmap   = R_LoadTexture2D(loadmodel->texturepool, va("%s_nmap", basename), width, height, temp2, TEXTYPE_RGBA, (r_mipskins.integer ? TEXF_MIPMAP : 0) | (precache ? TEXF_PRECACHE : 0), NULL);
+       Mem_Free(temp1);
+       skinframe->gloss  = NULL;
+       skinframe->pants  = GL_TextureForSkinLayer(skindata, width, height, va("%s_pants", basename), palette_pantsaswhite, false); // pants
+       skinframe->shirt  = GL_TextureForSkinLayer(skindata, width, height, va("%s_shirt", basename), palette_shirtaswhite, false); // shirt
+       skinframe->glow   = GL_TextureForSkinLayer(skindata, width, height, va("%s_glow", basename), palette_onlyfullbrights, precache); // glow
        if (skinframe->pants || skinframe->shirt)
        {
-               skinframe->base   = GL_SkinSplit (skindata, skintemp, width, height, 0x3FBD, va("%s_normal", basename), false); // normal (no special colors)
-               skinframe->merged = GL_SkinSplit (skindata, skintemp, width, height, 0x3FFF, va("%s_body", basename), precache); // body (normal + pants + shirt, but not glow)
+               skinframe->base   = GL_TextureForSkinLayer(skindata, width, height, va("%s_normal", basename), palette_nocolormapnofullbrights, false); // normal (no special colors)
+               skinframe->merged = GL_TextureForSkinLayer(skindata, width, height, va("%s_body", basename), palette_nofullbrights, precache); // body (normal + pants + shirt, but not glow)
        }
        else
-               skinframe->base   = GL_SkinSplit (skindata, skintemp, width, height, 0x3FFF, va("%s_base", basename), precache); // no special colors
+               skinframe->base   = GL_TextureForSkinLayer(skindata, width, height, va("%s_base", basename), palette_nofullbrights, precache); // no special colors
        // quake model skins don't have alpha
        skinframe->fog = NULL;
        return true;
@@ -250,10 +211,8 @@ static int Mod_LoadInternalSkin (char *basename, qbyte *skindata, qbyte *skintem
 #define BOUNDF(VALUE,MIN,MAX) if (VALUE < MIN || VALUE >= MAX) Host_Error("model %s has an invalid ##VALUE (%f exceeds %f - %f)\n", loadmodel->name, VALUE, MIN, MAX);
 extern void R_Model_Alias_Draw(entity_render_t *ent);
 extern void R_Model_Alias_DrawFakeShadow(entity_render_t *ent);
-extern void R_Model_Alias_DrawDepth(entity_render_t *ent);
-extern void R_Model_Alias_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, int visiblevolume);
-extern void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, float lightradius2, float lightdistbias, float lightsubtract, float *lightcolor);
-extern void R_Model_Alias_DrawOntoLight(entity_render_t *ent);
+extern void R_Model_Alias_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius);
+extern void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius2, float lightdistbias, float lightsubtract, float *lightcolor);
 void Mod_LoadAliasModel (model_t *mod, void *buffer)
 {
        int                                             i, j, version, numverts, totalposes, totalskins, skinwidth, skinheight, totalverts, groupframes, groupskins;
@@ -268,7 +227,6 @@ void Mod_LoadAliasModel (model_t *mod, void *buffer)
        float                                   scales, scalet, scale[3], translate[3], interval;
        qbyte                                   *datapointer, *startframes, *startskins;
        char                                    name[MAX_QPATH];
-       qbyte                                   *skintemp = NULL;
        skinframe_t                             tempskinframe;
        animscene_t                             *tempskinscenes;
        skinframe_t                             *tempskinframes;
@@ -289,10 +247,8 @@ void Mod_LoadAliasModel (model_t *mod, void *buffer)
        loadmodel->DrawSky = NULL;
        loadmodel->Draw = R_Model_Alias_Draw;
        loadmodel->DrawFakeShadow = R_Model_Alias_DrawFakeShadow;
-       loadmodel->DrawDepth = R_Model_Alias_DrawDepth;
        loadmodel->DrawShadowVolume = R_Model_Alias_DrawShadowVolume;
        loadmodel->DrawLight = R_Model_Alias_DrawLight;
-       loadmodel->DrawOntoLight = R_Model_Alias_DrawOntoLight;
 
        loadmodel->numskins = LittleLong(pinmodel->numskins);
        BOUNDI(loadmodel->numskins,0,256);
@@ -370,7 +326,6 @@ void Mod_LoadAliasModel (model_t *mod, void *buffer)
        }
 
        // load the skins
-       skintemp = Mem_Alloc(tempmempool, skinwidth * skinheight);
        loadmodel->skinscenes = Mem_Alloc(loadmodel->mempool, loadmodel->numskins * sizeof(animscene_t));
        loadmodel->skinframes = Mem_Alloc(loadmodel->mempool, totalskins * sizeof(skinframe_t));
        totalskins = 0;
@@ -413,12 +368,11 @@ void Mod_LoadAliasModel (model_t *mod, void *buffer)
                        else
                                sprintf (name, "%s_%i", loadmodel->name, i);
                        if (!Mod_LoadExternalSkin(name, loadmodel->skinframes + totalskins, i == 0))
-                               Mod_LoadInternalSkin(name, (qbyte *)datapointer, skintemp, skinwidth, skinheight, loadmodel->skinframes + totalskins, i == 0);
+                               Mod_LoadInternalSkin(name, (qbyte *)datapointer, skinwidth, skinheight, loadmodel->skinframes + totalskins, i == 0);
                        datapointer += skinwidth * skinheight;
                        totalskins++;
                }
        }
-       Mem_Free(skintemp);
        // check for skins that don't exist in the model, but do exist as external images
        // (this was added because yummyluv kept pestering me about support for it)
        for (;;)
@@ -616,10 +570,8 @@ void Mod_LoadQ2AliasModel (model_t *mod, void *buffer)
        loadmodel->DrawSky = NULL;
        loadmodel->Draw = R_Model_Alias_Draw;
        loadmodel->DrawFakeShadow = R_Model_Alias_DrawFakeShadow;
-       loadmodel->DrawDepth = R_Model_Alias_DrawDepth;
        loadmodel->DrawShadowVolume = R_Model_Alias_DrawShadowVolume;
        loadmodel->DrawLight = R_Model_Alias_DrawLight;
-       loadmodel->DrawOntoLight = R_Model_Alias_DrawOntoLight;
 
        if (LittleLong(pinmodel->num_tris < 1) || LittleLong(pinmodel->num_tris) > MD2MAX_TRIANGLES)
                Host_Error ("%s has invalid number of triangles: %i", loadmodel->name, LittleLong(pinmodel->num_tris));
@@ -655,16 +607,18 @@ void Mod_LoadQ2AliasModel (model_t *mod, void *buffer)
        inskin = (void*)(base + LittleLong(pinmodel->ofs_skins));
        if (loadmodel->numskins)
        {
-               loadmodel->skinscenes = Mem_Alloc(loadmodel->mempool, sizeof(animscene_t) * loadmodel->numskins);
-               loadmodel->skinframes = Mem_Alloc(loadmodel->mempool, sizeof(skinframe_t) * loadmodel->numskins);
+               loadmodel->skinscenes = Mem_Alloc(loadmodel->mempool, sizeof(animscene_t) * loadmodel->numskins + sizeof(skinframe_t) * loadmodel->numskins);
+               loadmodel->skinframes = (void *)(loadmodel->skinscenes + loadmodel->numskins);
                for (i = 0;i < loadmodel->numskins;i++)
                {
                        loadmodel->skinscenes[i].firstframe = i;
                        loadmodel->skinscenes[i].framecount = 1;
                        loadmodel->skinscenes[i].loop = true;
                        loadmodel->skinscenes[i].framerate = 10;
-                       loadmodel->skinframes[i].base = loadtextureimagewithmask (loadmodel->texturepool, inskin, 0, 0, true, r_mipskins.integer, true);
+                       loadmodel->skinframes[i].base = loadtextureimagewithmaskandnmap (loadmodel->texturepool, inskin, 0, 0, true, TEXF_ALPHA | TEXF_PRECACHE | (r_mipskins.integer ? TEXF_MIPMAP : 0), 1);
                        loadmodel->skinframes[i].fog = image_masktex;
+                       loadmodel->skinframes[i].nmap = image_nmaptex;
+                       loadmodel->skinframes[i].gloss = NULL;
                        loadmodel->skinframes[i].pants = NULL;
                        loadmodel->skinframes[i].shirt = NULL;
                        loadmodel->skinframes[i].glow = NULL;
@@ -806,28 +760,18 @@ void Mod_LoadQ2AliasModel (model_t *mod, void *buffer)
        Mod_BuildTriangleNeighbors(loadmodel->mdlmd2data_triangleneighbors, loadmodel->mdlmd2data_indices, loadmodel->numtris);
 }
 
-static void zymswapintblock(int *m, int size)
-{
-       size /= 4;
-       while(size--)
-       {
-               *m = BigLong(*m);
-               m++;
-       }
-}
-
 extern void R_Model_Zymotic_DrawSky(entity_render_t *ent);
 extern void R_Model_Zymotic_Draw(entity_render_t *ent);
 extern void R_Model_Zymotic_DrawFakeShadow(entity_render_t *ent);
-extern void R_Model_Zymotic_DrawDepth(entity_render_t *ent);
-extern void R_Model_Zymotic_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, int visiblevolume);
-extern void R_Model_Zymotic_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, float lightradius2, float lightdistbias, float lightsubtract, float *lightcolor);
-extern void R_Model_Zymotic_DrawOntoLight(entity_render_t *ent);
+extern void R_Model_Zymotic_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius);
+extern void R_Model_Zymotic_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius2, float lightdistbias, float lightsubtract, float *lightcolor);
 void Mod_LoadZymoticModel(model_t *mod, void *buffer)
 {
        zymtype1header_t *pinmodel, *pheader;
+       qbyte *pbase;
 
        pinmodel = (void *)buffer;
+       pbase = buffer;
        if (memcmp(pinmodel->id, "ZYMOTICMODEL", 12))
                Host_Error ("Mod_LoadZymoticModel: %s is not a zymotic model\n");
        if (BigLong(pinmodel->type) != 1)
@@ -838,10 +782,8 @@ void Mod_LoadZymoticModel(model_t *mod, void *buffer)
        loadmodel->DrawSky = NULL;
        loadmodel->Draw = R_Model_Zymotic_Draw;
        loadmodel->DrawFakeShadow = NULL;//R_Model_Zymotic_DrawFakeShadow;
-       loadmodel->DrawDepth = NULL;//R_Model_Zymotic_DrawDepth;
        loadmodel->DrawShadowVolume = NULL;//R_Model_Zymotic_DrawShadowVolume;
        loadmodel->DrawLight = NULL;//R_Model_Zymotic_DrawLight;
-       loadmodel->DrawOntoLight = NULL;//R_Model_Zymotic_DrawOntoLight;
 
        // byteswap header
        pheader = pinmodel;
@@ -932,7 +874,7 @@ void Mod_LoadZymoticModel(model_t *mod, void *buffer)
                zymscene_t *scene;
        //      zymlump_t lump_scenes; // zymscene_t scene[numscenes]; // name and other information for each scene (see zymscene struct)
                loadmodel->animscenes = Mem_Alloc(loadmodel->mempool, sizeof(animscene_t) * loadmodel->numframes);
-               scene = (void *) (pheader->lump_scenes.start + buffer);
+               scene = (void *) (pheader->lump_scenes.start + pbase);
                numposes = pheader->lump_poses.length / pheader->numbones / sizeof(float[3][4]);
                for (i = 0;i < pheader->numscenes;i++)
                {
@@ -956,7 +898,7 @@ void Mod_LoadZymoticModel(model_t *mod, void *buffer)
                float *poses;
        //      zymlump_t lump_poses; // float pose[numposes][numbones][3][4]; // animation data
                loadmodel->zymdata_poses = Mem_Alloc(loadmodel->mempool, pheader->lump_poses.length);
-               poses = (void *) (pheader->lump_poses.start + buffer);
+               poses = (void *) (pheader->lump_poses.start + pbase);
                for (i = 0;i < pheader->lump_poses.length / 4;i++)
                        loadmodel->zymdata_poses[i] = BigFloat(poses[i]);
        }
@@ -966,7 +908,7 @@ void Mod_LoadZymoticModel(model_t *mod, void *buffer)
                zymbone_t *bone;
        //      zymlump_t lump_bones; // zymbone_t bone[numbones];
                loadmodel->zymdata_bones = Mem_Alloc(loadmodel->mempool, pheader->numbones * sizeof(zymbone_t));
-               bone = (void *) (pheader->lump_bones.start + buffer);
+               bone = (void *) (pheader->lump_bones.start + pbase);
                for (i = 0;i < pheader->numbones;i++)
                {
                        memcpy(loadmodel->zymdata_bones[i].name, bone[i].name, sizeof(bone[i].name));
@@ -981,7 +923,7 @@ void Mod_LoadZymoticModel(model_t *mod, void *buffer)
                unsigned int i, *bonecount;
        //      zymlump_t lump_vertbonecounts; // int vertbonecounts[numvertices]; // how many bones influence each vertex (separate mainly to make this compress better)
                loadmodel->zymdata_vertbonecounts = Mem_Alloc(loadmodel->mempool, pheader->numbones * sizeof(int));
-               bonecount = (void *) (pheader->lump_vertbonecounts.start + buffer);
+               bonecount = (void *) (pheader->lump_vertbonecounts.start + pbase);
                for (i = 0;i < pheader->numbones;i++)
                {
                        loadmodel->zymdata_vertbonecounts[i] = BigLong(bonecount[i]);
@@ -995,7 +937,7 @@ void Mod_LoadZymoticModel(model_t *mod, void *buffer)
                zymvertex_t *vertdata;
        //      zymlump_t lump_verts; // zymvertex_t vert[numvertices]; // see vertex struct
                loadmodel->zymdata_verts = Mem_Alloc(loadmodel->mempool, pheader->lump_verts.length);
-               vertdata = (void *) (pheader->lump_verts.start + buffer);
+               vertdata = (void *) (pheader->lump_verts.start + pbase);
                for (i = 0;i < pheader->lump_verts.length / 4;i++)
                {
                        loadmodel->zymdata_verts[i].bonenum = BigLong(vertdata[i].bonenum);
@@ -1010,7 +952,7 @@ void Mod_LoadZymoticModel(model_t *mod, void *buffer)
                float *intexcoord, *outtexcoord;
        //      zymlump_t lump_texcoords; // float texcoords[numvertices][2];
                loadmodel->zymdata_texcoords = outtexcoord = Mem_Alloc(loadmodel->mempool, pheader->numverts * sizeof(float[4]));
-               intexcoord = (void *) (pheader->lump_texcoords.start + buffer);
+               intexcoord = (void *) (pheader->lump_texcoords.start + pbase);
                for (i = 0;i < pheader->numverts;i++);
                {
                        outtexcoord[i*4+0] = BigFloat(intexcoord[i*2+0]);
@@ -1028,7 +970,7 @@ void Mod_LoadZymoticModel(model_t *mod, void *buffer)
                if (pheader->lump_render.length != count)
                        Host_Error("Mod_LoadZymoticModel: renderlist is wrong size in %s (is %i bytes, should be %i bytes)\n", loadmodel->name, pheader->lump_render.length, count);
                outrenderlist = loadmodel->zymdata_renderlist = Mem_Alloc(loadmodel->mempool, count);
-               renderlist = (void *) (pheader->lump_render.start + buffer);
+               renderlist = (void *) (pheader->lump_render.start + pbase);
                renderlistend = (void *) ((qbyte *) renderlist + pheader->lump_render.length);
                for (i = 0;i < pheader->numshaders;i++)
                {
@@ -1057,14 +999,14 @@ void Mod_LoadZymoticModel(model_t *mod, void *buffer)
                unsigned int i;
                char *shadername;
        //      zymlump_t lump_shaders; // char shadername[numshaders][32]; // shaders used on this model
-               shadername = (void *) (pheader->lump_shaders.start + buffer);
+               shadername = (void *) (pheader->lump_shaders.start + pbase);
                for (i = 0;i < pheader->numshaders;i++)
-                       loadmodel->zymdata_textures[i] = loadtextureimage(loadmodel->texturepool, shadername + i * 32, 0, 0, true, r_mipskins.integer, true);
+                       loadmodel->zymdata_textures[i] = loadtextureimage(loadmodel->texturepool, shadername + i * 32, 0, 0, true, TEXF_ALPHA | TEXF_PRECACHE | (r_mipskins.integer ? TEXF_MIPMAP : 0));
        }
 
        {
        //      zymlump_t lump_trizone; // byte trizone[numtris]; // see trizone explanation
                loadmodel->zymdata_trizone = Mem_Alloc(loadmodel->mempool, pheader->numtris);
-               memcpy(loadmodel->zymdata_trizone, (void *) (pheader->lump_trizone.start + buffer), pheader->numtris);
+               memcpy(loadmodel->zymdata_trizone, (void *) (pheader->lump_trizone.start + pbase), pheader->numtris);
        }
 }