merge the model_merge branch into HEAD. This chops up the model loading code

into something a litter easier to maintain (I hope) as most common bits have
been merged. I'm not 100% satisfied with alias frames, but that can wait till
later.

NOTE: d_copy.S currently ALWAYS produces asm output. This IS a bug, but I was
too lazy to convert it to C (hopefully it won't matter as I think svgalib is for
x86 Linux (and *BSD?) only anyway.
This commit is contained in:
Bill Currie 2000-09-12 00:56:52 +00:00
commit 42bf156a01
20 changed files with 1457 additions and 2587 deletions

View file

@ -270,15 +270,16 @@ Alias models are position independent, so the cache manager can move them.
==============================================================================
*/
/* NOTE: the first three lines must match maliasgroupframedesc_t */
typedef struct
{
trivertx_t bboxmin;
trivertx_t bboxmax;
int frame;
aliasframetype_t type;
int firstpose;
int numposes;
float interval;
trivertx_t bboxmin;
trivertx_t bboxmax;
int frame;
char name[16];
} maliasframedesc_t;
@ -318,21 +319,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 +332,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;
@ -465,4 +454,6 @@ void Mod_TouchModel (char *name);
mleaf_t *Mod_PointInLeaf (float *p, model_t *model);
byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model);
model_t *Mod_FindName (char *name);
#endif // _MODEL_H

1
source/.gdbinit Normal file
View file

@ -0,0 +1 @@
set args -nodga -nosound +set _windowed_mouse 0

1
source/.gitignore vendored
View file

@ -1,3 +1,4 @@
.vimrc
*.a
*.d
*.o

View file

@ -49,6 +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_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)
@ -133,7 +134,8 @@ soft_SOURCES= d_edge.c d_fill.c d_init.c d_modech.c d_part.c d_polyse.c \
d_scan.c d_sky.c d_sprite.c d_surf.c d_vars.c d_zpoint.c \
draw.c r_aclip.c r_alias.c r_bsp.c r_draw.c r_edge.c r_efrag.c \
r_light.c r_main.c r_misc.c sw_part.c r_sky.c r_sprite.c \
r_surf.c r_vars.c screen.c model.c sw_view.c $(soft_ASM)
r_surf.c r_vars.c screen.c sw_model_alias.c sw_model_brush.c \
sw_model_sprite.c sw_view.c $(soft_ASM)
#
# ... GGI
@ -188,7 +190,7 @@ nuq_x11_DEPENDENCIES=libqfsys.a libqfsnd.a libqfcd.a libqfnet.a
#
ogl_SOURCES= gl_draw.c gl_mesh.c gl_part.c gl_refrag.c gl_rlight.c \
gl_rmain.c gl_rmisc.c gl_rsurf.c gl_screen.c gl_view.c \
gl_warp.c gl_model.c
gl_warp.c gl_model_alias.c gl_model_brush.c gl_model_sprite.c
#
# ... 3Dfx Voodoo 1 and 2 SVGAlib-based console GL

View file

@ -33,7 +33,7 @@
#include "quakeasm.h"
#include "asm_draw.h"
#ifdef USE_INTEL_ASM
//#ifdef USE_INTEL_ASM
.data
LCopyWidth: .long 0
@ -173,4 +173,4 @@ LLRowLoop:
popl %ebp // restore the caller's stack frame
ret
#endif /* USE_INTEL_ASM */
//#endif /* USE_INTEL_ASM */

View file

@ -32,6 +32,7 @@
#ifndef USE_INTEL_ASM
#include "qtypes.h"
// all global and static refresh variables are collected in a contiguous block
// to avoid cache conflicts.

View file

@ -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;
}

352
source/gl_model_alias.c Normal file
View file

