home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / glquake_src / gl_model.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-02-17  |  41.6 KB  |  1,844 lines

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // models.c -- model loading and caching
  21.  
  22. // models are the only shared resource between a client and server running
  23. // on the same machine.
  24.  
  25. #include "quakedef.h"
  26.  
  27. model_t *loadmodel;
  28. char  loadname[32]; // for hunk tags
  29.  
  30. void Mod_LoadSpriteModel (model_t *mod, void *buffer);
  31. void Mod_LoadBrushModel (model_t *mod, void *buffer);
  32. void Mod_LoadAliasModel (model_t *mod, void *buffer);
  33. model_t *Mod_LoadModel (model_t *mod, qboolean crash);
  34.  
  35. byte  mod_novis[MAX_MAP_LEAFS/8];
  36.  
  37. #define MAX_MOD_KNOWN 512
  38. model_t mod_known[MAX_MOD_KNOWN];
  39. int   mod_numknown;
  40.  
  41. cvar_t gl_subdivide_size = {"gl_subdivide_size", "128", true};
  42.  
  43. /*
  44. ===============
  45. Mod_Init
  46. ===============
  47. */
  48. void Mod_Init (void)
  49. {
  50.   Cvar_RegisterVariable (&gl_subdivide_size);
  51.   memset (mod_novis, 0xff, sizeof(mod_novis));
  52. }
  53.  
  54. /*
  55. ===============
  56. Mod_Init
  57.  
  58. Caches the data if needed
  59. ===============
  60. */
  61. void *Mod_Extradata (model_t *mod)
  62. {
  63.   void  *r;
  64.   
  65.   r = Cache_Check (&mod->cache);
  66.   if (r)
  67.     return r;
  68.  
  69.   Mod_LoadModel (mod, true);
  70.   
  71.   if (!mod->cache.data)
  72.     Sys_Error ("Mod_Extradata: caching failed");
  73.   return mod->cache.data;
  74. }
  75.  
  76. /*
  77. ===============
  78. Mod_PointInLeaf
  79. ===============
  80. */
  81. mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model)
  82. {
  83.   mnode_t   *node;
  84.   float   d;
  85.   mplane_t  *plane;
  86.   
  87.   if (!model || !model->nodes)
  88.     Sys_Error ("Mod_PointInLeaf: bad model");
  89.  
  90.   node = model->nodes;
  91.   while (1)
  92.   {
  93.     if (node->contents < 0)
  94.       return (mleaf_t *)node;
  95.     plane = node->plane;
  96.     d = DotProduct (p,plane->normal) - plane->dist;
  97.     if (d > 0)
  98.       node = node->children[0];
  99.     else
  100.       node = node->children[1];
  101.   }
  102.   
  103.   return NULL;  // never reached
  104. }
  105.  
  106.  
  107. /*
  108. ===================
  109. Mod_DecompressVis
  110. ===================
  111. */
  112. byte *Mod_DecompressVis (byte *in, model_t *model)
  113. {
  114.   static byte decompressed[MAX_MAP_LEAFS/8];
  115.   int   c;
  116.   byte  *out;
  117.   int   row;
  118.  
  119.   row = (model->numleafs+7)>>3; 
  120.   out = decompressed;
  121.  
  122. #if 0
  123.   memcpy (out, in, row);
  124. #else
  125.   if (!in)
  126.   { // no vis info, so make all visible
  127.  
  128.     while (row)
  129.     {
  130.       *out++ = 0xff;
  131.       row--;
  132.     }
  133.    
  134.     return decompressed;    
  135.   }
  136.  
  137.   do
  138.   {
  139.     if (*in)
  140.     {
  141.       *out++ = *in++;
  142.       continue;
  143.     }
  144.   
  145.     c = in[1];
  146.     in += 2;
  147.     while (c)
  148.     {
  149.       *out++ = 0;
  150.       c--;
  151.     }
  152.   } while (out - decompressed < row);
  153. #endif
  154.   
  155.   return decompressed;
  156. }
  157.  
  158. byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model)
  159. {
  160.   if (leaf == model->leafs)
  161.     return mod_novis;
  162.   return Mod_DecompressVis (leaf->compressed_vis, model);
  163. }
  164.  
  165. /*
  166. ===================
  167. Mod_ClearAll
  168. ===================
  169. */
  170. void Mod_ClearAll (void)
  171. {
  172.   int   i;
  173.   model_t *mod;
  174.   
  175.   for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
  176.     if (mod->type != mod_alias)
  177.       mod->needload = true;
  178. }
  179.  
  180. /*
  181. ==================
  182. Mod_FindName
  183.  
  184. ==================
  185. */
  186. model_t *Mod_FindName (char *name)
  187. {
  188.   int   i;
  189.   model_t *mod;
  190.   
  191.   if (!name[0])
  192.     Sys_Error ("Mod_ForName: NULL name");
  193.     
  194. //
  195. // search the currently loaded models
  196. //
  197.   for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
  198.     if (!strcmp (mod->name, name) )
  199.       break;
  200.       
  201.   if (i == mod_numknown)
  202.   {
  203.     if (mod_numknown == MAX_MOD_KNOWN)
  204.       Sys_Error ("mod_numknown == MAX_MOD_KNOWN");
  205.     strcpy (mod->name, name);
  206.     mod->needload = true;
  207.     mod_numknown++;
  208.   }
  209.  
  210.   return mod;
  211. }
  212.  
  213. /*
  214. ==================
  215. Mod_TouchModel
  216.  
  217. ==================
  218. */
  219. void Mod_TouchModel (char *name)
  220. {
  221.   model_t *mod;
  222.   
  223.   mod = Mod_FindName (name);
  224.   
  225.   if (!mod->needload)
  226.   {
  227.     if (mod->type == mod_alias)
  228.       Cache_Check (&mod->cache);
  229.   }
  230. }
  231.  
  232. /*
  233. ==================
  234. Mod_LoadModel
  235.  
  236. Loads a model into the cache
  237. ==================
  238. */
  239. model_t *Mod_LoadModel (model_t *mod, qboolean crash)
  240. {
  241.   void  *d;
  242.   unsigned *buf;
  243.   byte  stackbuf[1024];   // avoid dirtying the cache heap
  244.  
  245.   if (!mod->needload)
  246.   {
  247.     if (mod->type == mod_alias)
  248.     {
  249.       d = Cache_Check (&mod->cache);
  250.       if (d)
  251.         return mod;
  252.     }
  253.     else
  254.       return mod;   // not cached at all
  255.   }
  256.  
  257. //
  258. // because the world is so huge, load it one piece at a time
  259. //
  260.   if (!crash)
  261.   {
  262.   
  263.   }
  264.   
  265. //
  266. // load the file
  267. //
  268.   buf = (unsigned *)COM_LoadStackFile (mod->name, stackbuf, sizeof(stackbuf));
  269.   if (!buf)
  270.   {
  271.     if (crash)
  272.       Sys_Error ("Mod_NumForName: %s not found", mod->name);
  273.     return NULL;
  274.   }
  275.   
  276. //
  277. // allocate a new model
  278. //
  279.   COM_FileBase (mod->name, loadname);
  280.   
  281.   loadmodel = mod;
  282.  
  283. //
  284. // fill it in
  285. //
  286.  
  287. // call the apropriate loader
  288.   mod->needload = false;
  289.   
  290.   switch (LittleLong(*(unsigned *)buf))
  291.   {
  292.   case IDPOLYHEADER:
  293.     Mod_LoadAliasModel (mod, buf);
  294.     break;
  295.     
  296.   case IDSPRITEHEADER:
  297.     Mod_LoadSpriteModel (mod, buf);
  298.     break;
  299.   
  300.   default:
  301.     Mod_LoadBrushModel (mod, buf);
  302.     break;
  303.   }
  304.  
  305.   return mod;
  306. }
  307.  
  308. /*
  309. ==================
  310. Mod_ForName
  311.  
  312. Loads in a model for the given name
  313. ==================
  314. */
  315. model_t *Mod_ForName (char *name, qboolean crash)
  316. {
  317.   model_t *mod;
  318.   
  319.   mod = Mod_FindName (name);
  320.   
  321.   return Mod_LoadModel (mod, crash);
  322. }
  323.  
  324.  
  325. /*
  326. ===============================================================================
  327.  
  328.           BRUSHMODEL LOADING
  329.  
  330. ===============================================================================
  331. */
  332.  
  333. byte  *mod_base;
  334.  
  335.  
  336. /*
  337. =================
  338. Mod_LoadTextures
  339. =================
  340. */
  341. void Mod_LoadTextures (lump_t *l)
  342. {
  343.   int   i, j, pixels, num, max, altmax;
  344.   miptex_t  *mt;
  345.   texture_t *tx, *tx2;
  346.   texture_t *anims[10];
  347.   texture_t *altanims[10];
  348.   dmiptexlump_t *m;
  349.  
  350.   if (!l->filelen)
  351.   {
  352.     loadmodel->textures = NULL;
  353.     return;
  354.   }
  355.   m = (dmiptexlump_t *)(mod_base + l->fileofs);
  356.   
  357.   m->nummiptex = LittleLong (m->nummiptex);
  358.   
  359.   loadmodel->numtextures = m->nummiptex;
  360.   loadmodel->textures = Hunk_AllocName (m->nummiptex * sizeof(*loadmodel->textures) , loadname);
  361.  
  362.   for (i=0 ; i<m->nummiptex ; i++)
  363.   {
  364.     m->dataofs[i] = LittleLong(m->dataofs[i]);
  365.     if (m->dataofs[i] == -1)
  366.       continue;
  367.     mt = (miptex_t *)((byte *)m + m->dataofs[i]);
  368.     mt->width = LittleLong (mt->width);
  369.     mt->height = LittleLong (mt->height);
  370.     for (j=0 ; j<MIPLEVELS ; j++)
  371.       mt->offsets[j] = LittleLong (mt->offsets[j]);
  372.     
  373.     if ( (mt->width & 15) || (mt->height & 15) )
  374.       Sys_Error ("Texture %s is not 16 aligned", mt->name);
  375.     pixels = mt->width*mt->height/64*85;
  376.     tx = Hunk_AllocName (sizeof(texture_t) +pixels, loadname );
  377.     loadmodel->textures[i] = tx;
  378.  
  379.     memcpy (tx->name, mt->name, sizeof(tx->name));
  380.     tx->width = mt->width;
  381.     tx->height = mt->height;
  382.     for (j=0 ; j<MIPLEVELS ; j++)
  383.       tx->offsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t);
  384.     // the pixels immediately follow the structures
  385.     memcpy ( tx+1, mt+1, pixels);
  386.     
  387.  
  388.     if (!Q_strncmp(mt->name,"sky",3)) 
  389.       R_InitSky (tx);
  390.     else
  391.     {
  392.       //texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR;
  393.       texture_mode = GL_LINEAR;
  394.       tx->gl_texturenum = GL_LoadTexture (mt->name, tx->width, tx->height, (byte *)(tx+1), true, false);
  395.       //texture_mode = GL_LINEAR;
  396.     }
  397.   }
  398.  
  399. //
  400. // sequence the animations
  401. //
  402.   for (i=0 ; i<m->nummiptex ; i++)
  403.   {
  404.     tx = loadmodel->textures[i];
  405.     if (!tx || tx->name[0] != '+')
  406.       continue;
  407.     if (tx->anim_next)
  408.       continue; // allready sequenced
  409.  
  410.   // find the number of frames in the animation
  411.     memset (anims, 0, sizeof(anims));
  412.     memset (altanims, 0, sizeof(altanims));
  413.  
  414.     max = tx->name[1];
  415.     altmax = 0;
  416.     if (max >= 'a' && max <= 'z')
  417.       max -= 'a' - 'A';
  418.     if (max >= '0' && max <= '9')
  419.     {
  420.       max -= '0';
  421.       altmax = 0;
  422.       anims[max] = tx;
  423.       max++;
  424.     }
  425.     else if (max >= 'A' && max <= 'J')
  426.     {
  427.       altmax = max - 'A';
  428.       max = 0;
  429.       altanims[altmax] = tx;
  430.       altmax++;
  431.     }
  432.     else
  433.       Sys_Error ("Bad animating texture %s", tx->name);
  434.  
  435.     for (j=i+1 ; j<m->nummiptex ; j++)
  436.     {
  437.       tx2 = loadmodel->textures[j];
  438.       if (!tx2 || tx2->name[0] != '+')
  439.         continue;
  440.       if (strcmp (tx2->name+2, tx->name+2))
  441.         continue;
  442.  
  443.       num = tx2->name[1];
  444.       if (num >= 'a' && num <= 'z')
  445.         num -= 'a' - 'A';
  446.       if (num >= '0' && num <= '9')
  447.       {
  448.         num -= '0';
  449.         anims[num] = tx2;
  450.         if (num+1 > max)
  451.           max = num + 1;
  452.       }
  453.       else if (num >= 'A' && num <= 'J')
  454.       {
  455.         num = num - 'A';
  456.         altanims[num] = tx2;
  457.         if (num+1 > altmax)
  458.           altmax = num+1;
  459.       }
  460.       else
  461.         Sys_Error ("Bad animating texture %s", tx->name);
  462.     }
  463.     
  464. #define ANIM_CYCLE  2
  465.   // link them all together
  466.     for (j=0 ; j<max ; j++)
  467.     {
  468.       tx2 = anims[j];
  469.       if (!tx2)
  470.         Sys_Error ("Missing frame %i of %s",j, tx->name);
  471.       tx2->anim_total = max * ANIM_CYCLE;
  472.       tx2->anim_min = j * ANIM_CYCLE;
  473.       tx2->anim_max = (j+1) * ANIM_CYCLE;
  474.       tx2->anim_next = anims[ (j+1)%max ];
  475.       if (altmax)
  476.         tx2->alternate_anims = altanims[0];
  477.     }
  478.     for (j=0 ; j<altmax ; j++)
  479.     {
  480.       tx2 = altanims[j];
  481.       if (!tx2)
  482.         Sys_Error ("Missing frame %i of %s",j, tx->name);
  483.       tx2->anim_total = altmax * ANIM_CYCLE;
  484.       tx2->anim_min = j * ANIM_CYCLE;
  485.       tx2->anim_max = (j+1) * ANIM_CYCLE;
  486.       tx2->anim_next = altanims[ (j+1)%altmax ];
  487.       if (max)
  488.         tx2->alternate_anims = anims[0];
  489.     }
  490.   }
  491. }
  492.  
  493. /*
  494. =================
  495. Mod_LoadLighting
  496. =================
  497. */
  498. void Mod_LoadLighting (lump_t *l)
  499. {
  500.   if (!l->filelen)
  501.   {
  502.     loadmodel->lightdata = NULL;
  503.     return;
  504.   }
  505.   loadmodel->lightdata = Hunk_AllocName ( l->filelen, loadname);  
  506.   memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen);
  507. }
  508.  
  509.  
  510. /*
  511. =================
  512. Mod_LoadVisibility
  513. =================
  514. */
  515. void Mod_LoadVisibility (lump_t *l)
  516. {
  517.   if (!l->filelen)
  518.   {
  519.     loadmodel->visdata = NULL;
  520.     return;
  521.   }
  522.   loadmodel->visdata = Hunk_AllocName ( l->filelen, loadname);  
  523.   memcpy (loadmodel->visdata, mod_base + l->fileofs, l->filelen);
  524. }
  525.  
  526.  
  527. /*
  528. =================
  529. Mod_LoadEntities
  530. =================
  531. */
  532. void Mod_LoadEntities (lump_t *l)
  533. {
  534.   if (!l->filelen)
  535.   {
  536.     loadmodel->entities = NULL;
  537.     return;
  538.   }
  539.   loadmodel->entities = Hunk_AllocName ( l->filelen, loadname); 
  540.   memcpy (loadmodel->entities, mod_base + l->fileofs, l->filelen);
  541. }
  542.  
  543.  
  544. /*
  545. =================
  546. Mod_LoadVertexes
  547. =================
  548. */
  549. void Mod_LoadVertexes (lump_t *l)
  550. {
  551.   dvertex_t *in;
  552.   mvertex_t *out;
  553.   int     i, count;
  554.  
  555.   in = (void *)(mod_base + l->fileofs);
  556.   if (l->filelen % sizeof(*in))
  557.     Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  558.   count = l->filelen / sizeof(*in);
  559.   out = Hunk_AllocName ( count*sizeof(*out), loadname); 
  560.  
  561.   loadmodel->vertexes = out;
  562.   loadmodel->numvertexes = count;
  563.  
  564.   for ( i=0 ; i<count ; i++, in++, out++)
  565.   {
  566.     out->position[0] = LittleFloat (in->point[0]);
  567.     out->position[1] = LittleFloat (in->point[1]);
  568.     out->position[2] = LittleFloat (in->point[2]);
  569.   }
  570. }
  571.  
  572. /*
  573. =================
  574. Mod_LoadSubmodels
  575. =================
  576. */
  577. void Mod_LoadSubmodels (lump_t *l)
  578. {
  579.   dmodel_t  *in;
  580.   dmodel_t  *out;
  581.   int     i, j, count;
  582.  
  583.   in = (void *)(mod_base + l->fileofs);
  584.   if (l->filelen % sizeof(*in))
  585.     Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  586.   count = l->filelen / sizeof(*in);
  587.   out = Hunk_AllocName ( count*sizeof(*out), loadname); 
  588.  
  589.   loadmodel->submodels = out;
  590.   loadmodel->numsubmodels = count;
  591.  
  592.   for ( i=0 ; i<count ; i++, in++, out++)
  593.   {
  594.     for (j=0 ; j<3 ; j++)
  595.     { // spread the mins / maxs by a pixel
  596.       out->mins[j] = LittleFloat (in->mins[j]) - 1;
  597.       out->maxs[j] = LittleFloat (in->maxs[j]) + 1;
  598.       out->origin[j] = LittleFloat (in->origin[j]);
  599.     }
  600.     for (j=0 ; j<MAX_MAP_HULLS ; j++)
  601.       out->headnode[j] = LittleLong (in->headnode[j]);
  602.     out->visleafs = LittleLong (in->visleafs);
  603.     out->firstface = LittleLong (in->firstface);
  604.     out->numfaces = LittleLong (in->numfaces);
  605.   }
  606. }
  607.  
  608. /*
  609. =================
  610. Mod_LoadEdges
  611. =================
  612. */
  613. void Mod_LoadEdges (lump_t *l)
  614. {
  615.   dedge_t *in;
  616.   medge_t *out;
  617.   int   i, count;
  618.  
  619.   in = (void *)(mod_base + l->fileofs);
  620.   if (l->filelen % sizeof(*in))
  621.     Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  622.   count = l->filelen / sizeof(*in);
  623.   out = Hunk_AllocName ( (count + 1) * sizeof(*out), loadname); 
  624.  
  625.   loadmodel->edges = out;
  626.   loadmodel->numedges = count;
  627.  
  628.   for ( i=0 ; i<count ; i++, in++, out++)
  629.   {
  630.     out->v[0] = (unsigned short)LittleShort(in->v[0]);
  631.     out->v[1] = (unsigned short)LittleShort(in->v[1]);
  632.   }
  633. }
  634.  
  635. /*
  636. =================
  637. Mod_LoadTexinfo
  638. =================
  639. */
  640. void Mod_LoadTexinfo (lump_t *l)
  641. {
  642.   texinfo_t *in;
  643.   mtexinfo_t *out;
  644.   int   i, j, count;
  645.   int   miptex;
  646.   float len1, len2;
  647.  
  648.   in = (void *)(mod_base + l->fileofs);
  649.   if (l->filelen % sizeof(*in))
  650.     Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  651.   count = l->filelen / sizeof(*in);
  652.   out = Hunk_AllocName ( count*sizeof(*out), loadname); 
  653.  
  654.   loadmodel->texinfo = out;
  655.   loadmodel->numtexinfo = count;
  656.  
  657.   for ( i=0 ; i<count ; i++, in++, out++)
  658.   {
  659.     for (j=0 ; j<8 ; j++)
  660.       out->vecs[0][j] = LittleFloat (in->vecs[0][j]);
  661.     len1 = Length (out->vecs[0]);
  662.     len2 = Length (out->vecs[1]);
  663.     len1 = (len1 + len2)/2;
  664.     if (len1 < 0.32)
  665.       out->mipadjust = 4;
  666.     else if (len1 < 0.49)
  667.       out->mipadjust = 3;
  668.     else if (len1 < 0.99)
  669.       out->mipadjust = 2;
  670.     else
  671.       out->mipadjust = 1;
  672. #if 0
  673.     if (len1 + len2 < 0.001)
  674.       out->mipadjust = 1;   // don't crash
  675.     else
  676.       out->mipadjust = 1 / floor( (len1+len2)/2 + 0.1 );
  677. #endif
  678.  
  679.     miptex = LittleLong (in->miptex);
  680.     out->flags = LittleLong (in->flags);
  681.   
  682.     if (!loadmodel->textures)
  683.     {
  684.       out->texture = r_notexture_mip; // checkerboard texture
  685.       out->flags = 0;
  686.     }
  687.     else
  688.     {
  689.       if (miptex >= loadmodel->numtextures)
  690.         Sys_Error ("miptex >= loadmodel->numtextures");
  691.       out->texture = loadmodel->textures[miptex];
  692.       if (!out->texture)
  693.       {
  694.         out->texture = r_notexture_mip; // texture not found
  695.         out->flags = 0;
  696.       }
  697.     }
  698.   }
  699. }
  700.  
  701. /*
  702. ================
  703. CalcSurfaceExtents
  704.  
  705. Fills in s->texturemins[] and s->extents[]
  706. ================
  707. */
  708. void CalcSurfaceExtents (msurface_t *s)
  709. {
  710.   float mins[2], maxs[2], val;
  711.   int   i,j, e;
  712.   mvertex_t *v;
  713.   mtexinfo_t  *tex;
  714.   int   bmins[2], bmaxs[2];
  715.  
  716.   mins[0] = mins[1] = 999999;
  717.   maxs[0] = maxs[1] = -99999;
  718.  
  719.   tex = s->texinfo;
  720.   
  721.   for (i=0 ; i<s->numedges ; i++)
  722.   {
  723.     e = loadmodel->surfedges[s->firstedge+i];
  724.     if (e >= 0)
  725.       v = &loadmodel->vertexes[loadmodel->edges[e].v[0]];
  726.     else
  727.       v = &loadmodel->vertexes[loadmodel->edges[-e].v[1]];
  728.     
  729.     for (j=0 ; j<2 ; j++)
  730.     {
  731.       val = v->position[0] * tex->vecs[j][0] + 
  732.         v->position[1] * tex->vecs[j][1] +
  733.         v->position[2] * tex->vecs[j][2] +
  734.         tex->vecs[j][3];
  735.       if (val < mins[j])
  736.         mins[j] = val;
  737.       if (val > maxs[j])
  738.         maxs[j] = val;
  739.     }
  740.   }
  741.  
  742.   for (i=0 ; i<2 ; i++)
  743.   { 
  744.     bmins[i] = floor(mins[i]/16);
  745.     bmaxs[i] = ceil(maxs[i]/16);
  746.  
  747.     s->texturemins[i] = bmins[i] * 16;
  748.     s->extents[i] = (bmaxs[i] - bmins[i]) * 16;
  749.     if ( !(tex->flags & TEX_SPECIAL) && s->extents[i] > 512 /* 256 */ )
  750.       Sys_Error ("Bad surface extents");
  751.   }
  752. }
  753.  
  754.  
  755. /*
  756. =================
  757. Mod_LoadFaces
  758. =================
  759. */
  760. void Mod_LoadFaces (lump_t *l)
  761. {
  762.   dface_t   *in;
  763.   msurface_t  *out;
  764.   int     i, count, surfnum;
  765.   int     planenum, side;
  766.  
  767.   in = (void *)(mod_base + l->fileofs);
  768.   if (l->filelen % sizeof(*in))
  769.     Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  770.   count = l->filelen / sizeof(*in);
  771.   out = Hunk_AllocName ( count*sizeof(*out), loadname); 
  772.  
  773.   loadmodel->surfaces = out;
  774.   loadmodel->numsurfaces = count;
  775.  
  776.   for ( surfnum=0 ; surfnum<count ; surfnum++, in++, out++)
  777.   {
  778.     out->firstedge = LittleLong(in->firstedge);
  779.     out->numedges = LittleShort(in->numedges);    
  780.     out->flags = 0;
  781.  
  782.     planenum = LittleShort(in->planenum);
  783.     side = LittleShort(in->side);
  784.     if (side)
  785.       out->flags |= SURF_PLANEBACK;     
  786.  
  787.     out->plane = loadmodel->planes + planenum;
  788.  
  789.     out->texinfo = loadmodel->texinfo + LittleShort (in->texinfo);
  790.  
  791.     CalcSurfaceExtents (out);
  792.         
  793.   // lighting info
  794.  
  795.     for (i=0 ; i<MAXLIGHTMAPS ; i++)
  796.       out->styles[i] = in->styles[i];
  797.     i = LittleLong(in->lightofs);
  798.     if (i == -1)
  799.       out->samples = NULL;
  800.     else
  801.       out->samples = loadmodel->lightdata + i;
  802.     
  803.   // set the drawing flags flag
  804.     
  805.     if (!Q_strncmp(out->texinfo->texture->name,"sky",3))  // sky
  806.     {
  807.       out->flags |= (SURF_DRAWSKY | SURF_DRAWTILED);
  808. #ifndef QUAKE2
  809.       GL_SubdivideSurface (out);  // cut up polygon for warps
  810. #endif
  811.       continue;
  812.     }
  813.     
  814.     if (!Q_strncmp(out->texinfo->texture->name,"*",1))    // turbulent
  815.     {
  816.       out->flags |= (SURF_DRAWTURB | SURF_DRAWTILED);
  817.       for (i=0 ; i<2 ; i++)
  818.       {
  819.         out->extents[i] = 16384;
  820.         out->texturemins[i] = -8192;
  821.       }
  822.       GL_SubdivideSurface (out);  // cut up polygon for warps
  823.       continue;
  824.     }
  825.  
  826.   }
  827. }
  828.  
  829.  
  830. /*
  831. =================
  832. Mod_SetParent
  833. =================
  834. */
  835. void Mod_SetParent (mnode_t *node, mnode_t *parent)
  836. {
  837.   node->parent = parent;
  838.   if (node->contents < 0)
  839.     return;
  840.   Mod_SetParent (node->children[0], node);
  841.   Mod_SetParent (node->children[1], node);
  842. }
  843.  
  844. /*
  845. =================
  846. Mod_LoadNodes
  847. =================
  848. */
  849. void Mod_LoadNodes (lump_t *l)
  850. {
  851.   int     i, j, count, p;
  852.   dnode_t   *in;
  853.   mnode_t   *out;
  854.  
  855.   in = (void *)(mod_base + l->fileofs);
  856.   if (l->filelen % sizeof(*in))
  857.     Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  858.   count = l->filelen / sizeof(*in);
  859.   out = Hunk_AllocName ( count*sizeof(*out), loadname); 
  860.  
  861.   loadmodel->nodes = out;
  862.   loadmodel->numnodes = count;
  863.  
  864.   for ( i=0 ; i<count ; i++, in++, out++)
  865.   {
  866.     for (j=0 ; j<3 ; j++)
  867.     {
  868.       out->minmaxs[j] = LittleShort (in->mins[j]);
  869.       out->minmaxs[3+j] = LittleShort (in->maxs[j]);
  870.     }
  871.   
  872.     p = LittleLong(in->planenum);
  873.     out->plane = loadmodel->planes + p;
  874.  
  875.     out->firstsurface = LittleShort (in->firstface);
  876.     out->numsurfaces = LittleShort (in->numfaces);
  877.     
  878.     for (j=0 ; j<2 ; j++)
  879.     {
  880.       p = LittleShort (in->children[j]);
  881.       if (p >= 0)
  882.         out->children[j] = loadmodel->nodes + p;
  883.       else
  884.         out->children[j] = (mnode_t *)(loadmodel->leafs + (-1 - p));
  885.     }
  886.   }
  887.   
  888.   Mod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs
  889. }
  890.  
  891. /*
  892. =================
  893. Mod_LoadLeafs
  894. =================
  895. */
  896. void Mod_LoadLeafs (lump_t *l)
  897. {
  898.   dleaf_t   *in;
  899.   mleaf_t   *out;
  900.   int     i, j, count, p;
  901.  
  902.   in = (void *)(mod_base + l->fileofs);
  903.   if (l->filelen % sizeof(*in))
  904.     Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  905.   count = l->filelen / sizeof(*in);
  906.   out = Hunk_AllocName ( count*sizeof(*out), loadname); 
  907.  
  908.   loadmodel->leafs = out;
  909.   loadmodel->numleafs = count;
  910.  
  911.   for ( i=0 ; i<count ; i++, in++, out++)
  912.   {
  913.     for (j=0 ; j<3 ; j++)
  914.     {
  915.       out->minmaxs[j] = LittleShort (in->mins[j]);
  916.       out->minmaxs[3+j] = LittleShort (in->maxs[j]);
  917.     }
  918.  
  919.     p = LittleLong(in->contents);
  920.     out->contents = p;
  921.  
  922.     out->firstmarksurface = loadmodel->marksurfaces +
  923.       LittleShort(in->firstmarksurface);
  924.     out->nummarksurfaces = LittleShort(in->nummarksurfaces);
  925.     
  926.     p = LittleLong(in->visofs);
  927.     if (p == -1)
  928.       out->compressed_vis = NULL;
  929.     else
  930.       out->compressed_vis = loadmodel->visdata + p;
  931.     out->efrags = NULL;
  932.     
  933.     for (j=0 ; j<4 ; j++)
  934.       out->ambient_sound_level[j] = in->ambient_level[j];
  935.  
  936.     // gl underwater warp
  937.     if (out->contents != CONTENTS_EMPTY)
  938.     {
  939.       for (j=0 ; j<out->nummarksurfaces ; j++)
  940.         out->firstmarksurface[j]->flags |= SURF_UNDERWATER;
  941.     }
  942.   } 
  943. }
  944.  
  945. /*
  946. =================
  947. Mod_LoadClipnodes
  948. =================
  949. */
  950. void Mod_LoadClipnodes (lump_t *l)
  951. {
  952.   dclipnode_t *in, *out;
  953.   int     i, count;
  954.   hull_t    *hull;
  955.  
  956.   in = (void *)(mod_base + l->fileofs);
  957.   if (l->filelen % sizeof(*in))
  958.     Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  959.   count = l->filelen / sizeof(*in);
  960.   out = Hunk_AllocName ( count*sizeof(*out), loadname); 
  961.  
  962.   loadmodel->clipnodes = out;
  963.   loadmodel->numclipnodes = count;
  964.  
  965.   hull = &loadmodel->hulls[1];
  966.   hull->clipnodes = out;
  967.   hull->firstclipnode = 0;
  968.   hull->lastclipnode = count-1;
  969.   hull->planes = loadmodel->planes;
  970.   hull->clip_mins[0] = -16;
  971.   hull->clip_mins[1] = -16;
  972.   hull->clip_mins[2] = -24;
  973.   hull->clip_maxs[0] = 16;
  974.   hull->clip_maxs[1] = 16;
  975.   hull->clip_maxs[2] = 32;
  976.  
  977.   hull = &loadmodel->hulls[2];
  978.   hull->clipnodes = out;
  979.   hull->firstclipnode = 0;
  980.   hull->lastclipnode = count-1;
  981.   hull->planes = loadmodel->planes;
  982.   hull->clip_mins[0] = -32;
  983.   hull->clip_mins[1] = -32;
  984.   hull->clip_mins[2] = -24;
  985.   hull->clip_maxs[0] = 32;
  986.   hull->clip_maxs[1] = 32;
  987.   hull->clip_maxs[2] = 64;
  988.  
  989.   for (i=0 ; i<count ; i++, out++, in++)
  990.   {
  991.     out->planenum = LittleLong(in->planenum);
  992.     out->children[0] = LittleShort(in->children[0]);
  993.     out->children[1] = LittleShort(in->children[1]);
  994.   }
  995. }
  996.  
  997. /*
  998. =================
  999. Mod_MakeHull0
  1000.  
  1001. Deplicate the drawing hull structure as a clipping hull
  1002. =================
  1003. */
  1004. void Mod_MakeHull0 (void)
  1005. {
  1006.   mnode_t   *in, *child;
  1007.   dclipnode_t *out;
  1008.   int     i, j, count;
  1009.   hull_t    *hull;
  1010.   
  1011.   hull = &loadmodel->hulls[0];  
  1012.   
  1013.   in = loadmodel->nodes;
  1014.   count = loadmodel->numnodes;
  1015.   out = Hunk_AllocName ( count*sizeof(*out), loadname); 
  1016.  
  1017.   hull->clipnodes = out;
  1018.   hull->firstclipnode = 0;
  1019.   hull->lastclipnode = count-1;
  1020.   hull->planes = loadmodel->planes;
  1021.  
  1022.   for (i=0 ; i<count ; i++, out++, in++)
  1023.   {
  1024.     out->planenum = in->plane - loadmodel->planes;
  1025.     for (j=0 ; j<2 ; j++)
  1026.     {
  1027.       child = in->children[j];
  1028.       if (child->contents < 0)
  1029.         out->children[j] = child->contents;
  1030.       else
  1031.         out->children[j] = child - loadmodel->nodes;
  1032.     }
  1033.   }
  1034. }
  1035.  
  1036. /*
  1037. =================
  1038. Mod_LoadMarksurfaces
  1039. =================
  1040. */
  1041. void Mod_LoadMarksurfaces (lump_t *l)
  1042.   int   i, j, count;
  1043.   short   *in;
  1044.   msurface_t **out;
  1045.   
  1046.   in = (void *)(mod_base + l->fileofs);
  1047.   if (l->filelen % sizeof(*in))
  1048.     Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  1049.   count = l->filelen / sizeof(*in);
  1050.   out = Hunk_AllocName ( count*sizeof(*out), loadname); 
  1051.  
  1052.   loadmodel->marksurfaces = out;
  1053.   loadmodel->nummarksurfaces = count;
  1054.  
  1055.   for ( i=0 ; i<count ; i++)
  1056.   {
  1057.     j = LittleShort(in[i]);
  1058.     if (j >= loadmodel->numsurfaces)
  1059.       Sys_Error ("Mod_ParseMarksurfaces: bad surface number");
  1060.     out[i] = loadmodel->surfaces + j;
  1061.   }
  1062. }
  1063.  
  1064. /*
  1065. =================
  1066. Mod_LoadSurfedges
  1067. =================
  1068. */
  1069. void Mod_LoadSurfedges (lump_t *l)
  1070.   int   i, count;
  1071.   int   *in, *out;
  1072.   
  1073.   in = (void *)(mod_base + l->fileofs);
  1074.   if (l->filelen % sizeof(*in))
  1075.     Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  1076.   count = l->filelen / sizeof(*in);
  1077.   out = Hunk_AllocName ( count*sizeof(*out), loadname); 
  1078.  
  1079.   loadmodel->surfedges = out;
  1080.   loadmodel->numsurfedges = count;
  1081.  
  1082.   for ( i=0 ; i<count ; i++)
  1083.     out[i] = LittleLong (in[i]);
  1084. }
  1085.  
  1086.  
  1087. /*
  1088. =================
  1089. Mod_LoadPlanes
  1090. =================
  1091. */
  1092. void Mod_LoadPlanes (lump_t *l)
  1093. {
  1094.   int     i, j;
  1095.   mplane_t  *out;
  1096.   dplane_t  *in;
  1097.   int     count;
  1098.   int     bits;
  1099.   
  1100.   in = (void *)(mod_base + l->fileofs);
  1101.   if (l->filelen % sizeof(*in))
  1102.     Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  1103.   count = l->filelen / sizeof(*in);
  1104.   out = Hunk_AllocName ( count*2*sizeof(*out), loadname); 
  1105.   
  1106.   loadmodel->planes = out;
  1107.   loadmodel->numplanes = count;
  1108.  
  1109.   for ( i=0 ; i<count ; i++, in++, out++)
  1110.   {
  1111.     bits = 0;
  1112.     for (j=0 ; j<3 ; j++)
  1113.     {
  1114.       out->normal[j] = LittleFloat (in->normal[j]);
  1115.       if (out->normal[j] < 0)
  1116.         bits |= 1<<j;
  1117.     }
  1118.  
  1119.     out->dist = LittleFloat (in->dist);
  1120.     out->type = LittleLong (in->type);
  1121.     out->signbits = bits;
  1122.   }
  1123. }
  1124.  
  1125. /*
  1126. =================
  1127. RadiusFromBounds
  1128. =================
  1129. */
  1130. float RadiusFromBounds (vec3_t mins, vec3_t maxs)
  1131. {
  1132.   int   i;
  1133.   vec3_t  corner;
  1134.  
  1135.   for (i=0 ; i<3 ; i++)
  1136.   {
  1137.     corner[i] = fabs(mins[i]) > fabs(maxs[i]) ? fabs(mins[i]) : fabs(maxs[i]);
  1138.   }
  1139.  
  1140.   return Length (corner);
  1141. }
  1142.  
  1143. /*
  1144. =================
  1145. Mod_LoadBrushModel
  1146. =================
  1147. */
  1148. void Mod_LoadBrushModel (model_t *mod, void *buffer)
  1149. {
  1150.   int     i, j;
  1151.   dheader_t *header;
  1152.   dmodel_t  *bm;
  1153.   
  1154.   loadmodel->type = mod_brush;
  1155.   
  1156.   header = (dheader_t *)buffer;
  1157.  
  1158.   i = LittleLong (header->version);
  1159.   if (i != BSPVERSION)
  1160.     Sys_Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION);
  1161.  
  1162. // swap all the lumps
  1163.   mod_base = (byte *)header;
  1164.  
  1165.   for (i=0 ; i<sizeof(dheader_t)/4 ; i++)
  1166.     ((int *)header)[i] = LittleLong ( ((int *)header)[i]);
  1167.  
  1168. // load into heap
  1169.   
  1170.   Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]);
  1171.   Mod_LoadEdges (&header->lumps[LUMP_EDGES]);
  1172.   Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]);
  1173.   Mod_LoadTextures (&header->lumps[LUMP_TEXTURES]);
  1174.   Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]);
  1175.   Mod_LoadPlanes (&header->lumps[LUMP_PLANES]);
  1176.   Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]);
  1177.   Mod_LoadFaces (&header->lumps[LUMP_FACES]);
  1178.   Mod_LoadMarksurfaces (&header->lumps[LUMP_MARKSURFACES]);
  1179.   Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]);
  1180.   Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]);
  1181.   Mod_LoadNodes (&header->lumps[LUMP_NODES]);
  1182.   Mod_LoadClipnodes (&header->lumps[LUMP_CLIPNODES]);
  1183.   Mod_LoadEntities (&header->lumps[LUMP_ENTITIES]);
  1184.   Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]);
  1185.  
  1186.   Mod_MakeHull0 ();
  1187.   
  1188.   mod->numframes = 2;   // regular and alternate animation
  1189.   
  1190. //
  1191. // set up the submodels (FIXME: this is confusing)
  1192. //
  1193.   for (i=0 ; i<mod->numsubmodels ; i++)
  1194.   {
  1195.     bm = &mod->submodels[i];
  1196.  
  1197.     mod->hulls[0].firstclipnode = bm->headnode[0];
  1198.     for (j=1 ; j<MAX_MAP_HULLS ; j++)
  1199.     {
  1200.       mod->hulls[j].firstclipnode = bm->headnode[j];
  1201.       mod->hulls[j].lastclipnode = mod->numclipnodes-1;
  1202.     }
  1203.     
  1204.     mod->firstmodelsurface = bm->firstface;
  1205.     mod->nummodelsurfaces = bm->numfaces;
  1206.     
  1207.     VectorCopy (bm->maxs, mod->maxs);
  1208.     VectorCopy (bm->mins, mod->mins);
  1209.  
  1210.     mod->radius = RadiusFromBounds (mod->mins, mod->maxs);
  1211.  
  1212.     mod->numleafs = bm->visleafs;
  1213.  
  1214.     if (i < mod->numsubmodels-1)
  1215.     { // duplicate the basic information
  1216.       char  name[10];
  1217.  
  1218.       sprintf (name, "*%i", i+1);
  1219.       loadmodel = Mod_FindName (name);
  1220.       *loadmodel = *mod;
  1221.       strcpy (loadmodel->name, name);
  1222.       mod = loadmodel;
  1223.     }
  1224.   }
  1225. }
  1226.  
  1227. /*
  1228. ==============================================================================
  1229.  
  1230. ALIAS MODELS
  1231.  
  1232. ==============================================================================
  1233. */
  1234.  
  1235. aliashdr_t  *pheader;
  1236.  
  1237. stvert_t  stverts[MAXALIASVERTS];
  1238. mtriangle_t triangles[MAXALIASTRIS];
  1239.  
  1240. // a pose is a single set of vertexes.  a frame may be
  1241. // an animating sequence of poses
  1242. trivertx_t  *poseverts[MAXALIASFRAMES];
  1243. int     posenum;
  1244.  
  1245. byte    **player_8bit_texels_tbl;
  1246. byte    *player_8bit_texels;
  1247.  
  1248. /*
  1249. =================
  1250. Mod_LoadAliasFrame
  1251. =================
  1252. */
  1253. void * Mod_LoadAliasFrame (void * pin, maliasframedesc_t *frame)
  1254. {
  1255.   trivertx_t    *pframe, *pinframe;
  1256.   int       i, j;
  1257.   daliasframe_t *pdaliasframe;
  1258.   
  1259.   pdaliasframe = (daliasframe_t *)pin;
  1260.  
  1261.   strcpy (frame->name, pdaliasframe->name);
  1262.   frame->firstpose = posenum;
  1263.   frame->numposes = 1;
  1264.  
  1265.   for (i=0 ; i<3 ; i++)
  1266.   {
  1267.   // these are byte values, so we don't have to worry about
  1268.   // endianness
  1269.     frame->bboxmin.v[i] = pdaliasframe->bboxmin.v[i];
  1270.     frame->bboxmin.v[i] = pdaliasframe->bboxmax.v[i];
  1271.   }
  1272.  
  1273.   pinframe = (trivertx_t *)(pdaliasframe + 1);
  1274.  
  1275.   poseverts[posenum] = pinframe;
  1276.   posenum++;
  1277.  
  1278.   pinframe += pheader->numverts;
  1279.  
  1280.   return (void *)pinframe;
  1281. }
  1282.  
  1283.  
  1284. /*
  1285. =================
  1286. Mod_LoadAliasGroup
  1287. =================
  1288. */
  1289. void *Mod_LoadAliasGroup (void * pin,  maliasframedesc_t *frame)
  1290. {
  1291.   daliasgroup_t   *pingroup;
  1292.   int         i, numframes;
  1293.   daliasinterval_t  *pin_intervals;
  1294.   void        *ptemp;
  1295.   
  1296.   pingroup = (daliasgroup_t *)pin;
  1297.  
  1298.   numframes = LittleLong (pingroup->numframes);
  1299.  
  1300.   frame->firstpose = posenum;
  1301.   frame->numposes = numframes;
  1302.  
  1303.   for (i=0 ; i<3 ; i++)
  1304.   {
  1305.   // these are byte values, so we don't have to worry about endianness
  1306.     frame->bboxmin.v[i] = pingroup->bboxmin.v[i];
  1307.     frame->bboxmin.v[i] = pingroup->bboxmax.v[i];
  1308.   }
  1309.  
  1310.   pin_intervals = (daliasinterval_t *)(pingroup + 1);
  1311.  
  1312.   frame->interval = LittleFloat (pin_intervals->interval);
  1313.  
  1314.   pin_intervals += numframes;
  1315.  
  1316.   ptemp = (void *)pin_intervals;
  1317.  
  1318.   for (i=0 ; i<numframes ; i++)
  1319.   {
  1320.     poseverts[posenum] = (trivertx_t *)((daliasframe_t *)ptemp + 1);
  1321.     posenum++;
  1322.  
  1323.     ptemp = (trivertx_t *)((daliasframe_t *)ptemp + 1) + pheader->numverts;
  1324.   }
  1325.  
  1326.   return ptemp;
  1327. }
  1328.  
  1329. //=========================================================
  1330.  
  1331. /*
  1332. =================
  1333. Mod_FloodFillSkin
  1334.  
  1335. Fill background pixels so mipmapping doesn't have haloes - Ed
  1336. =================
  1337. */
  1338.  
  1339. typedef struct
  1340. {
  1341.   short   x, y;
  1342. } floodfill_t;
  1343.  
  1344. extern unsigned d_8to24table[];
  1345.  
  1346. // must be a power of 2
  1347. #define FLOODFILL_FIFO_SIZE 0x1000
  1348. #define FLOODFILL_FIFO_MASK (FLOODFILL_FIFO_SIZE - 1)
  1349.  
  1350. #define FLOODFILL_STEP( off, dx, dy ) \
  1351. { \
  1352.   if (pos[off] == fillcolor) \
  1353.   { \
  1354.     pos[off] = 255; \
  1355.     fifo[inpt].x = x + (dx), fifo[inpt].y = y + (dy); \
  1356.     inpt = (inpt + 1) & FLOODFILL_FIFO_MASK; \
  1357.   } \
  1358.   else if (pos[off] != 255) fdc = pos[off]; \
  1359. }
  1360.  
  1361. void Mod_FloodFillSkin( byte *skin, int skinwidth, int skinheight )
  1362. {
  1363.   byte        fillcolor = *skin; // assume this is the pixel to fill
  1364.   floodfill_t     fifo[FLOODFILL_FIFO_SIZE];
  1365.   int         inpt = 0, outpt = 0;
  1366.   int         filledcolor = -1;
  1367.   int         i;
  1368.  
  1369.   if (filledcolor == -1)
  1370.   {
  1371.     filledcolor = 0;
  1372.     // attempt to find opaque black
  1373.     for (i = 0; i < 256; ++i)
  1374.       if (d_8to24table[i] == (255 << 0)) // alpha 1.0
  1375.       {
  1376.         filledcolor = i;
  1377.         break;
  1378.       }
  1379.   }
  1380.  
  1381.   // can't fill to filled color or to transparent color (used as visited marker)
  1382.   if ((fillcolor == filledcolor) || (fillcolor == 255))
  1383.   {
  1384.     //printf( "not filling skin from %d to %d\n", fillcolor, filledcolor );
  1385.     return;
  1386.   }
  1387.  
  1388.   fifo[inpt].x = 0, fifo[inpt].y = 0;
  1389.   inpt = (inpt + 1) & FLOODFILL_FIFO_MASK;
  1390.  
  1391.   while (outpt != inpt)
  1392.   {
  1393.     int     x = fifo[outpt].x, y = fifo[outpt].y;
  1394.     int     fdc = filledcolor;
  1395.     byte    *pos = &skin[x + skinwidth * y];
  1396.  
  1397.     outpt = (outpt + 1) & FLOODFILL_FIFO_MASK;
  1398.  
  1399.     if (x > 0)        FLOODFILL_STEP( -1, -1, 0 );
  1400.     if (x < skinwidth - 1)  FLOODFILL_STEP( 1, 1, 0 );
  1401.     if (y > 0)        FLOODFILL_STEP( -skinwidth, 0, -1 );
  1402.     if (y < skinheight - 1) FLOODFILL_STEP( skinwidth, 0, 1 );
  1403.     skin[x + skinwidth * y] = fdc;
  1404.   }
  1405. }
  1406.  
  1407. /*
  1408. ===============
  1409. Mod_LoadAllSkins
  1410. ===============
  1411. */
  1412. void *Mod_LoadAllSkins (int numskins, daliasskintype_t *pskintype)
  1413. {
  1414.   int   i, j, k;
  1415.   char  name[32];
  1416.   int   s;
  1417.   byte  *copy;
  1418.   byte  *skin;
  1419.   byte  *texels;
  1420.   daliasskingroup_t   *pinskingroup;
  1421.   int   groupskins;
  1422.   daliasskininterval_t  *pinskinintervals;
  1423.   
  1424.   skin = (byte *)(pskintype + 1);
  1425.  
  1426.   if (numskins < 1 || numskins > MAX_SKINS)
  1427.     Sys_Error ("Mod_LoadAliasModel: Invalid # of skins: %d\n", numskins);
  1428.  
  1429.   s = pheader->skinwidth * pheader->skinheight;
  1430.  
  1431.   for (i=0 ; i<numskins ; i++)
  1432.   {
  1433.     if (pskintype->type == ALIAS_SKIN_SINGLE) {
  1434.       Mod_FloodFillSkin( skin, pheader->skinwidth, pheader->skinheight );
  1435.  
  1436.       // save 8 bit texels for the player model to remap
  1437.   //    if (!strcmp(loadmodel->name,"progs/player.mdl")) {
  1438.         texels = Hunk_AllocName(s, loadname);
  1439.         pheader->texels[i] = texels - (byte *)pheader;
  1440.         memcpy (texels, (byte *)(pskintype + 1), s);
  1441.   //    }
  1442.       sprintf (name, "%s_%i", loadmodel->name, i);
  1443.       pheader->gl_texturenum[i][0] =
  1444.       pheader->gl_texturenum[i][1] =
  1445.       pheader->gl_texturenum[i][2] =
  1446.       pheader->gl_texturenum[i][3] =
  1447.         GL_LoadTexture (name, pheader->skinwidth, 
  1448.         pheader->skinheight, (byte *)(pskintype + 1), true, false);
  1449.       pskintype = (daliasskintype_t *)((byte *)(pskintype+1) + s);
  1450.     } else {
  1451.       // animating skin group.  yuck.
  1452.       pskintype++;
  1453.       pinskingroup = (daliasskingroup_t *)pskintype;
  1454.       groupskins = LittleLong (pinskingroup->numskins);
  1455.       pinskinintervals = (daliasskininterval_t *)(pinskingroup + 1);
  1456.  
  1457.       pskintype = (void *)(pinskinintervals + groupskins);
  1458.  
  1459.       for (j=0 ; j<groupskins ; j++)
  1460.       {
  1461.           Mod_FloodFillSkin( skin, pheader->skinwidth, pheader->skinheight );
  1462.           if (j == 0) {
  1463.             texels = Hunk_AllocName(s, loadname);
  1464.             pheader->texels[i] = texels - (byte *)pheader;
  1465.             memcpy (texels, (byte *)(pskintype), s);
  1466.           }
  1467.           sprintf (name, "%s_%i_%i", loadmodel->name, i,j);
  1468.           pheader->gl_texturenum[i][j&3] = 
  1469.             GL_LoadTexture (name, pheader->skinwidth, 
  1470.             pheader->skinheight, (byte *)(pskintype), true, false);
  1471.           pskintype = (daliasskintype_t *)((byte *)(pskintype) + s);
  1472.       }
  1473.       k = j;
  1474.       for (/* */; j < 4; j++)
  1475.         pheader->gl_texturenum[i][j&3] = 
  1476.         pheader->gl_texturenum[i][j - k]; 
  1477.     }
  1478.   }
  1479.  
  1480.   return (void *)pskintype;
  1481. }
  1482.  
  1483. //=========================================================================
  1484.  
  1485. /*
  1486. =================
  1487. Mod_LoadAliasModel
  1488. =================
  1489. */
  1490. void Mod_LoadAliasModel (model_t *mod, void *buffer)
  1491. {
  1492.   int         i, j;
  1493.   mdl_t       *pinmodel;
  1494.   stvert_t      *pinstverts;
  1495.   dtriangle_t     *pintriangles;
  1496.   int         version, numframes, numskins;
  1497.   int         size;
  1498.   daliasframetype_t *pframetype;
  1499.   daliasskintype_t  *pskintype;
  1500.   int         start, end, total;
  1501.   
  1502.   start = Hunk_LowMark ();
  1503.  
  1504.   pinmodel = (mdl_t *)buffer;
  1505.  
  1506.   version = LittleLong (pinmodel->version);
  1507.   if (version != ALIAS_VERSION)
  1508.     Sys_Error ("%s has wrong version number (%i should be %i)",
  1509.          mod->name, version, ALIAS_VERSION);
  1510.  
  1511. //
  1512. // allocate space for a working header, plus all the data except the frames,
  1513. // skin and group info
  1514. //
  1515.   size =  sizeof (aliashdr_t) 
  1516.       + (LittleLong (pinmodel->numframes) - 1) *
  1517.       sizeof (pheader->frames[0]);
  1518.   pheader = Hunk_AllocName (size, loadname);
  1519.   
  1520.   mod->flags = LittleLong (pinmodel->flags);
  1521.  
  1522. //
  1523. // endian-adjust and copy the data, starting with the alias model header
  1524. //
  1525.   pheader->boundingradius = LittleFloat (pinmodel->boundingradius);
  1526.   pheader->numskins = LittleLong (pinmodel->numskins);
  1527.   pheader->skinwidth = LittleLong (pinmodel->skinwidth);
  1528.   pheader->skinheight = LittleLong (pinmodel->skinheight);
  1529.  
  1530.   if (pheader->skinheight > MAX_LBM_HEIGHT)
  1531.     Sys_Error ("model %s has a skin taller than %d", mod->name,
  1532.            MAX_LBM_HEIGHT);
  1533.  
  1534.   pheader->numverts = LittleLong (pinmodel->numverts);
  1535.  
  1536.   if (pheader->numverts <= 0)
  1537.     Sys_Error ("model %s has no vertices", mod->name);
  1538.  
  1539.   if (pheader->numverts > MAXALIASVERTS)
  1540.     Sys_Error ("model %s has too many vertices", mod->name);
  1541.  
  1542.   pheader->numtris = LittleLong (pinmodel->numtris);
  1543.  
  1544.   if (pheader->numtris <= 0)
  1545.     Sys_Error ("model %s has no triangles", mod->name);
  1546.  
  1547.   pheader->numframes = LittleLong (pinmodel->numframes);
  1548.   numframes = pheader->numframes;
  1549.   if (numframes < 1)
  1550.     Sys_Error ("Mod_LoadAliasModel: Invalid # of frames: %d\n", numframes);
  1551.  
  1552.   pheader->size = LittleFloat (pinmodel->size) * ALIAS_BASE_SIZE_RATIO;
  1553.   mod->synctype = LittleLong (pinmodel->synctype);
  1554.   mod->numframes = pheader->numframes;
  1555.  
  1556.   for (i=0 ; i<3 ; i++)
  1557.   {
  1558.     pheader->scale[i] = LittleFloat (pinmodel->scale[i]);
  1559.     pheader->scale_origin[i] = LittleFloat (pinmodel->scale_origin[i]);
  1560.     pheader->eyeposition[i] = LittleFloat (pinmodel->eyeposition[i]);
  1561.   }
  1562.  
  1563.  
  1564. //
  1565. // load the skins
  1566. //
  1567.   pskintype = (daliasskintype_t *)&pinmodel[1];
  1568.   pskintype = Mod_LoadAllSkins (pheader->numskins, pskintype);
  1569.  
  1570. //
  1571. // load base s and t vertices
  1572. //
  1573.   pinstverts = (stvert_t *)pskintype;
  1574.  
  1575.   for (i=0 ; i<pheader->numverts ; i++)
  1576.   {
  1577.     stverts[i].onseam = LittleLong (pinstverts[i].onseam);
  1578.     stverts[i].s = LittleLong (pinstverts[i].s);
  1579.     stverts[i].t = LittleLong (pinstverts[i].t);
  1580.   }
  1581.  
  1582. //
  1583. // load triangle lists
  1584. //
  1585.   pintriangles = (dtriangle_t *)&pinstverts[pheader->numverts];
  1586.  
  1587.   for (i=0 ; i<pheader->numtris ; i++)
  1588.   {
  1589.     triangles[i].facesfront = LittleLong (pintriangles[i].facesfront);
  1590.  
  1591.     for (j=0 ; j<3 ; j++)
  1592.     {
  1593.       triangles[i].vertindex[j] =
  1594.           LittleLong (pintriangles[i].vertindex[j]);
  1595.     }
  1596.   }
  1597.  
  1598. //
  1599. // load the frames
  1600. //
  1601.   posenum = 0;
  1602.   pframetype = (daliasframetype_t *)&pintriangles[pheader->numtris];
  1603.  
  1604.   for (i=0 ; i<numframes ; i++)
  1605.   {
  1606.     aliasframetype_t  frametype;
  1607.  
  1608.     frametype = LittleLong (pframetype->type);
  1609.  
  1610.     if (frametype == ALIAS_SINGLE)
  1611.     {
  1612.       pframetype = (daliasframetype_t *)
  1613.           Mod_LoadAliasFrame (pframetype + 1, &pheader->frames[i]);
  1614.     }
  1615.     else
  1616.     {
  1617.       pframetype = (daliasframetype_t *)
  1618.           Mod_LoadAliasGroup (pframetype + 1, &pheader->frames[i]);
  1619.     }
  1620.   }
  1621.  
  1622.   pheader->numposes = posenum;
  1623.  
  1624.   mod->type = mod_alias;
  1625.  
  1626. // FIXME: do this right
  1627.   mod->mins[0] = mod->mins[1] = mod->mins[2] = -16;
  1628.   mod->maxs[0] = mod->maxs[1] = mod->maxs[2] = 16;
  1629.  
  1630.   //
  1631.   // build the draw lists
  1632.   //
  1633.   GL_MakeAliasModelDisplayLists (mod, pheader);
  1634.  
  1635. //
  1636. // move the complete, relocatable alias model to the cache
  1637. //  
  1638.   end = Hunk_LowMark ();
  1639.   total = end - start;
  1640.   
  1641.   Cache_Alloc (&mod->cache, total, loadname);
  1642.   if (!mod->cache.data)
  1643.     return;
  1644.   memcpy (mod->cache.data, pheader, total);
  1645.  
  1646.   Hunk_FreeToLowMark (start);
  1647. }
  1648.  
  1649. //=============================================================================
  1650.  
  1651. /*
  1652. =================
  1653. Mod_LoadSpriteFrame
  1654. =================
  1655. */
  1656. void * Mod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum)
  1657. {
  1658.   dspriteframe_t    *pinframe;
  1659.   mspriteframe_t    *pspriteframe;
  1660.   int         i, width, height, size, origin[2];
  1661.   unsigned short    *ppixout;
  1662.   byte        *ppixin;
  1663.   char        name[64];
  1664.  
  1665.   pinframe = (dspriteframe_t *)pin;
  1666.  
  1667.   width = LittleLong (pinframe->width);
  1668.   height = LittleLong (pinframe->height);
  1669.   size = width * height;
  1670.  
  1671.   pspriteframe = Hunk_AllocName (sizeof (mspriteframe_t),loadname);
  1672.  
  1673.   Q_memset (pspriteframe, 0, sizeof (mspriteframe_t));
  1674.  
  1675.   *ppframe = pspriteframe;
  1676.  
  1677.   pspriteframe->width = width;
  1678.   pspriteframe->height = height;
  1679.   origin[0] = LittleLong (pinframe->origin[0]);
  1680.   origin[1] = LittleLong (pinframe->origin[1]);
  1681.  
  1682.   pspriteframe->up = origin[1];
  1683.   pspriteframe->down = origin[1] - height;
  1684.   pspriteframe->left = origin[0];
  1685.   pspriteframe->right = width + origin[0];
  1686.  
  1687.   sprintf (name, "%s_%i", loadmodel->name, framenum);
  1688.   pspriteframe->gl_texturenum = GL_LoadTexture (name, width, height, (byte *)(pinframe + 1), true, true);
  1689.  
  1690.   return (void *)((byte *)pinframe + sizeof (dspriteframe_t) + size);
  1691. }
  1692.  
  1693.  
  1694. /*
  1695. =================
  1696. Mod_LoadSpriteGroup
  1697. =================
  1698. */
  1699. void * Mod_LoadSpriteGroup (void * pin, mspriteframe_t **ppframe, int framenum)
  1700. {
  1701.   dspritegroup_t    *pingroup;
  1702.   mspritegroup_t    *pspritegroup;
  1703.   int         i, numframes;
  1704.   dspriteinterval_t *pin_intervals;
  1705.   float       *poutintervals;
  1706.   void        *ptemp;
  1707.  
  1708.   pingroup = (dspritegroup_t *)pin;
  1709.  
  1710.   numframes = LittleLong (pingroup->numframes);
  1711.  
  1712.   pspritegroup = Hunk_AllocName (sizeof (mspritegroup_t) +
  1713.         (numframes - 1) * sizeof (pspritegroup->frames[0]), loadname);
  1714.  
  1715.   pspritegroup->numframes = numframes;
  1716.  
  1717.   *ppframe = (mspriteframe_t *)pspritegroup;
  1718.  
  1719.   pin_intervals = (dspriteinterval_t *)(pingroup + 1);
  1720.  
  1721.   poutintervals = Hunk_AllocName (numframes * sizeof (float), loadname);
  1722.  
  1723.   pspritegroup->intervals = poutintervals;
  1724.  
  1725.   for (i=0 ; i<numframes ; i++)
  1726.   {
  1727.     *poutintervals = LittleFloat (pin_intervals->interval);
  1728.     if (*poutintervals <= 0.0)
  1729.       Sys_Error ("Mod_LoadSpriteGroup: interval<=0");
  1730.  
  1731.     poutintervals++;
  1732.     pin_intervals++;
  1733.   }
  1734.  
  1735.   ptemp = (void *)pin_intervals;
  1736.  
  1737.   for (i=0 ; i<numframes ; i++)
  1738.   {
  1739.     ptemp = Mod_LoadSpriteFrame (ptemp, &pspritegroup->frames[i], framenum * 100 + i);
  1740.   }
  1741.  
  1742.   return ptemp;
  1743. }
  1744.  
  1745.  
  1746. /*
  1747. =================
  1748. Mod_LoadSpriteModel
  1749. =================
  1750. */
  1751. void Mod_LoadSpriteModel (model_t *mod, void *buffer)
  1752. {
  1753.   int         i;
  1754.   int         version;
  1755.   dsprite_t     *pin;
  1756.   msprite_t     *psprite;
  1757.   int         numframes;
  1758.   int         size;
  1759.   dspriteframetype_t  *pframetype;
  1760.   
  1761.   pin = (dsprite_t *)buffer;
  1762.  
  1763.   version = LittleLong (pin->version);
  1764.   if (version != SPRITE_VERSION)
  1765.     Sys_Error ("%s has wrong version number "
  1766.          "(%i should be %i)", mod->name, version, SPRITE_VERSION);
  1767.  
  1768.   numframes = LittleLong (pin->numframes);
  1769.  
  1770.   size = sizeof (msprite_t) + (numframes - 1) * sizeof (psprite->frames);
  1771.  
  1772.   psprite = Hunk_AllocName (size, loadname);
  1773.  
  1774.   mod->cache.data = psprite;
  1775.  
  1776.   psprite->type = LittleLong (pin->type);
  1777.   psprite->maxwidth = LittleLong (pin->width);
  1778.   psprite->maxheight = LittleLong (pin->height);
  1779.   psprite->beamlength = LittleFloat (pin->beamlength);
  1780.   mod->synctype = LittleLong (pin->synctype);
  1781.   psprite->numframes = numframes;
  1782.  
  1783.   mod->mins[0] = mod->mins[1] = -psprite->maxwidth/2;
  1784.   mod->maxs[0] = mod->maxs[1] = psprite->maxwidth/2;
  1785.   mod->mins[2] = -psprite->maxheight/2;
  1786.   mod->maxs[2] = psprite->maxheight/2;
  1787.   
  1788. //
  1789. // load the frames
  1790. //
  1791.   if (numframes < 1)
  1792.     Sys_Error ("Mod_LoadSpriteModel: Invalid # of frames: %d\n", numframes);
  1793.  
  1794.   mod->numframes = numframes;
  1795.  
  1796.   pframetype = (dspriteframetype_t *)(pin + 1);
  1797.  
  1798.   for (i=0 ; i<numframes ; i++)
  1799.   {
  1800.     spriteframetype_t frametype;
  1801.  
  1802.     frametype = LittleLong (pframetype->type);
  1803.     psprite->frames[i].type = frametype;
  1804.  
  1805.     if (frametype == SPR_SINGLE)
  1806.     {
  1807.       pframetype = (dspriteframetype_t *)
  1808.           Mod_LoadSpriteFrame (pframetype + 1,
  1809.                      &psprite->frames[i].frameptr, i);
  1810.     }
  1811.     else
  1812.     {
  1813.       pframetype = (dspriteframetype_t *)
  1814.           Mod_LoadSpriteGroup (pframetype + 1,
  1815.                      &psprite->frames[i].frameptr, i);
  1816.     }
  1817.   }
  1818.  
  1819.   mod->type = mod_sprite;
  1820. }
  1821.  
  1822. //=============================================================================
  1823.  
  1824. /*
  1825. ================
  1826. Mod_Print
  1827. ================
  1828. */
  1829. void Mod_Print (void)
  1830. {
  1831.   int   i;
  1832.   model_t *mod;
  1833.  
  1834.   Con_Printf ("Cached models:\n");
  1835.   for (i=0, mod=mod_known ; i < mod_numknown ; i++, mod++)
  1836.   {
  1837.     Con_Printf ("%8p : %s\n",mod->cache.data, mod->name);
  1838.   }
  1839. }
  1840.  
  1841.  
  1842.