home *** CD-ROM | disk | FTP | other *** search
/ CD/PC Actual Thematic 7: Programming / CDAT7.iso / Share / Codigo / hh / rsource.exe / Heretic Source / R_DATA.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-13  |  14.4 KB  |  702 lines

  1.  
  2. // R_data.c
  3.  
  4. #include "DoomDef.h"
  5. #include "R_local.h"
  6. #include "P_local.h"
  7.  
  8. extern void CheckAbortStartup(void);
  9.  
  10. typedef struct
  11. {
  12.     int        originx;    // block origin (allways UL), which has allready
  13.     int        originy;    // accounted  for the patch's internal origin
  14.     int        patch;
  15. } texpatch_t;
  16.  
  17. // a maptexturedef_t describes a rectangular texture, which is composed of one
  18. // or more mappatch_t structures that arrange graphic patches
  19. typedef struct
  20. {
  21.     char        name[8];        // for switch changing, etc
  22.     short        width;
  23.     short        height;
  24.     short        patchcount;
  25.     texpatch_t    patches[1];        // [patchcount] drawn back to front
  26.                                 //  into the cached texture
  27. } texture_t;
  28.  
  29.  
  30.  
  31. int        firstflat, lastflat, numflats;
  32. int        firstpatch, lastpatch, numpatches;
  33. int        firstspritelump, lastspritelump, numspritelumps;
  34.  
  35. int            numtextures;
  36. texture_t    **textures;
  37. int            *texturewidthmask;
  38. fixed_t        *textureheight;        // needed for texture pegging
  39. int            *texturecompositesize;
  40. short        **texturecolumnlump;
  41. unsigned short        **texturecolumnofs;
  42. byte        **texturecomposite;
  43.  
  44. int            *flattranslation;        // for global animation
  45. int            *texturetranslation;    // for global animation
  46.  
  47. fixed_t        *spritewidth;        // needed for pre rendering
  48. fixed_t        *spriteoffset;
  49. fixed_t        *spritetopoffset;
  50.  
  51. lighttable_t    *colormaps;
  52.  
  53.  
  54. /*
  55. ==============================================================================
  56.  
  57.                         MAPTEXTURE_T CACHING
  58.  
  59. when a texture is first needed, it counts the number of composite columns
  60. required in the texture and allocates space for a column directory and any
  61. new columns.  The directory will simply point inside other patches if there
  62. is only one patch in a given column, but any columns with multiple patches
  63. will have new column_ts generated.
  64.  
  65. ==============================================================================
  66. */
  67.  
  68. /*
  69. ===================
  70. =
  71. = R_DrawColumnInCache
  72. =
  73. = Clip and draw a column from a patch into a cached post
  74. =
  75. ===================
  76. */
  77.  
  78. void R_DrawColumnInCache (column_t *patch, byte *cache, int originy, int cacheheight)
  79. {
  80.     int        count, position;
  81.     byte    *source, *dest;
  82.     
  83.     dest = (byte *)cache + 3;
  84.     
  85.     while (patch->topdelta != 0xff)
  86.     {
  87.         source = (byte *)patch + 3;
  88.         count = patch->length;
  89.         position = originy + patch->topdelta;
  90.         if (position < 0)
  91.         {
  92.             count += position;
  93.             position = 0;
  94.         }
  95.         if (position + count > cacheheight)
  96.             count = cacheheight - position;
  97.         if (count > 0)
  98.             memcpy (cache + position, source, count);
  99.         
  100.         patch = (column_t *)(  (byte *)patch + patch->length
  101. + 4);
  102.     }
  103. }
  104.  
  105.  
  106. /*
  107. ===================
  108. =
  109. = R_GenerateComposite
  110. =
  111. ===================
  112. */
  113.  
  114. void R_GenerateComposite (int texnum)
  115. {
  116.     byte        *block;
  117.     texture_t    *texture;
  118.     texpatch_t    *patch;    
  119.     patch_t        *realpatch;
  120.     int            x, x1, x2;
  121.     int            i;
  122.     column_t    *patchcol;
  123.     short        *collump;
  124.     unsigned short *colofs;
  125.     
  126.     texture = textures[texnum];
  127.     block = Z_Malloc (texturecompositesize[texnum], PU_STATIC, 
  128.         &texturecomposite[texnum]);    
  129.     collump = texturecolumnlump[texnum];
  130.     colofs = texturecolumnofs[texnum];
  131.         
  132. //
  133. // composite the columns together
  134. //
  135.     patch = texture->patches;
  136.         
  137.     for (i=0 , patch = texture->patches; i<texture->patchcount ; i++, patch++)
  138.     {
  139.         realpatch = W_CacheLumpNum (patch->patch, PU_CACHE);
  140.         x1 = patch->originx;
  141.         x2 = x1 + SHORT(realpatch->width);
  142.  
  143.         if (x1<0)
  144.             x = 0;
  145.         else
  146.             x = x1;
  147.         if (x2 > texture->width)
  148.             x2 = texture->width;
  149.  
  150.         for ( ; x<x2 ; x++)
  151.         {
  152.             if (collump[x] >= 0)
  153.                 continue;        // column does not have multiple patches
  154.             patchcol = (column_t *)((byte *)realpatch + 
  155.                 LONG(realpatch->columnofs[x-x1]));
  156.             R_DrawColumnInCache (patchcol, block + colofs[x], patch->originy,
  157.             texture->height);
  158.         }
  159.                         
  160.     }
  161.  
  162. // now that the texture has been built, it is purgable
  163.     Z_ChangeTag (block, PU_CACHE);
  164. }
  165.  
  166.  
  167. /*
  168. ===================
  169. =
  170. = R_GenerateLookup
  171. =
  172. ===================
  173. */
  174.  
  175. void R_GenerateLookup (int texnum)
  176. {
  177.     texture_t    *texture;
  178.     byte        *patchcount;        // [texture->width]
  179.     texpatch_t    *patch;    
  180.     patch_t        *realpatch;
  181.     int            x, x1, x2;
  182.     int            i;
  183.     short        *collump;
  184.     unsigned short    *colofs;
  185.     
  186.     texture = textures[texnum];
  187.  
  188.     texturecomposite[texnum] = 0;    // composited not created yet
  189.     texturecompositesize[texnum] = 0;
  190.     collump = texturecolumnlump[texnum];
  191.     colofs = texturecolumnofs[texnum];
  192.     
  193. //
  194. // count the number of columns that are covered by more than one patch
  195. // fill in the lump / offset, so columns with only a single patch are
  196. // all done
  197. //
  198.     patchcount = (byte *)alloca (texture->width);
  199.     memset (patchcount, 0, texture->width);
  200.     patch = texture->patches;
  201.         
  202.     for (i=0 , patch = texture->patches; i<texture->patchcount ; i++, patch++)
  203.     {
  204.         realpatch = W_CacheLumpNum (patch->patch, PU_CACHE);
  205.         x1 = patch->originx;
  206.         x2 = x1 + SHORT(realpatch->width);
  207.         if (x1 < 0)
  208.             x = 0;
  209.         else
  210.             x = x1;
  211.         if (x2 > texture->width)
  212.             x2 = texture->width;
  213.         for ( ; x<x2 ; x++)
  214.         {
  215.             patchcount[x]++;
  216.             collump[x] = patch->patch;
  217.             colofs[x] = LONG(realpatch->columnofs[x-x1])+3;
  218.         }
  219.     }
  220.     
  221.     for (x=0 ; x<texture->width ; x++)
  222.     {
  223.         if (!patchcount[x])
  224.         {
  225.             printf ("R_GenerateLookup: column without a patch (%s)\n", texture->name);
  226.             return;
  227.         }
  228. //            I_Error ("R_GenerateLookup: column without a patch");
  229.         if (patchcount[x] > 1)
  230.         {
  231.             collump[x] = -1;    // use the cached block
  232.             colofs[x] = texturecompositesize[texnum];
  233.             if (texturecompositesize[texnum] > 0x10000-texture->height)
  234.                 I_Error ("R_GenerateLookup: texture %i is >64k",texnum);
  235.             texturecompositesize[texnum] += texture->height;
  236.         }
  237.     }    
  238. }
  239.  
  240.  
  241. /*
  242. ================
  243. =
  244. = R_GetColumn
  245. =
  246. ================
  247. */
  248.  
  249. byte *R_GetColumn (int tex, int col)
  250. {
  251.     int    lump, ofs;
  252.     
  253.     col &= texturewidthmask[tex];
  254.     lump = texturecolumnlump[tex][col];
  255.     ofs = texturecolumnofs[tex][col];
  256.     if (lump > 0)
  257.         return (byte *)W_CacheLumpNum(lump,PU_CACHE)+ofs;
  258.     if (!texturecomposite[tex])
  259.         R_GenerateComposite (tex);
  260.     return texturecomposite[tex] + ofs;
  261. }
  262.  
  263.  
  264. /*
  265. ==================
  266. =
  267. = R_InitTextures
  268. =
  269. = Initializes the texture list with the textures from the world map
  270. =
  271. ==================
  272. */
  273.  
  274. void R_InitTextures (void)
  275. {
  276.     maptexture_t    *mtexture;
  277.     texture_t        *texture;
  278.     mappatch_t    *mpatch;
  279.     texpatch_t    *patch;
  280.     int            i,j;
  281.     int            *maptex, *maptex2, *maptex1;
  282.     char        name[9], *names, *name_p;
  283.     int            *patchlookup;
  284.     int            totalwidth;
  285.     int            nummappatches;
  286.     int            offset, maxoff, maxoff2;
  287.     int            numtextures1, numtextures2;
  288.     int            *directory;
  289.  
  290. //
  291. // load the patch names from pnames.lmp
  292. //
  293.     name[8] = 0;
  294.     names = W_CacheLumpName ("PNAMES", PU_STATIC);
  295.     nummappatches = LONG ( *((int *)names) );
  296.     name_p = names+4;
  297.     patchlookup = alloca (nummappatches*sizeof(*patchlookup));
  298.     for (i=0 ; i<nummappatches ; i++)
  299.     {
  300.         strncpy (name,name_p+i*8, 8);
  301.         patchlookup[i] = W_CheckNumForName (name);
  302.     }
  303.     Z_Free (names);
  304.  
  305. //
  306. // load the map texture definitions from textures.lmp
  307. //
  308.     maptex = maptex1 = W_CacheLumpName ("TEXTURE1", PU_STATIC);
  309.     numtextures1 = LONG(*maptex);
  310.     maxoff = W_LumpLength (W_GetNumForName ("TEXTURE1"));
  311.     directory = maptex+1;
  312.  
  313.     if (W_CheckNumForName ("TEXTURE2") != -1)
  314.     {
  315.         maptex2 = W_CacheLumpName ("TEXTURE2", PU_STATIC);
  316.         numtextures2 = LONG(*maptex2);
  317.         maxoff2 = W_LumpLength (W_GetNumForName ("TEXTURE2"));
  318.     }
  319.     else
  320.     {
  321.         maptex2 = NULL;
  322.         numtextures2 = 0;
  323.         maxoff2 = 0;
  324.     }
  325.     numtextures = numtextures1 + numtextures2;
  326.  
  327.     //
  328.     //    Init the startup thermometer at this point...
  329.     //
  330.     {
  331.         int    spramount;
  332.         spramount = W_GetNumForName("S_END") - W_GetNumForName("S_START") + 1;
  333.         InitThermo(spramount + numtextures + 6);
  334.     }
  335.  
  336.     textures = Z_Malloc (numtextures*4, PU_STATIC, 0);
  337.     texturecolumnlump = Z_Malloc (numtextures*4, PU_STATIC, 0);
  338.     texturecolumnofs = Z_Malloc (numtextures*4, PU_STATIC, 0);
  339.     texturecomposite = Z_Malloc (numtextures*4, PU_STATIC, 0);
  340.     texturecompositesize = Z_Malloc (numtextures*4, PU_STATIC, 0);
  341.     texturewidthmask = Z_Malloc (numtextures*4, PU_STATIC, 0);
  342.     textureheight = Z_Malloc (numtextures*4, PU_STATIC, 0);
  343.  
  344.     totalwidth = 0;
  345.  
  346.     for (i=0 ; i<numtextures ; i++, directory++)
  347.     {
  348.         #ifdef __NEXT__
  349.         if(!(i&63))
  350.             printf (".");
  351.         #else
  352.         IncThermo();
  353.         #endif
  354.         if (i == numtextures1)
  355.         {    // start looking in second texture file
  356.             maptex = maptex2;
  357.             maxoff = maxoff2;
  358.             directory = maptex+1;
  359.         }
  360.  
  361.         offset = LONG(*directory);
  362.         if (offset > maxoff)
  363.             I_Error ("R_InitTextures: bad texture directory");
  364.         mtexture = (maptexture_t *) ( (byte *)maptex + offset);
  365.         texture = textures[i] = Z_Malloc (sizeof(texture_t) 
  366.             + sizeof(texpatch_t)*(SHORT(mtexture->patchcount)-1), PU_STATIC,
  367.             0);
  368.         texture->width = SHORT(mtexture->width);
  369.         texture->height = SHORT(mtexture->height);
  370.         texture->patchcount = SHORT(mtexture->patchcount);
  371.         memcpy (texture->name, mtexture->name, sizeof(texture->name));
  372.         mpatch = &mtexture->patches[0];
  373.         patch = &texture->patches[0];
  374.         for (j=0 ; j<texture->patchcount ; j++, mpatch++, patch++)
  375.         {
  376.             patch->originx = SHORT(mpatch->originx);
  377.             patch->originy = SHORT(mpatch->originy);
  378.             patch->patch = patchlookup[SHORT(mpatch->patch)];
  379.             if (patch->patch == -1)
  380.                 I_Error (
  381.                 "R_InitTextures: Missing patch in texture %s",texture->name);
  382.         }        
  383.         texturecolumnlump[i] = Z_Malloc (texture->width*2, PU_STATIC,0);
  384.         texturecolumnofs[i] = Z_Malloc (texture->width*2, PU_STATIC,0);
  385.         j = 1;
  386.         while (j*2 <= texture->width)
  387.             j<<=1;
  388.         texturewidthmask[i] = j-1;
  389.         textureheight[i] = texture->height<<FRACBITS;
  390.         
  391.         totalwidth += texture->width;
  392.     }
  393.  
  394.     Z_Free (maptex1);
  395.     if (maptex2)
  396.         Z_Free (maptex2);
  397.  
  398. //
  399. // precalculate whatever possible
  400. //        
  401.     for(i = 0; i < numtextures; i++)
  402.     {
  403.         R_GenerateLookup(i);
  404.         CheckAbortStartup();
  405.     }
  406.  
  407. //
  408. // translation table for global animation
  409. //
  410.     texturetranslation = Z_Malloc ((numtextures+1)*4, PU_STATIC, 0);
  411.     for (i=0 ; i<numtextures ; i++)
  412.         texturetranslation[i] = i;
  413. }
  414.  
  415.  
  416. /*
  417. ================
  418. =
  419. = R_InitFlats
  420. =
  421. =================
  422. */
  423.  
  424. void R_InitFlats (void)
  425. {
  426.     int        i;
  427.     
  428.     firstflat = W_GetNumForName ("F_START") + 1;
  429.     lastflat = W_GetNumForName ("F_END") - 1;
  430.     numflats = lastflat - firstflat + 1;
  431.     
  432. // translation table for global animation
  433.     flattranslation = Z_Malloc ((numflats+1)*4, PU_STATIC, 0);
  434.     for (i=0 ; i<numflats ; i++)
  435.         flattranslation[i] = i;
  436. }
  437.  
  438.  
  439. /*
  440. ================
  441. =
  442. = R_InitSpriteLumps
  443. =
  444. = Finds the width and hoffset of all sprites in the wad, so the sprite doesn't
  445. = need to be cached just for the header during rendering
  446. =================
  447. */
  448.  
  449. void R_InitSpriteLumps (void)
  450. {
  451.     int        i;
  452.     patch_t    *patch;
  453.  
  454.     firstspritelump = W_GetNumForName ("S_START") + 1;
  455.     lastspritelump = W_GetNumForName ("S_END") - 1;
  456.     numspritelumps = lastspritelump - firstspritelump + 1;
  457.     spritewidth = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
  458.     spriteoffset = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
  459.     spritetopoffset = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
  460.  
  461.     for (i=0 ; i< numspritelumps ; i++)
  462.     {
  463.         #ifdef __NEXT__
  464.         if (!(i&63))
  465.             printf (".");
  466.         #else
  467.         IncThermo();
  468.         #endif
  469.         patch = W_CacheLumpNum (firstspritelump+i, PU_CACHE);
  470.         spritewidth[i] = SHORT(patch->width)<<FRACBITS;
  471.         spriteoffset[i] = SHORT(patch->leftoffset)<<FRACBITS;
  472.         spritetopoffset[i] = SHORT(patch->topoffset)<<FRACBITS;
  473.     }
  474. }
  475.  
  476.  
  477. /*
  478. ================
  479. =
  480. = R_InitColormaps
  481. =
  482. =================
  483. */
  484.  
  485. void R_InitColormaps (void)
  486. {
  487.     int    lump, length;
  488. //
  489. // load in the light tables
  490. // 256 byte align tables
  491. //
  492.     lump = W_GetNumForName("COLORMAP");
  493.     length = W_LumpLength (lump) + 255;
  494.     colormaps = Z_Malloc (length, PU_STATIC, 0);
  495.     colormaps = (byte *)( ((int)colormaps + 255)&~0xff);
  496.     W_ReadLump (lump,colormaps);
  497. }
  498.  
  499.  
  500. /*
  501. ================
  502. =
  503. = R_InitData
  504. =
  505. = Locates all the lumps that will be used by all views
  506. = Must be called after W_Init
  507. =================
  508. */
  509.  
  510. void R_InitData (void)
  511. {
  512.     tprintf("\nR_InitTextures ",0);
  513.     R_InitTextures ();
  514. //printf (".");
  515.     tprintf("R_InitFlats\n",0);
  516.     R_InitFlats ();
  517.     IncThermo();
  518. //printf (".");
  519.     tprintf("R_InitSpriteLumps ",0);
  520.     R_InitSpriteLumps ();
  521.     IncThermo();
  522. //printf (".");
  523.     R_InitColormaps ();
  524. }
  525.  
  526.  
  527. //=============================================================================
  528.  
  529. /*
  530. ================
  531. =
  532. = R_FlatNumForName
  533. =
  534. ================
  535. */
  536.  
  537. int    R_FlatNumForName (char *name)
  538. {
  539.     int        i;
  540.     char    namet[9];
  541.  
  542.     i = W_CheckNumForName (name);
  543.     if (i == -1)
  544.     {
  545.         namet[8] = 0;
  546.         memcpy (namet, name,8);
  547.         I_Error ("R_FlatNumForName: %s not found",namet);
  548.     }
  549.     return i - firstflat;
  550. }
  551.  
  552.  
  553. /*
  554. ================
  555. =
  556. = R_CheckTextureNumForName
  557. =
  558. ================
  559. */
  560.  
  561. int    R_CheckTextureNumForName (char *name)
  562. {
  563.     int        i;
  564.     
  565.     if (name[0] == '-')        // no texture marker
  566.         return 0;
  567.         
  568.     for (i=0 ; i<numtextures ; i++)
  569.         if (!strncasecmp (textures[i]->name, name, 8) )
  570.             return i;
  571.         
  572.     return -1;
  573. }
  574.  
  575.  
  576. /*
  577. ================
  578. =
  579. = R_TextureNumForName
  580. =
  581. ================
  582. */
  583.  
  584. int    R_TextureNumForName (char *name)
  585. {
  586.     int        i;
  587.     //char    namet[9];
  588.     
  589.     i = R_CheckTextureNumForName (name);
  590.     if (i==-1)
  591.         I_Error ("R_TextureNumForName: %s not found",name);
  592.     
  593.     return i;
  594. }
  595.  
  596.  
  597. /*
  598. =================
  599. =
  600. = R_PrecacheLevel
  601. =
  602. = Preloads all relevent graphics for the level
  603. =================
  604. */
  605.  
  606. int        flatmemory, texturememory, spritememory;
  607.  
  608. void R_PrecacheLevel (void)
  609. {
  610.     char            *flatpresent;
  611.     char            *texturepresent;
  612.     char            *spritepresent;
  613.     int                i,j,k, lump;
  614.     texture_t        *texture;
  615.     thinker_t        *th;
  616.     spriteframe_t    *sf;
  617.  
  618.     if (demoplayback)
  619.         return;
  620.             
  621. //
  622. // precache flats
  623. //    
  624.     flatpresent = alloca(numflats);
  625.     memset (flatpresent,0,numflats);    
  626.     for (i=0 ; i<numsectors ; i++)
  627.     {
  628.         flatpresent[sectors[i].floorpic] = 1;
  629.         flatpresent[sectors[i].ceilingpic] = 1;
  630.     }
  631.     
  632.     flatmemory = 0;
  633.     for (i=0 ; i<numflats ; i++)
  634.         if (flatpresent[i])
  635.         {
  636.             lump = firstflat + i;
  637.             flatmemory += lumpinfo[lump].size;
  638.             W_CacheLumpNum(lump, PU_CACHE);
  639.         }
  640.         
  641. //
  642. // precache textures
  643. //
  644.     texturepresent = alloca(numtextures);
  645.     memset (texturepresent,0, numtextures);
  646.     
  647.     for (i=0 ; i<numsides ; i++)
  648.     {
  649.         texturepresent[sides[i].toptexture] = 1;
  650.         texturepresent[sides[i].midtexture] = 1;
  651.         texturepresent[sides[i].bottomtexture] = 1;
  652.     }
  653.     
  654.     texturepresent[skytexture] = 1;
  655.     
  656.     texturememory = 0;
  657.     for (i=0 ; i<numtextures ; i++)
  658.     {
  659.         if (!texturepresent[i])
  660.             continue;
  661.         texture = textures[i];
  662.         for (j=0 ; j<texture->patchcount ; j++)
  663.         {
  664.             lump = texture->patches[j].patch;
  665.             texturememory += lumpinfo[lump].size;
  666.             W_CacheLumpNum(lump , PU_CACHE);
  667.         }
  668.     }
  669.     
  670. //
  671. // precache sprites
  672. //
  673.     spritepresent = alloca(numsprites);
  674.     memset (spritepresent,0, numsprites);
  675.     
  676.     for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
  677.     {
  678.         if (th->function == P_MobjThinker)
  679.             spritepresent[((mobj_t *)th)->sprite] = 1;
  680.     }
  681.     
  682.     spritememory = 0;
  683.     for (i=0 ; i<numsprites ; i++)
  684.     {
  685.         if (!spritepresent[i])
  686.             continue;
  687.         for (j=0 ; j<sprites[i].numframes ; j++)
  688.         {
  689.             sf = &sprites[i].spriteframes[j];
  690.             for (k=0 ; k<8 ; k++)
  691.             {
  692.                 lump = firstspritelump + sf->lump[k];
  693.                 spritememory += lumpinfo[lump].size;
  694.                 W_CacheLumpNum(lump , PU_CACHE);
  695.             }
  696.         }
  697.     }
  698. }
  699.  
  700.  
  701.  
  702.  
  703.