/* ================= Mod_LoadAliasModel ================= */ void Mod_LoadAliasModel(const model_loader_t *loader, model_t *mod, void *buffer, const model_t *loadmodel, const char *loadname) { byte *container; int i, j, pad; mdl_t *pinmodel; stvert_t *pinstverts; dtriangle_t *pintriangles; int version, numframes; int size; daliasframetype_t *pframetype; daliasframe_t *frame; daliasgroup_t *group; daliasskintype_t *pskintype; int start, end, total; float *intervals; #ifdef QW_HACK const char *crcmodel = NULL; if (!strcmp(loadmodel->name, "progs/player.mdl")) crcmodel = "pmodel"; if (!strcmp(loadmodel->name, "progs/eyes.mdl")) crcmodel = "emodel"; if (crcmodel) { uint16_t crc = CRC_Block(buffer, com_filesize); Info_SetValueForKey(cls.userinfo, crcmodel, va("%d", (int)crc), MAX_INFO_STRING); if (cls.state >= ca_connected) { MSG_WriteByte(&cls.netchan.message, clc_stringcmd); MSG_WriteStringf(&cls.netchan.message, "setinfo %s %d", crcmodel, (int)crc); } } #endif start = Hunk_LowMark(); pinmodel = (mdl_t *)buffer; #ifdef MSB_FIRST version = LittleLong(pinmodel->version); #else version = (pinmodel->version); #endif if (version != ALIAS_VERSION) Sys_Error("%s has wrong version number (%i should be %i)", mod->name, version, ALIAS_VERSION); // allocate space for a working header, plus all the data except the frames, // skin and group info pad = loader->Aliashdr_Padding(); #ifdef MSB_FIRST size = pad + sizeof(aliashdr_t) + LittleLong(pinmodel->numframes) * sizeof(pheader->frames[0]); #else size = pad + sizeof(aliashdr_t) + (pinmodel->numframes) * sizeof(pheader->frames[0]); #endif container = (byte*)Hunk_AllocName(size, loadname); pheader = (aliashdr_t *)(container + pad); #ifdef MSB_FIRST mod->flags = LittleLong(pinmodel->flags); // endian-adjust and copy the data, starting with the alias model header pheader->numskins = LittleLong(pinmodel->numskins); pheader->skinwidth = LittleLong(pinmodel->skinwidth); pheader->skinheight = LittleLong(pinmodel->skinheight); #else mod->flags = (pinmodel->flags); pheader->numskins = (pinmodel->numskins); pheader->skinwidth = (pinmodel->skinwidth); pheader->skinheight = (pinmodel->skinheight); #endif if (pheader->skinheight > MAX_LBM_HEIGHT) Sys_Error("model %s has a skin taller than %d", mod->name, MAX_LBM_HEIGHT); #ifdef MSB_FIRST pheader->numverts = LittleLong(pinmodel->numverts); #else pheader->numverts = (pinmodel->numverts); #endif if (pheader->numverts <= 0) Sys_Error("model %s has no vertices", mod->name); if (pheader->numverts > MAXALIASVERTS) Sys_Error("model %s has too many vertices", mod->name); #ifdef MSB_FIRST pheader->numtris = LittleLong(pinmodel->numtris); #else pheader->numtris = (pinmodel->numtris); #endif if (pheader->numtris <= 0) Sys_Error("model %s has no triangles", mod->name); #ifdef MSB_FIRST pheader->numframes = LittleLong(pinmodel->numframes); pheader->size = LittleFloat(pinmodel->size) * ALIAS_BASE_SIZE_RATIO; mod->synctype = (synctype_t)LittleLong(pinmodel->synctype); #else pheader->numframes = (pinmodel->numframes); pheader->size = (pinmodel->size) * ALIAS_BASE_SIZE_RATIO; mod->synctype = (synctype_t)(pinmodel->synctype); #endif mod->numframes = pheader->numframes; for (i = 0; i < 3; i++) { #ifdef MSB_FIRST pheader->scale[i] = LittleFloat(pinmodel->scale[i]); pheader->scale_origin[i] = LittleFloat(pinmodel->scale_origin[i]); #else pheader->scale[i] = (pinmodel->scale[i]); pheader->scale_origin[i] = (pinmodel->scale_origin[i]); #endif } // load the skins pskintype = (daliasskintype_t *)&pinmodel[1]; pskintype = (daliasskintype_t *)Mod_LoadAllSkins(loader, loadmodel, pheader->numskins, pskintype, loadname); // set base s and t vertices pinstverts = (stvert_t *)pskintype; for (i = 0; i < pheader->numverts; i++) { #ifdef MSB_FIRST stverts[i].onseam = LittleLong(pinstverts[i].onseam); stverts[i].s = LittleLong(pinstverts[i].s); stverts[i].t = LittleLong(pinstverts[i].t); #else stverts[i].onseam = (pinstverts[i].onseam); stverts[i].s = (pinstverts[i].s); stverts[i].t = (pinstverts[i].t); #endif } // set up the triangles pintriangles = (dtriangle_t *)&pinstverts[pheader->numverts]; for (i = 0; i < pheader->numtris; i++) { #ifdef MSB_FIRST triangles[i].facesfront = LittleLong(pintriangles[i].facesfront); #else triangles[i].facesfront = (pintriangles[i].facesfront); #endif for (j = 0; j < 3; j++) { #ifdef MSB_FIRST triangles[i].vertindex[j] = LittleLong(pintriangles[i].vertindex[j]); #else triangles[i].vertindex[j] = (pintriangles[i].vertindex[j]); #endif if (triangles[i].vertindex[j] < 0 || triangles[i].vertindex[j] >= pheader->numverts) Sys_Error("%s: invalid vertex index (%d of %d) in %s\n", __func__, triangles[i].vertindex[j], pheader->numverts, mod->name); } } /* load the frames */ numframes = pheader->numframes; if (numframes < 1) Sys_Error("%s: Invalid # of frames: %d", __func__, numframes); posenum = 0; pframetype = (daliasframetype_t *)&pintriangles[pheader->numtris]; for (i = 0; i < numframes; i++) { #ifdef MSB_FIRST if (LittleLong(pframetype->type) == ALIAS_SINGLE) #else if ((pframetype->type) == ALIAS_SINGLE) #endif { frame = (daliasframe_t *)(pframetype + 1); Mod_LoadAliasFrame(frame, &pheader->frames[i]); pframetype = (daliasframetype_t *)&frame->verts[pheader->numverts]; } else { group = (daliasgroup_t *)(pframetype + 1); pframetype = Mod_LoadAliasGroup(group, &pheader->frames[i], loadname); } } pheader->numposes = posenum; mod->type = mod_alias; // FIXME: do this right mod->mins[0] = mod->mins[1] = mod->mins[2] = -16; mod->maxs[0] = mod->maxs[1] = mod->maxs[2] = 16; /* Save the frame intervals */ intervals = (float*)Hunk_Alloc(pheader->numposes * sizeof(float)); pheader->poseintervals = (byte *)intervals - (byte *)pheader; for (i = 0; i < pheader->numposes; i++) intervals[i] = poseintervals[i]; /* Save the mesh data (verts, stverts, triangles) */ loader->LoadMeshData(loadmodel, pheader, triangles, stverts, poseverts); // move the complete, relocatable alias model to the cache end = Hunk_LowMark(); total = end - start; Cache_AllocPadded(&mod->cache, pad, total - pad, loadname); if (!mod->cache.data) return; memcpy((byte *)mod->cache.data - pad, container, total); Hunk_FreeToLowMark(start); }
/* * ============== * Cache_Alloc * ============== */ void * Cache_Alloc(cache_user_t *c, int size, const char *name) { return Cache_AllocPadded(c, 0, size, name); }