X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=model_shared.c;h=edf096aaeba004612a3ee13bca1f0f15cca08705;hb=66e2a20b4a20d03de1098a3c76186cb0ce316f21;hp=6b06ead1b18ac63c8408b52c172c1dff87513c46;hpb=9ab16034ceaba3a147d9c4afee8f4ac75e5ac319;p=xonotic%2Fdarkplaces.git diff --git a/model_shared.c b/model_shared.c index 6b06ead1..edf096aa 100644 --- a/model_shared.c +++ b/model_shared.c @@ -192,6 +192,101 @@ void R_Model_Null_Draw(entity_render_t *ent) return; } + +typedef void (*mod_framegroupify_parsegroups_t) (unsigned int i, int start, int len, float fps, qboolean loop, void *pass); + +int Mod_FrameGroupify_ParseGroups(const char *buf, mod_framegroupify_parsegroups_t cb, void *pass) +{ + const char *bufptr; + int start, len; + float fps; + unsigned int i; + qboolean loop; + + bufptr = buf; + i = 0; + for(;;) + { + // an anim scene! + if (!COM_ParseToken_Simple(&bufptr, true, false)) + break; + if (!strcmp(com_token, "\n")) + continue; // empty line + start = atoi(com_token); + if (!COM_ParseToken_Simple(&bufptr, true, false)) + break; + if (!strcmp(com_token, "\n")) + { + Con_Printf("framegroups file: missing number of frames\n"); + continue; + } + len = atoi(com_token); + if (!COM_ParseToken_Simple(&bufptr, true, false)) + break; + // we default to looping as it's usually wanted, so to NOT loop you append a 0 + if (strcmp(com_token, "\n")) + { + fps = atof(com_token); + if (!COM_ParseToken_Simple(&bufptr, true, false)) + break; + if (strcmp(com_token, "\n")) + loop = atoi(com_token); + else + loop = true; + } + else + { + fps = 20; + loop = true; + } + + if(cb) + cb(i, start, len, fps, loop, pass); + ++i; + } + + return i; +} + +void Mod_FrameGroupify_ParseGroups_Count (unsigned int i, int start, int len, float fps, qboolean loop, void *pass) +{ + unsigned int *cnt = (unsigned int *) pass; + ++*cnt; +} + +void Mod_FrameGroupify_ParseGroups_Store (unsigned int i, int start, int len, float fps, qboolean loop, void *pass) +{ + dp_model_t *mod = (dp_model_t *) pass; + animscene_t *anim = &mod->animscenes[i]; + dpsnprintf(anim->name, sizeof(anim[i].name), "groupified_%d", i); + anim->firstframe = bound(0, start, mod->num_poses - 1); + anim->framecount = bound(1, len, mod->num_poses - anim->firstframe); + anim->framerate = max(1, fps); + anim->loop = !!loop; + //Con_Printf("frame group %d is %d %d %f %d\n", i, start, len, fps, loop); +} + +void Mod_FrameGroupify(dp_model_t *mod, const char *buf) +{ + unsigned int cnt; + + // 0. count + cnt = Mod_FrameGroupify_ParseGroups(buf, NULL, NULL); + if(!cnt) + { + Con_Printf("no scene found in framegroups file, aborting\n"); + return; + } + mod->numframes = cnt; + + // 1. reallocate + // (we do not free the previous animscenes, but model unloading will free the pool owning them, so it's okay) + mod->animscenes = (animscene_t *) Mem_Alloc(mod->mempool, sizeof(animscene_t) * mod->numframes); + + // 2. parse + Mod_FrameGroupify_ParseGroups(buf, Mod_FrameGroupify_ParseGroups_Store, mod); +} + /* ================== Mod_LoadModel @@ -328,6 +423,13 @@ dp_model_t *Mod_LoadModel(dp_model_t *mod, qboolean crash, qboolean checkdisk) else Con_Printf("Mod_LoadModel: model \"%s\" is of unknown/unsupported type\n", mod->name); Mem_Free(buf); + buf = FS_LoadFile (va("%s.framegroups", mod->name), tempmempool, false, &filesize); + if(buf) + { + Mod_FrameGroupify(mod, buf); + Mem_Free(buf); + } + Mod_BuildVBOs(); } else if (crash) @@ -1237,7 +1339,14 @@ static void Q3Shader_AddToHash (q3shaderinfo_t* shader) { if (strcasecmp (entry->shader.name, shader->name) == 0) { - Con_Printf("Shader '%s' already defined\n", shader->name); + unsigned char *start, *end, *start2; + start = (unsigned char *) (&shader->Q3SHADERINFO_COMPARE_START); + end = ((unsigned char *) (&shader->Q3SHADERINFO_COMPARE_END)) + sizeof(shader->Q3SHADERINFO_COMPARE_END); + start2 = (unsigned char *) (&entry->shader.Q3SHADERINFO_COMPARE_START); + if(memcmp(start, start2, end - start)) + Con_Printf("Shader '%s' already defined, ignoring mismatching redeclaration\n", shader->name); + else + Con_DPrintf("Shader '%s' already defined\n", shader->name); return; } lastEntry = entry; @@ -1912,6 +2021,9 @@ nothing GL_ZERO GL_ONE if (shader->backgroundlayer >= 0) { q3shaderinfo_layer_t* backgroundlayer = shader->layers + shader->backgroundlayer; + // copy over one secondarylayer parameter + memcpy(texture->backgroundtcmods, backgroundlayer->tcmods, sizeof(texture->backgroundtcmods)); + // load the textures texture->backgroundnumskinframes = backgroundlayer->numframes; texture->backgroundskinframerate = backgroundlayer->framerate; for (j = 0;j < backgroundlayer->numframes;j++) @@ -2187,9 +2299,9 @@ void Mod_MakeSortedSurfaces(dp_model_t *mod) int *firstsurfacefortexture; int *numsurfacesfortexture; if (!mod->sortedmodelsurfaces) - mod->sortedmodelsurfaces = Mem_Alloc(loadmodel->mempool, mod->nummodelsurfaces * sizeof(*mod->sortedmodelsurfaces)); - firstsurfacefortexture = Mem_Alloc(tempmempool, mod->num_textures * sizeof(*firstsurfacefortexture)); - numsurfacesfortexture = Mem_Alloc(tempmempool, mod->num_textures * sizeof(*numsurfacesfortexture)); + mod->sortedmodelsurfaces = (int *) Mem_Alloc(loadmodel->mempool, mod->nummodelsurfaces * sizeof(*mod->sortedmodelsurfaces)); + firstsurfacefortexture = (int *) Mem_Alloc(tempmempool, mod->num_textures * sizeof(*firstsurfacefortexture)); + numsurfacesfortexture = (int *) Mem_Alloc(tempmempool, mod->num_textures * sizeof(*numsurfacesfortexture)); memset(numsurfacesfortexture, 0, mod->num_textures * sizeof(*numsurfacesfortexture)); for (j = 0;j < mod->nummodelsurfaces;j++) { @@ -2623,7 +2735,7 @@ static void Mod_Decompile_f(void) if ((animname[l] < '0' || animname[l] > '9') && animname[l] != '_') k = l + 1; animname[k] = 0; - count = (mod->num_poses / mod->num_bones) - first; + count = mod->num_poses - first; for (j = i + 1;j < mod->numframes;j++) { strlcpy(animname2, mod->animscenes[j].name, sizeof(animname2));