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