r_data.c 18 KB

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