@ -0,0 +1,352 @@
/*
gl_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;
/*
==============================================================================
ALIAS MODELS
==============================================================================
*/
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];
/*
=================
Mod_FloodFillSkin
Fill background pixels so mipmapping doesn't have haloes - Ed
=================
*/
typedef struct
{
short x, y;
} floodfill_t;
extern unsigned d_8to24table[];
// must be a power of 2
#define FLOODFILL_FIFO_SIZE 0x1000
#define FLOODFILL_FIFO_MASK (FLOODFILL_FIFO_SIZE - 1)
#define FLOODFILL_STEP( off, dx, dy ) \
{ \
if (pos[off] == fillcolor) \
{ \
pos[off] = 255; \
fifo[inpt].x = x + (dx), fifo[inpt].y = y + (dy); \
inpt = (inpt + 1) & FLOODFILL_FIFO_MASK; \
} \
else if (pos[off] != 255) fdc = pos[off]; \
}
void Mod_FloodFillSkin( byte *skin, int skinwidth, int skinheight )
{
byte fillcolor = *skin; // assume this is the pixel to fill
floodfill_t fifo[FLOODFILL_FIFO_SIZE];
int inpt = 0, outpt = 0;
int filledcolor = -1;
int i;
if (filledcolor == -1)
{
filledcolor = 0;
// attempt to find opaque black
for (i = 0; i < 256; ++i)
if (d_8to24table[i] == (255 << 0)) // alpha 1.0
{
filledcolor = i;
break;
}
}
// can't fill to filled color or to transparent color (used as visited marker)
if ((fillcolor == filledcolor) || (fillcolor == 255))
{
//printf( "not filling skin from %d to %d\n", fillcolor, filledcolor );
return;
}
fifo[inpt].x = 0, fifo[inpt].y = 0;
inpt = (inpt + 1) & FLOODFILL_FIFO_MASK;
while (outpt != inpt)
{
int x = fifo[outpt].x, y = fifo[outpt].y;
int fdc = filledcolor;
byte *pos = &skin[x + skinwidth * y];
outpt = (outpt + 1) & FLOODFILL_FIFO_MASK;
if (x > 0) FLOODFILL_STEP( -1, -1, 0 );
if (x < skinwidth - 1) FLOODFILL_STEP( 1, 1, 0 );
if (y > 0) FLOODFILL_STEP( -skinwidth, 0, -1 );
if (y < skinheight - 1) FLOODFILL_STEP( skinwidth, 0, 1 );
skin[x + skinwidth * y] = fdc;
}
}
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, int *pskinindex)
{
int i, j, k;
int skinsize;
byte *skin;
daliasskingroup_t *pinskingroup;
int groupskins;
daliasskininterval_t *pinskinintervals;
skin = (byte *)pskintype;
if (numskins < 1 || numskins > MAX_SKINS)
Sys_Error ("Mod_LoadAliasModel: Invalid # of skins: %d\n", numskins);
skinsize = pheader->mdl.skinwidth * pheader->mdl.skinheight;
for (i=0 ; i<numskins ; i++)
{
if (pskintype->type == ALIAS_SKIN_SINGLE) {
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 (skinsize > sizeof(player_8bit_texels))
Sys_Error ("Player skin too large");
memcpy (player_8bit_texels, skin, skinsize);
}
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];
}
} else {
// animating skin group. yuck.
Con_Printf("Animating Skin Group, if you get this message please notify warp@debian.org\n");
pskintype++;
pinskingroup = (daliasskingroup_t *)pskintype;
groupskins = LittleLong (pinskingroup->numskins);
pinskinintervals = (daliasskininterval_t *)(pinskingroup + 1);
pskintype = (void *)(pinskinintervals + groupskins);
skin = (byte *)pskintype;
for (j=0 ; j<groupskins ; j++)
{
skin+=4;
skin = Mod_LoadSkin (skin, skinsize, i, j, true);
}
k = j;
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 *)skin;
}
/*
=================
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;
}

95
source/gl_model_brush.c Normal file
View file

@ -0,0 +1,95 @@
/*
gl_model_brush.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;
extern byte mod_novis[];
extern byte *mod_base;
const int mod_lightmap_bytes = 3;
void
Mod_LoadMMNearest(miptex_t *mt, texture_t *tx)
{
texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR;
tx->gl_texturenum = GL_LoadTexture (mt->name, tx->width, tx->height, (byte *)(tx+1), true, false, 1);
texture_mode = GL_LINEAR;
}
/*
=================
Mod_LoadLighting
=================
*/
void Mod_LoadLighting (lump_t *l)
{
int i;
byte *in, *out;
byte d;
char litfilename[1024];
if (!l->filelen)
{
loadmodel->lightdata = NULL;
return;
}
strcpy(litfilename, loadmodel->name);
COM_StripExtension(litfilename, litfilename);
strcat(litfilename, ".lit");
loadmodel->lightdata = (byte*) COM_LoadHunkFile (litfilename);
if (!loadmodel->lightdata) // expand the white lighting data
{
loadmodel->lightdata = Hunk_AllocName ( l->filelen*3, litfilename);
in = loadmodel->lightdata + l->filelen*2; // place the file at the end, so it will not be overwritten until the very last write
out = loadmodel->lightdata;
memcpy (in, mod_base + l->fileofs, l->filelen);
for (i = 0;i < l->filelen;i++)
{
d = *in++;
*out++ = d;
*out++ = d;
*out++ = d;
}
}
}

