mirror of
https://git.code.sf.net/p/quake/nuq
synced 2025-04-14 14:01:15 +00:00
the model merge hack is almost complete. gl works but sw sefaults due to
the alias model verts, tris and frames not being loaded correctly.
This commit is contained in:
parent
ff69e3f2f3
commit
73162d8783
8 changed files with 523 additions and 768 deletions
|
@ -318,21 +318,12 @@ typedef struct mtriangle_s {
|
|||
|
||||
#define MAX_SKINS 32
|
||||
typedef struct {
|
||||
int ident;
|
||||
int version;
|
||||
vec3_t scale;
|
||||
vec3_t scale_origin;
|
||||
float boundingradius;
|
||||
vec3_t eyeposition;
|
||||
int numskins;
|
||||
int skinwidth;
|
||||
int skinheight;
|
||||
int numverts;
|
||||
int numtris;
|
||||
int numframes;
|
||||
synctype_t synctype;
|
||||
int flags;
|
||||
float size;
|
||||
int model;
|
||||
int stverts;
|
||||
int skindesc;
|
||||
int triangles;
|
||||
|
||||
mdl_t mdl;
|
||||
|
||||
int numposes;
|
||||
int poseverts;
|
||||
|
@ -340,11 +331,8 @@ typedef struct {
|
|||
int commands; // gl command list with embedded s/t
|
||||
int gl_texturenum[MAX_SKINS][4];
|
||||
int gl_fb_texturenum[MAX_SKINS][4];
|
||||
int model;
|
||||
int stverts;
|
||||
int skindesc;
|
||||
int triangles;
|
||||
int texels[MAX_SKINS]; // only for player skins
|
||||
|
||||
maliasframedesc_t frames[1];
|
||||
} aliashdr_t;
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ common_ASM= sys_ia32.S worlda.S $(math_ASM)
|
|||
#endif
|
||||
|
||||
common_SOURCES= crc.c cvar.c cmd.c mathlib.c wad.c world.c \
|
||||
model.c model_brush.c model_sprite.c \
|
||||
model.c model_alias.c model_brush.c model_sprite.c \
|
||||
msg.c r_part.c sizebuf.c qendian.c qargs.c quakefs.c \
|
||||
va.c quakeio.c link.c com.c \
|
||||
zone.c $(common_ASM)
|
||||
|
|
|
@ -109,7 +109,7 @@ int StripLength (int starttri, int startv)
|
|||
|
||||
// look for a matching triangle
|
||||
nexttri:
|
||||
for (j=starttri+1, check=&triangles[starttri+1] ; j<pheader->numtris ; j++, check++)
|
||||
for (j=starttri+1, check=&triangles[starttri+1] ; j<pheader->mdl.numtris ; j++, check++)
|
||||
{
|
||||
if (check->facesfront != last->facesfront)
|
||||
continue;
|
||||
|
@ -143,7 +143,7 @@ nexttri:
|
|||
done:
|
||||
|
||||
// clear the temp used flags
|
||||
for (j=starttri+1 ; j<pheader->numtris ; j++)
|
||||
for (j=starttri+1 ; j<pheader->mdl.numtris ; j++)
|
||||
if (used[j] == 2)
|
||||
used[j] = 0;
|
||||
|
||||
|
@ -179,7 +179,7 @@ int FanLength (int starttri, int startv)
|
|||
|
||||
// look for a matching triangle
|
||||
nexttri:
|
||||
for (j=starttri+1, check=&triangles[starttri+1] ; j<pheader->numtris ; j++, check++)
|
||||
for (j=starttri+1, check=&triangles[starttri+1] ; j<pheader->mdl.numtris ; j++, check++)
|
||||
{
|
||||
if (check->facesfront != last->facesfront)
|
||||
continue;
|
||||
|
@ -210,7 +210,7 @@ nexttri:
|
|||
done:
|
||||
|
||||
// clear the temp used flags
|
||||
for (j=starttri+1 ; j<pheader->numtris ; j++)
|
||||
for (j=starttri+1 ; j<pheader->mdl.numtris ; j++)
|
||||
if (used[j] == 2)
|
||||
used[j] = 0;
|
||||
|
||||
|
@ -242,7 +242,7 @@ void BuildTris (void)
|
|||
numorder = 0;
|
||||
numcommands = 0;
|
||||
memset (used, 0, sizeof(used));
|
||||
for (i=0 ; i<pheader->numtris ; i++)
|
||||
for (i=0 ; i<pheader->mdl.numtris ; i++)
|
||||
{
|
||||
// pick an unused triangle and start the trifan
|
||||
if (used[i])
|
||||
|
@ -289,9 +289,9 @@ void BuildTris (void)
|
|||
s = stverts[k].s;
|
||||
t = stverts[k].t;
|
||||
if (!triangles[besttris[0]].facesfront && stverts[k].onseam)
|
||||
s += pheader->skinwidth / 2; // on back side
|
||||
s = (s + 0.5) / pheader->skinwidth;
|
||||
t = (t + 0.5) / pheader->skinheight;
|
||||
s += pheader->mdl.skinwidth / 2; // on back side
|
||||
s = (s + 0.5) / pheader->mdl.skinwidth;
|
||||
t = (t + 0.5) / pheader->mdl.skinheight;
|
||||
|
||||
*(float *)&commands[numcommands++] = s;
|
||||
*(float *)&commands[numcommands++] = t;
|
||||
|
@ -300,10 +300,10 @@ void BuildTris (void)
|
|||
|
||||
commands[numcommands++] = 0; // end of list marker
|
||||
|
||||
Con_DPrintf ("%3i tri %3i vert %3i cmd\n", pheader->numtris, numorder, numcommands);
|
||||
Con_DPrintf ("%3i tri %3i vert %3i cmd\n", pheader->mdl.numtris, numorder, numcommands);
|
||||
|
||||
allverts += numorder;
|
||||
alltris += pheader->numtris;
|
||||
alltris += pheader->mdl.numtris;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
gl_model.c
|
||||
gl_model_alias.c
|
||||
|
||||
model loading and caching
|
||||
|
||||
|
@ -51,100 +51,17 @@ ALIAS MODELS
|
|||
==============================================================================
|
||||
*/
|
||||
|
||||
aliashdr_t *pheader;
|
||||
extern aliashdr_t *pheader;
|
||||
|
||||
stvert_t stverts[MAXALIASVERTS];
|
||||
mtriangle_t triangles[MAXALIASTRIS];
|
||||
extern stvert_t stverts[MAXALIASVERTS];
|
||||
extern mtriangle_t triangles[MAXALIASTRIS];
|
||||
|
||||
// a pose is a single set of vertexes. a frame may be
|
||||
// an animating sequence of poses
|
||||
trivertx_t *poseverts[MAXALIASFRAMES];
|
||||
int posenum;
|
||||
extern trivertx_t *poseverts[MAXALIASFRAMES];
|
||||
extern int posenum;
|
||||
|
||||
byte player_8bit_texels[320*200];
|
||||
|
||||
/*
|
||||
=================
|
||||
Mod_LoadAliasFrame
|
||||
=================
|
||||
*/
|
||||
void * Mod_LoadAliasFrame (void * pin, maliasframedesc_t *frame)
|
||||
{
|
||||
trivertx_t *pinframe;
|
||||
int i;
|
||||
daliasframe_t *pdaliasframe;
|
||||
|
||||
pdaliasframe = (daliasframe_t *)pin;
|
||||
|
||||
strcpy (frame->name, pdaliasframe->name);
|
||||
frame->firstpose = posenum;
|
||||
frame->numposes = 1;
|
||||
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
// these are byte values, so we don't have to worry about
|
||||
// endianness
|
||||
frame->bboxmin.v[i] = pdaliasframe->bboxmin.v[i];
|
||||
frame->bboxmin.v[i] = pdaliasframe->bboxmax.v[i];
|
||||
}
|
||||
|
||||
pinframe = (trivertx_t *)(pdaliasframe + 1);
|
||||
|
||||
poseverts[posenum] = pinframe;
|
||||
posenum++;
|
||||
|
||||
pinframe += pheader->numverts;
|
||||
|
||||
return (void *)pinframe;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
Mod_LoadAliasGroup
|
||||
=================
|
||||
*/
|
||||
void *Mod_LoadAliasGroup (void * pin, maliasframedesc_t *frame)
|
||||
{
|
||||
daliasgroup_t *pingroup;
|
||||
int i, numframes;
|
||||
daliasinterval_t *pin_intervals;
|
||||
void *ptemp;
|
||||
|
||||
pingroup = (daliasgroup_t *)pin;
|
||||
|
||||
numframes = LittleLong (pingroup->numframes);
|
||||
|
||||
frame->firstpose = posenum;
|
||||
frame->numposes = numframes;
|
||||
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
// these are byte values, so we don't have to worry about endianness
|
||||
frame->bboxmin.v[i] = pingroup->bboxmin.v[i];
|
||||
frame->bboxmin.v[i] = pingroup->bboxmax.v[i];
|
||||
}
|
||||
|
||||
pin_intervals = (daliasinterval_t *)(pingroup + 1);
|
||||
|
||||
frame->interval = LittleFloat (pin_intervals->interval);
|
||||
|
||||
pin_intervals += numframes;
|
||||
|
||||
ptemp = (void *)pin_intervals;
|
||||
|
||||
for (i=0 ; i<numframes ; i++)
|
||||
{
|
||||
poseverts[posenum] = (trivertx_t *)((daliasframe_t *)ptemp + 1);
|
||||
posenum++;
|
||||
|
||||
ptemp = (trivertx_t *)((daliasframe_t *)ptemp + 1) + pheader->numverts;
|
||||
}
|
||||
|
||||
return ptemp;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
extern byte player_8bit_texels[320*200];
|
||||
|
||||
/*
|
||||
=================
|
||||
|
@ -222,92 +139,109 @@ void Mod_FloodFillSkin( byte *skin, int skinwidth, int skinheight )
|
|||
}
|
||||
}
|
||||
|
||||
void *Mod_LoadSkin (byte *skin, int skinsize, int snum, int gnum, qboolean group)
|
||||
{
|
||||
int j;
|
||||
char name[32];
|
||||
|
||||
Mod_FloodFillSkin( skin, pheader->mdl.skinwidth, pheader->mdl.skinheight );
|
||||
|
||||
// This block is GL fullbright support for objects...
|
||||
{
|
||||
int pixels;
|
||||
byte *ptexel;
|
||||
|
||||
// Check for fullbright pixels..
|
||||
pixels = pheader->mdl.skinwidth * pheader->mdl.skinheight;
|
||||
ptexel = (byte *)(skin + 1);
|
||||
|
||||
for (j=0 ; j<pixels ; j++) {
|
||||
if (ptexel[j] >= 256-32) {
|
||||
loadmodel->hasfullbrights = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (loadmodel->hasfullbrights) {
|
||||
byte *ptexels;
|
||||
|
||||
//ptexels = Hunk_Alloc(s);
|
||||
ptexels = malloc(pixels);
|
||||
|
||||
if (group) {
|
||||
snprintf(name, sizeof(name), "fb_%s_%i_%i", loadmodel->name,snum,gnum);
|
||||
} else {
|
||||
snprintf(name, sizeof(name), "fb_%s_%i", loadmodel->name,snum);
|
||||
}
|
||||
Con_DPrintf("FB Model ID: '%s'\n", name);
|
||||
for (j=0 ; j<pixels ; j++) {
|
||||
if (ptexel[j] >= 256-32) {
|
||||
ptexels[j] = ptexel[j];
|
||||
} else {
|
||||
ptexels[j] = 255;
|
||||
}
|
||||
}
|
||||
pheader->gl_fb_texturenum[snum][gnum] =
|
||||
GL_LoadTexture (name, pheader->mdl.skinwidth,
|
||||
pheader->mdl.skinheight, ptexels, true, true, 1);
|
||||
|
||||
free(ptexels);
|
||||
}
|
||||
}
|
||||
|
||||
if (group) {
|
||||
snprintf(name, sizeof(name), "%s_%i_%i", loadmodel->name,snum,gnum);
|
||||
} else {
|
||||
snprintf(name, sizeof(name), "%s_%i", loadmodel->name,snum);
|
||||
}
|
||||
pheader->gl_texturenum[snum][gnum] =
|
||||
GL_LoadTexture (name, pheader->mdl.skinwidth,
|
||||
pheader->mdl.skinheight, skin, true, false, 1);
|
||||
// alpha param was true for non group skins
|
||||
return skin + skinsize;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Mod_LoadAllSkins
|
||||
===============
|
||||
*/
|
||||
void *Mod_LoadAllSkins (int numskins, daliasskintype_t *pskintype)
|
||||
void *Mod_LoadAllSkins (int numskins, daliasskintype_t *pskintype, int *pskinindex)
|
||||
{
|
||||
int i, j, k;
|
||||
char name[32];
|
||||
int s;
|
||||
int skinsize;
|
||||
byte *skin;
|
||||
daliasskingroup_t *pinskingroup;
|
||||
int groupskins;
|
||||
daliasskininterval_t *pinskinintervals;
|
||||
|
||||
skin = (byte *)(pskintype + 1);
|
||||
skin = (byte *)pskintype;
|
||||
|
||||
if (numskins < 1 || numskins > MAX_SKINS)
|
||||
Sys_Error ("Mod_LoadAliasModel: Invalid # of skins: %d\n", numskins);
|
||||
|
||||
s = pheader->skinwidth * pheader->skinheight;
|
||||
skinsize = pheader->mdl.skinwidth * pheader->mdl.skinheight;
|
||||
|
||||
for (i=0 ; i<numskins ; i++)
|
||||
{
|
||||
if (pskintype->type == ALIAS_SKIN_SINGLE) {
|
||||
Mod_FloodFillSkin( skin, pheader->skinwidth, pheader->skinheight );
|
||||
skin+=4;
|
||||
skin = Mod_LoadSkin (skin, skinsize, i, 0, false);
|
||||
|
||||
// save 8 bit texels for the player model to remap
|
||||
if (!strcmp(loadmodel->name,"progs/player.mdl"))
|
||||
{
|
||||
if (s > sizeof(player_8bit_texels))
|
||||
if (skinsize > sizeof(player_8bit_texels))
|
||||
Sys_Error ("Player skin too large");
|
||||
memcpy (player_8bit_texels, (byte *)(pskintype + 1), s);
|
||||
memcpy (player_8bit_texels, skin, skinsize);
|
||||
}
|
||||
|
||||
// This block is GL fullbright support for objects...
|
||||
{
|
||||
int pixels;
|
||||
byte *ptexel;
|
||||
|
||||
// Check for fullbright pixels..
|
||||
pixels = pheader->skinwidth * pheader->skinheight;
|
||||
ptexel = (byte *)(pskintype + 1);
|
||||
|
||||
for (j=0 ; j<pixels ; j++) {
|
||||
if (ptexel[j] >= 256-32) {
|
||||
loadmodel->hasfullbrights = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (loadmodel->hasfullbrights) {
|
||||
byte *ptexels;
|
||||
|
||||
//ptexels = Hunk_Alloc(s);
|
||||
ptexels = malloc(pixels);
|
||||
|
||||
snprintf(name, sizeof(name), "fb_%s_%i", loadmodel->name,i);
|
||||
Con_DPrintf("FB Model ID: '%s'\n", name);
|
||||
for (j=0 ; j<pixels ; j++) {
|
||||
if (ptexel[j] >= 256-32) {
|
||||
ptexels[j] = ptexel[j];
|
||||
} else {
|
||||
ptexels[j] = 255;
|
||||
}
|
||||
}
|
||||
pheader->gl_fb_texturenum[i][0] =
|
||||
pheader->gl_fb_texturenum[i][1] =
|
||||
pheader->gl_fb_texturenum[i][2] =
|
||||
pheader->gl_fb_texturenum[i][3] =
|
||||
GL_LoadTexture (name, pheader->skinwidth,
|
||||
pheader->skinheight, ptexels, true, true, 1);
|
||||
|
||||
free(ptexels);
|
||||
}
|
||||
for (j=1; j < 4; j++) {
|
||||
pheader->gl_texturenum[i][j] =
|
||||
pheader->gl_texturenum[i][j - 1];
|
||||
pheader->gl_fb_texturenum[i][j] =
|
||||
pheader->gl_fb_texturenum[i][j - 1];
|
||||
}
|
||||
|
||||
|
||||
snprintf (name, sizeof(name), "%s_%i", loadmodel->name, i);
|
||||
pheader->gl_texturenum[i][0] =
|
||||
pheader->gl_texturenum[i][1] =
|
||||
pheader->gl_texturenum[i][2] =
|
||||
pheader->gl_texturenum[i][3] =
|
||||
GL_LoadTexture (name, pheader->skinwidth,
|
||||
pheader->skinheight, (byte *)(pskintype + 1), true, true, 1);
|
||||
pskintype = (daliasskintype_t *)((byte *)(pskintype+1) + s);
|
||||
} else {
|
||||
// animating skin group. yuck.
|
||||
Con_Printf("Animating Skin Group, if you get this message please notify warp@debian.org\n");
|
||||
|
@ -317,189 +251,22 @@ void *Mod_LoadAllSkins (int numskins, daliasskintype_t *pskintype)
|
|||
pinskinintervals = (daliasskininterval_t *)(pinskingroup + 1);
|
||||
|
||||
pskintype = (void *)(pinskinintervals + groupskins);
|
||||
skin = (byte *)pskintype;
|
||||
|
||||
for (j=0 ; j<groupskins ; j++)
|
||||
{
|
||||
Mod_FloodFillSkin( skin, pheader->skinwidth, pheader->skinheight );
|
||||
snprintf (name, sizeof(name), "%s_%i_%i", loadmodel->name, i,j);
|
||||
pheader->gl_texturenum[i][j&3] =
|
||||
GL_LoadTexture (name, pheader->skinwidth,
|
||||
pheader->skinheight, (byte *)(pskintype), true, false, 1);
|
||||
pskintype = (daliasskintype_t *)((byte *)(pskintype) + s);
|
||||
skin+=4;
|
||||
skin = Mod_LoadSkin (skin, skinsize, i, j, true);
|
||||
}
|
||||
k = j;
|
||||
for (/* */; j < 4; j++)
|
||||
pheader->gl_texturenum[i][j&3] =
|
||||
pheader->gl_texturenum[i][j - k];
|
||||
for (/* */; j < 4; j++) {
|
||||
pheader->gl_texturenum[i][j] =
|
||||
pheader->gl_texturenum[i][j - k];
|
||||
pheader->gl_fb_texturenum[i][j] =
|
||||
pheader->gl_fb_texturenum[i][j - k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (void *)pskintype;
|
||||
}
|
||||
|
||||
|
||||
//=========================================================================
|
||||
|
||||
/*
|
||||
=================
|
||||
Mod_LoadAliasModel
|
||||
=================
|
||||
*/
|
||||
void Mod_LoadAliasModel (model_t *mod, void *buffer)
|
||||
{
|
||||
int i, j;
|
||||
mdl_t *pinmodel;
|
||||
stvert_t *pinstverts;
|
||||
dtriangle_t *pintriangles;
|
||||
int version, numframes;
|
||||
int size;
|
||||
daliasframetype_t *pframetype;
|
||||
daliasskintype_t *pskintype;
|
||||
int start, end, total;
|
||||
|
||||
start = Hunk_LowMark ();
|
||||
|
||||
pinmodel = (mdl_t *)buffer;
|
||||
|
||||
version = LittleLong (pinmodel->version);
|
||||
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
|
||||
//
|
||||
size = sizeof (aliashdr_t)
|
||||
+ (LittleLong (pinmodel->numframes) - 1) *
|
||||
sizeof (pheader->frames[0]);
|
||||
pheader = Hunk_AllocName (size, loadname);
|
||||
|
||||
mod->flags = LittleLong (pinmodel->flags);
|
||||
|
||||
//
|
||||
// endian-adjust and copy the data, starting with the alias model header
|
||||
//
|
||||
pheader->boundingradius = LittleFloat (pinmodel->boundingradius);
|
||||
pheader->numskins = LittleLong (pinmodel->numskins);
|
||||
pheader->skinwidth = LittleLong (pinmodel->skinwidth);
|
||||
pheader->skinheight = LittleLong (pinmodel->skinheight);
|
||||
|
||||
if (pheader->skinheight > MAX_LBM_HEIGHT)
|
||||
Sys_Error ("model %s has a skin taller than %d", mod->name,
|
||||
MAX_LBM_HEIGHT);
|
||||
|
||||
pheader->numverts = LittleLong (pinmodel->numverts);
|
||||
|
||||
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);
|
||||
|
||||
pheader->numtris = LittleLong (pinmodel->numtris);
|
||||
|
||||
if (pheader->numtris <= 0)
|
||||
Sys_Error ("model %s has no triangles", mod->name);
|
||||
|
||||
pheader->numframes = LittleLong (pinmodel->numframes);
|
||||
numframes = pheader->numframes;
|
||||
if (numframes < 1)
|
||||
Sys_Error ("Mod_LoadAliasModel: Invalid # of frames: %d\n", numframes);
|
||||
|
||||
pheader->size = LittleFloat (pinmodel->size) * ALIAS_BASE_SIZE_RATIO;
|
||||
mod->synctype = LittleLong (pinmodel->synctype);
|
||||
mod->numframes = pheader->numframes;
|
||||
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
pheader->scale[i] = LittleFloat (pinmodel->scale[i]);
|
||||
pheader->scale_origin[i] = LittleFloat (pinmodel->scale_origin[i]);
|
||||
pheader->eyeposition[i] = LittleFloat (pinmodel->eyeposition[i]);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// load the skins
|
||||
//
|
||||
pskintype = (daliasskintype_t *)&pinmodel[1];
|
||||
pskintype = Mod_LoadAllSkins (pheader->numskins, pskintype);
|
||||
|
||||
//
|
||||
// load base s and t vertices
|
||||
//
|
||||
pinstverts = (stvert_t *)pskintype;
|
||||
|
||||
for (i=0 ; i<pheader->numverts ; i++)
|
||||
{
|
||||
stverts[i].onseam = LittleLong (pinstverts[i].onseam);
|
||||
stverts[i].s = LittleLong (pinstverts[i].s);
|
||||
stverts[i].t = LittleLong (pinstverts[i].t);
|
||||
}
|
||||
|
||||
//
|
||||
// load triangle lists
|
||||
//
|
||||
pintriangles = (dtriangle_t *)&pinstverts[pheader->numverts];
|
||||
|
||||
for (i=0 ; i<pheader->numtris ; i++)
|
||||
{
|
||||
triangles[i].facesfront = LittleLong (pintriangles[i].facesfront);
|
||||
|
||||
for (j=0 ; j<3 ; j++)
|
||||
{
|
||||
triangles[i].vertindex[j] =
|
||||
LittleLong (pintriangles[i].vertindex[j]);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// load the frames
|
||||
//
|
||||
posenum = 0;
|
||||
pframetype = (daliasframetype_t *)&pintriangles[pheader->numtris];
|
||||
|
||||
for (i=0 ; i<numframes ; i++)
|
||||
{
|
||||
aliasframetype_t frametype;
|
||||
|
||||
frametype = LittleLong (pframetype->type);
|
||||
|
||||
if (frametype == ALIAS_SINGLE)
|
||||
{
|
||||
pframetype = (daliasframetype_t *)
|
||||
Mod_LoadAliasFrame (pframetype + 1, &pheader->frames[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
pframetype = (daliasframetype_t *)
|
||||
Mod_LoadAliasGroup (pframetype + 1, &pheader->frames[i]);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
//
|
||||
// build the draw lists
|
||||
//
|
||||
GL_MakeAliasModelDisplayLists (mod, pheader);
|
||||
|
||||
//
|
||||
// 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);
|
||||
return (void *)skin;
|
||||
}
|
||||
|
|
|
@ -469,9 +469,9 @@ static void GL_DrawAliasShadow (aliashdr_t *paliashdr, int posenum)
|
|||
order += 2;
|
||||
|
||||
// normals and vertexes come from the frame list
|
||||
point[0] = verts->v[0] * paliashdr->scale[0] + paliashdr->scale_origin[0];
|
||||
point[1] = verts->v[1] * paliashdr->scale[1] + paliashdr->scale_origin[1];
|
||||
point[2] = verts->v[2] * paliashdr->scale[2] + paliashdr->scale_origin[2];
|
||||
point[0] = verts->v[0] * paliashdr->mdl.scale[0] + paliashdr->mdl.scale_origin[0];
|
||||
point[1] = verts->v[1] * paliashdr->mdl.scale[1] + paliashdr->mdl.scale_origin[1];
|
||||
point[2] = verts->v[2] * paliashdr->mdl.scale[2] + paliashdr->mdl.scale_origin[2];
|
||||
|
||||
point[0] -= shadevector[0]*(point[2]+lheight);
|
||||
point[1] -= shadevector[1]*(point[2]+lheight);
|
||||
|
@ -499,7 +499,7 @@ static void R_SetupAliasFrame (int frame, aliashdr_t *paliashdr, qboolean fb)
|
|||
int pose, numposes;
|
||||
float interval;
|
||||
|
||||
if ((frame >= paliashdr->numframes) || (frame < 0))
|
||||
if ((frame >= paliashdr->mdl.numframes) || (frame < 0))
|
||||
{
|
||||
Con_DPrintf ("R_AliasSetupFrame: no such frame %d\n", frame);
|
||||
frame = 0;
|
||||
|
@ -599,7 +599,7 @@ static void R_DrawAliasModel (entity_t *e)
|
|||
//
|
||||
paliashdr = (aliashdr_t *)Mod_Extradata (currententity->model);
|
||||
|
||||
c_alias_polys += paliashdr->numtris;
|
||||
c_alias_polys += paliashdr->mdl.numtris;
|
||||
|
||||
//
|
||||
// draw all the triangles
|
||||
|
@ -613,14 +613,14 @@ static void R_DrawAliasModel (entity_t *e)
|
|||
|
||||
if (!strcmp (clmodel->name, "progs/eyes.mdl") )
|
||||
{
|
||||
glTranslatef (paliashdr->scale_origin[0], paliashdr->scale_origin[1], paliashdr->scale_origin[2] - (22 + 8));
|
||||
glTranslatef (paliashdr->mdl.scale_origin[0], paliashdr->mdl.scale_origin[1], paliashdr->mdl.scale_origin[2] - (22 + 8));
|
||||
// double size of eyes, since they are really hard to see in gl
|
||||
glScalef (paliashdr->scale[0]*2, paliashdr->scale[1]*2, paliashdr->scale[2]*2);
|
||||
glScalef (paliashdr->mdl.scale[0]*2, paliashdr->mdl.scale[1]*2, paliashdr->mdl.scale[2]*2);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTranslatef (paliashdr->scale_origin[0], paliashdr->scale_origin[1], paliashdr->scale_origin[2]);
|
||||
glScalef (paliashdr->scale[0], paliashdr->scale[1], paliashdr->scale[2]);
|
||||
glTranslatef (paliashdr->mdl.scale_origin[0], paliashdr->mdl.scale_origin[1], paliashdr->mdl.scale_origin[2]);
|
||||
glScalef (paliashdr->mdl.scale[0], paliashdr->mdl.scale[1], paliashdr->mdl.scale[2]);
|
||||
}
|
||||
|
||||
anim = (int)(cl.time*10) & 3;
|
||||
|
|
|
@ -340,8 +340,8 @@ void R_TranslatePlayerSkin (int playernum)
|
|||
return; // only translate skins on alias models
|
||||
|
||||
paliashdr = (aliashdr_t *)Mod_Extradata (model);
|
||||
s = paliashdr->skinwidth * paliashdr->skinheight;
|
||||
if (currententity->skinnum < 0 || currententity->skinnum >= paliashdr->numskins) {
|
||||
s = paliashdr->mdl.skinwidth * paliashdr->mdl.skinheight;
|
||||
if (currententity->skinnum < 0 || currententity->skinnum >= paliashdr->mdl.numskins) {
|
||||
Con_Printf("(%d): Invalid player skin #%d\n", playernum, currententity->skinnum);
|
||||
original = (byte *)paliashdr + paliashdr->texels[0];
|
||||
} else
|
||||
|
@ -349,8 +349,8 @@ void R_TranslatePlayerSkin (int playernum)
|
|||
if (s & 3)
|
||||
Sys_Error ("R_TranslateSkin: s&3");
|
||||
|
||||
inwidth = paliashdr->skinwidth;
|
||||
inheight = paliashdr->skinheight;
|
||||
inwidth = paliashdr->mdl.skinwidth;
|
||||
inheight = paliashdr->mdl.skinheight;
|
||||
|
||||
// because this happens during gameplay, do it fast
|
||||
// instead of sending it through gl_upload 8
|
||||
|
|
314
source/model_alias.c
Normal file
314
source/model_alias.c
Normal file
|
@ -0,0 +1,314 @@
|
|||
/*
|
||||
model_alias.c
|
||||
|
||||
model loading and caching
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
// models are the only shared resource between a client and server running
|
||||
// on the same machine.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "r_local.h"
|
||||
#include "sys.h"
|
||||
#include "console.h"
|
||||
#include "qendian.h"
|
||||
#include "checksum.h"
|
||||
#include "glquake.h"
|
||||
|
||||
extern char loadname[];
|
||||
extern model_t *loadmodel;
|
||||
|
||||
void *Mod_LoadAllSkins (int numskins, daliasskintype_t *pskintype, int *pskinindex);
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
ALIAS MODELS
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
aliashdr_t *pheader;
|
||||
|
||||
stvert_t stverts[MAXALIASVERTS];
|
||||
mtriangle_t triangles[MAXALIASTRIS];
|
||||
|
||||
// a pose is a single set of vertexes. a frame may be
|
||||
// an animating sequence of poses
|
||||
trivertx_t *poseverts[MAXALIASFRAMES];
|
||||
int posenum;
|
||||
|
||||
byte player_8bit_texels[320*200];
|
||||
|
||||
/*
|
||||
=================
|
||||
Mod_LoadAliasFrame
|
||||
=================
|
||||
*/
|
||||
void * Mod_LoadAliasFrame (void * pin, maliasframedesc_t *frame)
|
||||
{
|
||||
trivertx_t *pinframe;
|
||||
int i;
|
||||
daliasframe_t *pdaliasframe;
|
||||
|
||||
pdaliasframe = (daliasframe_t *)pin;
|
||||
|
||||
strcpy (frame->name, pdaliasframe->name);
|
||||
frame->firstpose = posenum;
|
||||
frame->numposes = 1;
|
||||
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
// these are byte values, so we don't have to worry about
|
||||
// endianness
|
||||
frame->bboxmin.v[i] = pdaliasframe->bboxmin.v[i];
|
||||
frame->bboxmin.v[i] = pdaliasframe->bboxmax.v[i];
|
||||
}
|
||||
|
||||
pinframe = (trivertx_t *)(pdaliasframe + 1);
|
||||
|
||||
poseverts[posenum] = pinframe;
|
||||
posenum++;
|
||||
|
||||
pinframe += pheader->mdl.numverts;
|
||||
|
||||
return (void *)pinframe;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
Mod_LoadAliasGroup
|
||||
=================
|
||||
*/
|
||||
void *Mod_LoadAliasGroup (void * pin, maliasframedesc_t *frame)
|
||||
{
|
||||
daliasgroup_t *pingroup;
|
||||
int i, numframes;
|
||||
daliasinterval_t *pin_intervals;
|
||||
void *ptemp;
|
||||
|
||||
pingroup = (daliasgroup_t *)pin;
|
||||
|
||||
numframes = LittleLong (pingroup->numframes);
|
||||
|
||||
frame->firstpose = posenum;
|
||||
frame->numposes = numframes;
|
||||
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
// these are byte values, so we don't have to worry about endianness
|
||||
frame->bboxmin.v[i] = pingroup->bboxmin.v[i];
|
||||
frame->bboxmin.v[i] = pingroup->bboxmax.v[i];
|
||||
}
|
||||
|
||||
pin_intervals = (daliasinterval_t *)(pingroup + 1);
|
||||
|
||||
frame->interval = LittleFloat (pin_intervals->interval);
|
||||
|
||||
pin_intervals += numframes;
|
||||
|
||||
ptemp = (void *)pin_intervals;
|
||||
|
||||
for (i=0 ; i<numframes ; i++)
|
||||
{
|
||||
poseverts[posenum] = (trivertx_t *)((daliasframe_t *)ptemp + 1);
|
||||
posenum++;
|
||||
|
||||
ptemp = (trivertx_t *)((daliasframe_t *)ptemp + 1) + pheader->mdl.numverts;
|
||||
}
|
||||
|
||||
return ptemp;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
|
||||
/*
|
||||
=================
|
||||
Mod_LoadAliasModel
|
||||
=================
|
||||
*/
|
||||
void Mod_LoadAliasModel (model_t *mod, void *buffer)
|
||||
{
|
||||
int i, j;
|
||||
mdl_t *pinmodel, *pmodel;
|
||||
stvert_t *pinstverts;
|
||||
dtriangle_t *pintriangles;
|
||||
int version, numframes;
|
||||
int size;
|
||||
daliasframetype_t *pframetype;
|
||||
daliasskintype_t *pskintype;
|
||||
int start, end, total;
|
||||
|
||||
start = Hunk_LowMark ();
|
||||
|
||||
pinmodel = (mdl_t *)buffer;
|
||||
|
||||
version = LittleLong (pinmodel->version);
|
||||
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
|
||||
//
|
||||
size = (int)&((aliashdr_t*)0)->frames[LittleLong (pinmodel->numframes)];
|
||||
pheader = Hunk_AllocName (size, loadname);
|
||||
memset(pheader, 0, size);
|
||||
pmodel = &pheader->mdl;
|
||||
pheader->model = (byte*)pmodel - (byte*)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)
|
||||
Sys_Error ("model %s has a skin taller than %d", mod->name,
|
||||
MAX_LBM_HEIGHT);
|
||||
|
||||
pmodel->numverts = LittleLong (pinmodel->numverts);
|
||||
|
||||
if (pmodel->numverts <= 0)
|
||||
Sys_Error ("model %s has no vertices", mod->name);
|
||||
|
||||
if (pmodel->numverts > MAXALIASVERTS)
|
||||
Sys_Error ("model %s has too many vertices", mod->name);
|
||||
|
||||
pmodel->numtris = LittleLong (pinmodel->numtris);
|
||||
|
||||
if (pmodel->numtris <= 0)
|
||||
Sys_Error ("model %s has no triangles", mod->name);
|
||||
|
||||
pmodel->numframes = LittleLong (pinmodel->numframes);
|
||||
numframes = pmodel->numframes;
|
||||
if (numframes < 1)
|
||||
Sys_Error ("Mod_LoadAliasModel: Invalid # of frames: %d\n", 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]);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// load the skins
|
||||
//
|
||||
pskintype = (daliasskintype_t *)&pinmodel[1];
|
||||
pskintype = Mod_LoadAllSkins (pheader->mdl.numskins, pskintype, &pheader->skindesc);
|
||||
|
||||
//
|
||||
// load base s and t vertices
|
||||
//
|
||||
pinstverts = (stvert_t *)pskintype;
|
||||
|
||||
for (i=0 ; i<pheader->mdl.numverts ; i++)
|
||||
{
|
||||
stverts[i].onseam = LittleLong (pinstverts[i].onseam);
|
||||
stverts[i].s = LittleLong (pinstverts[i].s);
|
||||
stverts[i].t = LittleLong (pinstverts[i].t);
|
||||
}
|
||||
|
||||
//
|
||||
// load triangle lists
|
||||
//
|
||||
pintriangles = (dtriangle_t *)&pinstverts[pheader->mdl.numverts];
|
||||
|
||||
for (i=0 ; i<pheader->mdl.numtris ; i++)
|
||||
{
|
||||
triangles[i].facesfront = LittleLong (pintriangles[i].facesfront);
|
||||
|
||||
for (j=0 ; j<3 ; j++)
|
||||
{
|
||||
triangles[i].vertindex[j] =
|
||||
LittleLong (pintriangles[i].vertindex[j]);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// load the frames
|
||||
//
|
||||
posenum = 0;
|
||||
pframetype = (daliasframetype_t *)&pintriangles[pheader->mdl.numtris];
|
||||
|
||||
for (i=0 ; i<numframes ; i++)
|
||||
{
|
||||
aliasframetype_t frametype;
|
||||
|
||||
frametype = LittleLong (pframetype->type);
|
||||
|
||||
if (frametype == ALIAS_SINGLE)
|
||||
{
|
||||
pframetype = (daliasframetype_t *)
|
||||
Mod_LoadAliasFrame (pframetype + 1, &pheader->frames[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
pframetype = (daliasframetype_t *)
|
||||
Mod_LoadAliasGroup (pframetype + 1, &pheader->frames[i]);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
//
|
||||
// build the draw lists
|
||||
//
|
||||
GL_MakeAliasModelDisplayLists (mod, pheader);
|
||||
|
||||
//
|
||||
// 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);
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
model.c
|
||||
sw_model_alias.c
|
||||
|
||||
model loading and caching
|
||||
|
||||
|
@ -26,6 +26,9 @@
|
|||
$Id$
|
||||
*/
|
||||
|
||||
// models are the only shared resource between a client and server running
|
||||
// on the same machine.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
@ -35,8 +38,10 @@
|
|||
#include "console.h"
|
||||
#include "qendian.h"
|
||||
#include "checksum.h"
|
||||
#include "glquake.h"
|
||||
|
||||
extern char loadname[];
|
||||
extern model_t *loadmodel;
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
@ -46,434 +51,115 @@ 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)
|
||||
Sys_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)
|
||||
extern aliashdr_t *pheader;
|
||||
|
||||
extern stvert_t stverts[MAXALIASVERTS];
|
||||
extern mtriangle_t triangles[MAXALIASTRIS];
|
||||
|
||||
// a pose is a single set of vertexes. a frame may be
|
||||
// an animating sequence of poses
|
||||
extern trivertx_t *poseverts[MAXALIASFRAMES];
|
||||
extern int posenum;
|
||||
|
||||
extern byte player_8bit_texels[320*200];
|
||||
|
||||
void *Mod_LoadSkin (byte *skin, int skinsize, int *pskinindex, int snum, int gnum)
|
||||
{
|
||||
byte *pskin;
|
||||
ushort *pusskin;
|
||||
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)
|
||||
{
|
||||
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
|
||||
{
|
||||
switch (r_pixbytes) {
|
||||
case 1:
|
||||
memcpy (pskin, skin, skinsize);
|
||||
break;
|
||||
case 2:
|
||||
pusskin = (ushort*)skin;
|
||||
for (i=0; i<skinsize; i++)
|
||||
pusskin[i] = d_8to16table[skin[i]];
|
||||
break;
|
||||
default:
|
||||
Sys_Error ("Mod_LoadAliasSkin: driver set invalid r_pixbytes: %d\n",
|
||||
r_pixbytes);
|
||||
r_pixbytes);
|
||||
break;
|
||||
}
|
||||
|
||||
pinskin += skinsize;
|
||||
|
||||
return ((void *)pinskin);
|
||||
return skin + skinsize;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
Mod_LoadAliasSkinGroup
|
||||
=================
|
||||
===============
|
||||
Mod_LoadAllSkins
|
||||
===============
|
||||
*/
|
||||
void * Mod_LoadAliasSkinGroup (void * pin, int *pskinindex, int skinsize,
|
||||
aliashdr_t *pheader)
|
||||
void *Mod_LoadAllSkins (int numskins, daliasskintype_t *pskintype, int *pskinindex)
|
||||
{
|
||||
int i, j;
|
||||
int skinsize;
|
||||
byte *skin;
|
||||
int groupskins;
|
||||
daliasskingroup_t *pinskingroup;
|
||||
maliasskingroup_t *paliasskingroup;
|
||||
int i, numskins;
|
||||
daliasskininterval_t *pinskinintervals;
|
||||
maliasskindesc_t *pskindesc;
|
||||
maliasskingroup_t *paliasskingroup;
|
||||
float *poutskinintervals;
|
||||
void *ptemp;
|
||||
|
||||
pinskingroup = (daliasskingroup_t *)pin;
|
||||
skin = (byte *)pskintype;
|
||||
|
||||
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)
|
||||
Sys_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;
|
||||
|
||||
start = Hunk_LowMark ();
|
||||
|
||||
pinmodel = (mdl_t *)buffer;
|
||||
|
||||
version = LittleLong (pinmodel->version);
|
||||
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
|
||||
//
|
||||
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)
|
||||
Sys_Error ("model %s has a skin taller than %d", mod->name,
|
||||
MAX_LBM_HEIGHT);
|
||||
|
||||
pmodel->numverts = LittleLong (pinmodel->numverts);
|
||||
|
||||
if (pmodel->numverts <= 0)
|
||||
Sys_Error ("model %s has no vertices", mod->name);
|
||||
|
||||
if (pmodel->numverts > MAXALIASVERTS)
|
||||
Sys_Error ("model %s has too many vertices", mod->name);
|
||||
|
||||
pmodel->numtris = LittleLong (pinmodel->numtris);
|
||||
|
||||
if (pmodel->numtris <= 0)
|
||||
Sys_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)
|
||||
Sys_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)
|
||||
if (numskins < 1 || numskins > MAX_SKINS)
|
||||
Sys_Error ("Mod_LoadAliasModel: Invalid # of skins: %d\n", numskins);
|
||||
|
||||
pskintype = (daliasskintype_t *)&pinmodel[1];
|
||||
|
||||
skinsize = pheader->mdl.skinwidth * pheader->mdl.skinheight;
|
||||
pskindesc = Hunk_AllocName (numskins * sizeof (maliasskindesc_t),
|
||||
loadname);
|
||||
|
||||
pheader->skindesc = (byte *)pskindesc - (byte *)pheader;
|
||||
|
||||
for (i=0 ; i<numskins ; i++)
|
||||
{
|
||||
aliasskintype_t skintype;
|
||||
if (pskintype->type == ALIAS_SKIN_SINGLE) {
|
||||
skin+=4;
|
||||
skin = Mod_LoadSkin (skin, skinsize, &pskindesc[i].skin, i, 0);
|
||||
} else {
|
||||
pskintype++;
|
||||
pinskingroup = (daliasskingroup_t *)pskintype;
|
||||
groupskins = LittleLong (pinskingroup->numskins);
|
||||
|
||||
skintype = LittleLong (pskintype->type);
|
||||
pskindesc[i].type = skintype;
|
||||
j = sizeof (maliasskingroup_t) +
|
||||
(groupskins - 1) * sizeof (paliasskingroup->skindescs[0]);
|
||||
j = (int)&((maliasskingroup_t*)0)->skindescs[groupskins];
|
||||
paliasskingroup = Hunk_AllocName (j, loadname);
|
||||
paliasskingroup->numskins = groupskins;
|
||||
|
||||
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);
|
||||
*pskinindex = (byte *)paliasskingroup - (byte *)pheader;
|
||||
|
||||
pinskinintervals = (daliasskininterval_t *)(pinskingroup + 1);
|
||||
poutskinintervals = Hunk_AllocName (groupskins * sizeof (float),loadname);
|
||||
paliasskingroup->intervals = (byte *)poutskinintervals - (byte *)pheader;
|
||||
for (i=0 ; i<groupskins ; i++) {
|
||||
*poutskinintervals = LittleFloat (pinskinintervals->interval);
|
||||
if (*poutskinintervals <= 0)
|
||||
Sys_Error ("Mod_LoadAliasSkinGroup: interval<=0");
|
||||
|
||||
poutskinintervals++;
|
||||
pinskinintervals++;
|
||||
}
|
||||
|
||||
pskintype = (void *)pinskinintervals;
|
||||
skin = (byte *)pskintype;
|
||||
|
||||
for (j=0 ; j<groupskins ; j++)
|
||||
{
|
||||
skin+=4;
|
||||
skin = Mod_LoadSkin (skin, skinsize, &paliasskingroup->skindescs[i].skin, i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// 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)
|
||||
Sys_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);
|
||||
return (void *)skin;
|
||||
}
|
||||
|
||||
void GL_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr)
|
||||
{
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue