r_data.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746
  1. /* Emacs style mode select -*- C++ -*-
  2. *-----------------------------------------------------------------------------
  3. *
  4. *
  5. * PrBoom: a Doom port merged with LxDoom and LSDLDoom
  6. * based on BOOM, a modified and improved DOOM engine
  7. * Copyright (C) 1999 by
  8. * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
  9. * Copyright (C) 1999-2002 by
  10. * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
  11. * Copyright 2005, 2006 by
  12. * Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
  13. *
  14. * This program is free software; you can redistribute it and/or
  15. * modify it under the terms of the GNU General Public License
  16. * as published by the Free Software Foundation; either version 2
  17. * of the License, or (at your option) any later version.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License
  25. * along with this program; if not, write to the Free Software
  26. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  27. * 02111-1307, USA.
  28. *
  29. * DESCRIPTION:
  30. * Preparation of data for rendering,
  31. * generation of lookups, caching, retrieval by name.
  32. *
  33. *-----------------------------------------------------------------------------*/
  34. #include "doomstat.h"
  35. #include "w_wad.h"
  36. #include "r_draw.h"
  37. #include "r_main.h"
  38. #include "r_sky.h"
  39. #include "i_system.h"
  40. #include "r_bsp.h"
  41. #include "r_things.h"
  42. #include "p_tick.h"
  43. #include "lprintf.h" // jff 08/03/98 - declaration of lprintf
  44. #include "p_tick.h"
  45. //
  46. // Graphics.
  47. // DOOM graphics for walls and sprites
  48. // is stored in vertical runs of opaque pixels (posts).
  49. // A column is composed of zero or more posts,
  50. // a patch or sprite is composed of zero or more columns.
  51. //
  52. //
  53. // Texture definition.
  54. // Each texture is composed of one or more patches,
  55. // with patches being lumps stored in the WAD.
  56. // The lumps are referenced by number, and patched
  57. // into the rectangular texture space using origin
  58. // and possibly other attributes.
  59. //
  60. typedef struct
  61. {
  62. short originx;
  63. short originy;
  64. short patch;
  65. short stepdir; // unused in Doom but might be used in Phase 2 Boom
  66. short colormap; // unused in Doom but might be used in Phase 2 Boom
  67. } PACKEDATTR mappatch_t;
  68. typedef struct
  69. {
  70. char name[8];
  71. char pad2[4]; // unused
  72. short width;
  73. short height;
  74. char pad[4]; // unused in Doom but might be used in Boom Phase 2
  75. short patchcount;
  76. mappatch_t patches[1];
  77. } PACKEDATTR maptexture_t;
  78. // A maptexturedef_t describes a rectangular texture, which is composed
  79. // of one or more mappatch_t structures that arrange graphic patches.
  80. // killough 4/17/98: make firstcolormaplump,lastcolormaplump external
  81. int firstcolormaplump, lastcolormaplump; // killough 4/17/98
  82. int firstflat, lastflat, numflats;
  83. int firstspritelump, lastspritelump, numspritelumps;
  84. int numtextures;
  85. texture_t **textures; // proff - 04/05/2000 removed static for OpenGL
  86. fixed_t *textureheight; //needed for texture pegging (and TFE fix - killough)
  87. int *flattranslation; // for global animation
  88. int *texturetranslation;
  89. //
  90. // R_GetTextureColumn
  91. //
  92. const byte *R_GetTextureColumn(const rpatch_t *texpatch, int col) {
  93. while (col < 0)
  94. col += texpatch->width;
  95. col &= texpatch->widthmask;
  96. return texpatch->columns[col].pixels;
  97. }
  98. //
  99. // R_InitTextures
  100. // Initializes the texture list
  101. // with the textures from the world map.
  102. //
  103. static void R_InitTextures (void)
  104. {
  105. const maptexture_t *mtexture;
  106. texture_t *texture;
  107. const mappatch_t *mpatch;
  108. texpatch_t *patch;
  109. int i, j;
  110. int maptex_lump[2] = {-1, -1};
  111. const int *maptex;
  112. const int *maptex1, *maptex2;
  113. char name[9];
  114. int names_lump; // cph - new wad lump handling
  115. const char *names; // cph -
  116. const char *name_p;// const*'s
  117. int *patchlookup;
  118. int totalwidth;
  119. int nummappatches;
  120. int offset;
  121. int maxoff, maxoff2;
  122. int numtextures1, numtextures2;
  123. const int *directory;
  124. int errors = 0;
  125. // Load the patch names from pnames.lmp.
  126. name[8] = 0;
  127. names = W_CacheLumpNum(names_lump = W_GetNumForName("PNAMES"));
  128. nummappatches = LONG(*((const int *)names));
  129. name_p = names+4;
  130. patchlookup = malloc(nummappatches*sizeof(*patchlookup)); // killough
  131. for (i=0 ; i<nummappatches ; i++)
  132. {
  133. strncpy (name,name_p+i*8, 8);
  134. patchlookup[i] = W_CheckNumForName(name);
  135. if (patchlookup[i] == -1)
  136. {
  137. // killough 4/17/98:
  138. // Some wads use sprites as wall patches, so repeat check and
  139. // look for sprites this time, but only if there were no wall
  140. // patches found. This is the same as allowing for both, except
  141. // that wall patches always win over sprites, even when they
  142. // appear first in a wad. This is a kludgy solution to the wad
  143. // lump namespace problem.
  144. patchlookup[i] = (W_CheckNumForName)(name, ns_sprites);
  145. if (patchlookup[i] == -1 && devparm)
  146. //jff 8/3/98 use logical output routine
  147. lprintf(LO_WARN,"\nWarning: patch %.8s, index %d does not exist",name,i);
  148. }
  149. }
  150. W_UnlockLumpNum(names_lump); // cph - release the lump
  151. // Load the map texture definitions from textures.lmp.
  152. // The data is contained in one or two lumps,
  153. // TEXTURE1 for shareware, plus TEXTURE2 for commercial.
  154. maptex = maptex1 = W_CacheLumpNum(maptex_lump[0] = W_GetNumForName("TEXTURE1"));
  155. numtextures1 = LONG(*maptex);
  156. maxoff = W_LumpLength(maptex_lump[0]);
  157. directory = maptex+1;
  158. if (W_CheckNumForName("TEXTURE2") != -1)
  159. {
  160. maptex2 = W_CacheLumpNum(maptex_lump[1] = W_GetNumForName("TEXTURE2"));
  161. numtextures2 = LONG(*maptex2);
  162. maxoff2 = W_LumpLength(maptex_lump[1]);
  163. }
  164. else
  165. {
  166. maptex2 = NULL;
  167. numtextures2 = 0;
  168. maxoff2 = 0;
  169. }
  170. numtextures = numtextures1 + numtextures2;
  171. // killough 4/9/98: make column offsets 32-bit;
  172. // clean up malloc-ing to use sizeof
  173. textures = Z_Malloc(numtextures*sizeof*textures, PU_STATIC, 0);
  174. textureheight = Z_Malloc(numtextures*sizeof*textureheight, PU_STATIC, 0);
  175. totalwidth = 0;
  176. for (i=0 ; i<numtextures ; i++, directory++)
  177. {
  178. if (i == numtextures1)
  179. {
  180. // Start looking in second texture file.
  181. maptex = maptex2;
  182. maxoff = maxoff2;
  183. directory = maptex+1;
  184. }
  185. offset = LONG(*directory);
  186. if (offset > maxoff)
  187. I_Error("R_InitTextures: Bad texture directory");
  188. mtexture = (const maptexture_t *) ( (const byte *)maptex + offset);
  189. texture = textures[i] =
  190. Z_Malloc(sizeof(texture_t) +
  191. sizeof(texpatch_t)*(SHORT(mtexture->patchcount)-1),
  192. PU_STATIC, 0);
  193. texture->width = SHORT(mtexture->width);
  194. texture->height = SHORT(mtexture->height);
  195. texture->patchcount = SHORT(mtexture->patchcount);
  196. /* Mattias Engdegård emailed me of the following explenation of
  197. * why memcpy doesnt work on some systems:
  198. * "I suppose it is the mad unaligned allocation
  199. * going on (and which gcc in some way manages to cope with
  200. * through the __attribute__ ((packed))), and which it forgets
  201. * when optimizing memcpy (to a single word move) since it appears
  202. * to be aligned. Technically a gcc bug, but I can't blame it when
  203. * it's stressed with that amount of
  204. * non-standard nonsense."
  205. * So in short the unaligned struct confuses gcc's optimizer so
  206. * i took the memcpy out alltogether to avoid future problems-Jess
  207. */
  208. /* The above was #ifndef SPARC, but i got a mail from
  209. * Putera Joseph F NPRI <PuteraJF@Npt.NUWC.Navy.Mil> containing:
  210. * I had to use the memcpy function on a sparc machine. The
  211. * other one would give me a core dump.
  212. * cph - I find it hard to believe that sparc memcpy is broken,
  213. * but I don't believe the pointers to memcpy have to be aligned
  214. * either. Use fast memcpy on other machines anyway.
  215. */
  216. /*
  217. proff - I took this out, because Oli Kraus (olikraus@yahoo.com) told
  218. me the memcpy produced a buserror. Since this function isn't time-
  219. critical I'm using the for loop now.
  220. */
  221. /*
  222. #ifndef GCC
  223. memcpy(texture->name, mtexture->name, sizeof(texture->name));
  224. #else
  225. */
  226. {
  227. int j;
  228. for(j=0;j<sizeof(texture->name);j++)
  229. texture->name[j]=mtexture->name[j];
  230. }
  231. /* #endif */
  232. mpatch = mtexture->patches;
  233. patch = texture->patches;
  234. for (j=0 ; j<texture->patchcount ; j++, mpatch++, patch++)
  235. {
  236. patch->originx = SHORT(mpatch->originx);
  237. patch->originy = SHORT(mpatch->originy);
  238. patch->patch = patchlookup[SHORT(mpatch->patch)];
  239. if (patch->patch == -1)
  240. {
  241. //jff 8/3/98 use logical output routine
  242. lprintf(LO_ERROR,"\nR_InitTextures: Missing patch %d in texture %.8s",
  243. SHORT(mpatch->patch), texture->name); // killough 4/17/98
  244. ++errors;
  245. }
  246. }
  247. for (j=1; j*2 <= texture->width; j<<=1)
  248. ;
  249. texture->widthmask = j-1;
  250. textureheight[i] = texture->height<<FRACBITS;
  251. totalwidth += texture->width;
  252. }
  253. free(patchlookup); // killough
  254. for (i=0; i<2; i++) // cph - release the TEXTUREx lumps
  255. if (maptex_lump[i] != -1)
  256. W_UnlockLumpNum(maptex_lump[i]);
  257. if (errors)
  258. I_Error("R_InitTextures: %d errors", errors);
  259. // Precalculate whatever possible.
  260. if (devparm) // cph - If in development mode, generate now so all errors are found at once
  261. for (i=0 ; i<numtextures ; i++)
  262. {
  263. // proff - This is for the new renderer now
  264. R_CacheTextureCompositePatchNum(i);
  265. R_UnlockTextureCompositePatchNum(i);
  266. }
  267. if (errors)
  268. I_Error("R_InitTextures: %d errors", errors);
  269. // Create translation table for global animation.
  270. // killough 4/9/98: make column offsets 32-bit;
  271. // clean up malloc-ing to use sizeof
  272. texturetranslation =
  273. Z_Malloc((numtextures+1)*sizeof*texturetranslation, PU_STATIC, 0);
  274. for (i=0 ; i<numtextures ; i++)
  275. texturetranslation[i] = i;
  276. // killough 1/31/98: Initialize texture hash table
  277. for (i = 0; i<numtextures; i++)
  278. textures[i]->index = -1;
  279. while (--i >= 0)
  280. {
  281. int j = W_LumpNameHash(textures[i]->name) % (unsigned) numtextures;
  282. textures[i]->next = textures[j]->index; // Prepend to chain
  283. textures[j]->index = i;
  284. }
  285. }
  286. //
  287. // R_InitFlats
  288. //
  289. static void R_InitFlats(void)
  290. {
  291. int i;
  292. firstflat = W_GetNumForName("F_START") + 1;
  293. lastflat = W_GetNumForName("F_END") - 1;
  294. numflats = lastflat - firstflat + 1;
  295. // Create translation table for global animation.
  296. // killough 4/9/98: make column offsets 32-bit;
  297. // clean up malloc-ing to use sizeof
  298. flattranslation =
  299. Z_Malloc((numflats+1)*sizeof(*flattranslation), PU_STATIC, 0);
  300. for (i=0 ; i<numflats ; i++)
  301. flattranslation[i] = i;
  302. }
  303. //
  304. // R_InitSpriteLumps
  305. // Finds the width and hoffset of all sprites in the wad,
  306. // so the sprite does not need to be cached completely
  307. // just for having the header info ready during rendering.
  308. //
  309. static void R_InitSpriteLumps(void)
  310. {
  311. firstspritelump = W_GetNumForName("S_START") + 1;
  312. lastspritelump = W_GetNumForName("S_END") - 1;
  313. numspritelumps = lastspritelump - firstspritelump + 1;
  314. }
  315. //
  316. // R_InitColormaps
  317. //
  318. // killough 3/20/98: rewritten to allow dynamic colormaps
  319. // and to remove unnecessary 256-byte alignment
  320. //
  321. // killough 4/4/98: Add support for C_START/C_END markers
  322. //
  323. static void R_InitColormaps(void)
  324. {
  325. int i;
  326. firstcolormaplump = W_GetNumForName("C_START");
  327. lastcolormaplump = W_GetNumForName("C_END");
  328. numcolormaps = lastcolormaplump - firstcolormaplump;
  329. colormaps = Z_Malloc(sizeof(*colormaps) * numcolormaps, PU_STATIC, 0);
  330. colormaps[0] = (const lighttable_t *)W_CacheLumpName("COLORMAP");
  331. for (i=1; i<numcolormaps; i++)
  332. colormaps[i] = (const lighttable_t *)W_CacheLumpNum(i+firstcolormaplump);
  333. // cph - always lock
  334. }
  335. // killough 4/4/98: get colormap number from name
  336. // killough 4/11/98: changed to return -1 for illegal names
  337. // killough 4/17/98: changed to use ns_colormaps tag
  338. int R_ColormapNumForName(const char *name)
  339. {
  340. register int i = 0;
  341. if (strncasecmp(name,"COLORMAP",8)) // COLORMAP predefined to return 0
  342. if ((i = (W_CheckNumForName)(name, ns_colormaps)) != -1)
  343. i -= firstcolormaplump;
  344. return i;
  345. }
  346. /*
  347. * R_ColourMap
  348. *
  349. * cph 2001/11/17 - unify colour maping logic in a single place;
  350. * obsoletes old c_scalelight stuff
  351. */
  352. static inline int between(int l,int u,int x)
  353. { return (l > x ? l : x > u ? u : x); }
  354. const lighttable_t* R_ColourMap(int lightlevel, fixed_t spryscale)
  355. {
  356. if (fixedcolormap) return fixedcolormap;
  357. else {
  358. if (curline)
  359. if (curline->v1->y == curline->v2->y)
  360. lightlevel -= 1 << LIGHTSEGSHIFT;
  361. else
  362. if (curline->v1->x == curline->v2->x)
  363. lightlevel += 1 << LIGHTSEGSHIFT;
  364. lightlevel += extralight << LIGHTSEGSHIFT;
  365. /* cph 2001/11/17 -
  366. * Work out what colour map to use, remembering to clamp it to the number of
  367. * colour maps we actually have. This formula is basically the one from the
  368. * original source, just brought into one place. The main difference is it
  369. * throws away less precision in the lightlevel half, so it supports 32
  370. * light levels in WADs compared to Doom's 16.
  371. *
  372. * Note we can make it more accurate if we want - we should keep all the
  373. * precision until the final step, so slight scale differences can count
  374. * against slight light level variations.
  375. */
  376. return fullcolormap + between(0,NUMCOLORMAPS-1,
  377. ((256-lightlevel)*2*NUMCOLORMAPS/256) - 4
  378. - (FixedMul(spryscale,pspriteiscale)/2 >> LIGHTSCALESHIFT)
  379. )*256;
  380. }
  381. }
  382. //
  383. // R_InitTranMap
  384. //
  385. // Initialize translucency filter map
  386. //
  387. // By Lee Killough 2/21/98
  388. //
  389. int tran_filter_pct = 66; // filter percent
  390. #define TSC 12 /* number of fixed point digits in filter percent */
  391. void R_InitTranMap(int progress)
  392. {
  393. int lump = W_CheckNumForName("TRANMAP");
  394. // If a tranlucency filter map lump is present, use it
  395. if (lump != -1) // Set a pointer to the translucency filter maps.
  396. main_tranmap = W_CacheLumpNum(lump); // killough 4/11/98
  397. else if (W_CheckNumForName("PLAYPAL")!=-1) // can be called before WAD loaded
  398. { // Compose a default transparent filter map based on PLAYPAL.
  399. const byte *playpal = W_CacheLumpName("PLAYPAL");
  400. byte *my_tranmap;
  401. char fname[PATH_MAX+1];
  402. struct {
  403. unsigned char pct;
  404. unsigned char playpal[256];
  405. } cache;
  406. FILE *cachefp = fopen(strcat(strcpy(fname, I_DoomExeDir()), "/tranmap.dat"),"rb");
  407. main_tranmap = my_tranmap = Z_Malloc(256*256, PU_STATIC, 0); // killough 4/11/98
  408. // Use cached translucency filter if it's available
  409. if (!cachefp ||
  410. fread(&cache, 1, sizeof cache, cachefp) != sizeof cache ||
  411. cache.pct != tran_filter_pct ||
  412. memcmp(cache.playpal, playpal, sizeof cache.playpal) ||
  413. fread(my_tranmap, 256, 256, cachefp) != 256 ) // killough 4/11/98
  414. {
  415. long pal[3][256], tot[256], pal_w1[3][256];
  416. long w1 = ((unsigned long) tran_filter_pct<<TSC)/100;
  417. long w2 = (1l<<TSC)-w1;
  418. if (progress)
  419. lprintf(LO_INFO, "Tranmap build [ ]\x08\x08\x08\x08\x08\x08\x08\x08\x08");
  420. // First, convert playpal into long int type, and transpose array,
  421. // for fast inner-loop calculations. Precompute tot array.
  422. {
  423. register int i = 255;
  424. register const unsigned char *p = playpal+255*3;
  425. do
  426. {
  427. register long t,d;
  428. pal_w1[0][i] = (pal[0][i] = t = p[0]) * w1;
  429. d = t*t;
  430. pal_w1[1][i] = (pal[1][i] = t = p[1]) * w1;
  431. d += t*t;
  432. pal_w1[2][i] = (pal[2][i] = t = p[2]) * w1;
  433. d += t*t;
  434. p -= 3;
  435. tot[i] = d << (TSC-1);
  436. }
  437. while (--i>=0);
  438. }
  439. // Next, compute all entries using minimum arithmetic.
  440. {
  441. int i,j;
  442. byte *tp = my_tranmap;
  443. for (i=0;i<256;i++)
  444. {
  445. long r1 = pal[0][i] * w2;
  446. long g1 = pal[1][i] * w2;
  447. long b1 = pal[2][i] * w2;
  448. if (!(i & 31) && progress)
  449. //jff 8/3/98 use logical output routine
  450. lprintf(LO_INFO,".");
  451. for (j=0;j<256;j++,tp++)
  452. {
  453. register int color = 255;
  454. register long err;
  455. long r = pal_w1[0][j] + r1;
  456. long g = pal_w1[1][j] + g1;
  457. long b = pal_w1[2][j] + b1;
  458. long best = LONG_MAX;
  459. do
  460. if ((err = tot[color] - pal[0][color]*r
  461. - pal[1][color]*g - pal[2][color]*b) < best)
  462. best = err, *tp = color;
  463. while (--color >= 0);
  464. }
  465. }
  466. }
  467. if ((cachefp = fopen(fname,"wb")) != NULL) // write out the cached translucency map
  468. {
  469. cache.pct = tran_filter_pct;
  470. memcpy(cache.playpal, playpal, 256);
  471. fseek(cachefp, 0, SEEK_SET);
  472. fwrite(&cache, 1, sizeof cache, cachefp);
  473. fwrite(main_tranmap, 256, 256, cachefp);
  474. // CPhipps - leave close for a few lines...
  475. }
  476. }
  477. if (cachefp) // killough 11/98: fix filehandle leak
  478. fclose(cachefp);
  479. W_UnlockLumpName("PLAYPAL");
  480. }
  481. }
  482. //
  483. // R_InitData
  484. // Locates all the lumps
  485. // that will be used by all views
  486. // Must be called after W_Init.
  487. //
  488. void R_InitData(void)
  489. {
  490. lprintf(LO_INFO, "Textures ");
  491. R_InitTextures();
  492. lprintf(LO_INFO, "Flats ");
  493. R_InitFlats();
  494. lprintf(LO_INFO, "Sprites ");
  495. R_InitSpriteLumps();
  496. if (default_translucency) // killough 3/1/98
  497. R_InitTranMap(1); // killough 2/21/98, 3/6/98
  498. R_InitColormaps(); // killough 3/20/98
  499. }
  500. //
  501. // R_FlatNumForName
  502. // Retrieval, get a flat number for a flat name.
  503. //
  504. // killough 4/17/98: changed to use ns_flats namespace
  505. //
  506. int R_FlatNumForName(const char *name) // killough -- const added
  507. {
  508. int i = (W_CheckNumForName)(name, ns_flats);
  509. if (i == -1)
  510. I_Error("R_FlatNumForName: %.8s not found", name);
  511. return i - firstflat;
  512. }
  513. //
  514. // R_CheckTextureNumForName
  515. // Check whether texture is available.
  516. // Filter out NoTexture indicator.
  517. //
  518. // Rewritten by Lee Killough to use hash table for fast lookup. Considerably
  519. // reduces the time needed to start new levels. See w_wad.c for comments on
  520. // the hashing algorithm, which is also used for lump searches.
  521. //
  522. // killough 1/21/98, 1/31/98
  523. //
  524. int PUREFUNC R_CheckTextureNumForName(const char *name)
  525. {
  526. int i = NO_TEXTURE;
  527. if (*name != '-') // "NoTexture" marker.
  528. {
  529. i = textures[W_LumpNameHash(name) % (unsigned) numtextures]->index;
  530. while (i >= 0 && strncasecmp(textures[i]->name,name,8))
  531. i = textures[i]->next;
  532. }
  533. return i;
  534. }
  535. //
  536. // R_TextureNumForName
  537. // Calls R_CheckTextureNumForName,
  538. // aborts with error message.
  539. //
  540. int PUREFUNC R_TextureNumForName(const char *name) // const added -- killough
  541. {
  542. int i = R_CheckTextureNumForName(name);
  543. if (i == -1)
  544. I_Error("R_TextureNumForName: %.8s not found", name);
  545. return i;
  546. }
  547. //
  548. // R_SafeTextureNumForName
  549. // Calls R_CheckTextureNumForName, and changes any error to NO_TEXTURE
  550. int PUREFUNC R_SafeTextureNumForName(const char *name, int snum)
  551. {
  552. int i = R_CheckTextureNumForName(name);
  553. if (i == -1) {
  554. i = NO_TEXTURE; // e6y - return "no texture"
  555. lprintf(LO_DEBUG,"bad texture '%s' in sidedef %d\n",name,snum);
  556. }
  557. return i;
  558. }
  559. //
  560. // R_PrecacheLevel
  561. // Preloads all relevant graphics for the level.
  562. //
  563. // Totally rewritten by Lee Killough to use less memory,
  564. // to avoid using alloca(), and to improve performance.
  565. // cph - new wad lump handling, calls cache functions but acquires no locks
  566. static inline void precache_lump(int l)
  567. {
  568. W_CacheLumpNum(l); W_UnlockLumpNum(l);
  569. }
  570. void R_PrecacheLevel(void)
  571. {
  572. register int i;
  573. register byte *hitlist;
  574. if (demoplayback)
  575. return;
  576. {
  577. size_t size = numflats > numsprites ? numflats : numsprites;
  578. hitlist = malloc((size_t)numtextures > size ? numtextures : size);
  579. }
  580. // Precache flats.
  581. memset(hitlist, 0, numflats);
  582. for (i = numsectors; --i >= 0; )
  583. hitlist[sectors[i].floorpic] = hitlist[sectors[i].ceilingpic] = 1;
  584. for (i = numflats; --i >= 0; )
  585. if (hitlist[i])
  586. precache_lump(firstflat + i);
  587. // Precache textures.
  588. memset(hitlist, 0, numtextures);
  589. for (i = numsides; --i >= 0;)
  590. hitlist[sides[i].bottomtexture] =
  591. hitlist[sides[i].toptexture] =
  592. hitlist[sides[i].midtexture] = 1;
  593. // Sky texture is always present.
  594. // Note that F_SKY1 is the name used to
  595. // indicate a sky floor/ceiling as a flat,
  596. // while the sky texture is stored like
  597. // a wall texture, with an episode dependend
  598. // name.
  599. hitlist[skytexture] = 1;
  600. for (i = numtextures; --i >= 0; )
  601. if (hitlist[i])
  602. {
  603. texture_t *texture = textures[i];
  604. int j = texture->patchcount;
  605. while (--j >= 0)
  606. precache_lump(texture->patches[j].patch);
  607. }
  608. // Precache sprites.
  609. memset(hitlist, 0, numsprites);
  610. {
  611. thinker_t *th = NULL;
  612. while ((th = P_NextThinker(th,th_all)) != NULL)
  613. if (th->function == P_MobjThinker)
  614. hitlist[((mobj_t *)th)->sprite] = 1;
  615. }
  616. for (i=numsprites; --i >= 0;)
  617. if (hitlist[i])
  618. {
  619. int j = sprites[i].numframes;
  620. while (--j >= 0)
  621. {
  622. short *sflump = sprites[i].spriteframes[j].lump;
  623. int k = 7;
  624. do
  625. precache_lump(firstspritelump + sflump[k]);
  626. while (--k >= 0);
  627. }
  628. }
  629. free(hitlist);
  630. }
  631. // Proff - Added for OpenGL
  632. void R_SetPatchNum(patchnum_t *patchnum, const char *name)
  633. {
  634. const rpatch_t *patch = R_CachePatchName(name);
  635. patchnum->width = patch->width;
  636. patchnum->height = patch->height;
  637. patchnum->leftoffset = patch->leftoffset;
  638. patchnum->topoffset = patch->topoffset;
  639. patchnum->lumpnum = W_GetNumForName(name);
  640. R_UnlockPatchName(name);
  641. }