81
source/gl_model_sprite.c Normal file
View file

@ -0,0 +1,81 @@
/*
gl_model_sprite.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$
*/
#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;
/*
=================
Mod_LoadSpriteFrame
=================
*/
void * Mod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum)
{
dspriteframe_t *pinframe;
mspriteframe_t *pspriteframe;
int width, height, size, origin[2];
char name[64];
pinframe = (dspriteframe_t *)pin;
width = LittleLong (pinframe->width);
height = LittleLong (pinframe->height);
size = width * height;
pspriteframe = Hunk_AllocName (sizeof (mspriteframe_t),loadname);
memset (pspriteframe, 0, sizeof (mspriteframe_t));
*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];
snprintf (name, sizeof(name), "%s_%i", loadmodel->name, framenum);
pspriteframe->gl_texturenum = GL_LoadTexture (name, width, height, (byte *)(pinframe + 1), true, true, 1);
return (void *)((byte *)pinframe + sizeof (dspriteframe_t) + size);
}

View file

@ -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;

View file

@ -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

View file

@ -34,6 +34,7 @@
#include "mathlib.h"
#include "sys.h"
#include "model.h"
vec3_t vec3_origin = {0,0,0};
int nanmask = 255<<23;

File diff suppressed because it is too large Load diff

237
source/model_alias.c Normal file
View file

@ -0,0 +1,237 @@
/*
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];
void *Mod_LoadAliasFrame (void * pin, maliasframedesc_t *frame);
void *Mod_LoadAliasGroup (void * pin, maliasframedesc_t *frame);
//=========================================================================
/*
=================
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);
pheader->frames[i].type = frametype;
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);
}

File diff suppressed because it is too large Load diff

175
source/model_sprite.c Normal file
View file

@ -0,0 +1,175 @@
/*
model_sprite.c
sprite 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_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum);
/*
=================
Mod_LoadSpriteGroup
=================
*/
void * Mod_LoadSpriteGroup (void * pin, mspriteframe_t **ppframe, int framenum)
{
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)
Sys_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], framenum * 100 + 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)
Sys_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)
Sys_Error ("Mod_LoadSpriteModel: Invalid # of frames: %d\n", numframes);
mod->numframes = numframes;
mod->flags = 0;
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, i);
}
else
{
pframetype = (dspriteframetype_t *)
Mod_LoadSpriteGroup (pframetype + 1,
&psprite->frames[i].frameptr, i);
}
}
mod->type = mod_sprite;
}

293
source/sw_model_alias.c Normal file
View file

