Subversion Repositories Kolibri OS

Rev

Rev 298 | Blame | Last modification | View Log | Download | RSS feed

  1. // Emacs style mode select   -*- C++ -*-
  2. //-----------------------------------------------------------------------------
  3. //
  4. // $Id:$
  5. //
  6. // Copyright (C) 1993-1996 by id Software, Inc.
  7. //
  8. // This source is available for distribution and/or modification
  9. // only under the terms of the DOOM Source Code License as
  10. // published by id Software. All rights reserved.
  11. //
  12. // The source is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
  15. // for more details.
  16. //
  17. // $Log:$
  18. //
  19. // Revision 1.3  1997/01/29 20:10
  20. // DESCRIPTION:
  21. //      Preparation of data for rendering,
  22. //      generation of lookups, caching, retrieval by name.
  23. //
  24. //-----------------------------------------------------------------------------
  25.  
  26.  
  27. static const char
  28. rcsid[] = "$Id: r_data.c,v 1.4 1997/02/03 16:47:55 b1 Exp $";
  29.  
  30. #include "i_system.h"
  31. #include "z_zone.h"
  32.  
  33. #include "m_swap.h"
  34.  
  35. #include "w_wad.h"
  36.  
  37. #include "doomdef.h"
  38. #include "r_local.h"
  39. #include "p_local.h"
  40.  
  41. #include "doomstat.h"
  42. #include "r_sky.h"
  43.  
  44. #include  <malloc.h>
  45.  
  46.  
  47. #include "r_data.h"
  48.  
  49. //
  50. // Graphics.
  51. // DOOM graphics for walls and sprites
  52. // is stored in vertical runs of opaque pixels (posts).
  53. // A column is composed of zero or more posts,
  54. // a patch or sprite is composed of zero or more columns.
  55. //
  56.  
  57.  
  58.  
  59. //
  60. // Texture definition.
  61. // Each texture is composed of one or more patches,
  62. // with patches being lumps stored in the WAD.
  63. // The lumps are referenced by number, and patched
  64. // into the rectangular texture space using origin
  65. // and possibly other attributes.
  66. //
  67. typedef struct
  68. {
  69.     short       originx;
  70.     short       originy;
  71.     short       patch;
  72.     short       stepdir;
  73.     short       colormap;
  74. } mappatch_t;
  75.  
  76.  
  77. //
  78. // Texture definition.
  79. // A DOOM wall texture is a list of patches
  80. // which are to be combined in a predefined order.
  81. //
  82. typedef struct
  83. {
  84.     char                name[8];
  85.     int                 masked;
  86.     short               width;
  87.     short               height;
  88.     void                **columndirectory;      // OBSOLETE
  89.     short               patchcount;
  90.     mappatch_t  patches[1];
  91. } maptexture_t;
  92.  
  93.  
  94. // A single patch from a texture definition,
  95. //  basically a rectangular area within
  96. //  the texture rectangle.
  97. typedef struct
  98. {
  99.     // Block origin (allways UL),
  100.     // which has allready accounted
  101.     // for the internal origin of the patch.
  102.     int         originx;        
  103.     int         originy;
  104.     int         patch;
  105. } texpatch_t;
  106.  
  107.  
  108. // A maptexturedef_t describes a rectangular texture,
  109. //  which is composed of one or more mappatch_t structures
  110. //  that arrange graphic patches.
  111. typedef struct
  112. {
  113.     // Keep name for switch changing, etc.
  114.     char        name[8];                
  115.     short int   width;
  116.     short int   height;
  117.    
  118.     // All the patches[patchcount]
  119.     //  are drawn back to front into the cached texture.
  120.     short int   patchcount;
  121.     texpatch_t  patches[1];            
  122.    
  123. } texture_t;
  124.  
  125.  
  126.  
  127. int             firstflat;
  128. int             lastflat;
  129. int             numflats;
  130.  
  131. int             firstpatch;
  132. int             lastpatch;
  133. int             numpatches;
  134.  
  135. int             firstspritelump;
  136. int             lastspritelump;
  137. int             numspritelumps;
  138.  
  139. int             numtextures;
  140. texture_t**     textures;
  141.  
  142.  
  143. int*                    texturewidthmask;
  144. // needed for texture pegging
  145. fixed_t*                textureheight;          
  146. int*                    texturecompositesize;
  147. short**                 texturecolumnlump;
  148. unsigned short**        texturecolumnofs;
  149. byte**                  texturecomposite;
  150.  
  151. // for global animation
  152. int*            flattranslation;
  153. int*            texturetranslation;
  154.  
  155. // needed for pre rendering
  156. fixed_t*        spritewidth;    
  157. fixed_t*        spriteoffset;
  158. fixed_t*        spritetopoffset;
  159.  
  160. lighttable_t    *colormaps;
  161.  
  162.  
  163. //
  164. // MAPTEXTURE_T CACHING
  165. // When a texture is first needed,
  166. //  it counts the number of composite columns
  167. //  required in the texture and allocates space
  168. //  for a column directory and any new columns.
  169. // The directory will simply point inside other patches
  170. //  if there is only one patch in a given column,
  171. //  but any columns with multiple patches
  172. //  will have new column_ts generated.
  173. //
  174.  
  175.  
  176.  
  177. //
  178. // R_DrawColumnInCache
  179. // Clip and draw a column
  180. //  from a patch into a cached post.
  181. //
  182. void
  183. R_DrawColumnInCache
  184. ( column_t*     patch,
  185.   byte*         cache,
  186.   int           originy,
  187.   int           cacheheight )
  188. {
  189.     int         count;
  190.     int         position;
  191.     byte*       source;
  192.     byte*       dest;
  193.        
  194.     dest = (byte *)cache + 3;
  195.        
  196.     while (patch->topdelta != 0xff)
  197.     {
  198.         source = (byte *)patch + 3;
  199.         count = patch->length;
  200.         position = originy + patch->topdelta;
  201.  
  202.         if (position < 0)
  203.         {
  204.             count += position;
  205.             position = 0;
  206.         }
  207.  
  208.         if (position + count > cacheheight)
  209.             count = cacheheight - position;
  210.  
  211.         if (count > 0)
  212.             memcpy (cache + position, source, count);
  213.                
  214.         patch = (column_t *)(  (byte *)patch + patch->length + 4);
  215.     }
  216. }
  217.  
  218.  
  219.  
  220. //
  221. // R_GenerateComposite
  222. // Using the texture definition,
  223. //  the composite texture is created from the patches,
  224. //  and each column is cached.
  225. //
  226. void R_GenerateComposite (int texnum)
  227. {
  228.     byte*               block;
  229.     texture_t*          texture;
  230.     texpatch_t*         patch;  
  231.     patch_t*            realpatch;
  232.     int                 x;
  233.     int                 x1;
  234.     int                 x2;
  235.     int                 i;
  236.     column_t*           patchcol;
  237.     short*              collump;
  238.     unsigned short*     colofs;
  239.        
  240.     texture = textures[texnum];
  241.  
  242.     block = Z_Malloc (texturecompositesize[texnum],
  243.                       PU_STATIC,
  244.                       &texturecomposite[texnum]);      
  245.  
  246.     collump = texturecolumnlump[texnum];
  247.     colofs = texturecolumnofs[texnum];
  248.    
  249.     // Composite the columns together.
  250.     patch = texture->patches;
  251.                
  252.     for (i=0 , patch = texture->patches;
  253.          i<texture->patchcount;
  254.          i++, patch++)
  255.     {
  256.         realpatch = W_CacheLumpNum (patch->patch, PU_CACHE);
  257.         x1 = patch->originx;
  258.         x2 = x1 + SHORT(realpatch->width);
  259.  
  260.         if (x1<0)
  261.             x = 0;
  262.         else
  263.             x = x1;
  264.        
  265.         if (x2 > texture->width)
  266.             x2 = texture->width;
  267.  
  268.         for ( ; x<x2 ; x++)
  269.         {
  270.             // Column does not have multiple patches?
  271.             if (collump[x] >= 0)
  272.                 continue;
  273.            
  274.             patchcol = (column_t *)((byte *)realpatch
  275.                                     + LONG(realpatch->columnofs[x-x1]));
  276.             R_DrawColumnInCache (patchcol,
  277.                                  block + colofs[x],
  278.                                  patch->originy,
  279.                                  texture->height);
  280.         }
  281.                                                
  282.     }
  283.  
  284.     // Now that the texture has been built in column cache,
  285.     //  it is purgable from zone memory.
  286.     Z_ChangeTag (block, PU_CACHE);
  287. }
  288.  
  289.  
  290.  
  291. //
  292. // R_GenerateLookup
  293. //
  294. void R_GenerateLookup (int texnum)
  295. {
  296.     texture_t*          texture;
  297.     byte*               patchcount;     // patchcount[texture->width]
  298.     texpatch_t*         patch;  
  299.     patch_t*            realpatch;
  300.     int                 x;
  301.     int                 x1;
  302.     int                 x2;
  303.     int                 i;
  304.     short*              collump;
  305.     unsigned short*     colofs;
  306.        
  307.     texture = textures[texnum];
  308.  
  309.     // Composited texture not created yet.
  310.     texturecomposite[texnum] = 0;
  311.    
  312.     texturecompositesize[texnum] = 0;
  313.     collump = texturecolumnlump[texnum];
  314.     colofs = texturecolumnofs[texnum];
  315.    
  316.     // Now count the number of columns
  317.     //  that are covered by more than one patch.
  318.     // Fill in the lump / offset, so columns
  319.     //  with only a single patch are all done.
  320.     patchcount = (byte *)alloca (texture->width);
  321.     memset (patchcount, 0, texture->width);
  322.     patch = texture->patches;
  323.                
  324.     for (i=0 , patch = texture->patches;
  325.          i<texture->patchcount;
  326.          i++, patch++)
  327.     {
  328.         realpatch = W_CacheLumpNum (patch->patch, PU_CACHE);
  329.         x1 = patch->originx;
  330.         x2 = x1 + SHORT(realpatch->width);
  331.        
  332.         if (x1 < 0)
  333.             x = 0;
  334.         else
  335.             x = x1;
  336.  
  337.         if (x2 > texture->width)
  338.             x2 = texture->width;
  339.         for ( ; x<x2 ; x++)
  340.         {
  341.             patchcount[x]++;
  342.             collump[x] = patch->patch;
  343.             colofs[x] = LONG(realpatch->columnofs[x-x1])+3;
  344.         }
  345.     }
  346.        
  347.     for (x=0 ; x<texture->width ; x++)
  348.     {
  349.         if (!patchcount[x])
  350.         {
  351.             printf ("R_GenerateLookup: column without a patch (%s)\n",
  352.                     texture->name);
  353.             return;
  354.         }
  355.         // I_Error ("R_GenerateLookup: column without a patch");
  356.        
  357.         if (patchcount[x] > 1)
  358.         {
  359.             // Use the cached block.
  360.             collump[x] = -1;    
  361.             colofs[x] = texturecompositesize[texnum];
  362.            
  363.             if (texturecompositesize[texnum] > 0x10000-texture->height)
  364.             {
  365.                 I_Error ("R_GenerateLookup: texture %i is >64k",
  366.                          texnum);
  367.             }
  368.            
  369.             texturecompositesize[texnum] += texture->height;
  370.         }
  371.     }  
  372. }
  373.  
  374.  
  375.  
  376.  
  377. //
  378. // R_GetColumn
  379. //
  380. byte*
  381. R_GetColumn
  382. ( int           tex,
  383.   int           col )
  384. {
  385.     int         lump;
  386.     int         ofs;
  387.        
  388.     col &= texturewidthmask[tex];
  389.     lump = texturecolumnlump[tex][col];
  390.     ofs = texturecolumnofs[tex][col];
  391.    
  392.     if (lump > 0)
  393.         return (byte *)W_CacheLumpNum(lump,PU_CACHE)+ofs;
  394.  
  395.     if (!texturecomposite[tex])
  396.         R_GenerateComposite (tex);
  397.  
  398.     return texturecomposite[tex] + ofs;
  399. }
  400.  
  401.  
  402.  
  403.  
  404. //
  405. // R_InitTextures
  406. // Initializes the texture list
  407. //  with the textures from the world map.
  408. //
  409. void R_InitTextures (void)
  410. {
  411.     maptexture_t*       mtexture;
  412.     texture_t*          texture;
  413.     mappatch_t*         mpatch;
  414.     texpatch_t*         patch;
  415.  
  416.     int                 i;
  417.     int                 j;
  418.  
  419.     int*                maptex;
  420.     int*                maptex2;
  421.     int*                maptex1;
  422.    
  423.     char                name[9];
  424.     char*               names;
  425.     char*               name_p;
  426.    
  427.     int*                patchlookup;
  428.    
  429.     int                 totalwidth;
  430.     int                 nummappatches;
  431.     int                 offset;
  432.     int                 maxoff;
  433.     int                 maxoff2;
  434.     int                 numtextures1;
  435.     int                 numtextures2;
  436.  
  437.     int*                directory;
  438.    
  439.     int                 temp1;
  440.     int                 temp2;
  441.     int                 temp3;
  442.  
  443.    
  444.     // Load the patch names from pnames.lmp.
  445.     name[8] = 0;        
  446.     names = W_CacheLumpName ("PNAMES", PU_STATIC);
  447.     nummappatches = LONG ( *((int *)names) );
  448.     name_p = names+4;
  449.     patchlookup = alloca (nummappatches*sizeof(*patchlookup));
  450.    
  451.     for (i=0 ; i<nummappatches ; i++)
  452.     {
  453.         strncpy (name,name_p+i*8, 8);
  454.         patchlookup[i] = W_CheckNumForName (name);
  455.     }
  456.     Z_Free (names);
  457.    
  458.     // Load the map texture definitions from textures.lmp.
  459.     // The data is contained in one or two lumps,
  460.     //  TEXTURE1 for shareware, plus TEXTURE2 for commercial.
  461.     maptex = maptex1 = W_CacheLumpName ("TEXTURE1", PU_STATIC);
  462.     numtextures1 = LONG(*maptex);
  463.     maxoff = W_LumpLength (W_GetNumForName ("TEXTURE1"));
  464.     directory = maptex+1;
  465.        
  466.     if (W_CheckNumForName ("TEXTURE2") != -1)
  467.     {
  468.         maptex2 = W_CacheLumpName ("TEXTURE2", PU_STATIC);
  469.         numtextures2 = LONG(*maptex2);
  470.         maxoff2 = W_LumpLength (W_GetNumForName ("TEXTURE2"));
  471.     }
  472.     else
  473.     {
  474.         maptex2 = NULL;
  475.         numtextures2 = 0;
  476.         maxoff2 = 0;
  477.     }
  478.     numtextures = numtextures1 + numtextures2;
  479.        
  480.     textures = Z_Malloc (numtextures*4, PU_STATIC, 0);
  481.     texturecolumnlump = Z_Malloc (numtextures*4, PU_STATIC, 0);
  482.     texturecolumnofs = Z_Malloc (numtextures*4, PU_STATIC, 0);
  483.     texturecomposite = Z_Malloc (numtextures*4, PU_STATIC, 0);
  484.     texturecompositesize = Z_Malloc (numtextures*4, PU_STATIC, 0);
  485.     texturewidthmask = Z_Malloc (numtextures*4, PU_STATIC, 0);
  486.     textureheight = Z_Malloc (numtextures*4, PU_STATIC, 0);
  487.  
  488.     totalwidth = 0;
  489.    
  490.     //  Really complex printing shit...
  491.     temp1 = W_GetNumForName ("S_START");  // P_???????
  492.     temp2 = W_GetNumForName ("S_END") - 1;
  493.     temp3 = ((temp2-temp1+63)/64) + ((numtextures+63)/64);
  494.     printf("[");
  495.     for (i = 0; i < temp3; i++)
  496.         printf(" ");
  497.     printf("         ]");
  498.     for (i = 0; i < temp3; i++)
  499.         printf("\x8");
  500.     printf("\x8\x8\x8\x8\x8\x8\x8\x8\x8\x8");  
  501.        
  502.     for (i=0 ; i<numtextures ; i++, directory++)
  503.     {
  504.         if (!(i&63))
  505.             printf (".");
  506.  
  507.         if (i == numtextures1)
  508.         {
  509.             // Start looking in second texture file.
  510.             maptex = maptex2;
  511.             maxoff = maxoff2;
  512.             directory = maptex+1;
  513.         }
  514.                
  515.         offset = LONG(*directory);
  516.  
  517.         if (offset > maxoff)
  518.             I_Error ("R_InitTextures: bad texture directory");
  519.        
  520.         mtexture = (maptexture_t *) ( (byte *)maptex + offset);
  521.  
  522.         texture = textures[i] =
  523.             Z_Malloc (sizeof(texture_t)
  524.                       + sizeof(texpatch_t)*(SHORT(mtexture->patchcount)-1),
  525.                       PU_STATIC, 0);
  526.        
  527.         texture->width = SHORT(mtexture->width);
  528.         texture->height = SHORT(mtexture->height);
  529.         texture->patchcount = SHORT(mtexture->patchcount);
  530.  
  531.         memcpy (texture->name, mtexture->name, sizeof(texture->name));
  532.         mpatch = &mtexture->patches[0];
  533.         patch = &texture->patches[0];
  534.  
  535.         for (j=0 ; j<texture->patchcount ; j++, mpatch++, patch++)
  536.         {
  537.             patch->originx = SHORT(mpatch->originx);
  538.             patch->originy = SHORT(mpatch->originy);
  539.             patch->patch = patchlookup[SHORT(mpatch->patch)];
  540.             if (patch->patch == -1)
  541.             {
  542.                 I_Error ("R_InitTextures: Missing patch in texture %s",
  543.                          texture->name);
  544.             }
  545.         }              
  546.         texturecolumnlump[i] = Z_Malloc (texture->width*2, PU_STATIC,0);
  547.         texturecolumnofs[i] = Z_Malloc (texture->width*2, PU_STATIC,0);
  548.  
  549.         j = 1;
  550.         while (j*2 <= texture->width)
  551.             j<<=1;
  552.  
  553.         texturewidthmask[i] = j-1;
  554.         textureheight[i] = texture->height<<FRACBITS;
  555.                
  556.         totalwidth += texture->width;
  557.     }
  558.  
  559.     Z_Free (maptex1);
  560.     if (maptex2)
  561.         Z_Free (maptex2);
  562.    
  563.     // Precalculate whatever possible.  
  564.     for (i=0 ; i<numtextures ; i++)
  565.         R_GenerateLookup (i);
  566.    
  567.     // Create translation table for global animation.
  568.     texturetranslation = Z_Malloc ((numtextures+1)*4, PU_STATIC, 0);
  569.    
  570.     for (i=0 ; i<numtextures ; i++)
  571.         texturetranslation[i] = i;
  572. }
  573.  
  574.  
  575.  
  576. //
  577. // R_InitFlats
  578. //
  579. void R_InitFlats (void)
  580. {
  581.     int         i;
  582.        
  583.     firstflat = W_GetNumForName ("F_START") + 1;
  584.     lastflat = W_GetNumForName ("F_END") - 1;
  585.     numflats = lastflat - firstflat + 1;
  586.        
  587.     // Create translation table for global animation.
  588.     flattranslation = Z_Malloc ((numflats+1)*4, PU_STATIC, 0);
  589.    
  590.     for (i=0 ; i<numflats ; i++)
  591.         flattranslation[i] = i;
  592. }
  593.  
  594.  
  595. //
  596. // R_InitSpriteLumps
  597. // Finds the width and hoffset of all sprites in the wad,
  598. //  so the sprite does not need to be cached completely
  599. //  just for having the header info ready during rendering.
  600. //
  601. void R_InitSpriteLumps (void)
  602. {
  603.     int         i;
  604.     patch_t     *patch;
  605.        
  606.     firstspritelump = W_GetNumForName ("S_START") + 1;
  607.     lastspritelump = W_GetNumForName ("S_END") - 1;
  608.    
  609.     numspritelumps = lastspritelump - firstspritelump + 1;
  610.     spritewidth = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
  611.     spriteoffset = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
  612.     spritetopoffset = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
  613.        
  614.     for (i=0 ; i< numspritelumps ; i++)
  615.     {
  616.         if (!(i&63))
  617.             printf (".");
  618.  
  619.         patch = W_CacheLumpNum (firstspritelump+i, PU_CACHE);
  620.         spritewidth[i] = SHORT(patch->width)<<FRACBITS;
  621.         spriteoffset[i] = SHORT(patch->leftoffset)<<FRACBITS;
  622.         spritetopoffset[i] = SHORT(patch->topoffset)<<FRACBITS;
  623.     }
  624. }
  625.  
  626.  
  627.  
  628. //
  629. // R_InitColormaps
  630. //
  631. void R_InitColormaps (void)
  632. {
  633.     int lump, length;
  634.    
  635.     // Load in the light tables,
  636.     //  256 byte align tables.
  637.     lump = W_GetNumForName("COLORMAP");
  638.     length = W_LumpLength (lump) + 255;
  639.     colormaps = Z_Malloc (length, PU_STATIC, 0);
  640.     colormaps = (byte *)( ((int)colormaps + 255)&~0xff);
  641.     W_ReadLump (lump,colormaps);
  642. }
  643.  
  644.  
  645.  
  646. //
  647. // R_InitData
  648. // Locates all the lumps
  649. //  that will be used by all views
  650. // Must be called after W_Init.
  651. //
  652. void R_InitData (void)
  653. {
  654.     R_InitTextures ();
  655.     printf ("InitTextures\n\r");
  656.     R_InitFlats ();
  657.     printf ("InitFlats\n\r");
  658.     R_InitSpriteLumps ();
  659.     printf ("InitSprites\n\r");
  660.     R_InitColormaps ();
  661.     printf ("InitColormaps\n\r");
  662. }
  663.  
  664.  
  665.  
  666. //
  667. // R_FlatNumForName
  668. // Retrieval, get a flat number for a flat name.
  669. //
  670. int R_FlatNumForName (char* name)
  671. {
  672.     int         i;
  673.     char        namet[9];
  674.  
  675.     i = W_CheckNumForName (name);
  676.  
  677.     if (i == -1)
  678.     {
  679.         namet[8] = 0;
  680.         memcpy (namet, name,8);
  681.         I_Error ("R_FlatNumForName: %s not found",namet);
  682.     }
  683.     return i - firstflat;
  684. }
  685.  
  686.  
  687.  
  688.  
  689. //
  690. // R_CheckTextureNumForName
  691. // Check whether texture is available.
  692. // Filter out NoTexture indicator.
  693. //
  694. int     R_CheckTextureNumForName (char *name)
  695. {
  696.     int         i;
  697.  
  698.     // "NoTexture" marker.
  699.     if (name[0] == '-')        
  700.         return 0;
  701.                
  702.     for (i=0 ; i<numtextures ; i++)
  703.         if (!strnicmp (textures[i]->name, name, 8) )
  704.             return i;
  705.                
  706.     return -1;
  707. }
  708.  
  709. //
  710. // R_TextureNumForName
  711. // Calls R_CheckTextureNumForName,
  712. //  aborts with error message.
  713. //
  714. int     R_TextureNumForName (char* name)
  715. {
  716.     int         i;
  717.        
  718.     i = R_CheckTextureNumForName (name);
  719.  
  720.     if (i==-1)
  721.     {
  722.         I_Error ("R_TextureNumForName: %s not found",
  723.                  name);
  724.     }
  725.     return i;
  726. }
  727.  
  728.  
  729.  
  730.  
  731. //
  732. // R_PrecacheLevel
  733. // Preloads all relevant graphics for the level.
  734. //
  735. int             flatmemory;
  736. int             texturememory;
  737. int             spritememory;
  738.  
  739. void R_PrecacheLevel (void)
  740. {
  741.     char*               flatpresent;
  742.     char*               texturepresent;
  743.     char*               spritepresent;
  744.  
  745.     int                 i;
  746.     int                 j;
  747.     int                 k;
  748.     int                 lump;
  749.    
  750.     texture_t*          texture;
  751.     thinker_t*          th;
  752.     spriteframe_t*      sf;
  753.  
  754.     if (demoplayback)
  755.         return;
  756.    
  757.     // Precache flats.
  758.     flatpresent = alloca(numflats);
  759.     memset (flatpresent,0,numflats);    
  760.  
  761.     for (i=0 ; i<numsectors ; i++)
  762.     {
  763.         flatpresent[sectors[i].floorpic] = 1;
  764.         flatpresent[sectors[i].ceilingpic] = 1;
  765.     }
  766.        
  767.     flatmemory = 0;
  768.  
  769.     for (i=0 ; i<numflats ; i++)
  770.     {
  771.         if (flatpresent[i])
  772.         {
  773.             lump = firstflat + i;
  774.             flatmemory += lumpinfo[lump].size;
  775.             W_CacheLumpNum(lump, PU_CACHE);
  776.         }
  777.     }
  778.    
  779.     // Precache textures.
  780.     texturepresent = alloca(numtextures);
  781.     memset (texturepresent,0, numtextures);
  782.        
  783.     for (i=0 ; i<numsides ; i++)
  784.     {
  785.         texturepresent[sides[i].toptexture] = 1;
  786.         texturepresent[sides[i].midtexture] = 1;
  787.         texturepresent[sides[i].bottomtexture] = 1;
  788.     }
  789.  
  790.     // Sky texture is always present.
  791.     // Note that F_SKY1 is the name used to
  792.     //  indicate a sky floor/ceiling as a flat,
  793.     //  while the sky texture is stored like
  794.     //  a wall texture, with an episode dependend
  795.     //  name.
  796.     texturepresent[skytexture] = 1;
  797.        
  798.     texturememory = 0;
  799.     for (i=0 ; i<numtextures ; i++)
  800.     {
  801.         if (!texturepresent[i])
  802.             continue;
  803.  
  804.         texture = textures[i];
  805.        
  806.         for (j=0 ; j<texture->patchcount ; j++)
  807.         {
  808.             lump = texture->patches[j].patch;
  809.             texturememory += lumpinfo[lump].size;
  810.             W_CacheLumpNum(lump , PU_CACHE);
  811.         }
  812.     }
  813.    
  814.     // Precache sprites.
  815.     spritepresent = alloca(numsprites);
  816.     memset (spritepresent,0, numsprites);
  817.        
  818.     for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
  819.     {
  820.         if (th->function.acp1 == (actionf_p1)P_MobjThinker)
  821.             spritepresent[((mobj_t *)th)->sprite] = 1;
  822.     }
  823.        
  824.     spritememory = 0;
  825.     for (i=0 ; i<numsprites ; i++)
  826.     {
  827.         if (!spritepresent[i])
  828.             continue;
  829.  
  830.         for (j=0 ; j<sprites[i].numframes ; j++)
  831.         {
  832.             sf = &sprites[i].spriteframes[j];
  833.             for (k=0 ; k<8 ; k++)
  834.             {
  835.                 lump = firstspritelump + sf->lump[k];
  836.                 spritememory += lumpinfo[lump].size;
  837.                 W_CacheLumpNum(lump , PU_CACHE);
  838.             }
  839.         }
  840.     }
  841. }
  842.  
  843.  
  844.  
  845.  
  846.