X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=model_alias.c;h=c62cb9c98d47324777a0b8a6320a463a306e0077;hb=edc56fcfd3eca0f72e49f815f332b62a01046e4c;hp=85c6ddd273e3b530229ae1a5f7e77fe190ae05ff;hpb=bc6e12f9c8c430e98d6cf89c96c3bfeb903e90d1;p=xonotic%2Fdarkplaces.git diff --git a/model_alias.c b/model_alias.c index 85c6ddd2..c62cb9c9 100644 --- a/model_alias.c +++ b/model_alias.c @@ -27,11 +27,6 @@ void Mod_AliasInit (void) Cvar_RegisterVariable(&r_mipskins); } -static void Mod_Alias_SERAddEntity(void) -{ - R_Clip_AddBox(currentrenderentity->mins, currentrenderentity->maxs, R_Entity_Callback, currentrenderentity, NULL); -} - // LordHavoc: proper bounding box considerations static float aliasbboxmin[3], aliasbboxmax[3], modelyawradius, modelradius; @@ -95,7 +90,7 @@ static void Mod_ConvertAliasVerts (int inverts, vec3_t scale, vec3_t translate, Con_Printf("Mod_ConvertAliasVerts: \"%s\", %i invalid normal indices found\n", loadmodel->name, invalidnormals); } -static void Mod_MDL_LoadFrames (long datapointer, int inverts, int outverts, vec3_t scale, vec3_t translate) +static void Mod_MDL_LoadFrames (qbyte * datapointer, int inverts, int outverts, vec3_t scale, vec3_t translate) { daliasframetype_t *pframetype; daliasframe_t *pinframe; @@ -160,10 +155,10 @@ static void Mod_MDL_LoadFrames (long datapointer, int inverts, int outverts, vec } } -static rtexture_t *GL_SkinSplitShirt(byte *in, byte *out, int width, int height, int bits, char *name, int precache) +static rtexture_t *GL_SkinSplitShirt(qbyte *in, qbyte *out, int width, int height, int bits, char *name, int precache) { int i, pixels, passed; - byte pixeltest[16]; + qbyte pixeltest[16]; for (i = 0;i < 16;i++) pixeltest[i] = (bits & (1 << i)) != 0; pixels = width*height; @@ -190,10 +185,10 @@ static rtexture_t *GL_SkinSplitShirt(byte *in, byte *out, int width, int height, return NULL; } -static rtexture_t *GL_SkinSplit(byte *in, byte *out, int width, int height, int bits, char *name, int precache) +static rtexture_t *GL_SkinSplit(qbyte *in, qbyte *out, int width, int height, int bits, char *name, int precache) { int i, pixels, passed; - byte pixeltest[16]; + qbyte pixeltest[16]; for (i = 0;i < 16;i++) pixeltest[i] = (bits & (1 << i)) != 0; pixels = width*height; @@ -216,39 +211,39 @@ static rtexture_t *GL_SkinSplit(byte *in, byte *out, int width, int height, int return NULL; } -static void Mod_LoadSkin (char *basename, byte *skindata, byte *skintemp, int width, int height, skinframe_t *skinframe, int precache) +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->pants = NULL; - skinframe->shirt = NULL; + 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->merged = NULL; - if (skinframe->base) + 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) +{ + if (!skindata || !skintemp) + 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 + if (skinframe->pants || skinframe->shirt) { - 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->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) } else - { - skinframe->base = loadtextureimagewithmask(loadmodel->texturepool, basename, 0, 0, false, true, true); - skinframe->fog = image_masktex; - if (!skinframe->base) - { - 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 - 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) - } - else - skinframe->base = GL_SkinSplit (skindata, skintemp, width, height, 0x3FFF, va("%s_base", basename), precache); // no special colors - // quake model skins don't have alpha - skinframe->fog = NULL; - } - } + skinframe->base = GL_SkinSplit (skindata, skintemp, width, height, 0x3FFF, va("%s_base", basename), precache); // no special colors + // quake model skins don't have alpha + skinframe->fog = NULL; + return true; } #define BOUNDI(VALUE,MIN,MAX) if (VALUE < MIN || VALUE >= MAX) Host_Error("model %s has an invalid ##VALUE (%d exceeds %d - %d)\n", loadmodel->name, VALUE, MIN, MAX); @@ -265,13 +260,16 @@ void Mod_LoadAliasModel (model_t *mod, void *buffer) daliasframetype_t *pinframetype; daliasgroup_t *pinframegroup; float scales, scalet, scale[3], translate[3], interval; - long datapointer, startframes, startskins; + qbyte *datapointer, *startframes, *startskins; char name[MAX_QPATH]; - byte *skintemp = NULL; + qbyte *skintemp = NULL; + skinframe_t tempskinframe; + animscene_t *tempskinscenes; + skinframe_t *tempskinframes; modelyawradius = 0; modelradius = 0; - datapointer = (long) buffer; + datapointer = buffer; pinmodel = (mdl_t *)datapointer; datapointer += sizeof(mdl_t); @@ -401,12 +399,42 @@ void Mod_LoadAliasModel (model_t *mod, void *buffer) sprintf (name, "%s_%i_%i", loadmodel->name, i, j); else sprintf (name, "%s_%i", loadmodel->name, i); - Mod_LoadSkin(name, (byte *)datapointer, skintemp, skinwidth, skinheight, loadmodel->skinframes + totalskins, i == 0); + if (!Mod_LoadExternalSkin(name, loadmodel->skinframes + totalskins, i == 0)) + Mod_LoadInternalSkin(name, (qbyte *)datapointer, skintemp, 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 (;;) + { + sprintf (name, "%s_%i", loadmodel->name, loadmodel->numskins); + if (Mod_LoadExternalSkin(name, &tempskinframe, loadmodel->numskins == 0)) + { + // expand the arrays to make room + tempskinscenes = loadmodel->skinscenes; + tempskinframes = loadmodel->skinframes; + loadmodel->skinscenes = Mem_Alloc(loadmodel->mempool, (loadmodel->numskins + 1) * sizeof(animscene_t)); + loadmodel->skinframes = Mem_Alloc(loadmodel->mempool, (totalskins + 1) * sizeof(skinframe_t)); + memcpy(loadmodel->skinscenes, tempskinscenes, loadmodel->numskins * sizeof(animscene_t)); + memcpy(loadmodel->skinframes, tempskinframes, totalskins * sizeof(skinframe_t)); + Mem_Free(tempskinscenes); + Mem_Free(tempskinframes); + // store the info about the new skin + strcpy(loadmodel->skinscenes[loadmodel->numskins].name, name); + loadmodel->skinscenes[loadmodel->numskins].firstframe = totalskins; + loadmodel->skinscenes[loadmodel->numskins].framecount = 1; + loadmodel->skinscenes[loadmodel->numskins].framerate = 10.0f; + loadmodel->skinscenes[loadmodel->numskins].loop = true; + loadmodel->skinframes[totalskins] = tempskinframe; + loadmodel->numskins++; + totalskins++; + } + else + break; + } // store texture coordinates into temporary array, they will be stored after usage is determined (triangle data) scales = 1.0 / skinwidth; @@ -484,12 +512,8 @@ void Mod_LoadAliasModel (model_t *mod, void *buffer) Mod_MDL_LoadFrames (startframes, numverts, totalverts, scale, translate); - // LordHavoc: fixed model bbox - was //FIXME: do this right - //loadmodel->mins[0] = loadmodel->mins[1] = loadmodel->mins[2] = -16; - //loadmodel->maxs[0] = loadmodel->maxs[1] = loadmodel->maxs[2] = 16; modelyawradius = sqrt(modelyawradius); modelradius = sqrt(modelradius); -// loadmodel->modelradius = modelradius; for (j = 0;j < 3;j++) { loadmodel->normalmins[j] = aliasbboxmin[j]; @@ -501,8 +525,7 @@ void Mod_LoadAliasModel (model_t *mod, void *buffer) loadmodel->yawmins[2] = loadmodel->normalmins[2]; loadmodel->yawmaxs[2] = loadmodel->normalmaxs[2]; - loadmodel->SERAddEntity = Mod_Alias_SERAddEntity; - loadmodel->Draw = R_DrawAliasModel; + loadmodel->Draw = R_DrawQ1Q2AliasModel; loadmodel->DrawSky = NULL; loadmodel->DrawShadow = NULL; } @@ -548,7 +571,7 @@ void Mod_LoadQ2AliasModel (model_t *mod, void *buffer) { int *vertremap; md2_t *pinmodel; - long base; + qbyte *base; int version, end; int i, j, k, hashindex, num, numxyz, numst, xyz, st; float *stverts, s, t; @@ -559,7 +582,7 @@ void Mod_LoadQ2AliasModel (model_t *mod, void *buffer) float st[2]; } *hash, **md2verthash, *md2verthashdata; - long datapointer; + qbyte *datapointer; md2frame_t *pinframe; char *inskin; md2triangle_t *intri; @@ -567,7 +590,7 @@ void Mod_LoadQ2AliasModel (model_t *mod, void *buffer) int skinwidth, skinheight; pinmodel = buffer; - base = (long) buffer; + base = buffer; version = LittleLong (pinmodel->version); if (version != MD2ALIAS_VERSION) @@ -576,8 +599,7 @@ void Mod_LoadQ2AliasModel (model_t *mod, void *buffer) loadmodel->type = mod_alias; loadmodel->aliastype = ALIASTYPE_MDLMD2; - loadmodel->SERAddEntity = Mod_Alias_SERAddEntity; - loadmodel->Draw = R_DrawAliasModel; + loadmodel->Draw = R_DrawQ1Q2AliasModel; loadmodel->DrawSky = NULL; loadmodel->DrawShadow = NULL; @@ -749,7 +771,6 @@ void Mod_LoadQ2AliasModel (model_t *mod, void *buffer) // LordHavoc: model bbox modelyawradius = sqrt(modelyawradius); modelradius = sqrt(modelradius); -// loadmodel->modelradius = modelradius; for (j = 0;j < 3;j++) { loadmodel->normalmins[j] = aliasbboxmin[j]; @@ -774,7 +795,7 @@ static void zymswapintblock(int *m, int size) void Mod_LoadZymoticModel(model_t *mod, void *buffer) { - int i, pbase, *bonecount; + int i, pbase, *bonecount, numposes; unsigned int count, a, b, c, *renderlist, *renderlistend; rtexture_t **texture; char *shadername; @@ -845,6 +866,7 @@ void Mod_LoadZymoticModel(model_t *mod, void *buffer) loadmodel->skinframes->glow = NULL; loadmodel->skinframes->merged = NULL; loadmodel->numskins = 1; + numposes = pheader->lump_poses.length / sizeof(float[3][4]) / pheader->numbones; // go through the lumps, swapping things @@ -867,6 +889,12 @@ void Mod_LoadZymoticModel(model_t *mod, void *buffer) loadmodel->animscenes[i].framerate = scene->framerate; loadmodel->animscenes[i].loop = (scene->flags & ZYMSCENEFLAG_NOLOOP) == 0; + if ((unsigned int) loadmodel->animscenes[i].firstframe >= numposes) + Host_Error("Mod_LoadZymoticModel: scene firstframe (%i) >= numposes (%i)\n", loadmodel->animscenes[i].firstframe, numposes); + if ((unsigned int) loadmodel->animscenes[i].firstframe + (unsigned int) loadmodel->animscenes[i].framecount > numposes) + Host_Error("Mod_LoadZymoticModel: scene firstframe (%i) + framecount (%i) >= numposes (%i)\n", loadmodel->animscenes[i].firstframe, loadmodel->animscenes[i].framecount, numposes); + if (loadmodel->animscenes[i].framerate < 0) + Host_Error("Mod_LoadZymoticModel: scene framerate (%f) < 0\n", loadmodel->animscenes[i].framerate); scene++; } @@ -900,7 +928,7 @@ void Mod_LoadZymoticModel(model_t *mod, void *buffer) zymswapintblock((void *) (pheader->lump_render.start + pbase), pheader->lump_render.length); // validate renderlist and swap winding order of tris renderlist = (void *) (pheader->lump_render.start + pbase); - renderlistend = (void *) ((byte *) renderlist + pheader->lump_render.length); + renderlistend = (void *) ((qbyte *) renderlist + pheader->lump_render.length); i = pheader->numshaders * sizeof(int) + pheader->numtris * sizeof(int[3]); if (pheader->lump_render.length != i) Host_Error("Mod_LoadZymoticModel: renderlist is wrong size in %s (is %i bytes, should be %i bytes)\n", loadmodel->name, pheader->lump_render.length, i); @@ -941,7 +969,6 @@ void Mod_LoadZymoticModel(model_t *mod, void *buffer) // model bbox modelradius = pheader->radius; -// loadmodel->modelradius = pheader->radius; for (i = 0;i < 3;i++) { loadmodel->normalmins[i] = pheader->mins[i]; @@ -958,8 +985,8 @@ void Mod_LoadZymoticModel(model_t *mod, void *buffer) loadmodel->yawmins[2] = loadmodel->normalmins[2]; loadmodel->yawmaxs[2] = loadmodel->normalmaxs[2]; - loadmodel->SERAddEntity = Mod_Alias_SERAddEntity; - loadmodel->Draw = R_DrawAliasModel; + loadmodel->Draw = R_DrawZymoticModel; loadmodel->DrawSky = NULL; loadmodel->DrawShadow = NULL; } +