@ -0,0 +1,293 @@
/*
sw_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;
/*
==============================================================================
ALIAS MODELS
==============================================================================
*/
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;
pskin = Hunk_AllocName (skinsize * r_pixbytes, loadname);
*pskinindex = (byte *)pskin - (byte *)pheader;
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);
break;
}
return skin + skinsize;
}
/*
===============
Mod_LoadAllSkins
===============
*/
void *Mod_LoadAllSkins (int numskins, daliasskintype_t *pskintype, int *pskinindex)
{
int i, j;
int skinsize;
byte *skin;
int groupskins;
daliasskingroup_t *pinskingroup;
daliasskininterval_t *pinskinintervals;
maliasskindesc_t *pskindesc;
maliasskingroup_t *paliasskingroup;
float *poutskinintervals;
skin = (byte *)pskintype;
if (numskins < 1 || numskins > MAX_SKINS)
Sys_Error ("Mod_LoadAliasModel: Invalid # of skins: %d\n", numskins);
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++)
{
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);
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;
*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);
}
}
}
return (void *)skin;
}
void GL_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr)
{
int i, j;
stvert_t *pstverts;
mtriangle_t *ptri;
int numv = hdr->mdl.numverts;
int numt = hdr->mdl.numtris;
pstverts = (stvert_t *)Hunk_AllocName(numv * sizeof(stvert_t),loadname);
ptri = (mtriangle_t *)Hunk_AllocName(numt * sizeof(mtriangle_t),loadname);
hdr->stverts = (byte *)pstverts - (byte *)hdr;
hdr->triangles = (byte *)ptri - (byte *)hdr;
for (i=0; i<numv; i++) {
pstverts[i].onseam = stverts[i].onseam;
pstverts[i].s = stverts[i].s << 16;
pstverts[i].t = stverts[i].t << 16;
}
for (i=0; i<numt; i++) {
ptri[i].facesfront = triangles[i].facesfront;
for (j=0; j<3; j++) {
ptri[i].vertindex[j] = triangles[i].vertindex[j];
}
}
}
/*
=================
Mod_LoadAliasFrame
=================
*/
void * Mod_LoadAliasFrame (void * pin, maliasframedesc_t *frame)
{
trivertx_t *pframe, *pinframe;
int i, j;
daliasframe_t *pdaliasframe;
pdaliasframe = (daliasframe_t *)pin;
strcpy (frame->name, pdaliasframe->name);
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->bboxmax.v[i] = pdaliasframe->bboxmax.v[i];
}
pinframe = (trivertx_t *)(pdaliasframe + 1);
pframe = Hunk_AllocName (pheader->mdl.numverts * sizeof(*pframe), loadname);
frame->frame = (byte *)pframe - (byte *)pheader;
for (j=0 ; j<pheader->mdl.numverts ; 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 += pheader->mdl.numverts;
return (void *)pinframe;
}
/*
=================
Mod_LoadAliasGroup
=================
*/
void * Mod_LoadAliasGroup (void * pin, maliasframedesc_t *frame)
{
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
frame->bboxmin.v[i] = pingroup->bboxmin.v[i];
frame->bboxmax.v[i] = pingroup->bboxmax.v[i];
}
frame->frame = (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, (maliasframedesc_t*)&paliasgroup->frames[i]);
}
return ptemp;
}

70
source/sw_model_brush.c Normal file
View file

@ -0,0 +1,70 @@
/*
sw_model_brush.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$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "r_local.h"
#include "sys.h"
#include "console.h"
#include "qendian.h"
#include "checksum.h"
extern char loadname[];
extern model_t *loadmodel;
extern byte mod_novis[];
extern byte *mod_base;
const int mod_lightmap_bytes = 1;
void
GL_SubdivideSurface (msurface_t *fa)
{
}
void
Mod_LoadMMNearest(miptex_t *mt, texture_t *tx)
{
}
/*
=================
Mod_LoadLighting
=================
*/
void Mod_LoadLighting (lump_t *l)
{
if (!l->filelen)
{
loadmodel->lightdata = NULL;
return;
}
loadmodel->lightdata = Hunk_AllocName ( l->filelen, loadname);
memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen);
}

95
source/sw_model_sprite.c Normal file
View file

@ -0,0 +1,95 @@
/*
sw_model_sprite.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$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "r_local.h"
#include "sys.h"
#include "console.h"
#include "qendian.h"
#include "checksum.h"
extern char loadname[];
/*
=================
Mod_LoadSpriteFrame
=================
*/
void * Mod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum)
{
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);
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)
{
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
{
Sys_Error ("Mod_LoadSpriteFrame: driver set invalid r_pixbytes: %d\n",
r_pixbytes);
}
return (void *)((byte *)pinframe + sizeof (dspriteframe_t) + size);
}