home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #2 / amigaacscoverdisc1998-021998.iso / games / doom / source / linuxdoom-1.10 / r_data.c < prev    next >
C/C++ Source or Header  |  1997-12-22  |  18KB  |  850 lines

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