mirror of
https://git.code.sf.net/p/quake/newtree
synced 2025-05-31 17:21:46 +00:00
merged. much easier once I realised I was trying too hard :)
This commit is contained in:
parent
393bf43fee
commit
ec2526b44b
2 changed files with 769 additions and 1903 deletions
772
source/model.c
772
source/model.c
|
@ -22,7 +22,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
// models are the only shared resource between a client and server running
|
// models are the only shared resource between a client and server running
|
||||||
// on the same machine.
|
// on the same machine.
|
||||||
|
|
||||||
|
#ifdef SERVERONLY
|
||||||
#include "qwsvdef.h"
|
#include "qwsvdef.h"
|
||||||
|
#else
|
||||||
|
#include "quakedef.h"
|
||||||
|
#include "r_local.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef SERVERONLY
|
#ifdef SERVERONLY
|
||||||
#define ERROR SV_Error
|
#define ERROR SV_Error
|
||||||
|
@ -57,6 +62,30 @@ void Mod_Init (void)
|
||||||
memset (mod_novis, 0xff, sizeof(mod_novis));
|
memset (mod_novis, 0xff, sizeof(mod_novis));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef SERVERONLY
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
Mod_Init
|
||||||
|
|
||||||
|
Caches the data if needed
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
void *Mod_Extradata (model_t *mod)
|
||||||
|
{
|
||||||
|
void *r;
|
||||||
|
|
||||||
|
r = Cache_Check (&mod->cache);
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
Mod_LoadModel (mod, true);
|
||||||
|
|
||||||
|
if (!mod->cache.data)
|
||||||
|
ERROR ("Mod_Extradata: caching failed");
|
||||||
|
return mod->cache.data;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===============
|
===============
|
||||||
Mod_PointInLeaf
|
Mod_PointInLeaf
|
||||||
|
@ -192,6 +221,26 @@ model_t *Mod_FindName (char *name)
|
||||||
return mod;
|
return mod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef SERVERONLY
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
Mod_TouchModel
|
||||||
|
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
void Mod_TouchModel (char *name)
|
||||||
|
{
|
||||||
|
model_t *mod;
|
||||||
|
|
||||||
|
mod = Mod_FindName (name);
|
||||||
|
|
||||||
|
if (!mod->needload)
|
||||||
|
{
|
||||||
|
if (mod->type == mod_alias)
|
||||||
|
Cache_Check (&mod->cache);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==================
|
==================
|
||||||
|
@ -243,7 +292,24 @@ model_t *Mod_LoadModel (model_t *mod, qboolean crash)
|
||||||
// call the apropriate loader
|
// call the apropriate loader
|
||||||
mod->needload = false;
|
mod->needload = false;
|
||||||
|
|
||||||
|
#ifdef SERVERONLY
|
||||||
Mod_LoadBrushModel (mod, buf);
|
Mod_LoadBrushModel (mod, buf);
|
||||||
|
#else
|
||||||
|
switch (LittleLong(*(unsigned *)buf))
|
||||||
|
{
|
||||||
|
case IDPOLYHEADER:
|
||||||
|
Mod_LoadAliasModel (mod, buf);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IDSPRITEHEADER:
|
||||||
|
Mod_LoadSpriteModel (mod, buf);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Mod_LoadBrushModel (mod, buf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return mod;
|
return mod;
|
||||||
}
|
}
|
||||||
|
@ -326,6 +392,10 @@ void Mod_LoadTextures (lump_t *l)
|
||||||
tx->offsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t);
|
tx->offsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t);
|
||||||
// the pixels immediately follow the structures
|
// the pixels immediately follow the structures
|
||||||
memcpy ( tx+1, mt+1, pixels);
|
memcpy ( tx+1, mt+1, pixels);
|
||||||
|
#ifndef SERVERONLY
|
||||||
|
if (!Q_strncmp(mt->name,"sky",3))
|
||||||
|
R_InitSky (tx);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -595,10 +665,15 @@ void Mod_LoadTexinfo (lump_t *l)
|
||||||
len1 = Length (out->vecs[0]);
|
len1 = Length (out->vecs[0]);
|
||||||
len2 = Length (out->vecs[1]);
|
len2 = Length (out->vecs[1]);
|
||||||
|
|
||||||
if (len1 + len2 < 2 /*0.001*/)
|
len1 = (len1 + len2)/2;
|
||||||
out->mipadjust = 1;
|
if (len1 < 0.32)
|
||||||
|
out->mipadjust = 4;
|
||||||
|
else if (len1 < 0.49)
|
||||||
|
out->mipadjust = 3;
|
||||||
|
else if (len1 < 0.99)
|
||||||
|
out->mipadjust = 2;
|
||||||
else
|
else
|
||||||
out->mipadjust = 1 / floor( (len1+len2)/2 );
|
out->mipadjust = 1;
|
||||||
|
|
||||||
miptex = LittleLong (in->miptex);
|
miptex = LittleLong (in->miptex);
|
||||||
out->flags = LittleLong (in->flags);
|
out->flags = LittleLong (in->flags);
|
||||||
|
@ -1035,6 +1110,23 @@ void Mod_LoadPlanes (lump_t *l)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
RadiusFromBounds
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
float RadiusFromBounds (vec3_t mins, vec3_t maxs)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
vec3_t corner;
|
||||||
|
|
||||||
|
for (i=0 ; i<3 ; i++)
|
||||||
|
{
|
||||||
|
corner[i] = fabs(mins[i]) > fabs(maxs[i]) ? fabs(mins[i]) : fabs(maxs[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Length (corner);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=================
|
=================
|
||||||
|
@ -1115,6 +1207,7 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer)
|
||||||
|
|
||||||
mod->firstmodelsurface = bm->firstface;
|
mod->firstmodelsurface = bm->firstface;
|
||||||
mod->nummodelsurfaces = bm->numfaces;
|
mod->nummodelsurfaces = bm->numfaces;
|
||||||
|
mod->radius = RadiusFromBounds (mod->mins, mod->maxs);
|
||||||
|
|
||||||
VectorCopy (bm->maxs, mod->maxs);
|
VectorCopy (bm->maxs, mod->maxs);
|
||||||
VectorCopy (bm->mins, mod->mins);
|
VectorCopy (bm->mins, mod->mins);
|
||||||
|
@ -1133,4 +1226,677 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifndef SERVERONLY
|
||||||
|
|
||||||
|
/*
|
||||||
|
==============================================================================
|
||||||
|
|
||||||
|
ALIAS MODELS
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
Mod_LoadAliasFrame
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
void * Mod_LoadAliasFrame (void * pin, int *pframeindex, int numv,
|
||||||
|
trivertx_t *pbboxmin, trivertx_t *pbboxmax, aliashdr_t *pheader, char *name)
|
||||||
|
{
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
|
||||||
|
pinframe = (trivertx_t *)(pdaliasframe + 1);
|
||||||
|
pframe = Hunk_AllocName (numv * sizeof(*pframe), loadname);
|
||||||
|
|
||||||
|
*pframeindex = (byte *)pframe - (byte *)pheader;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
Mod_LoadAliasGroup
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
void * Mod_LoadAliasGroup (void * pin, int *pframeindex, int numv,
|
||||||
|
trivertx_t *pbboxmin, trivertx_t *pbboxmax, aliashdr_t *pheader, char *name)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
paliasgroup = Hunk_AllocName (sizeof (maliasgroup_t) +
|
||||||
|
(numframes - 1) * sizeof (paliasgroup->frames[0]), loadname);
|
||||||
|
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
|
||||||
|
*pframeindex = (byte *)paliasgroup - (byte *)pheader;
|
||||||
|
|
||||||
|
pin_intervals = (daliasinterval_t *)(pingroup + 1);
|
||||||
|
|
||||||
|
poutintervals = Hunk_AllocName (numframes * sizeof (float), loadname);
|
||||||
|
|
||||||
|
paliasgroup->intervals = (byte *)poutintervals - (byte *)pheader;
|
||||||
|
|
||||||
|
for (i=0 ; i<numframes ; i++)
|
||||||
|
{
|
||||||
|
*poutintervals = LittleFloat (pin_intervals->interval);
|
||||||
|
if (*poutintervals <= 0.0)
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptemp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
Mod_LoadAliasSkin
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
void * Mod_LoadAliasSkin (void * pin, int *pskinindex, int skinsize,
|
||||||
|
aliashdr_t *pheader)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
byte *pskin, *pinskin;
|
||||||
|
unsigned short *pusskin;
|
||||||
|
|
||||||
|
pskin = Hunk_AllocName (skinsize * r_pixbytes, loadname);
|
||||||
|
pinskin = (byte *)pin;
|
||||||
|
*pskinindex = (byte *)pskin - (byte *)pheader;
|
||||||
|
|
||||||
|
if (r_pixbytes == 1)
|
||||||
|
{
|
||||||
|
Q_memcpy (pskin, pinskin, skinsize);
|
||||||
|
}
|
||||||
|
else if (r_pixbytes == 2)
|
||||||
|
{
|
||||||
|
pusskin = (unsigned short *)pskin;
|
||||||
|
|
||||||
|
for (i=0 ; i<skinsize ; i++)
|
||||||
|
pusskin[i] = d_8to16table[pinskin[i]];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ERROR ("Mod_LoadAliasSkin: driver set invalid r_pixbytes: %d\n",
|
||||||
|
r_pixbytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
pinskin += skinsize;
|
||||||
|
|
||||||
|
return ((void *)pinskin);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
Mod_LoadAliasSkinGroup
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
|
||||||
|
paliasskingroup = Hunk_AllocName (sizeof (maliasskingroup_t) +
|
||||||
|
(numskins - 1) * sizeof (paliasskingroup->skindescs[0]),
|
||||||
|
loadname);
|
||||||
|
|
||||||
|
paliasskingroup->numskins = numskins;
|
||||||
|
|
||||||
|
*pskinindex = (byte *)paliasskingroup - (byte *)pheader;
|
||||||
|
|
||||||
|
pinskinintervals = (daliasskininterval_t *)(pinskingroup + 1);
|
||||||
|
|
||||||
|
poutskinintervals = Hunk_AllocName (numskins * sizeof (float),loadname);
|
||||||
|
|
||||||
|
paliasskingroup->intervals = (byte *)poutskinintervals - (byte *)pheader;
|
||||||
|
|
||||||
|
for (i=0 ; i<numskins ; i++)
|
||||||
|
{
|
||||||
|
*poutskinintervals = LittleFloat (pinskinintervals->interval);
|
||||||
|
if (*poutskinintervals <= 0)
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
Mod_LoadAliasModel
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
void Mod_LoadAliasModel (model_t *mod, void *buffer)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
mdl_t *pmodel, *pinmodel;
|
||||||
|
stvert_t *pstverts, *pinstverts;
|
||||||
|
aliashdr_t *pheader;
|
||||||
|
mtriangle_t *ptri;
|
||||||
|
dtriangle_t *pintriangles;
|
||||||
|
int version, numframes, numskins;
|
||||||
|
int size;
|
||||||
|
daliasframetype_t *pframetype;
|
||||||
|
daliasskintype_t *pskintype;
|
||||||
|
maliasskindesc_t *pskindesc;
|
||||||
|
int skinsize;
|
||||||
|
int start, end, total;
|
||||||
|
|
||||||
|
if (!strcmp(loadmodel->name, "progs/player.mdl") ||
|
||||||
|
!strcmp(loadmodel->name, "progs/eyes.mdl")) {
|
||||||
|
unsigned short crc;
|
||||||
|
byte *p;
|
||||||
|
int len;
|
||||||
|
char st[40];
|
||||||
|
|
||||||
|
CRC_Init(&crc);
|
||||||
|
for (len = com_filesize, p = buffer; len; len--, p++)
|
||||||
|
CRC_ProcessByte(&crc, *p);
|
||||||
|
|
||||||
|
sprintf(st, "%d", (int) crc);
|
||||||
|
Info_SetValueForKey (cls.userinfo,
|
||||||
|
!strcmp(loadmodel->name, "progs/player.mdl") ? pmodel_name : emodel_name,
|
||||||
|
st, MAX_INFO_STRING);
|
||||||
|
|
||||||
|
if (cls.state >= ca_connected) {
|
||||||
|
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
|
||||||
|
sprintf(st, "setinfo %s %d",
|
||||||
|
!strcmp(loadmodel->name, "progs/player.mdl") ? pmodel_name : emodel_name,
|
||||||
|
(int)crc);
|
||||||
|
SZ_Print (&cls.netchan.message, st);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
start = Hunk_LowMark ();
|
||||||
|
|
||||||
|
pinmodel = (mdl_t *)buffer;
|
||||||
|
|
||||||
|
version = LittleLong (pinmodel->version);
|
||||||
|
if (version != ALIAS_VERSION)
|
||||||
|
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
|
||||||
|
//
|
||||||
|
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_AllocName (size, loadname);
|
||||||
|
pmodel = (mdl_t *) ((byte *)&pheader[1] +
|
||||||
|
(LittleLong (pinmodel->numframes) - 1) *
|
||||||
|
sizeof (pheader->frames[0]));
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
ERROR ("model %s has a skin taller than %d", mod->name,
|
||||||
|
MAX_LBM_HEIGHT);
|
||||||
|
|
||||||
|
pmodel->numverts = LittleLong (pinmodel->numverts);
|
||||||
|
|
||||||
|
if (pmodel->numverts <= 0)
|
||||||
|
ERROR ("model %s has no vertices", mod->name);
|
||||||
|
|
||||||
|
if (pmodel->numverts > MAXALIASVERTS)
|
||||||
|
ERROR ("model %s has too many vertices", mod->name);
|
||||||
|
|
||||||
|
pmodel->numtris = LittleLong (pinmodel->numtris);
|
||||||
|
|
||||||
|
if (pmodel->numtris <= 0)
|
||||||
|
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)
|
||||||
|
ERROR ("Mod_LoadAliasModel: skinwidth not multiple of 4");
|
||||||
|
|
||||||
|
pheader->model = (byte *)pmodel - (byte *)pheader;
|
||||||
|
|
||||||
|
//
|
||||||
|
// load the skins
|
||||||
|
//
|
||||||
|
skinsize = pmodel->skinheight * pmodel->skinwidth;
|
||||||
|
|
||||||
|
if (numskins < 1)
|
||||||
|
ERROR ("Mod_LoadAliasModel: Invalid # of skins: %d\n", numskins);
|
||||||
|
|
||||||
|
pskintype = (daliasskintype_t *)&pinmodel[1];
|
||||||
|
|
||||||
|
pskindesc = Hunk_AllocName (numskins * sizeof (maliasskindesc_t),
|
||||||
|
loadname);
|
||||||
|
|
||||||
|
pheader->skindesc = (byte *)pskindesc - (byte *)pheader;
|
||||||
|
|
||||||
|
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)
|
||||||
|
ERROR ("Mod_LoadAliasModel: Invalid # of frames: %d\n", numframes);
|
||||||
|
|
||||||
|
pframetype = (daliasframetype_t *)&pintriangles[pmodel->numtris];
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
//
|
||||||
|
// move the complete, relocatable alias model to the cache
|
||||||
|
//
|
||||||
|
end = Hunk_LowMark ();
|
||||||
|
total = end - start;
|
||||||
|
|
||||||
|
Cache_Alloc (&mod->cache, total, loadname);
|
||||||
|
if (!mod->cache.data)
|
||||||
|
return;
|
||||||
|
memcpy (mod->cache.data, pheader, total);
|
||||||
|
|
||||||
|
Hunk_FreeToLowMark (start);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
Mod_LoadSpriteFrame
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
void * Mod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe)
|
||||||
|
{
|
||||||
|
dspriteframe_t *pinframe;
|
||||||
|
mspriteframe_t *pspriteframe;
|
||||||
|
int i, width, height, size, origin[2];
|
||||||
|
unsigned short *ppixout;
|
||||||
|
byte *ppixin;
|
||||||
|
|
||||||
|
pinframe = (dspriteframe_t *)pin;
|
||||||
|
|
||||||
|
width = LittleLong (pinframe->width);
|
||||||
|
height = LittleLong (pinframe->height);
|
||||||
|
size = width * height;
|
||||||
|
|
||||||
|
pspriteframe = Hunk_AllocName (sizeof (mspriteframe_t) + size*r_pixbytes,
|
||||||
|
loadname);
|
||||||
|
|
||||||
|
Q_memset (pspriteframe, 0, sizeof (mspriteframe_t) + size);
|
||||||
|
*ppframe = pspriteframe;
|
||||||
|
|
||||||
|
pspriteframe->width = width;
|
||||||
|
pspriteframe->height = height;
|
||||||
|
origin[0] = LittleLong (pinframe->origin[0]);
|
||||||
|
origin[1] = LittleLong (pinframe->origin[1]);
|
||||||
|
|
||||||
|
pspriteframe->up = origin[1];
|
||||||
|
pspriteframe->down = origin[1] - height;
|
||||||
|
pspriteframe->left = origin[0];
|
||||||
|
pspriteframe->right = width + origin[0];
|
||||||
|
|
||||||
|
if (r_pixbytes == 1)
|
||||||
|
{
|
||||||
|
Q_memcpy (&pspriteframe->pixels[0], (byte *)(pinframe + 1), size);
|
||||||
|
}
|
||||||
|
else if (r_pixbytes == 2)
|
||||||
|
{
|
||||||
|
ppixin = (byte *)(pinframe + 1);
|
||||||
|
ppixout = (unsigned short *)&pspriteframe->pixels[0];
|
||||||
|
|
||||||
|
for (i=0 ; i<size ; i++)
|
||||||
|
ppixout[i] = d_8to16table[ppixin[i]];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ERROR ("Mod_LoadSpriteFrame: driver set invalid r_pixbytes: %d\n",
|
||||||
|
r_pixbytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (void *)((byte *)pinframe + sizeof (dspriteframe_t) + size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
Mod_LoadSpriteGroup
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
void * Mod_LoadSpriteGroup (void * pin, mspriteframe_t **ppframe)
|
||||||
|
{
|
||||||
|
dspritegroup_t *pingroup;
|
||||||
|
mspritegroup_t *pspritegroup;
|
||||||
|
int i, numframes;
|
||||||
|
dspriteinterval_t *pin_intervals;
|
||||||
|
float *poutintervals;
|
||||||
|
void *ptemp;
|
||||||
|
|
||||||
|
pingroup = (dspritegroup_t *)pin;
|
||||||
|
|
||||||
|
numframes = LittleLong (pingroup->numframes);
|
||||||
|
|
||||||
|
pspritegroup = Hunk_AllocName (sizeof (mspritegroup_t) +
|
||||||
|
(numframes - 1) * sizeof (pspritegroup->frames[0]), loadname);
|
||||||
|
|
||||||
|
pspritegroup->numframes = numframes;
|
||||||
|
|
||||||
|
*ppframe = (mspriteframe_t *)pspritegroup;
|
||||||
|
|
||||||
|
pin_intervals = (dspriteinterval_t *)(pingroup + 1);
|
||||||
|
|
||||||
|
poutintervals = Hunk_AllocName (numframes * sizeof (float), loadname);
|
||||||
|
|
||||||
|
pspritegroup->intervals = poutintervals;
|
||||||
|
|
||||||
|
for (i=0 ; i<numframes ; i++)
|
||||||
|
{
|
||||||
|
*poutintervals = LittleFloat (pin_intervals->interval);
|
||||||
|
if (*poutintervals <= 0.0)
|
||||||
|
ERROR ("Mod_LoadSpriteGroup: interval<=0");
|
||||||
|
|
||||||
|
poutintervals++;
|
||||||
|
pin_intervals++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptemp = (void *)pin_intervals;
|
||||||
|
|
||||||
|
for (i=0 ; i<numframes ; i++)
|
||||||
|
{
|
||||||
|
ptemp = Mod_LoadSpriteFrame (ptemp, &pspritegroup->frames[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptemp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
Mod_LoadSpriteModel
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
void Mod_LoadSpriteModel (model_t *mod, void *buffer)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int version;
|
||||||
|
dsprite_t *pin;
|
||||||
|
msprite_t *psprite;
|
||||||
|
int numframes;
|
||||||
|
int size;
|
||||||
|
dspriteframetype_t *pframetype;
|
||||||
|
|
||||||
|
pin = (dsprite_t *)buffer;
|
||||||
|
|
||||||
|
version = LittleLong (pin->version);
|
||||||
|
if (version != SPRITE_VERSION)
|
||||||
|
ERROR ("%s has wrong version number "
|
||||||
|
"(%i should be %i)", mod->name, version, SPRITE_VERSION);
|
||||||
|
|
||||||
|
numframes = LittleLong (pin->numframes);
|
||||||
|
|
||||||
|
size = sizeof (msprite_t) + (numframes - 1) * sizeof (psprite->frames);
|
||||||
|
|
||||||
|
psprite = Hunk_AllocName (size, loadname);
|
||||||
|
|
||||||
|
mod->cache.data = psprite;
|
||||||
|
|
||||||
|
psprite->type = LittleLong (pin->type);
|
||||||
|
psprite->maxwidth = LittleLong (pin->width);
|
||||||
|
psprite->maxheight = LittleLong (pin->height);
|
||||||
|
psprite->beamlength = LittleFloat (pin->beamlength);
|
||||||
|
mod->synctype = LittleLong (pin->synctype);
|
||||||
|
psprite->numframes = numframes;
|
||||||
|
|
||||||
|
mod->mins[0] = mod->mins[1] = -psprite->maxwidth/2;
|
||||||
|
mod->maxs[0] = mod->maxs[1] = psprite->maxwidth/2;
|
||||||
|
mod->mins[2] = -psprite->maxheight/2;
|
||||||
|
mod->maxs[2] = psprite->maxheight/2;
|
||||||
|
|
||||||
|
//
|
||||||
|
// load the frames
|
||||||
|
//
|
||||||
|
if (numframes < 1)
|
||||||
|
ERROR ("Mod_LoadSpriteModel: Invalid # of frames: %d\n", numframes);
|
||||||
|
|
||||||
|
mod->numframes = numframes;
|
||||||
|
|
||||||
|
pframetype = (dspriteframetype_t *)(pin + 1);
|
||||||
|
|
||||||
|
for (i=0 ; i<numframes ; i++)
|
||||||
|
{
|
||||||
|
spriteframetype_t frametype;
|
||||||
|
|
||||||
|
frametype = LittleLong (pframetype->type);
|
||||||
|
psprite->frames[i].type = frametype;
|
||||||
|
|
||||||
|
if (frametype == SPR_SINGLE)
|
||||||
|
{
|
||||||
|
pframetype = (dspriteframetype_t *)
|
||||||
|
Mod_LoadSpriteFrame (pframetype + 1,
|
||||||
|
&psprite->frames[i].frameptr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pframetype = (dspriteframetype_t *)
|
||||||
|
Mod_LoadSpriteGroup (pframetype + 1,
|
||||||
|
&psprite->frames[i].frameptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod->type = mod_sprite;
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Mod_Print
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void Mod_Print (void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
model_t *mod;
|
||||||
|
|
||||||
|
Con_Printf ("Cached models:\n");
|
||||||
|
for (i=0, mod=mod_known ; i < mod_numknown ; i++, mod++)
|
||||||
|
{
|
||||||
|
Con_Printf ("%8p : %s\n",mod->cache.data, mod->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue