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