r_data.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782
  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. for(j=0;j<sizeof(texture->name);j++)
  228. texture->name[j]=mtexture->name[j];
  229. }
  230. /* #endif */
  231. mpatch = mtexture->patches;
  232. patch = texture->patches;
  233. for (j=0 ; j<texture->patchcount ; j++, mpatch++, patch++)
  234. {
  235. patch->originx = SHORT(mpatch->originx);
  236. patch->originy = SHORT(mpatch->originy);
  237. patch->patch = patchlookup[SHORT(mpatch->patch)];
  238. if (patch->patch == -1)
  239. {
  240. //jff 8/3/98 use logical output routine
  241. lprintf(LO_ERROR,"\nR_InitTextures: Missing patch %d in texture %.8s",
  242. SHORT(mpatch->patch), texture->name); // killough 4/17/98
  243. ++errors;
  244. }
  245. }
  246. for (j=1; j*2 <= texture->width; j<<=1)
  247. ;
  248. texture->widthmask = j-1;
  249. textureheight[i] = texture->height<<FRACBITS;
  250. totalwidth += texture->width;
  251. }
  252. free(patchlookup); // killough
  253. for (i=0; i<2; i++) // cph - release the TEXTUREx lumps
  254. if (maptex_lump[i] != -1)
  255. W_UnlockLumpNum(maptex_lump[i]);
  256. if (errors)
  257. I_Error("R_InitTextures: %d errors", errors);
  258. // Precalculate whatever possible.
  259. if (devparm) // cph - If in development mode, generate now so all errors are found at once
  260. for (i=0 ; i<numtextures ; i++)
  261. {
  262. // proff - This is for the new renderer now
  263. R_CacheTextureCompositePatchNum(i);
  264. R_UnlockTextureCompositePatchNum(i);
  265. }
  266. if (errors)
  267. I_Error("R_InitTextures: %d errors", errors);
  268. // Create translation table for global animation.
  269. // killough 4/9/98: make column offsets 32-bit;
  270. // clean up malloc-ing to use sizeof
  271. texturetranslation =
  272. Z_Malloc((numtextures+1)*sizeof*texturetranslation, PU_STATIC, 0);
  273. for (i=0 ; i<numtextures ; i++)
  274. texturetranslation[i] = i;
  275. // killough 1/31/98: Initialize texture hash table
  276. for (i = 0; i<numtextures; i++)
  277. textures[i]->index = -1;
  278. while (--i >= 0)
  279. {
  280. int texturej = W_LumpNameHash(textures[i]->name) % (unsigned) numtextures;
  281. textures[i]->next = textures[texturej]->index; // Prepend to chain
  282. textures[texturej]->index = i;
  283. }
  284. }
  285. //
  286. // R_InitFlats
  287. //
  288. static void R_InitFlats(void)
  289. {
  290. int i;
  291. firstflat = W_GetNumForName("F_START") + 1;
  292. lastflat = W_GetNumForName("F_END") - 1;
  293. numflats = lastflat - firstflat + 1;
  294. // Create translation table for global animation.
  295. // killough 4/9/98: make column offsets 32-bit;
  296. // clean up malloc-ing to use sizeof
  297. flattranslation =
  298. Z_Malloc((numflats+1)*sizeof(*flattranslation), PU_STATIC, 0);
  299. for (i=0 ; i<numflats ; i++)
  300. flattranslation[i] = i;
  301. }
  302. //
  303. // R_InitSpriteLumps
  304. // Finds the width and hoffset of all sprites in the wad,
  305. // so the sprite does not need to be cached completely
  306. // just for having the header info ready during rendering.
  307. //
  308. static void R_InitSpriteLumps(void)
  309. {
  310. firstspritelump = W_GetNumForName("S_START") + 1;
  311. lastspritelump = W_GetNumForName("S_END") - 1;
  312. numspritelumps = lastspritelump - firstspritelump + 1;
  313. }
  314. //
  315. // R_InitColormaps
  316. //
  317. // killough 3/20/98: rewritten to allow dynamic colormaps
  318. // and to remove unnecessary 256-byte alignment
  319. //
  320. // killough 4/4/98: Add support for C_START/C_END markers
  321. //
  322. static void R_InitColormaps(void)
  323. {
  324. int i;
  325. firstcolormaplump = W_GetNumForName("C_START");
  326. lastcolormaplump = W_GetNumForName("C_END");
  327. numcolormaps = lastcolormaplump - firstcolormaplump;
  328. colormaps = Z_Malloc(sizeof(*colormaps) * numcolormaps, PU_STATIC, 0);
  329. colormaps[0] = (const lighttable_t *)W_CacheLumpName("COLORMAP");
  330. for (i=1; i<numcolormaps; i++)
  331. colormaps[i] = (const lighttable_t *)W_CacheLumpNum(i+firstcolormaplump);
  332. // cph - always lock
  333. }
  334. // killough 4/4/98: get colormap number from name
  335. // killough 4/11/98: changed to return -1 for illegal names
  336. // killough 4/17/98: changed to use ns_colormaps tag
  337. int R_ColormapNumForName(const char *name)
  338. {
  339. register int i = 0;
  340. if (strncasecmp(name,"COLORMAP",8)) // COLORMAP predefined to return 0
  341. if ((i = (W_CheckNumForName)(name, ns_colormaps)) != -1)
  342. i -= firstcolormaplump;
  343. return i;
  344. }
  345. /*
  346. * R_ColourMap
  347. *
  348. * cph 2001/11/17 - unify colour maping logic in a single place;
  349. * obsoletes old c_scalelight stuff
  350. */
  351. static inline int between(int l,int u,int x)
  352. { return (l > x ? l : x > u ? u : x); }
  353. const lighttable_t* R_ColourMap(int lightlevel, fixed_t spriteyscale)
  354. {
  355. if (fixedcolormap) return fixedcolormap;
  356. else {
  357. if (curline)
  358. if (curline->v1->y == curline->v2->y)
  359. lightlevel -= 1 << LIGHTSEGSHIFT;
  360. else
  361. if (curline->v1->x == curline->v2->x)
  362. lightlevel += 1 << LIGHTSEGSHIFT;
  363. lightlevel += extralight << LIGHTSEGSHIFT;
  364. /* cph 2001/11/17 -
  365. * Work out what colour map to use, remembering to clamp it to the number of
  366. * colour maps we actually have. This formula is basically the one from the
  367. * original source, just brought into one place. The main difference is it
  368. * throws away less precision in the lightlevel half, so it supports 32
  369. * light levels in WADs compared to Doom's 16.
  370. *
  371. * Note we can make it more accurate if we want - we should keep all the
  372. * precision until the final step, so slight scale differences can count
  373. * against slight light level variations.
  374. */
  375. return fullcolormap + between(0,NUMCOLORMAPS-1,
  376. ((256-lightlevel)*2*NUMCOLORMAPS/256) - 4
  377. - (FixedMul(spriteyscale,pspriteiscale)/2 >> LIGHTSCALESHIFT)
  378. )*256;
  379. }
  380. }
  381. //
  382. // R_InitTranMap
  383. //
  384. // Initialize translucency filter map
  385. //
  386. // By Lee Killough 2/21/98
  387. //
  388. int tran_filter_pct = 66; // filter percent
  389. #define TSC 12 /* number of fixed point digits in filter percent */
  390. void R_InitTranMap(int progress)
  391. {
  392. int lump = W_CheckNumForName("TRANMAP");
  393. // If a tranlucency filter map lump is present, use it
  394. if (lump != -1) // Set a pointer to the translucency filter maps.
  395. main_tranmap = W_CacheLumpNum(lump); // killough 4/11/98
  396. else if (W_CheckNumForName("PLAYPAL")!=-1) // can be called before WAD loaded
  397. { // Compose a default transparent filter map based on PLAYPAL.
  398. const byte *playpal = W_CacheLumpName("PLAYPAL");
  399. byte *my_tranmap;
  400. char fname[PATH_MAX+1];
  401. struct {
  402. unsigned char pct;
  403. unsigned char playpal[256];
  404. } cache;
  405. FILE *cachefp = fopen(strcat(strcpy(fname, I_DoomExeDir()), "/tranmap.dat"),"rb");
  406. main_tranmap = my_tranmap = Z_Malloc(256*256, PU_STATIC, 0); // killough 4/11/98
  407. // Use cached translucency filter if it's available
  408. if (!cachefp ||
  409. fread(&cache, 1, sizeof cache, cachefp) != sizeof cache ||
  410. cache.pct != tran_filter_pct ||
  411. memcmp(cache.playpal, playpal, sizeof cache.playpal) ||
  412. fread(my_tranmap, 256, 256, cachefp) != 256 ) // killough 4/11/98
  413. {
  414. long pal[3][256], tot[256], pal_w1[3][256];
  415. long w1 = ((unsigned long) tran_filter_pct<<TSC)/100;
  416. long w2 = (1l<<TSC)-w1;
  417. if (progress)
  418. lprintf(LO_INFO, "Tranmap build [ ]\x08\x08\x08\x08\x08\x08\x08\x08\x08");
  419. // First, convert playpal into long int type, and transpose array,
  420. // for fast inner-loop calculations. Precompute tot array.
  421. {
  422. register int i = 255;
  423. register const unsigned char *p = playpal+255*3;
  424. do
  425. {
  426. register long t,d;
  427. pal_w1[0][i] = (pal[0][i] = t = p[0]) * w1;
  428. d = t*t;
  429. pal_w1[1][i] = (pal[1][i] = t = p[1]) * w1;
  430. d += t*t;
  431. pal_w1[2][i] = (pal[2][i] = t = p[2]) * w1;
  432. d += t*t;
  433. p -= 3;
  434. tot[i] = d << (TSC-1);
  435. }
  436. while (--i>=0);
  437. }
  438. // Next, compute all entries using minimum arithmetic.
  439. {
  440. int i,j;
  441. byte *tp = my_tranmap;
  442. for (i=0;i<256;i++)
  443. {
  444. long r1 = pal[0][i] * w2;
  445. long g1 = pal[1][i] * w2;
  446. long b1 = pal[2][i] * w2;
  447. if (!(i & 31) && progress)
  448. //jff 8/3/98 use logical output routine
  449. lprintf(LO_INFO,".");
  450. for (j=0;j<256;j++,tp++)
  451. {
  452. register int color = 255;
  453. register long err;
  454. long r = pal_w1[0][j] + r1;
  455. long g = pal_w1[1][j] + g1;
  456. long b = pal_w1[2][j] + b1;
  457. long best = LONG_MAX;
  458. do
  459. if ((err = tot[color] - pal[0][color]*r
  460. - pal[1][color]*g - pal[2][color]*b) < best)
  461. best = err, *tp = color;
  462. while (--color >= 0);
  463. }
  464. }
  465. }
  466. if ((cachefp = fopen(fname,"wb")) != NULL) // write out the cached translucency map
  467. {
  468. cache.pct = tran_filter_pct;
  469. memcpy(cache.playpal, playpal, 256);
  470. fseek(cachefp, 0, SEEK_SET);
  471. fwrite(&cache, 1, sizeof cache, cachefp);
  472. fwrite(main_tranmap, 256, 256, cachefp);
  473. // CPhipps - leave close for a few lines...
  474. }
  475. }
  476. if (cachefp) // killough 11/98: fix filehandle leak
  477. fclose(cachefp);
  478. W_UnlockLumpName("PLAYPAL");
  479. }
  480. }
  481. //
  482. // R_InitData
  483. // Locates all the lumps
  484. // that will be used by all views
  485. // Must be called after W_Init.
  486. //
  487. void R_InitData(void)
  488. {
  489. lprintf(LO_INFO, "Textures ");
  490. R_InitTextures();
  491. lprintf(LO_INFO, "Flats ");
  492. R_InitFlats();
  493. lprintf(LO_INFO, "Sprites ");
  494. R_InitSpriteLumps();
  495. if (default_translucency) // killough 3/1/98
  496. R_InitTranMap(1); // killough 2/21/98, 3/6/98
  497. R_InitColormaps(); // killough 3/20/98
  498. }
  499. //
  500. // R_FlatNumForName
  501. // Retrieval, get a flat number for a flat name.
  502. //
  503. // killough 4/17/98: changed to use ns_flats namespace
  504. //
  505. int R_FlatNumForName(const char *name) // killough -- const added
  506. {
  507. int i = (W_CheckNumForName)(name, ns_flats);
  508. if (i == -1)
  509. I_Error("R_FlatNumForName: %.8s not found", name);
  510. return i - firstflat;
  511. }
  512. //
  513. // R_CheckTextureNumForName
  514. // Check whether texture is available.
  515. // Filter out NoTexture indicator.
  516. //
  517. // Rewritten by Lee Killough to use hash table for fast lookup. Considerably
  518. // reduces the time needed to start new levels. See w_wad.c for comments on
  519. // the hashing algorithm, which is also used for lump searches.
  520. //
  521. // killough 1/21/98, 1/31/98
  522. //
  523. int PUREFUNC R_CheckTextureNumForName(const char *name)
  524. {
  525. int i = NO_TEXTURE;
  526. if (*name != '-') // "NoTexture" marker.
  527. {
  528. i = textures[W_LumpNameHash(name) % (unsigned) numtextures]->index;
  529. while (i >= 0 && strncasecmp(textures[i]->name,name,8))
  530. i = textures[i]->next;
  531. }
  532. return i;
  533. }
  534. // Maps textures with things we can't show in Germany to appropriate textures.
  535. static const char * germanyRemap[][2] = {
  536. { "ZZWOLF2", "ZZWOLF1" },
  537. { "ZZWOLF3", "ZZWOLF1" },
  538. { "ZZWOLF4", "ZZWOLF1" },
  539. { "ZZWOLF6", "ZZWOLF5" },
  540. { "ZZWOLF7", "ZZWOLF5" },
  541. { "ZZWOLF12", "ZZWOLF11" },
  542. { "ZZWOLF13", "ZZWOLF11" },
  543. { NULL, NULL }
  544. };
  545. //
  546. // R_RemapTextureForGermany
  547. // Given a texture name, returns a suitable replacement texture without any images of swastikas
  548. // or Hitler.
  549. //
  550. const char * R_RemapTextureForGermany( const char * name ) {
  551. return name;
  552. const char ** currentTestPair = germanyRemap[0];
  553. while ( currentTestPair[0] != NULL ) {
  554. if ( strncmp( currentTestPair[0], name, 8 ) == 0 ) {
  555. return currentTestPair[1];
  556. }
  557. currentTestPair += 2;
  558. }
  559. return name;
  560. }
  561. //
  562. // R_TextureNumForName
  563. // Calls R_CheckTextureNumForName,
  564. // aborts with error message.
  565. //
  566. int PUREFUNC R_TextureNumForName(const char *name) // const added -- killough
  567. {
  568. const char * remappedName = R_RemapTextureForGermany( name );
  569. int i = R_CheckTextureNumForName(remappedName);
  570. if (i == -1)
  571. I_Error("R_TextureNumForName: %.8s not found", remappedName);
  572. return i;
  573. }
  574. //
  575. // R_SafeTextureNumForName
  576. // Calls R_CheckTextureNumForName, and changes any error to NO_TEXTURE
  577. int PUREFUNC R_SafeTextureNumForName(const char *name, int snum)
  578. {
  579. const char * remappedName = R_RemapTextureForGermany( name );
  580. int i = R_CheckTextureNumForName(remappedName);
  581. if (i == -1) {
  582. i = NO_TEXTURE; // e6y - return "no texture"
  583. lprintf(LO_DEBUG,"bad texture '%s' in sidedef %d\n",remappedName,snum);
  584. }
  585. return i;
  586. }
  587. //
  588. // R_PrecacheLevel
  589. // Preloads all relevant graphics for the level.
  590. //
  591. // Totally rewritten by Lee Killough to use less memory,
  592. // to avoid using alloca(), and to improve performance.
  593. // cph - new wad lump handling, calls cache functions but acquires no locks
  594. static inline void precache_lump(int l)
  595. {
  596. W_CacheLumpNum(l); W_UnlockLumpNum(l);
  597. }
  598. void R_PrecacheLevel(void)
  599. {
  600. register int i;
  601. register byte *hitlist;
  602. if (demoplayback)
  603. return;
  604. {
  605. size_t size = numflats > numsprites ? numflats : numsprites;
  606. hitlist = malloc((size_t)numtextures > size ? numtextures : size);
  607. }
  608. // Precache flats.
  609. memset(hitlist, 0, numflats);
  610. for (i = numsectors; --i >= 0; )
  611. hitlist[sectors[i].floorpic] = hitlist[sectors[i].ceilingpic] = 1;
  612. for (i = numflats; --i >= 0; )
  613. if (hitlist[i])
  614. precache_lump(firstflat + i);
  615. // Precache textures.
  616. memset(hitlist, 0, numtextures);
  617. for (i = numsides; --i >= 0;)
  618. hitlist[sides[i].bottomtexture] =
  619. hitlist[sides[i].toptexture] =
  620. hitlist[sides[i].midtexture] = 1;
  621. // Sky texture is always present.
  622. // Note that F_SKY1 is the name used to
  623. // indicate a sky floor/ceiling as a flat,
  624. // while the sky texture is stored like
  625. // a wall texture, with an episode dependend
  626. // name.
  627. hitlist[skytexture] = 1;
  628. for (i = numtextures; --i >= 0; )
  629. if (hitlist[i])
  630. {
  631. texture_t *texture = textures[i];
  632. int j = texture->patchcount;
  633. while (--j >= 0)
  634. precache_lump(texture->patches[j].patch);
  635. }
  636. // Precache sprites.
  637. memset(hitlist, 0, numsprites);
  638. {
  639. thinker_t *th = NULL;
  640. while ((th = P_NextThinker(th,th_all)) != NULL)
  641. if (th->function == P_MobjThinker)
  642. hitlist[((mobj_t *)th)->sprite] = 1;
  643. }
  644. for (i=numsprites; --i >= 0;)
  645. if (hitlist[i])
  646. {
  647. int j = sprites[i].numframes;
  648. while (--j >= 0)
  649. {
  650. short *sflump = sprites[i].spriteframes[j].lump;
  651. int k = 7;
  652. do
  653. precache_lump(firstspritelump + sflump[k]);
  654. while (--k >= 0);
  655. }
  656. }
  657. free(hitlist);
  658. }
  659. // Proff - Added for OpenGL
  660. void R_SetPatchNum(patchnum_t *patchnum, const char *name)
  661. {
  662. const rpatch_t *patch = R_CachePatchName(name);
  663. patchnum->width = patch->width;
  664. patchnum->height = patch->height;
  665. patchnum->leftoffset = patch->leftoffset;
  666. patchnum->topoffset = patch->topoffset;
  667. patchnum->lumpnum = W_GetNumForName(name);
  668. R_UnlockPatchName(name);
  669. }