A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 1029 lines 32 kB view raw
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}