summaryrefslogtreecommitdiff
path: root/apps/plugins/doom/r_data.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/doom/r_data.c')
-rw-r--r--apps/plugins/doom/r_data.c975
1 files changed, 975 insertions, 0 deletions
diff --git a/apps/plugins/doom/r_data.c b/apps/plugins/doom/r_data.c
new file mode 100644
index 0000000000..aad16e4d95
--- /dev/null
+++ b/apps/plugins/doom/r_data.c
@@ -0,0 +1,975 @@
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-2000 by
10 * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 * 02111-1307, USA.
26 *
27 * DESCRIPTION:
28 * Preparation of data for rendering,
29 * generation of lookups, caching, retrieval by name.
30 *
31 *-----------------------------------------------------------------------------*/
32
33#include "doomstat.h"
34#include "w_wad.h"
35#include "r_main.h"
36#include "r_sky.h"
37#include "i_system.h"
38#include "m_swap.h"
39#include "p_tick.h"
40//#include "lprintf.h" // jff 08/03/98 - declaration of lprintf
41#include "rockmacros.h"
42//
43// Graphics.
44// DOOM graphics for walls and sprites
45// is stored in vertical runs of opaque pixels (posts).
46// A column is composed of zero or more posts,
47// a patch or sprite is composed of zero or more columns.
48//
49
50//
51// Texture definition.
52// Each texture is composed of one or more patches,
53// with patches being lumps stored in the WAD.
54// The lumps are referenced by number, and patched
55// into the rectangular texture space using origin
56// and possibly other attributes.
57//
58
59typedef struct
60{
61 short originx;
62 short originy;
63 short patch;
64 short stepdir; // unused in Doom but might be used in Phase 2 Boom
65 short colormap; // unused in Doom but might be used in Phase 2 Boom
66} PACKEDATTR mappatch_t;
67
68typedef struct
69{
70 char name[8];
71 boolean masked;
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
79// A maptexturedef_t describes a rectangular texture, which is composed
80// of one or more mappatch_t structures that arrange graphic patches.
81
82// killough 4/17/98: make firstcolormaplump,lastcolormaplump external
83int firstcolormaplump, lastcolormaplump; // killough 4/17/98
84
85int firstflat, lastflat, numflats;
86int firstspritelump, lastspritelump, numspritelumps;
87int numtextures;
88static texture_t **textures;
89fixed_t *textureheight; //needed for texture pegging (and TFE fix - killough)
90int *flattranslation; // for global animation
91int *texturetranslation;
92// needed for pre-rendering
93fixed_t *spritewidth, *spriteoffset, *spritetopoffset;
94
95//
96// MAPTEXTURE_T CACHING
97// When a texture is first needed,
98// it counts the number of composite columns
99// required in the texture and allocates space
100// for a column directory and any new columns.
101// The directory will simply point inside other patches
102// if there is only one patch in a given column,
103// but any columns with multiple patches
104// will have new column_ts generated.
105//
106
107//
108// R_DrawColumnInCache
109// Clip and draw a column
110// from a patch into a cached post.
111//
112// Rewritten by Lee Killough for performance and to fix Medusa bug
113//
114
115void R_DrawColumnInCache(const column_t *patch, byte *cache,
116 int originy, int cacheheight, byte *marks)
117{
118 while (patch->topdelta != 0xff)
119 {
120 int count = patch->length;
121 int position = originy + patch->topdelta;
122
123 if (position < 0)
124 {
125 count += position;
126 position = 0;
127 }
128
129 if (position + count > cacheheight)
130 count = cacheheight - position;
131
132 if (count > 0)
133 {
134 memcpy (cache + position, (byte *)patch + 3, count);
135
136 // killough 4/9/98: remember which cells in column have been drawn,
137 // so that column can later be converted into a series of posts, to
138 // fix the Medusa bug.
139
140 memset (marks + position, 0xff, count);
141 }
142
143 patch = (column_t *)((byte *) patch + patch->length + 4);
144 }
145}
146
147//
148// R_GenerateComposite
149// Using the texture definition,
150// the composite texture is created from the patches,
151// and each column is cached.
152//
153// Rewritten by Lee Killough for performance and to fix Medusa bug
154
155void R_GenerateComposite(int texnum)
156{
157 texture_t *texture = textures[texnum];
158 byte *block = Z_Malloc(texture->compositesize, PU_STATIC,
159 (void **)&texture->composite);
160 // Composite the columns together.
161 texpatch_t *patch = texture->patches;
162 short *collump = texture->columnlump;
163 unsigned *colofs = texture->columnofs; // killough 4/9/98: make 32-bit
164 int i = texture->patchcount;
165 // killough 4/9/98: marks to identify transparent regions in merged textures
166 byte *marks = calloc(texture->width, texture->height), *source;
167
168 for (; --i >=0; patch++)
169 {
170 const patch_t *realpatch = W_CacheLumpNum(patch->patch); // cph
171 int x1 = patch->originx, x2 = x1 + SHORT(realpatch->width);
172 const int *cofs = realpatch->columnofs-x1;
173 if (x1<0)
174 x1 = 0;
175 if (x2 > texture->width)
176 x2 = texture->width;
177 for (; x1<x2 ; x1++)
178 if (collump[x1] == -1) // Column has multiple patches?
179 // killough 1/25/98, 4/9/98: Fix medusa bug.
180 R_DrawColumnInCache((column_t*)((byte*)realpatch+LONG(cofs[x1])),
181 block+colofs[x1],patch->originy,texture->height,
182 marks + x1 * texture->height);
183
184 W_UnlockLumpNum(patch->patch); // cph - unlock the patch lump
185 }
186
187 // killough 4/9/98: Next, convert multipatched columns into true columns,
188 // to fix Medusa bug while still allowing for transparent regions.
189
190 source = malloc(texture->height); // temporary column
191 for (i=0; i < texture->width; i++)
192 if (collump[i] == -1) // process only multipatched columns
193 {
194 column_t *col = (column_t *)(block + colofs[i] - 3); // cached column
195 const byte *mark = marks + i * texture->height;
196 int j = 0;
197
198 // save column in temporary so we can shuffle it around
199 memcpy(source, (byte *) col + 3, texture->height);
200
201 for (;;) // reconstruct the column by scanning transparency marks
202 {
203 while (j < texture->height && !mark[j]) // skip transparent cells
204 j++;
205 if (j >= texture->height) // if at end of column
206 {
207 col->topdelta = -1; // end-of-column marker
208 break;
209 }
210 col->topdelta = j; // starting offset of post
211 for (col->length=0; j < texture->height && mark[j]; j++)
212 col->length++; // count opaque cells
213 // copy opaque cells from the temporary back into the column
214 memcpy((byte *) col + 3, source + col->topdelta, col->length);
215 col = (column_t *)((byte *) col + col->length + 4); // next post
216 }
217 }
218 free(source); // free temporary column
219 free(marks); // free transparency marks
220
221 // Now that the texture has been built in column cache,
222 // it is purgable from zone memory.
223
224 Z_ChangeTag(block, PU_CACHE);
225}
226
227//
228// R_GenerateLookup
229//
230// Rewritten by Lee Killough for performance and to fix Medusa bug
231//
232
233static void R_GenerateLookup(int texnum, int *const errors)
234{
235 texture_t *texture = textures[texnum];
236
237 // killough 4/9/98: make column offsets 32-bit;
238 // clean up malloc-ing to use sizeof
239 // CPhipps - moved allocing here
240 short *collump = texture->columnlump =
241 Z_Malloc(texture->width*sizeof(*texture->columnlump), PU_STATIC,0);
242 unsigned *colofs = texture->columnofs =
243 Z_Malloc(texture->width*sizeof(*texture->columnofs), PU_STATIC,0);
244
245 // killough 4/9/98: keep count of posts in addition to patches.
246 // Part of fix for medusa bug for multipatched 2s normals.
247
248 struct {
249 unsigned short patches, posts;
250 } *count = calloc(sizeof *count, texture->width);
251
252 {
253 int i = texture->patchcount;
254 const texpatch_t *patch = texture->patches;
255
256 while (--i >= 0)
257 {
258 int pat = patch->patch;
259 const patch_t *realpatch = W_CacheLumpNum(pat);
260 int x1 = patch++->originx, x2 = x1 + SHORT(realpatch->width), x = x1;
261 const int *cofs = realpatch->columnofs-x1;
262
263 if (x2 > texture->width)
264 x2 = texture->width;
265 if (x1 < 0)
266 x = 0;
267 for ( ; x<x2 ; x++)
268 {
269 // killough 4/9/98: keep a count of the number of posts in column,
270 // to fix Medusa bug while allowing for transparent multipatches.
271
272 const column_t *col = (column_t*)((byte*)realpatch+LONG(cofs[x]));
273 for (;col->topdelta != 0xff; count[x].posts++)
274 col = (column_t *)((byte *) col + col->length + 4);
275 count[x].patches++;
276 collump[x] = pat;
277 colofs[x] = LONG(cofs[x])+3;
278 }
279
280 W_UnlockLumpNum(pat);
281 }
282 }
283
284 // Composited texture not created yet.
285 texture->composite = NULL;
286
287 // Now count the number of columns
288 // that are covered by more than one patch.
289 // Fill in the lump / offset, so columns
290 // with only a single patch are all done.
291
292 {
293 int x = texture->width;
294 int height = texture->height;
295 int csize = 0;
296
297 while (--x >= 0)
298 {
299 if (!count[x].patches) // killough 4/9/98
300 {
301 //jff 8/3/98 use logical output routine
302 printf("\nR_GenerateLookup: Column %d is without a patch in texture %s",
303 x, texture->name);
304 if (errors) ++*errors;
305 else I_Error("R_GenerateLookup: Failed");
306 }
307 if (count[x].patches > 1) // killough 4/9/98
308 {
309 // killough 1/25/98, 4/9/98:
310 //
311 // Fix Medusa bug, by adding room for column header
312 // and trailer bytes for each post in merged column.
313 // For now, just allocate conservatively 4 bytes
314 // per post per patch per column, since we don't
315 // yet know how many posts the merged column will
316 // require, and it's bounded above by this limit.
317
318 collump[x] = -1; // mark lump as multipatched
319 colofs[x] = csize + 3; // three header bytes in a column
320 csize += 4*count[x].posts+1; // 1 stop byte plus 4 bytes per post
321 }
322 csize += height; // height bytes of texture data
323 }
324 texture->compositesize = csize;
325 }
326 free(count); // killough 4/9/98
327}
328
329//
330// R_GetColumn
331//
332
333const byte *R_GetColumn(int tex, int col)
334{
335 const texture_t *texture = textures[tex];
336 if (!texture->columnlump) R_GenerateLookup(tex, NULL);
337 {
338 int lump = texture->columnlump[col &= texture->widthmask];
339 int ofs = texture->columnofs[col]; // cph - WARNING: must be after the above line
340 // cph - remember the last lump, so we can unlock it if no longer needed,
341 // or reuse it if possible to reduce lump locking/unlocking
342 static int lastlump = -1;
343 static const byte* lastlumpdata;
344
345 if ((lump<=0) && (lastlump<=0))
346 lump = lastlump; // cph - force equal
347
348 if (lump != lastlump) {
349 // cph - must change the cached lump
350 if (lastlump>0)
351 W_UnlockLumpNum(lastlump);
352
353 if ((lastlump = lump) > 0)
354 lastlumpdata = W_CacheLumpNum(lump);
355#ifdef RANGECHECK
356 else
357 lastlumpdata = NULL;
358#endif
359 }
360
361 if (lump > 0)
362 return lastlumpdata + ofs;
363
364 if (!texture->composite)
365 R_GenerateComposite(tex);
366
367 return texture->composite + ofs;
368 }
369}
370
371//
372// R_InitTextures
373// Initializes the texture list
374// with the textures from the world map.
375//
376
377void R_InitTextures (void)
378{
379 maptexture_t *mtexture;
380 texture_t *texture;
381 mappatch_t *mpatch;
382 texpatch_t *patch;
383 int i, j;
384 int maptex_lump[2] = {-1, -1};
385 const int *maptex;
386 const int *maptex1, *maptex2;
387 char name[9];
388 int names_lump; // cph - new wad lump handling
389 const char *names; // cph -
390 const char *name_p;// const*'s
391 int *patchlookup;
392 int totalwidth;
393 int nummappatches;
394 int offset;
395 int maxoff, maxoff2;
396 int numtextures1, numtextures2;
397 const int *directory;
398 int errors = 0;
399
400 // Load the patch names from pnames.lmp.
401 name[8] = 0;
402 names = W_CacheLumpNum(names_lump = W_GetNumForName("PNAMES"));
403 nummappatches = LONG(*((const int *)names));
404 name_p = names+4;
405 patchlookup = malloc(nummappatches*sizeof(*patchlookup)); // killough
406
407 for (i=0 ; i<nummappatches ; i++)
408 {
409 strncpy (name,name_p+i*8, 8);
410 patchlookup[i] = W_CheckNumForName(name);
411 if (patchlookup[i] == -1)
412 {
413 // killough 4/17/98:
414 // Some wads use sprites as wall patches, so repeat check and
415 // look for sprites this time, but only if there were no wall
416 // patches found. This is the same as allowing for both, except
417 // that wall patches always win over sprites, even when they
418 // appear first in a wad. This is a kludgy solution to the wad
419 // lump namespace problem.
420
421 patchlookup[i] = (W_CheckNumForName)(name, ns_sprites);
422
423 if (patchlookup[i] == -1 && devparm)
424 //jff 8/3/98 use logical output routine
425 printf("\nWarning: patch %.8s, index %d does not exist",name,i);
426 }
427 }
428 W_UnlockLumpNum(names_lump); // cph - release the lump
429
430 // Load the map texture definitions from textures.lmp.
431 // The data is contained in one or two lumps,
432 // TEXTURE1 for shareware, plus TEXTURE2 for commercial.
433
434 maptex = maptex1 = W_CacheLumpNum(maptex_lump[0] = W_GetNumForName("TEXTURE1"));
435 numtextures1 = LONG(*maptex);
436 maxoff = W_LumpLength(maptex_lump[0]);
437 directory = maptex+1;
438
439 if (W_CheckNumForName("TEXTURE2") != -1)
440 {
441 maptex2 = W_CacheLumpNum(maptex_lump[1] = W_GetNumForName("TEXTURE2"));
442 numtextures2 = LONG(*maptex2);
443 maxoff2 = W_LumpLength(maptex_lump[1]);
444 }
445 else
446 {
447 maptex2 = NULL;
448 numtextures2 = 0;
449 maxoff2 = 0;
450 }
451 numtextures = numtextures1 + numtextures2;
452
453 // killough 4/9/98: make column offsets 32-bit;
454 // clean up malloc-ing to use sizeof
455
456 textures = Z_Malloc(numtextures*sizeof*textures, PU_STATIC, 0);
457 textureheight = Z_Malloc(numtextures*sizeof*textureheight, PU_STATIC, 0);
458
459 totalwidth = 0;
460
461 for (i=0 ; i<numtextures ; i++, directory++)
462 {
463 if (i == numtextures1)
464 {
465 // Start looking in second texture file.
466 maptex = maptex2;
467 maxoff = maxoff2;
468 directory = maptex+1;
469 }
470
471 offset = LONG(*directory);
472
473 if (offset > maxoff)
474 I_Error("R_InitTextures: Bad texture directory");
475
476 mtexture = (maptexture_t *) ( (byte *)maptex + offset);
477
478 texture = textures[i] =
479 Z_Malloc(sizeof(texture_t) +
480 sizeof(texpatch_t)*(SHORT(mtexture->patchcount)-1),
481 PU_STATIC, 0);
482
483 texture->width = SHORT(mtexture->width);
484 texture->height = SHORT(mtexture->height);
485 texture->patchcount = SHORT(mtexture->patchcount);
486
487 /* Mattias Engdegård emailed me of the following explenation of
488 * why memcpy doesnt work on some systems:
489 * "I suppose it is the mad unaligned allocation
490 * going on (and which gcc in some way manages to cope with
491 * through the __attribute__ ((packed))), and which it forgets
492 * when optimizing memcpy (to a single word move) since it appears
493 * to be aligned. Technically a gcc bug, but I can't blame it when
494 * it's stressed with that amount of
495 * non-standard nonsense."
496 * So in short the unaligned struct confuses gcc's optimizer so
497 * i took the memcpy out alltogether to avoid future problems-Jess
498 */
499 /* The above was #ifndef SPARC, but i got a mail from
500 * Putera Joseph F NPRI <PuteraJF@Npt.NUWC.Navy.Mil> containing:
501 * I had to use the memcpy function on a sparc machine. The
502 * other one would give me a core dump.
503 * cph - I find it hard to believe that sparc memcpy is broken,
504 * but I don't believe the pointers to memcpy have to be aligned
505 * either. Use fast memcpy on other machines anyway.
506 */
507 /*
508 proff - I took this out, because Oli Kraus (olikraus@yahoo.com) told
509 me the memcpy produced a buserror. Since this function isn't time-
510 critical I'm using the for loop now.
511 */
512 /*
513 #ifndef GCC
514 memcpy(texture->name, mtexture->name, sizeof(texture->name));
515 #else
516 */
517 {
518 unsigned int j;
519 for(j=0;j<sizeof(texture->name);j++)
520 texture->name[j]=mtexture->name[j];
521 }
522 /* #endif */
523
524 mpatch = mtexture->patches;
525 patch = texture->patches;
526
527 for (j=0 ; j<texture->patchcount ; j++, mpatch++, patch++)
528 {
529 patch->originx = SHORT(mpatch->originx);
530 patch->originy = SHORT(mpatch->originy);
531 patch->patch = patchlookup[SHORT(mpatch->patch)];
532 if (patch->patch == -1)
533 {
534 //jff 8/3/98 use logical output routine
535 printf("\nR_InitTextures: Missing patch %d in texture %s",
536 SHORT(mpatch->patch), texture->name); // killough 4/17/98
537 ++errors;
538 }
539 }
540
541 texture->columnofs = NULL; texture->columnlump = NULL;
542
543 for (j=1; j*2 <= texture->width; j<<=1)
544 ;
545 texture->widthmask = j-1;
546 textureheight[i] = texture->height<<FRACBITS;
547
548 totalwidth += texture->width;
549 }
550
551 free(patchlookup); // killough
552
553 for (i=0; i<2; i++) // cph - release the TEXTUREx lumps
554 if (maptex_lump[i] != -1)
555 W_UnlockLumpNum(maptex_lump[i]);
556
557 if (errors)
558 I_Error("R_InitTextures: %d errors", errors);
559
560 // Precalculate whatever possible.
561 if (devparm) // cph - If in development mode, generate now so all errors are found at once
562 for (i=0 ; i<numtextures ; i++)
563 R_GenerateLookup(i, &errors);
564
565 if (errors)
566 I_Error("R_InitTextures: %d errors", errors);
567
568 // Create translation table for global animation.
569 // killough 4/9/98: make column offsets 32-bit;
570 // clean up malloc-ing to use sizeof
571
572 texturetranslation =
573 Z_Malloc((numtextures+1)*sizeof*texturetranslation, PU_STATIC, 0);
574
575 for (i=0 ; i<numtextures ; i++)
576 texturetranslation[i] = i;
577
578 // killough 1/31/98: Initialize texture hash table
579 for (i = 0; i<numtextures; i++)
580 textures[i]->index = -1;
581 while (--i >= 0)
582 {
583 int j = W_LumpNameHash(textures[i]->name) % (unsigned) numtextures;
584 textures[i]->next = textures[j]->index; // Prepend to chain
585 textures[j]->index = i;
586 }
587}
588
589//
590// R_InitFlats
591//
592void R_InitFlats(void)
593{
594 int i;
595
596 firstflat = W_GetNumForName("F_START") + 1;
597 lastflat = W_GetNumForName("F_END") - 1;
598 numflats = lastflat - firstflat + 1;
599
600 // Create translation table for global animation.
601 // killough 4/9/98: make column offsets 32-bit;
602 // clean up malloc-ing to use sizeof
603
604 flattranslation =
605 Z_Malloc((numflats+1)*sizeof(*flattranslation), PU_STATIC, 0);
606
607 for (i=0 ; i<numflats ; i++)
608 flattranslation[i] = i;
609}
610
611//
612// R_InitSpriteLumps
613// Finds the width and hoffset of all sprites in the wad,
614// so the sprite does not need to be cached completely
615// just for having the header info ready during rendering.
616//
617void R_InitSpriteLumps(void)
618{
619 int i;
620 const patch_t *patch;
621
622 firstspritelump = W_GetNumForName("S_START") + 1;
623 lastspritelump = W_GetNumForName("S_END") - 1;
624 numspritelumps = lastspritelump - firstspritelump + 1;
625
626 // killough 4/9/98: make columnd offsets 32-bit;
627 // clean up malloc-ing to use sizeof
628
629 spritewidth = Z_Malloc(numspritelumps*sizeof*spritewidth, PU_STATIC, 0);
630 spriteoffset = Z_Malloc(numspritelumps*sizeof*spriteoffset, PU_STATIC, 0);
631 spritetopoffset =
632 Z_Malloc(numspritelumps*sizeof*spritetopoffset, PU_STATIC, 0);
633
634 for (i=0 ; i< numspritelumps ; i++)
635 {
636 patch = W_CacheLumpNum(firstspritelump+i);
637 spritewidth[i] = SHORT(patch->width)<<FRACBITS;
638 spriteoffset[i] = SHORT(patch->leftoffset)<<FRACBITS;
639 spritetopoffset[i] = SHORT(patch->topoffset)<<FRACBITS;
640 W_UnlockLumpNum(firstspritelump+i);
641 }
642}
643
644//
645// R_InitColormaps
646//
647// killough 3/20/98: rewritten to allow dynamic colormaps
648// and to remove unnecessary 256-byte alignment
649//
650// killough 4/4/98: Add support for C_START/C_END markers
651//
652
653void R_InitColormaps(void)
654{
655 int i;
656 firstcolormaplump = W_GetNumForName("C_START");
657 lastcolormaplump = W_GetNumForName("C_END");
658 numcolormaps = lastcolormaplump - firstcolormaplump;
659 colormaps = Z_Malloc(sizeof(*colormaps) * numcolormaps, PU_STATIC, 0);
660 colormaps[0] = (lighttable_t *)W_CacheLumpName("COLORMAP");
661 for (i=1; i<numcolormaps; i++)
662 colormaps[i] = (lighttable_t *)W_CacheLumpNum(i+firstcolormaplump);
663 // cph - always lock
664}
665
666// killough 4/4/98: get colormap number from name
667// killough 4/11/98: changed to return -1 for illegal names
668// killough 4/17/98: changed to use ns_colormaps tag
669
670int R_ColormapNumForName(const char *name)
671{
672 register int i = 0;
673 if (strncasecmp(name,"COLORMAP",8)) // COLORMAP predefined to return 0
674 if ((i = (W_CheckNumForName)(name, ns_colormaps)) != -1)
675 i -= firstcolormaplump;
676 return i;
677}
678
679//
680// R_InitTranMap
681//
682// Initialize translucency filter map
683//
684// By Lee Killough 2/21/98
685//
686
687struct _cache {
688 unsigned char pct;
689 unsigned char playpal[256];
690} cache;
691
692int tran_filter_pct = 66; // filter percent
693
694#define TSC 12 /* number of fixed point digits in filter percent */
695
696void R_InitTranMap(int progress)
697{
698 int lump = W_CheckNumForName("TRANMAP");
699
700 // If a tranlucency filter map lump is present, use it
701 if (lump != -1) // Set a pointer to the translucency filter maps.
702 main_tranmap = W_CacheLumpNum(lump); // killough 4/11/98
703 else
704 { // Compose a default transparent filter map based on PLAYPAL.
705 const byte *playpal = W_CacheLumpName("PLAYPAL");
706 byte *my_tranmap;
707
708 int cachefd = open(GAMEBASE"tranmap.dat",O_RDONLY);
709
710 main_tranmap = my_tranmap = Z_Malloc(256*256, PU_STATIC, 0); // killough 4/11/98
711
712 // Use cached translucency filter if it's available
713
714 if ((cachefd<0) ? cachefd = open(GAMEBASE"tranmap.dat",O_WRONLY | O_CREAT) , 1 :
715 read(cachefd, &cache, sizeof(cache)) != sizeof(cache) ||
716 cache.pct != tran_filter_pct ||
717 memcmp(cache.playpal, playpal, sizeof cache.playpal) ||
718 read(cachefd, my_tranmap, 256*256) != 256*256 ) // killough 4/11/98
719 {
720
721 long *stackdeath=malloc(256*7*sizeof(long)); // This was a bunch of static varibles, way too big for rockbox
722 long *pal[3], *tot, *pal_w1[3];
723 pal[0]=&stackdeath[0];
724 pal[1]=&stackdeath[256];
725 pal[2]=&stackdeath[256*2];
726 tot=&stackdeath[256*3];
727 pal_w1[0]=&stackdeath[256*4];
728 pal_w1[1]=&stackdeath[256*5];
729 pal_w1[2]=&stackdeath[256*6];
730 long w1 = ((unsigned long) tran_filter_pct<<TSC)/100;
731 long w2 = (1l<<TSC)-w1;
732
733 if (progress)
734 printf("Please wait: Tranmap build");
735 // First, convert playpal into long int type, and transpose array,
736 // for fast inner-loop calculations. Precompute tot array.
737
738 {
739 register int i = 255;
740 register const unsigned char *p = playpal+255*3;
741 do
742 {
743 register long t,d;
744 pal_w1[0][i] = (pal[0][i] = t = p[0]) * w1;
745 d = t*t;
746 pal_w1[1][i] = (pal[1][i] = t = p[1]) * w1;
747 d += t*t;
748 pal_w1[2][i] = (pal[2][i] = t = p[2]) * w1;
749 d += t*t;
750 p -= 3;
751 tot[i] = d << (TSC-1);
752 } while (--i>=0);
753 }
754
755 // Next, compute all entries using minimum arithmetic.
756
757 {
758 int i,j;
759 byte *tp = my_tranmap;
760 for (i=0;i<256;i++)
761 {
762 long r1 = pal[0][i] * w2;
763 long g1 = pal[1][i] * w2;
764 long b1 = pal[2][i] * w2;
765 if (!(i & 31) && progress)
766 //jff 8/3/98 use logical output routine
767 printf(" Computing: %d", 256/32-i/32);
768 for (j=0;j<256;j++,tp++)
769 {
770 register int color = 255;
771 register long err;
772 long r = pal_w1[0][j] + r1;
773 long g = pal_w1[1][j] + g1;
774 long b = pal_w1[2][j] + b1;
775 long best = LONG_MAX;
776 do
777 if ((err = tot[color] - pal[0][color]*r
778 - pal[1][color]*g - pal[2][color]*b) < best)
779 best = err, *tp = color;
780 while (--color >= 0);
781 }
782 }
783 }
784
785 free(stackdeath); // Free this beast
786
787 if (cachefd) // write out the cached translucency map
788 {
789 cache.pct = tran_filter_pct;
790 memcpy(cache.playpal, playpal, 256);
791 lseek(cachefd, 0, SEEK_SET);
792 write(cachefd, &cache, sizeof cache);
793 write(cachefd,main_tranmap, 256*256);
794 // CPhipps - leave close for a few lines...
795 }
796
797 }
798
799 if (cachefd) // killough 11/98: fix filehandle leak
800 close(cachefd);
801
802 W_UnlockLumpName("PLAYPAL");
803 }
804}
805
806//
807// R_InitData
808// Locates all the lumps
809// that will be used by all views
810// Must be called after W_Init.
811//
812void R_InitData (void)
813{
814 R_InitTextures ();
815 printf ("\nInitTextures");
816 R_InitFlats ();
817 printf ("\nInitFlats");
818 R_InitSpriteLumps ();
819 printf ("\nInitSprites");
820 if (general_translucency) // killough 3/1/98
821 R_InitTranMap(1);
822 R_InitColormaps ();
823 printf ("\nInitColormaps");
824}
825
826//
827// R_FlatNumForName
828// Retrieval, get a flat number for a flat name.
829//
830// killough 4/17/98: changed to use ns_flats namespace
831//
832
833int R_FlatNumForName(const char *name) // killough -- const added
834{
835 int i = (W_CheckNumForName)(name, ns_flats);
836 if (i == -1)
837 I_Error("R_FlatNumForName: %s not found", name);
838 return i - firstflat;
839}
840
841//
842// R_CheckTextureNumForName
843// Check whether texture is available.
844// Filter out NoTexture indicator.
845//
846// Rewritten by Lee Killough to use hash table for fast lookup. Considerably
847// reduces the time needed to start new levels. See w_wad.c for comments on
848// the hashing algorithm, which is also used for lump searches.
849//
850// killough 1/21/98, 1/31/98
851//
852
853int R_CheckTextureNumForName(const char *name)
854{
855 int i = 0;
856 if (*name != '-') // "NoTexture" marker.
857 {
858 i = textures[W_LumpNameHash(name) % (unsigned) numtextures]->index;
859 while (i >= 0 && strncasecmp(textures[i]->name,name,8))
860 i = textures[i]->next;
861 }
862 return i;
863}
864
865//
866// R_TextureNumForName
867// Calls R_CheckTextureNumForName,
868// aborts with error message.
869//
870
871int R_TextureNumForName(const char *name) // const added -- killough
872{
873 int i = R_CheckTextureNumForName(name);
874 if (i == -1)
875 I_Error("R_TextureNumForName: %s not found", name);
876 return i;
877}
878
879//
880// R_PrecacheLevel
881// Preloads all relevant graphics for the level.
882//
883// Totally rewritten by Lee Killough to use less memory,
884// to avoid using alloca(), and to improve performance.
885// cph - new wad lump handling, calls cache functions but acquires no locks
886
887void R_PrecacheLevel(void)
888{
889 register int i;
890 register byte *hitlist;
891
892 if (demoplayback)
893 return;
894
895 {
896 size_t size = numflats > numsprites ? numflats : numsprites;
897 hitlist = malloc((size_t)numtextures > size ? (unsigned)numtextures : size);
898 }
899 // Precache flats.
900
901 memset(hitlist, 0, numflats);
902
903 for (i = numsectors; --i >= 0; )
904 hitlist[sectors[i].floorpic] = hitlist[sectors[i].ceilingpic] = 1;
905
906 for (i = numflats; --i >= 0; )
907 if (hitlist[i])
908 (W_CacheLumpNum)(firstflat + i, 0);
909
910 // Precache textures.
911
912 memset(hitlist, 0, numtextures);
913
914 for (i = numsides; --i >= 0;)
915 hitlist[sides[i].bottomtexture] =
916 hitlist[sides[i].toptexture] =
917 hitlist[sides[i].midtexture] = 1;
918
919 // Sky texture is always present.
920 // Note that F_SKY1 is the name used to
921 // indicate a sky floor/ceiling as a flat,
922 // while the sky texture is stored like
923 // a wall texture, with an episode dependend
924 // name.
925
926 hitlist[skytexture] = 1;
927
928 for (i = numtextures; --i >= 0; )
929 if (hitlist[i])
930 {
931 texture_t *texture = textures[i];
932 int j = texture->patchcount;
933 while (--j >= 0)
934 (W_CacheLumpNum)(texture->patches[j].patch, 0);
935 }
936
937 // Precache sprites.
938 memset(hitlist, 0, numsprites);
939
940 {
941 thinker_t *th;
942 for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
943 if (th->function == P_MobjThinker)
944 hitlist[((mobj_t *)th)->sprite] = 1;
945 }
946
947 for (i=numsprites; --i >= 0;)
948 if (hitlist[i])
949 {
950 int j = sprites[i].numframes;
951 while (--j >= 0)
952 {
953 short *sflump = sprites[i].spriteframes[j].lump;
954 int k = 7;
955 do
956 (W_CacheLumpNum)(firstspritelump + sflump[k], 0);
957 while (--k >= 0);
958 }
959 }
960 free(hitlist);
961}
962
963// Proff - Added for OpenGL
964void R_SetPatchNum(patchnum_t *patchnum, const char *name)
965{
966 patch_t *patch;
967
968 patch = (patch_t *) W_CacheLumpName(name);
969 patchnum->width = patch->width;
970 patchnum->height = patch->height;
971 patchnum->leftoffset = patch->leftoffset;
972 patchnum->topoffset = patch->topoffset;
973 patchnum->lumpnum = W_GetNumForName(name);
974 W_UnlockLumpName(name);
975}