Sigrid Solveig Haflínudóttirstylea4bdd0f1 year agoHistory
350 lines · 9.4 KB · C
RawDownload
#include "quakedef.h" static void *Mod_LoadAliasFrame(	void *pin, int *pframeindex, int numv, trivertx_t *pbboxmin, trivertx_t *pbboxmax,	aliashdr_t *pheader, char *name, int aliasbboxmin[3], int aliasbboxmax[3]){	trivertx_t *pframe, *pinframe;	int i, j;	daliasframe_t *pdaliasframe; 	pdaliasframe = (daliasframe_t *)pin; 	strcpy(name, pdaliasframe->name); 	for(i = 0; i < 3; i++) {		// these are byte values, so we don't have to worry about		// endianness		pbboxmin->v[i] = pdaliasframe->bboxmin.v[i];		pbboxmax->v[i] = pdaliasframe->bboxmax.v[i];		aliasbboxmin[i] = min(aliasbboxmin[i], pbboxmin->v[i]);		aliasbboxmax[i] = max(aliasbboxmax[i], pbboxmax->v[i]);	} 	pinframe = (trivertx_t *)(pdaliasframe + 1);	*pframeindex = Hunk_From(pheader);	pframe = Hunk_Alloc(numv * sizeof(*pframe)); 	for(j = 0; j < numv; j++) {		int k; 		// these are all byte values, so no need to deal with endianness		pframe[j].lightnormalindex = pinframe[j].lightnormalindex; 		for(k = 0; k < 3; k++)			pframe[j].v[k] = pinframe[j].v[k];	} 	pinframe += numv; 	return (void *)pinframe;} static void *Mod_LoadAliasGroup(	void *pin, int *pframeindex, int numv, trivertx_t *pbboxmin, trivertx_t *pbboxmax,	aliashdr_t *pheader, char *name, int aliasbboxmin[3], int aliasbboxmax[3]){	daliasgroup_t *pingroup;	maliasgroup_t *paliasgroup;	int i, numframes;	daliasinterval_t *pin_intervals;	float *poutintervals;	void *ptemp; 	pingroup = (daliasgroup_t *)pin; 	numframes = LittleLong(pingroup->numframes); 	*pframeindex = Hunk_From(pheader);	paliasgroup =		Hunk_Alloc(sizeof(*paliasgroup) + (numframes - 1) * sizeof(paliasgroup->frames[0])); 	paliasgroup->numframes = numframes; 	for(i = 0; i < 3; i++) {		// these are byte values, so we don't have to worry about endianness		pbboxmin->v[i] = pingroup->bboxmin.v[i];		pbboxmax->v[i] = pingroup->bboxmax.v[i];		aliasbboxmin[i] = min(aliasbboxmin[i], pbboxmin->v[i]);		aliasbboxmax[i] = max(aliasbboxmax[i], pbboxmax->v[i]);	} 	pin_intervals = (daliasinterval_t *)(pingroup + 1); 	paliasgroup->intervals = Hunk_From(pheader);	poutintervals = Hunk_Alloc(numframes * sizeof(*poutintervals)); 	for(i = 0; i < numframes; i++) {		*poutintervals = LittleFloat(pin_intervals->interval);		if(*poutintervals <= 0.0)			Host_Error("Mod_LoadAliasGroup: interval<=0"); 		poutintervals++;		pin_intervals++;	} 	ptemp = (void *)pin_intervals; 	for(i = 0; i < numframes; i++) {		ptemp = Mod_LoadAliasFrame(			ptemp,			&paliasgroup->frames[i].frame,			numv,			&paliasgroup->frames[i].bboxmin,			&paliasgroup->frames[i].bboxmax,			pheader,			name,			aliasbboxmin,			aliasbboxmax		);	} 	return ptemp;} static void *Mod_LoadAliasSkin(void *pin, int *pskinindex, int skinsize, aliashdr_t *pheader){	byte *pinskin;	pixel_t *pskin; 	*pskinindex = Hunk_From(pheader);	pskin = Hunk_Alloc(skinsize * 4);	pinskin = (byte *)pin;	torgbx(pinskin, pskin, skinsize);	pinskin += skinsize;	return (void *)pinskin;} static void *Mod_LoadAliasSkinGroup(void *pin, int *pskinindex, int skinsize, aliashdr_t *pheader){	daliasskingroup_t *pinskingroup;	maliasskingroup_t *paliasskingroup;	int i, numskins;	daliasskininterval_t *pinskinintervals;	float *poutskinintervals;	void *ptemp; 	pinskingroup = (daliasskingroup_t *)pin; 	numskins = LittleLong(pinskingroup->numskins); 	*pskinindex = Hunk_From(pheader);	paliasskingroup = Hunk_Alloc(		sizeof(*paliasskingroup) + (numskins - 1) * sizeof(paliasskingroup->skindescs[0])	); 	paliasskingroup->numskins = numskins; 	pinskinintervals = (daliasskininterval_t *)(pinskingroup + 1); 	paliasskingroup->intervals = Hunk_From(pheader);	poutskinintervals = Hunk_Alloc(numskins * sizeof(*poutskinintervals)); 	for(i = 0; i < numskins; i++) {		*poutskinintervals = LittleFloat(pinskinintervals->interval);		if(*poutskinintervals <= 0)			Host_Error("Mod_LoadAliasSkinGroup: interval<=0"); 		poutskinintervals++;		pinskinintervals++;	} 	ptemp = (void *)pinskinintervals; 	for(i = 0; i < numskins; i++) {		ptemp = Mod_LoadAliasSkin(ptemp, &paliasskingroup->skindescs[i].skin, skinsize, pheader);	} 	return ptemp;} voidMod_LoadAliasModel(model_t *mod, void *buffer){	int i, version, numframes, numskins, size, skinsize, bboxmin[3], bboxmax[3];	mdl_t *pmodel, *pinmodel;	stvert_t *pstverts, *pinstverts;	aliashdr_t *pheader;	mtriangle_t *ptri;	dtriangle_t *pintriangles;	daliasframetype_t *pframetype;	daliasskintype_t *pskintype;	maliasskindesc_t *pskindesc; 	pinmodel = (mdl_t *)buffer; 	version = LittleLong(pinmodel->version);	if(version != ALIAS_VERSION)		Host_Error(			"%s has wrong version number (%d should be %d)", mod->name, version, ALIAS_VERSION		); 	// allocate space for a working header, plus all the data except the frames,	// skin and group info	size = sizeof(aliashdr_t) +		   (LittleLong(pinmodel->numframes) - 1) * sizeof(pheader->frames[0]) + sizeof(mdl_t) +		   LittleLong(pinmodel->numverts) * sizeof(stvert_t) +		   LittleLong(pinmodel->numtris) * sizeof(mtriangle_t); 	pheader = Hunk_Alloc(size);	pmodel = (mdl_t *)((byte *)&pheader[1] +					   (LittleLong(pinmodel->numframes) - 1) * sizeof(pheader->frames[0]));	pheader->model = (byte *)pmodel - (byte *)pheader; 	// mod->cache.data = pheader;	mod->flags = LittleLong(pinmodel->flags); 	// endian-adjust and copy the data, starting with the alias model header	pmodel->boundingradius = LittleFloat(pinmodel->boundingradius);	pmodel->numskins = LittleLong(pinmodel->numskins);	pmodel->skinwidth = LittleLong(pinmodel->skinwidth);	pmodel->skinheight = LittleLong(pinmodel->skinheight); 	if(pmodel->skinheight > MAX_LBM_HEIGHT)		Host_Error("model %s has a skin taller than %d", mod->name, MAX_LBM_HEIGHT); 	pmodel->numverts = LittleLong(pinmodel->numverts); 	if(pmodel->numverts <= 0)		Host_Error("model %s has no vertices", mod->name); 	if(pmodel->numverts > MAXALIASVERTS)		Host_Error("model %s has too many vertices", mod->name); 	pmodel->numtris = LittleLong(pinmodel->numtris); 	if(pmodel->numtris <= 0)		Host_Error("model %s has no triangles", mod->name); 	pmodel->numframes = LittleLong(pinmodel->numframes);	pmodel->size = LittleFloat(pinmodel->size) * ALIAS_BASE_SIZE_RATIO;	mod->synctype = LittleLong(pinmodel->synctype);	mod->numframes = pmodel->numframes; 	for(i = 0; i < 3; i++) {		pmodel->scale[i] = LittleFloat(pinmodel->scale[i]);		pmodel->scale_origin[i] = LittleFloat(pinmodel->scale_origin[i]);		pmodel->eyeposition[i] = LittleFloat(pinmodel->eyeposition[i]);	} 	numskins = pmodel->numskins;	numframes = pmodel->numframes; 	if(pmodel->skinwidth & 0x03)		Host_Error("Mod_LoadAliasModel: skinwidth not multiple of 4"); 	// load the skins	skinsize = pmodel->skinheight * pmodel->skinwidth; 	if(numskins < 1)		Host_Error("Mod_LoadAliasModel: Invalid # of skins: %d\n", numskins); 	pskintype = (daliasskintype_t *)&pinmodel[1]; 	pheader->skindesc = Hunk_From(pheader);	pskindesc = Hunk_Alloc(numskins * sizeof(*pskindesc)); 	for(i = 0; i < numskins; i++) {		aliasskintype_t skintype; 		skintype = LittleLong(pskintype->type);		pskindesc[i].type = skintype; 		if(skintype == ALIAS_SKIN_SINGLE) {			pskintype = (daliasskintype_t *)Mod_LoadAliasSkin(				pskintype + 1, &pskindesc[i].skin, skinsize, pheader			);		} else {			pskintype = (daliasskintype_t *)Mod_LoadAliasSkinGroup(				pskintype + 1, &pskindesc[i].skin, skinsize, pheader			);		}	} 	// set base s and t vertices	pstverts = (stvert_t *)&pmodel[1];	pinstverts = (stvert_t *)pskintype; 	pheader->stverts = (byte *)pstverts - (byte *)pheader; 	for(i = 0; i < pmodel->numverts; i++) {		pstverts[i].onseam = LittleLong(pinstverts[i].onseam);		// put s and t in 16.16 format		pstverts[i].s = LittleLong(pinstverts[i].s) << 16;		pstverts[i].t = LittleLong(pinstverts[i].t) << 16;	} 	// set up the triangles	ptri = (mtriangle_t *)&pstverts[pmodel->numverts];	pintriangles = (dtriangle_t *)&pinstverts[pmodel->numverts]; 	pheader->triangles = (byte *)ptri - (byte *)pheader; 	for(i = 0; i < pmodel->numtris; i++) {		int j; 		ptri[i].facesfront = LittleLong(pintriangles[i].facesfront); 		for(j = 0; j < 3; j++) {			ptri[i].vertindex[j] = LittleLong(pintriangles[i].vertindex[j]);		}	} 	// load the frames	if(numframes < 1)		Host_Error("Mod_LoadAliasModel: Invalid # of frames: %d\n", numframes); 	pframetype = (daliasframetype_t *)&pintriangles[pmodel->numtris];	bboxmin[0] = bboxmin[1] = bboxmin[2] = 999999;	bboxmax[0] = bboxmax[1] = bboxmax[2] = -999999; 	for(i = 0; i < numframes; i++) {		aliasframetype_t frametype; 		frametype = LittleLong(pframetype->type);		pheader->frames[i].type = frametype; 		if(frametype == ALIAS_SINGLE) {			pframetype = (daliasframetype_t *)Mod_LoadAliasFrame(				pframetype + 1,				&pheader->frames[i].frame,				pmodel->numverts,				&pheader->frames[i].bboxmin,				&pheader->frames[i].bboxmax,				pheader,				pheader->frames[i].name,				bboxmin,				bboxmax			);		} else {			pframetype = (daliasframetype_t *)Mod_LoadAliasGroup(				pframetype + 1,				&pheader->frames[i].frame,				pmodel->numverts,				&pheader->frames[i].bboxmin,				&pheader->frames[i].bboxmax,				pheader,				pheader->frames[i].name,				bboxmin,				bboxmax			);		}	} 	mod->type = mod_alias; 	for(i = 0; i < 3; i++) {		mod->mins[i] = bboxmin[i] * pmodel->scale[i] + pmodel->scale_origin[i];		mod->maxs[i] = bboxmax[i] * pmodel->scale[i] + pmodel->scale_origin[i];	} 	// move the complete, relocatable alias model to the cache 	Hunk_CacheFrom(&mod->cache, pheader);}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t