home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 14 / MA_Cover_14.iso / source / c / q1source_amy / qw / server / model.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-12-21  |  23.7 KB  |  1,138 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 "qwsvdef.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    256
  38. model_t    mod_known[MAX_MOD_KNOWN];
  39. int        mod_numknown;
  40.  
  41. texture_t    r_notexture_mip;
  42.  
  43. unsigned *model_checksum;
  44.  
  45. /*
  46. ===============
  47. Mod_Init
  48. ===============
  49. */
  50. void Mod_Init (void)
  51. {
  52.     memset (mod_novis, 0xff, sizeof(mod_novis));
  53. }
  54.  
  55. /*
  56. ===============
  57. Mod_PointInLeaf
  58. ===============
  59. */
  60. mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model)
  61. {
  62.     mnode_t        *node;
  63.     float        d;
  64.     mplane_t    *plane;
  65.     
  66.     if (!model || !model->nodes)
  67.         SV_Error ("Mod_PointInLeaf: bad model");
  68.  
  69.     node = model->nodes;
  70.     while (1)
  71.     {
  72.         if (node->contents < 0)
  73.             return (mleaf_t *)node;
  74.         plane = node->plane;
  75.         d = DotProduct (p,plane->normal) - plane->dist;
  76.         if (d > 0)
  77.             node = node->children[0];
  78.         else
  79.             node = node->children[1];
  80.     }
  81.     
  82.     return NULL;    // never reached
  83. }
  84.  
  85.  
  86. /*
  87. ===================
  88. Mod_DecompressVis
  89. ===================
  90. */
  91. byte *Mod_DecompressVis (byte *in, model_t *model)
  92. {
  93.     static byte    decompressed[MAX_MAP_LEAFS/8];
  94.     int        c;
  95.     byte    *out;
  96.     int        row;
  97.  
  98.     row = (model->numleafs+7)>>3;    
  99.     out = decompressed;
  100.  
  101. #if 0
  102.     memcpy (out, in, row);
  103. #else
  104.     if (!in)
  105.     {    // no vis info, so make all visible
  106.         while (row)
  107.         {
  108.             *out++ = 0xff;
  109.             row--;
  110.         }
  111.         return decompressed;        
  112.     }
  113.  
  114.     do
  115.     {
  116.         if (*in)
  117.         {
  118.             *out++ = *in++;
  119.             continue;
  120.         }
  121.     
  122.         c = in[1];
  123.         in += 2;
  124.         while (c)
  125.         {
  126.             *out++ = 0;
  127.             c--;
  128.         }
  129.     } while (out - decompressed < row);
  130. #endif
  131.     
  132.     return decompressed;
  133. }
  134.  
  135. byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model)
  136. {
  137.     if (leaf == model->leafs)
  138.         return mod_novis;
  139.     return Mod_DecompressVis (leaf->compressed_vis, model);
  140. }
  141.  
  142. /*
  143. ===================
  144. Mod_ClearAll
  145. ===================
  146. */
  147. void Mod_ClearAll (void)
  148. {
  149.     int        i;
  150.     model_t    *mod;
  151.     
  152.     for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
  153.         if (mod->type != mod_alias)
  154.             mod->needload = true;
  155. }
  156.  
  157. /*
  158. ==================
  159. Mod_FindName
  160.  
  161. ==================
  162. */
  163. model_t *Mod_FindName (char *name)
  164. {
  165.     int        i;
  166.     model_t    *mod;
  167.     
  168.     if (!name[0])
  169.         SV_Error ("Mod_ForName: NULL name");
  170.         
  171. //
  172. // search the currently loaded models
  173. //
  174.     for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
  175.         if (!strcmp (mod->name, name) )
  176.             break;
  177.             
  178.     if (i == mod_numknown)
  179.     {
  180.         if (mod_numknown == MAX_MOD_KNOWN)
  181.             SV_Error ("mod_numknown == MAX_MOD_KNOWN");
  182.         strcpy (mod->name, name);
  183.         mod->needload = true;
  184.         mod_numknown++;
  185.     }
  186.  
  187.     return mod;
  188. }
  189.  
  190.  
  191. /*
  192. ==================
  193. Mod_LoadModel
  194.  
  195. Loads a model into the cache
  196. ==================
  197. */
  198. model_t *Mod_LoadModel (model_t *mod, qboolean crash)
  199. {
  200.     void    *d;
  201.     unsigned *buf;
  202.     byte    stackbuf[1024];        // avoid dirtying the cache heap
  203.  
  204.     if (!mod->needload)
  205.     {
  206.         if (mod->type == mod_alias)
  207.         {
  208.             d = Cache_Check (&mod->cache);
  209.             if (d)
  210.                 return mod;
  211.         }
  212.         else
  213.             return mod;        // not cached at all
  214.     }
  215.     
  216. //
  217. // load the file
  218. //
  219.     buf = (unsigned *)COM_LoadStackFile (mod->name, stackbuf, sizeof(stackbuf));
  220.     if (!buf)
  221.     {
  222.         if (crash)
  223.             SV_Error ("Mod_NumForName: %s not found", mod->name);
  224.         return NULL;
  225.     }
  226.     
  227. //
  228. // allocate a new model
  229. //
  230.     COM_FileBase (mod->name, loadname);
  231.     
  232.     loadmodel = mod;
  233.  
  234. //
  235. // fill it in
  236. //
  237.  
  238. // call the apropriate loader
  239.     mod->needload = false;
  240.     
  241.     Mod_LoadBrushModel (mod, buf);
  242.  
  243.     return mod;
  244. }
  245.  
  246. /*
  247. ==================
  248. Mod_ForName
  249.  
  250. Loads in a model for the given name
  251. ==================
  252. */
  253. model_t *Mod_ForName (char *name, qboolean crash)
  254. {
  255.     model_t    *mod;
  256.     
  257.     mod = Mod_FindName (name);
  258.     
  259.     return Mod_LoadModel (mod, crash);
  260. }
  261.  
  262.  
  263. /*
  264. ===============================================================================
  265.  
  266.                     BRUSHMODEL LOADING
  267.  
  268. ===============================================================================
  269. */
  270.  
  271. byte    *mod_base;
  272.  
  273.  
  274. /*
  275. =================
  276. Mod_LoadTextures
  277. =================
  278. */
  279. void Mod_LoadTextures (lump_t *l)
  280. {
  281.     int        i, j, pixels, num, max, altmax;
  282.     miptex_t    *mt;
  283.     texture_t    *tx, *tx2;
  284.     texture_t    *anims[10];
  285.     texture_t    *altanims[10];
  286.     dmiptexlump_t *m;
  287.  
  288.     if (!l->filelen)
  289.     {
  290.         loadmodel->textures = NULL;
  291.         return;
  292.     }
  293.     m = (dmiptexlump_t *)(mod_base + l->fileofs);
  294.     
  295.     m->nummiptex = LittleLong (m->nummiptex);
  296.     
  297.     loadmodel->numtextures = m->nummiptex;
  298.     loadmodel->textures = Hunk_AllocName (m->nummiptex * sizeof(*loadmodel->textures) , loadname);
  299.  
  300.     for (i=0 ; i<m->nummiptex ; i++)
  301.     {
  302.         m->dataofs[i] = LittleLong(m->dataofs[i]);
  303.         if (m->dataofs[i] == -1)
  304.             continue;
  305.         mt = (miptex_t *)((byte *)m + m->dataofs[i]);
  306.         mt->width = LittleLong (mt->width);
  307.         mt->height = LittleLong (mt->height);
  308.         for (j=0 ; j<MIPLEVELS ; j++)
  309.             mt->offsets[j] = LittleLong (mt->offsets[j]);
  310.         
  311.         if ( (mt->width & 15) || (mt->height & 15) )
  312.             SV_Error ("Texture %s is not 16 aligned", mt->name);
  313.         pixels = mt->width*mt->height/64*85;
  314.         tx = Hunk_AllocName (sizeof(texture_t) +pixels, loadname );
  315.         loadmodel->textures[i] = tx;
  316.  
  317.         memcpy (tx->name, mt->name, sizeof(tx->name));
  318.         tx->width = mt->width;
  319.         tx->height = mt->height;
  320.         for (j=0 ; j<MIPLEVELS ; j++)
  321.             tx->offsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t);
  322.         // the pixels immediately follow the structures
  323.         memcpy ( tx+1, mt+1, pixels);
  324.     }
  325.  
  326. //
  327. // sequence the animations
  328. //
  329.     for (i=0 ; i<m->nummiptex ; i++)
  330.     {
  331.         tx = loadmodel->textures[i];
  332.         if (!tx || tx->name[0] != '+')
  333.             continue;
  334.         if (tx->anim_next)
  335.             continue;    // allready sequenced
  336.  
  337.     // find the number of frames in the animation
  338.         memset (anims, 0, sizeof(anims));
  339.         memset (altanims, 0, sizeof(altanims));
  340.  
  341.         max = tx->name[1];
  342.         altmax = 0;
  343.         if (max >= 'a' && max <= 'z')
  344.             max -= 'a' - 'A';
  345.         if (max >= '0' && max <= '9')
  346.         {
  347.             max -= '0';
  348.             altmax = 0;
  349.             anims[max] = tx;
  350.             max++;
  351.         }
  352.         else if (max >= 'A' && max <= 'J')
  353.         {
  354.             altmax = max - 'A';
  355.             max = 0;
  356.             altanims[altmax] = tx;
  357.             altmax++;
  358.         }
  359.         else
  360.             SV_Error ("Bad animating texture %s", tx->name);
  361.  
  362.         for (j=i+1 ; j<m->nummiptex ; j++)
  363.         {
  364.             tx2 = loadmodel->textures[j];
  365.             if (!tx2 || tx2->name[0] != '+')
  366.                 continue;
  367.             if (strcmp (tx2->name+2, tx->name+2))
  368.                 continue;
  369.  
  370.             num = tx2->name[1];
  371.             if (num >= 'a' && num <= 'z')
  372.                 num -= 'a' - 'A';
  373.             if (num >= '0' && num <= '9')
  374.             {
  375.                 num -= '0';
  376.                 anims[num] = tx2;
  377.                 if (num+1 > max)
  378.                     max = num + 1;
  379.             }
  380.             else if (num >= 'A' && num <= 'J')
  381.             {
  382.                 num = num - 'A';
  383.                 altanims[num] = tx2;
  384.                 if (num+1 > altmax)
  385.                     altmax = num+1;
  386.             }
  387.             else
  388.                 SV_Error ("Bad animating texture %s", tx->name);
  389.         }
  390.         
  391. #define    ANIM_CYCLE    2
  392.     // link them all together
  393.         for (j=0 ; j<max ; j++)
  394.         {
  395.             tx2 = anims[j];
  396.             if (!tx2)
  397.                 SV_Error ("Missing frame %i of %s",j, tx->name);
  398.             tx2->anim_total = max * ANIM_CYCLE;
  399.             tx2->anim_min = j * ANIM_CYCLE;
  400.             tx2->anim_max = (j+1) * ANIM_CYCLE;
  401.             tx2->anim_next = anims[ (j+1)%max ];
  402.             if (altmax)
  403.                 tx2->alternate_anims = altanims[0];
  404.         }
  405.         for (j=0 ; j<altmax ; j++)
  406.         {
  407.             tx2 = altanims[j];
  408.             if (!tx2)
  409.                 SV_Error ("Missing frame %i of %s",j, tx->name);
  410.             tx2->anim_total = altmax * ANIM_CYCLE;
  411.             tx2->anim_min = j * ANIM_CYCLE;
  412.             tx2->anim_max = (j+1) * ANIM_CYCLE;
  413.             tx2->anim_next = altanims[ (j+1)%altmax ];
  414.             if (max)
  415.                 tx2->alternate_anims = anims[0];
  416.         }
  417.     }
  418. }
  419.  
  420. /*
  421. =================
  422. Mod_LoadLighting
  423. =================
  424. */
  425. void Mod_LoadLighting (lump_t *l)
  426. {
  427.     if (!l->filelen)
  428.     {
  429.         loadmodel->lightdata = NULL;
  430.         return;
  431.     }
  432.     loadmodel->lightdata = Hunk_AllocName ( l->filelen, loadname);    
  433.     memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen);
  434. }
  435.  
  436.  
  437. /*
  438. =================
  439. Mod_LoadVisibility
  440. =================
  441. */
  442. void Mod_LoadVisibility (lump_t *l)
  443. {
  444.     if (!l->filelen)
  445.     {
  446.         loadmodel->visdata = NULL;
  447.         return;
  448.     }
  449.     loadmodel->visdata = Hunk_AllocName ( l->filelen, loadname);    
  450.     memcpy (loadmodel->visdata, mod_base + l->fileofs, l->filelen);
  451. }
  452.  
  453.  
  454. /*
  455. =================
  456. Mod_LoadEntities
  457. =================
  458. */
  459. void Mod_LoadEntities (lump_t *l)
  460. {
  461.     if (!l->filelen)
  462.     {
  463.         loadmodel->entities = NULL;
  464.         return;
  465.     }
  466.     loadmodel->entities = Hunk_AllocName ( l->filelen, loadname);    
  467.     memcpy (loadmodel->entities, mod_base + l->fileofs, l->filelen);
  468. }
  469.  
  470.  
  471. /*
  472. =================
  473. Mod_LoadVertexes
  474. =================
  475. */
  476. void Mod_LoadVertexes (lump_t *l)
  477. {
  478.     dvertex_t    *in;
  479.     mvertex_t    *out;
  480.     int            i, count;
  481.  
  482.     in = (void *)(mod_base + l->fileofs);
  483.     if (l->filelen % sizeof(*in))
  484.         SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  485.     count = l->filelen / sizeof(*in);
  486.     out = Hunk_AllocName ( count*sizeof(*out), loadname);    
  487.  
  488.     loadmodel->vertexes = out;
  489.     loadmodel->numvertexes = count;
  490.  
  491.     for ( i=0 ; i<count ; i++, in++, out++)
  492.     {
  493.         out->position[0] = LittleFloat (in->point[0]);
  494.         out->position[1] = LittleFloat (in->point[1]);
  495.         out->position[2] = LittleFloat (in->point[2]);
  496.     }
  497. }
  498.  
  499. /*
  500. =================
  501. Mod_LoadSubmodels
  502. =================
  503. */
  504. void Mod_LoadSubmodels (lump_t *l)
  505. {
  506.     dmodel_t    *in;
  507.     dmodel_t    *out;
  508.     int            i, j, count;
  509.  
  510.     in = (void *)(mod_base + l->fileofs);
  511.     if (l->filelen % sizeof(*in))
  512.         SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  513.     count = l->filelen / sizeof(*in);
  514.     out = Hunk_AllocName ( count*sizeof(*out), loadname);    
  515.  
  516.     loadmodel->submodels = out;
  517.     loadmodel->numsubmodels = count;
  518.  
  519.     for ( i=0 ; i<count ; i++, in++, out++)
  520.     {
  521.         for (j=0 ; j<3 ; j++)
  522.         {    // spread the mins / maxs by a pixel
  523.             out->mins[j] = LittleFloat (in->mins[j]) - 1;
  524.             out->maxs[j] = LittleFloat (in->maxs[j]) + 1;
  525.             out->origin[j] = LittleFloat (in->origin[j]);
  526.         }
  527.         for (j=0 ; j<MAX_MAP_HULLS ; j++)
  528.             out->headnode[j] = LittleLong (in->headnode[j]);
  529.         out->visleafs = LittleLong (in->visleafs);
  530.         out->firstface = LittleLong (in->firstface);
  531.         out->numfaces = LittleLong (in->numfaces);
  532.     }
  533. }
  534.  
  535. /*
  536. =================
  537. Mod_LoadEdges
  538. =================
  539. */
  540. void Mod_LoadEdges (lump_t *l)
  541. {
  542.     dedge_t *in;
  543.     medge_t *out;
  544.     int     i, count;
  545.  
  546.     in = (void *)(mod_base + l->fileofs);
  547.     if (l->filelen % sizeof(*in))
  548.         SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  549.     count = l->filelen / sizeof(*in);
  550.     out = Hunk_AllocName ( (count + 1) * sizeof(*out), loadname);    
  551.  
  552.     loadmodel->edges = out;
  553.     loadmodel->numedges = count;
  554.  
  555.     for ( i=0 ; i<count ; i++, in++, out++)
  556.     {
  557.         out->v[0] = (unsigned short)LittleShort(in->v[0]);
  558.         out->v[1] = (unsigned short)LittleShort(in->v[1]);
  559.     }
  560. }
  561.  
  562. /*
  563. =================
  564. Mod_LoadTexinfo
  565. =================
  566. */
  567. void Mod_LoadTexinfo (lump_t *l)
  568. {
  569.     texinfo_t *in;
  570.     mtexinfo_t *out;
  571.     int     i, j, count;
  572.     int        miptex;
  573.     float    len1, len2;
  574.  
  575.     in = (void *)(mod_base + l->fileofs);
  576.     if (l->filelen % sizeof(*in))
  577.         SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  578.     count = l->filelen / sizeof(*in);
  579.     out = Hunk_AllocName ( count*sizeof(*out), loadname);    
  580.  
  581.     loadmodel->texinfo = out;
  582.     loadmodel->numtexinfo = count;
  583.  
  584.     for ( i=0 ; i<count ; i++, in++, out++)
  585.     {
  586. #if 0
  587.         for (j=0 ; j<8 ; j++)
  588.             out->vecs[0][j] = LittleFloat (in->vecs[0][j]);
  589.         len1 = Length (in->vecs[0]);
  590.         len2 = Length (in->vecs[1]);
  591. #else
  592.         for (j=0 ; j<4 ; j++) {
  593.             out->vecs[0][j] = LittleFloat (in->vecs[0][j]);
  594.             out->vecs[1][j] = LittleFloat (in->vecs[1][j]);
  595.         }
  596.         len1 = Length (out->vecs[0]);
  597.         len2 = Length (out->vecs[1]);
  598. #endif
  599.         if (len1 + len2 < 2 /*0.001*/)
  600.             out->mipadjust = 1;
  601.         else
  602.             out->mipadjust = 1 / floor( (len1+len2)/2 );
  603.  
  604.         miptex = LittleLong (in->miptex);
  605.         out->flags = LittleLong (in->flags);
  606.     
  607.         if (!loadmodel->textures)
  608.         {
  609.             out->texture = &r_notexture_mip;    // checkerboard texture
  610.             out->flags = 0;
  611.         }
  612.         else
  613.         {
  614.             if (miptex >= loadmodel->numtextures)
  615.                 SV_Error ("miptex >= loadmodel->numtextures");
  616.             out->texture = loadmodel->textures[miptex];
  617.             if (!out->texture)
  618.             {
  619.                 out->texture = &r_notexture_mip; // texture not found
  620.                 out->flags = 0;
  621.             }
  622.         }
  623.     }
  624. }
  625.  
  626. /*
  627. ================
  628. CalcSurfaceExtents
  629.  
  630. Fills in s->texturemins[] and s->extents[]
  631. ================
  632. */
  633. void CalcSurfaceExtents (msurface_t *s)
  634. {
  635.     float    mins[2], maxs[2], val;
  636.     int        i,j, e;
  637.     mvertex_t    *v;
  638.     mtexinfo_t    *tex;
  639.     int        bmins[2], bmaxs[2];
  640.  
  641.     mins[0] = mins[1] = 999999;
  642.     maxs[0] = maxs[1] = -99999;
  643.  
  644.     tex = s->texinfo;
  645.     
  646.     for (i=0 ; i<s->numedges ; i++)
  647.     {
  648.         e = loadmodel->surfedges[s->firstedge+i];
  649.         if (e >= 0)
  650.             v = &loadmodel->vertexes[loadmodel->edges[e].v[0]];
  651.         else
  652.             v = &loadmodel->vertexes[loadmodel->edges[-e].v[1]];
  653.         
  654.         for (j=0 ; j<2 ; j++)
  655.         {
  656.             val = v->position[0] * tex->vecs[j][0] + 
  657.                 v->position[1] * tex->vecs[j][1] +
  658.                 v->position[2] * tex->vecs[j][2] +
  659.                 tex->vecs[j][3];
  660.             if (val < mins[j])
  661.                 mins[j] = val;
  662.             if (val > maxs[j])
  663.                 maxs[j] = val;
  664.         }
  665.     }
  666.  
  667.     for (i=0 ; i<2 ; i++)
  668.     {    
  669.         bmins[i] = floor(mins[i]/16);
  670.         bmaxs[i] = ceil(maxs[i]/16);
  671.  
  672.         s->texturemins[i] = bmins[i] * 16;
  673.         s->extents[i] = (bmaxs[i] - bmins[i]) * 16;
  674.         if ( !(tex->flags & TEX_SPECIAL) && s->extents[i] > 256)
  675.             SV_Error ("Bad surface extents");
  676.     }
  677. }
  678.  
  679.  
  680. /*
  681. =================
  682. Mod_LoadFaces
  683. =================
  684. */
  685. void Mod_LoadFaces (lump_t *l)
  686. {
  687.     dface_t        *in;
  688.     msurface_t     *out;
  689.     int            i, count, surfnum;
  690.     int            planenum, side;
  691.  
  692.     in = (void *)(mod_base + l->fileofs);
  693.     if (l->filelen % sizeof(*in))
  694.         SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  695.     count = l->filelen / sizeof(*in);
  696.     out = Hunk_AllocName ( count*sizeof(*out), loadname);    
  697.  
  698.     loadmodel->surfaces = out;
  699.     loadmodel->numsurfaces = count;
  700.  
  701.     for ( surfnum=0 ; surfnum<count ; surfnum++, in++, out++)
  702.     {
  703.         out->firstedge = LittleLong(in->firstedge);
  704.         out->numedges = LittleShort(in->numedges);        
  705.         out->flags = 0;
  706.  
  707.         planenum = LittleShort(in->planenum);
  708.         side = LittleShort(in->side);
  709.         if (side)
  710.             out->flags |= SURF_PLANEBACK;            
  711.  
  712.         out->plane = loadmodel->planes + planenum;
  713.  
  714.         out->texinfo = loadmodel->texinfo + LittleShort (in->texinfo);
  715.  
  716.         CalcSurfaceExtents (out);
  717.                 
  718.     // lighting info
  719.  
  720.         for (i=0 ; i<MAXLIGHTMAPS ; i++)
  721.             out->styles[i] = in->styles[i];
  722.         i = LittleLong(in->lightofs);
  723.         if (i == -1)
  724.             out->samples = NULL;
  725.         else
  726.             out->samples = loadmodel->lightdata + i;
  727.         
  728.     // set the drawing flags flag
  729.         
  730.         if (!Q_strncmp(out->texinfo->texture->name,"sky",3))    // sky
  731.         {
  732.             out->flags |= (SURF_DRAWSKY | SURF_DRAWTILED);
  733.             continue;
  734.         }
  735.         
  736.         if (!Q_strncmp(out->texinfo->texture->name,"*",1))        // turbulent
  737.         {
  738.             out->flags |= (SURF_DRAWTURB | SURF_DRAWTILED);
  739.             for (i=0 ; i<2 ; i++)
  740.             {
  741.                 out->extents[i] = 16384;
  742.                 out->texturemins[i] = -8192;
  743.             }
  744.             continue;
  745.         }
  746.     }
  747. }
  748.  
  749.  
  750. /*
  751. =================
  752. Mod_SetParent
  753. =================
  754. */
  755. void Mod_SetParent (mnode_t *node, mnode_t *parent)
  756. {
  757.     node->parent = parent;
  758.     if (node->contents < 0)
  759.         return;
  760.     Mod_SetParent (node->children[0], node);
  761.     Mod_SetParent (node->children[1], node);
  762. }
  763.  
  764. /*
  765. =================
  766. Mod_LoadNodes
  767. =================
  768. */
  769. void Mod_LoadNodes (lump_t *l)
  770. {
  771.     int            i, j, count, p;
  772.     dnode_t        *in;
  773.     mnode_t     *out;
  774.  
  775.     in = (void *)(mod_base + l->fileofs);
  776.     if (l->filelen % sizeof(*in))
  777.         SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  778.     count = l->filelen / sizeof(*in);
  779.     out = Hunk_AllocName ( count*sizeof(*out), loadname);    
  780.  
  781.     loadmodel->nodes = out;
  782.     loadmodel->numnodes = count;
  783.  
  784.     for ( i=0 ; i<count ; i++, in++, out++)
  785.     {
  786.         for (j=0 ; j<3 ; j++)
  787.         {
  788.             out->minmaxs[j] = LittleShort (in->mins[j]);
  789.             out->minmaxs[3+j] = LittleShort (in->maxs[j]);
  790.         }
  791.     
  792.         p = LittleLong(in->planenum);
  793.         out->plane = loadmodel->planes + p;
  794.  
  795.         out->firstsurface = LittleShort (in->firstface);
  796.         out->numsurfaces = LittleShort (in->numfaces);
  797.         
  798.         for (j=0 ; j<2 ; j++)
  799.         {
  800.             p = LittleShort (in->children[j]);
  801.             if (p >= 0)
  802.                 out->children[j] = loadmodel->nodes + p;
  803.             else
  804.                 out->children[j] = (mnode_t *)(loadmodel->leafs + (-1 - p));
  805.         }
  806.     }
  807.     
  808.     Mod_SetParent (loadmodel->nodes, NULL);    // sets nodes and leafs
  809. }
  810.  
  811. /*
  812. =================
  813. Mod_LoadLeafs
  814. =================
  815. */
  816. void Mod_LoadLeafs (lump_t *l)
  817. {
  818.     dleaf_t     *in;
  819.     mleaf_t     *out;
  820.     int            i, j, count, p;
  821.  
  822.     in = (void *)(mod_base + l->fileofs);
  823.     if (l->filelen % sizeof(*in))
  824.         SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  825.     count = l->filelen / sizeof(*in);
  826.     out = Hunk_AllocName ( count*sizeof(*out), loadname);    
  827.  
  828.     loadmodel->leafs = out;
  829.     loadmodel->numleafs = count;
  830.  
  831.     for ( i=0 ; i<count ; i++, in++, out++)
  832.     {
  833.         for (j=0 ; j<3 ; j++)
  834.         {
  835.             out->minmaxs[j] = LittleShort (in->mins[j]);
  836.             out->minmaxs[3+j] = LittleShort (in->maxs[j]);
  837.         }
  838.  
  839.         p = LittleLong(in->contents);
  840.         out->contents = p;
  841.  
  842.         out->firstmarksurface = loadmodel->marksurfaces +
  843.             LittleShort(in->firstmarksurface);
  844.         out->nummarksurfaces = LittleShort(in->nummarksurfaces);
  845.         
  846.         p = LittleLong(in->visofs);
  847.         if (p == -1)
  848.             out->compressed_vis = NULL;
  849.         else
  850.             out->compressed_vis = loadmodel->visdata + p;
  851.         out->efrags = NULL;
  852.         
  853.         for (j=0 ; j<4 ; j++)
  854.             out->ambient_sound_level[j] = in->ambient_level[j];
  855.     }    
  856. }
  857.  
  858. /*
  859. =================
  860. Mod_LoadClipnodes
  861. =================
  862. */
  863. void Mod_LoadClipnodes (lump_t *l)
  864. {
  865.     dclipnode_t *in, *out;
  866.     int            i, count;
  867.     hull_t        *hull;
  868.  
  869.     in = (void *)(mod_base + l->fileofs);
  870.     if (l->filelen % sizeof(*in))
  871.         SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  872.     count = l->filelen / sizeof(*in);
  873.     out = Hunk_AllocName ( count*sizeof(*out), loadname);    
  874.  
  875.     loadmodel->clipnodes = out;
  876.     loadmodel->numclipnodes = count;
  877.  
  878.     hull = &loadmodel->hulls[1];
  879.     hull->clipnodes = out;
  880.     hull->firstclipnode = 0;
  881.     hull->lastclipnode = count-1;
  882.     hull->planes = loadmodel->planes;
  883.     hull->clip_mins[0] = -16;
  884.     hull->clip_mins[1] = -16;
  885.     hull->clip_mins[2] = -24;
  886.     hull->clip_maxs[0] = 16;
  887.     hull->clip_maxs[1] = 16;
  888.     hull->clip_maxs[2] = 32;
  889.  
  890.     hull = &loadmodel->hulls[2];
  891.     hull->clipnodes = out;
  892.     hull->firstclipnode = 0;
  893.     hull->lastclipnode = count-1;
  894.     hull->planes = loadmodel->planes;
  895.     hull->clip_mins[0] = -32;
  896.     hull->clip_mins[1] = -32;
  897.     hull->clip_mins[2] = -24;
  898.     hull->clip_maxs[0] = 32;
  899.     hull->clip_maxs[1] = 32;
  900.     hull->clip_maxs[2] = 64;
  901.  
  902.     for (i=0 ; i<count ; i++, out++, in++)
  903.     {
  904.         out->planenum = LittleLong(in->planenum);
  905.         out->children[0] = LittleShort(in->children[0]);
  906.         out->children[1] = LittleShort(in->children[1]);
  907.     }
  908. }
  909.  
  910. /*
  911. =================
  912. Mod_MakeHull0
  913.  
  914. Deplicate the drawing hull structure as a clipping hull
  915. =================
  916. */
  917. void Mod_MakeHull0 (void)
  918. {
  919.     mnode_t        *in, *child;
  920.     dclipnode_t *out;
  921.     int            i, j, count;
  922.     hull_t        *hull;
  923.     
  924.     hull = &loadmodel->hulls[0];    
  925.     
  926.     in = loadmodel->nodes;
  927.     count = loadmodel->numnodes;
  928.     out = Hunk_AllocName ( count*sizeof(*out), loadname);    
  929.  
  930.     hull->clipnodes = out;
  931.     hull->firstclipnode = 0;
  932.     hull->lastclipnode = count-1;
  933.     hull->planes = loadmodel->planes;
  934.  
  935.     for (i=0 ; i<count ; i++, out++, in++)
  936.     {
  937.         out->planenum = in->plane - loadmodel->planes;
  938.         for (j=0 ; j<2 ; j++)
  939.         {
  940.             child = in->children[j];
  941.             if (child->contents < 0)
  942.                 out->children[j] = child->contents;
  943.             else
  944.                 out->children[j] = child - loadmodel->nodes;
  945.         }
  946.     }
  947. }
  948.  
  949. /*
  950. =================
  951. Mod_LoadMarksurfaces
  952. =================
  953. */
  954. void Mod_LoadMarksurfaces (lump_t *l)
  955. {    
  956.     int        i, j, count;
  957.     short        *in;
  958.     msurface_t **out;
  959.     
  960.     in = (void *)(mod_base + l->fileofs);
  961.     if (l->filelen % sizeof(*in))
  962.         SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  963.     count = l->filelen / sizeof(*in);
  964.     out = Hunk_AllocName ( count*sizeof(*out), loadname);    
  965.  
  966.     loadmodel->marksurfaces = out;
  967.     loadmodel->nummarksurfaces = count;
  968.  
  969.     for ( i=0 ; i<count ; i++)
  970.     {
  971.         j = LittleShort(in[i]);
  972.         if (j >= loadmodel->numsurfaces)
  973.             SV_Error ("Mod_ParseMarksurfaces: bad surface number");
  974.         out[i] = loadmodel->surfaces + j;
  975.     }
  976. }
  977.  
  978. /*
  979. =================
  980. Mod_LoadSurfedges
  981. =================
  982. */
  983. void Mod_LoadSurfedges (lump_t *l)
  984. {    
  985.     int        i, count;
  986.     int        *in, *out;
  987.     
  988.     in = (void *)(mod_base + l->fileofs);
  989.     if (l->filelen % sizeof(*in))
  990.         SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  991.     count = l->filelen / sizeof(*in);
  992.     out = Hunk_AllocName ( count*sizeof(*out), loadname);    
  993.  
  994.     loadmodel->surfedges = out;
  995.     loadmodel->numsurfedges = count;
  996.  
  997.     for ( i=0 ; i<count ; i++)
  998.         out[i] = LittleLong (in[i]);
  999. }
  1000.  
  1001. /*
  1002. =================
  1003. Mod_LoadPlanes
  1004. =================
  1005. */
  1006. void Mod_LoadPlanes (lump_t *l)
  1007. {
  1008.     int            i, j;
  1009.     mplane_t    *out;
  1010.     dplane_t     *in;
  1011.     int            count;
  1012.     int            bits;
  1013.     
  1014.     in = (void *)(mod_base + l->fileofs);
  1015.     if (l->filelen % sizeof(*in))
  1016.         SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  1017.     count = l->filelen / sizeof(*in);
  1018.     out = Hunk_AllocName ( count*2*sizeof(*out), loadname);    
  1019.     
  1020.     loadmodel->planes = out;
  1021.     loadmodel->numplanes = count;
  1022.  
  1023.     for ( i=0 ; i<count ; i++, in++, out++)
  1024.     {
  1025.         bits = 0;
  1026.         for (j=0 ; j<3 ; j++)
  1027.         {
  1028.             out->normal[j] = LittleFloat (in->normal[j]);
  1029.             if (out->normal[j] < 0)
  1030.                 bits |= 1<<j;
  1031.         }
  1032.  
  1033.         out->dist = LittleFloat (in->dist);
  1034.         out->type = LittleLong (in->type);
  1035.         out->signbits = bits;
  1036.     }
  1037. }
  1038.  
  1039.  
  1040. /*
  1041. =================
  1042. Mod_LoadBrushModel
  1043. =================
  1044. */
  1045. void Mod_LoadBrushModel (model_t *mod, void *buffer)
  1046. {
  1047.     int            i, j;
  1048.     dheader_t    *header;
  1049.     dmodel_t     *bm;
  1050.     
  1051.     loadmodel->type = mod_brush;
  1052.     
  1053.     header = (dheader_t *)buffer;
  1054.  
  1055.     i = LittleLong (header->version);
  1056.     if (i != BSPVERSION)
  1057.         SV_Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION);
  1058.  
  1059. // swap all the lumps
  1060.     mod_base = (byte *)header;
  1061.  
  1062.     for (i=0 ; i<sizeof(dheader_t)/4 ; i++)
  1063.         ((int *)header)[i] = LittleLong ( ((int *)header)[i]);
  1064.  
  1065. // load into heap
  1066.  
  1067.     mod->checksum = 0;
  1068.     mod->checksum2 = 0;
  1069.  
  1070.     // checksum all of the map, except for entities
  1071.     for (i = 0; i < HEADER_LUMPS; i++) {
  1072.         if (i == LUMP_ENTITIES)
  1073.             continue;
  1074.         mod->checksum ^= LittleLong(Com_BlockChecksum(mod_base + header->lumps[i].fileofs, 
  1075.             header->lumps[i].filelen));
  1076.  
  1077.         if (i == LUMP_VISIBILITY || i == LUMP_LEAFS || i == LUMP_NODES)
  1078.             continue;
  1079.         mod->checksum2 ^= LittleLong(Com_BlockChecksum(mod_base + header->lumps[i].fileofs, 
  1080.             header->lumps[i].filelen));
  1081.     }
  1082.  
  1083.     Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]);
  1084.     Mod_LoadEdges (&header->lumps[LUMP_EDGES]);
  1085.     Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]);
  1086.     Mod_LoadTextures (&header->lumps[LUMP_TEXTURES]);
  1087.     Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]);
  1088.     Mod_LoadPlanes (&header->lumps[LUMP_PLANES]);
  1089.     Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]);
  1090.     Mod_LoadFaces (&header->lumps[LUMP_FACES]);
  1091.     Mod_LoadMarksurfaces (&header->lumps[LUMP_MARKSURFACES]);
  1092.     Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]);
  1093.     Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]);
  1094.     Mod_LoadNodes (&header->lumps[LUMP_NODES]);
  1095.     Mod_LoadClipnodes (&header->lumps[LUMP_CLIPNODES]);
  1096.     Mod_LoadEntities (&header->lumps[LUMP_ENTITIES]);
  1097.     Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]);
  1098.  
  1099.     Mod_MakeHull0 ();
  1100.     
  1101.     mod->numframes = 2;        // regular and alternate animation
  1102.     
  1103. //
  1104. // set up the submodels (FIXME: this is confusing)
  1105. //
  1106.     for (i=0 ; i<mod->numsubmodels ; i++)
  1107.     {
  1108.         bm = &mod->submodels[i];
  1109.  
  1110.         mod->hulls[0].firstclipnode = bm->headnode[0];
  1111.         for (j=1 ; j<MAX_MAP_HULLS ; j++)
  1112.         {
  1113.             mod->hulls[j].firstclipnode = bm->headnode[j];
  1114.             mod->hulls[j].lastclipnode = mod->numclipnodes-1;
  1115.         }
  1116.         
  1117.         mod->firstmodelsurface = bm->firstface;
  1118.         mod->nummodelsurfaces = bm->numfaces;
  1119.         
  1120.         VectorCopy (bm->maxs, mod->maxs);
  1121.         VectorCopy (bm->mins, mod->mins);
  1122.     
  1123.         mod->numleafs = bm->visleafs;
  1124.  
  1125.         if (i < mod->numsubmodels-1)
  1126.         {    // duplicate the basic information
  1127.             char    name[10];
  1128.  
  1129.             sprintf (name, "*%i", i+1);
  1130.             loadmodel = Mod_FindName (name);
  1131.             *loadmodel = *mod;
  1132.             strcpy (loadmodel->name, name);
  1133.             mod = loadmodel;
  1134.         }
  1135.     }
  1136. }
  1137.  
  1138.