summaryrefslogtreecommitdiff
path: root/apps/plugins/doom/r_data.c
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2006-03-28 15:44:01 +0000
committerDave Chapman <dave@dchapman.com>2006-03-28 15:44:01 +0000
commit47f4a458d636a889e955e68f896708f1276febc0 (patch)
tree99f770c02ef606f0abbdcd332ac39e69830d8007 /apps/plugins/doom/r_data.c
parentfff7d6157d56f233cad5c2003475e47a5ff809a7 (diff)
downloadrockbox-47f4a458d636a889e955e68f896708f1276febc0.zip
rockbox-47f4a458d636a889e955e68f896708f1276febc0.tar.gz
rockbox-47f4a458d636a889e955e68f896708f1276febc0.tar.bz2
rockbox-47f4a458d636a889e955e68f896708f1276febc0.tar.xz
Patch #2969 - Doom! Currently only working on the H300.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9312 a1c6a512-1295-4272-9138-f99709370657
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 0000000..aad16e4
--- /dev/null
+++ b/apps/plugins/doom/r_data.c
@@ -0,0 +1,975 @@
+/* Emacs style mode select -*- C++ -*-
+ *-----------------------------------------------------------------------------
+ *
+ *
+ * PrBoom a Doom port merged with LxDoom and LSDLDoom
+ * based on BOOM, a modified and improved DOOM engine
+ * Copyright (C) 1999 by
+ * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
+ * Copyright (C) 1999-2000 by
+ * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * DESCRIPTION:
+ * Preparation of data for rendering,
+ * generation of lookups, caching, retrieval by name.
+ *
+ *-----------------------------------------------------------------------------*/
+
+#include "doomstat.h"
+#include "w_wad.h"
+#include "r_main.h"
+#include "r_sky.h"
+#include "i_system.h"
+#include "m_swap.h"
+#include "p_tick.h"
+//#include "lprintf.h" // jff 08/03/98 - declaration of lprintf
+#include "rockmacros.h"
+//
+// Graphics.
+// DOOM graphics for walls and sprites
+// is stored in vertical runs of opaque pixels (posts).
+// A column is composed of zero or more posts,
+// a patch or sprite is composed of zero or more columns.
+//
+
+//
+// Texture definition.
+// Each texture is composed of one or more patches,
+// with patches being lumps stored in the WAD.
+// The lumps are referenced by number, and patched
+// into the rectangular texture space using origin
+// and possibly other attributes.
+//
+
+typedef struct
+{
+ short originx;
+ short originy;
+ short patch;
+ short stepdir; // unused in Doom but might be used in Phase 2 Boom
+ short colormap; // unused in Doom but might be used in Phase 2 Boom
+} PACKEDATTR mappatch_t;
+
+typedef struct
+{
+ char name[8];
+ boolean masked;
+ short width;
+ short height;
+ char pad[4]; // unused in Doom but might be used in Boom Phase 2
+ short patchcount;
+ mappatch_t patches[1];
+} PACKEDATTR maptexture_t;
+
+// A maptexturedef_t describes a rectangular texture, which is composed
+// of one or more mappatch_t structures that arrange graphic patches.
+
+// killough 4/17/98: make firstcolormaplump,lastcolormaplump external
+int firstcolormaplump, lastcolormaplump; // killough 4/17/98
+
+int firstflat, lastflat, numflats;
+int firstspritelump, lastspritelump, numspritelumps;
+int numtextures;
+static texture_t **textures;
+fixed_t *textureheight; //needed for texture pegging (and TFE fix - killough)
+int *flattranslation; // for global animation
+int *texturetranslation;
+// needed for pre-rendering
+fixed_t *spritewidth, *spriteoffset, *spritetopoffset;
+
+//
+// MAPTEXTURE_T CACHING
+// When a texture is first needed,
+// it counts the number of composite columns
+// required in the texture and allocates space
+// for a column directory and any new columns.
+// The directory will simply point inside other patches
+// if there is only one patch in a given column,
+// but any columns with multiple patches
+// will have new column_ts generated.
+//
+
+//
+// R_DrawColumnInCache
+// Clip and draw a column
+// from a patch into a cached post.
+//
+// Rewritten by Lee Killough for performance and to fix Medusa bug
+//
+
+void R_DrawColumnInCache(const column_t *patch, byte *cache,
+ int originy, int cacheheight, byte *marks)
+{
+ while (patch->topdelta != 0xff)
+ {
+ int count = patch->length;
+ int position = originy + patch->topdelta;
+
+ if (position < 0)
+ {
+ count += position;
+ position = 0;
+ }
+
+ if (position + count > cacheheight)
+ count = cacheheight - position;
+
+ if (count > 0)
+ {
+ memcpy (cache + position, (byte *)patch + 3, count);
+
+ // killough 4/9/98: remember which cells in column have been drawn,
+ // so that column can later be converted into a series of posts, to
+ // fix the Medusa bug.
+
+ memset (marks + position, 0xff, count);
+ }
+
+ patch = (column_t *)((byte *) patch + patch->length + 4);
+ }
+}
+
+//
+// R_GenerateComposite
+// Using the texture definition,
+// the composite texture is created from the patches,
+// and each column is cached.
+//
+// Rewritten by Lee Killough for performance and to fix Medusa bug
+
+void R_GenerateComposite(int texnum)
+{
+ texture_t *texture = textures[texnum];
+ byte *block = Z_Malloc(texture->compositesize, PU_STATIC,
+ (void **)&texture->composite);
+ // Composite the columns together.
+ texpatch_t *patch = texture->patches;
+ short *collump = texture->columnlump;
+ unsigned *colofs = texture->columnofs; // killough 4/9/98: make 32-bit
+ int i = texture->patchcount;
+ // killough 4/9/98: marks to identify transparent regions in merged textures
+ byte *marks = calloc(texture->width, texture->height), *source;
+
+ for (; --i >=0; patch++)
+ {
+ const patch_t *realpatch = W_CacheLumpNum(patch->patch); // cph
+ int x1 = patch->originx, x2 = x1 + SHORT(realpatch->width);
+ const int *cofs = realpatch->columnofs-x1;
+ if (x1<0)
+ x1 = 0;
+ if (x2 > texture->width)
+ x2 = texture->width;
+ for (; x1<x2 ; x1++)
+ if (collump[x1] == -1) // Column has multiple patches?
+ // killough 1/25/98, 4/9/98: Fix medusa bug.
+ R_DrawColumnInCache((column_t*)((byte*)realpatch+LONG(cofs[x1])),
+ block+colofs[x1],patch->originy,texture->height,
+ marks + x1 * texture->height);
+
+ W_UnlockLumpNum(patch->patch); // cph - unlock the patch lump
+ }
+
+ // killough 4/9/98: Next, convert multipatched columns into true columns,
+ // to fix Medusa bug while still allowing for transparent regions.
+
+ source = malloc(texture->height); // temporary column
+ for (i=0; i < texture->width; i++)
+ if (collump[i] == -1) // process only multipatched columns
+ {
+ column_t *col = (column_t *)(block + colofs[i] - 3); // cached column
+ const byte *mark = marks + i * texture->height;
+ int j = 0;
+
+ // save column in temporary so we can shuffle it around
+ memcpy(source, (byte *) col + 3, texture->height);
+
+ for (;;) // reconstruct the column by scanning transparency marks
+ {
+ while (j < texture->height && !mark[j]) // skip transparent cells
+ j++;
+ if (j >= texture->height) // if at end of column
+ {
+ col->topdelta = -1; // end-of-column marker
+ break;
+ }
+ col->topdelta = j; // starting offset of post
+ for (col->length=0; j < texture->height && mark[j]; j++)
+ col->length++; // count opaque cells
+ // copy opaque cells from the temporary back into the column
+ memcpy((byte *) col + 3, source + col->topdelta, col->length);
+ col = (column_t *)((byte *) col + col->length + 4); // next post
+ }
+ }
+ free(source); // free temporary column
+ free(marks); // free transparency marks
+
+ // Now that the texture has been built in column cache,
+ // it is purgable from zone memory.
+
+ Z_ChangeTag(block, PU_CACHE);
+}
+
+//
+// R_GenerateLookup
+//
+// Rewritten by Lee Killough for performance and to fix Medusa bug
+//
+
+static void R_GenerateLookup(int texnum, int *const errors)
+{
+ texture_t *texture = textures[texnum];
+
+ // killough 4/9/98: make column offsets 32-bit;
+ // clean up malloc-ing to use sizeof
+ // CPhipps - moved allocing here
+ short *collump = texture->columnlump =
+ Z_Malloc(texture->width*sizeof(*texture->columnlump), PU_STATIC,0);
+ unsigned *colofs = texture->columnofs =
+ Z_Malloc(texture->width*sizeof(*texture->columnofs), PU_STATIC,0);
+
+ // killough 4/9/98: keep count of posts in addition to patches.
+ // Part of fix for medusa bug for multipatched 2s normals.
+
+ struct {
+ unsigned short patches, posts;
+ } *count = calloc(sizeof *count, texture->width);
+
+ {
+ int i = texture->patchcount;
+ const texpatch_t *patch = texture->patches;
+
+ while (--i >= 0)
+ {
+ int pat = patch->patch;
+ const patch_t *realpatch = W_CacheLumpNum(pat);
+ int x1 = patch++->originx, x2 = x1 + SHORT(realpatch->width), x = x1;
+ const int *cofs = realpatch->columnofs-x1;
+
+ if (x2 > texture->width)
+ x2 = texture->width;
+ if (x1 < 0)
+ x = 0;
+ for ( ; x<x2 ; x++)
+ {
+ // killough 4/9/98: keep a count of the number of posts in column,
+ // to fix Medusa bug while allowing for transparent multipatches.
+
+ const column_t *col = (column_t*)((byte*)realpatch+LONG(cofs[x]));
+ for (;col->topdelta != 0xff; count[x].posts++)
+ col = (column_t *)((byte *) col + col->length + 4);
+ count[x].patches++;
+ collump[x] = pat;
+ colofs[x] = LONG(cofs[x])+3;
+ }
+
+ W_UnlockLumpNum(pat);
+ }
+ }
+
+ // Composited texture not created yet.
+ texture->composite = NULL;
+
+ // Now count the number of columns
+ // that are covered by more than one patch.
+ // Fill in the lump / offset, so columns
+ // with only a single patch are all done.
+
+ {
+ int x = texture->width;
+ int height = texture->height;
+ int csize = 0;
+
+ while (--x >= 0)
+ {
+ if (!count[x].patches) // killough 4/9/98
+ {
+ //jff 8/3/98 use logical output routine
+ printf("\nR_GenerateLookup: Column %d is without a patch in texture %s",
+ x, texture->name);
+ if (errors) ++*errors;
+ else I_Error("R_GenerateLookup: Failed");
+ }
+ if (count[x].patches > 1) // killough 4/9/98
+ {
+ // killough 1/25/98, 4/9/98:
+ //
+ // Fix Medusa bug, by adding room for column header
+ // and trailer bytes for each post in merged column.
+ // For now, just allocate conservatively 4 bytes
+ // per post per patch per column, since we don't
+ // yet know how many posts the merged column will
+ // require, and it's bounded above by this limit.
+
+ collump[x] = -1; // mark lump as multipatched
+ colofs[x] = csize + 3; // three header bytes in a column
+ csize += 4*count[x].posts+1; // 1 stop byte plus 4 bytes per post
+ }
+ csize += height; // height bytes of texture data
+ }
+ texture->compositesize = csize;
+ }
+ free(count); // killough 4/9/98
+}
+
+//
+// R_GetColumn
+//
+
+const byte *R_GetColumn(int tex, int col)
+{
+ const texture_t *texture = textures[tex];
+ if (!texture->columnlump) R_GenerateLookup(tex, NULL);
+ {
+ int lump = texture->columnlump[col &= texture->widthmask];
+ int ofs = texture->columnofs[col]; // cph - WARNING: must be after the above line
+ // cph - remember the last lump, so we can unlock it if no longer needed,
+ // or reuse it if possible to reduce lump locking/unlocking
+ static int lastlump = -1;
+ static const byte* lastlumpdata;
+
+ if ((lump<=0) && (lastlump<=0))
+ lump = lastlump; // cph - force equal
+
+ if (lump != lastlump) {
+ // cph - must change the cached lump
+ if (lastlump>0)
+ W_UnlockLumpNum(lastlump);
+
+ if ((lastlump = lump) > 0)
+ lastlumpdata = W_CacheLumpNum(lump);
+#ifdef RANGECHECK
+ else
+ lastlumpdata = NULL;
+#endif
+ }
+
+ if (lump > 0)
+ return lastlumpdata + ofs;
+
+ if (!texture->composite)
+ R_GenerateComposite(tex);
+
+ return texture->composite + ofs;
+ }
+}
+
+//
+// R_InitTextures
+// Initializes the texture list
+// with the textures from the world map.
+//
+
+void R_InitTextures (void)
+{
+ maptexture_t *mtexture;
+ texture_t *texture;
+ mappatch_t *mpatch;
+ texpatch_t *patch;
+ int i, j;
+ int maptex_lump[2] = {-1, -1};
+ const int *maptex;
+ const int *maptex1, *maptex2;
+ char name[9];
+ int names_lump; // cph - new wad lump handling
+ const char *names; // cph -
+ const char *name_p;// const*'s
+ int *patchlookup;
+ int totalwidth;
+ int nummappatches;
+ int offset;
+ int maxoff, maxoff2;
+ int numtextures1, numtextures2;
+ const int *directory;
+ int errors = 0;
+
+ // Load the patch names from pnames.lmp.
+ name[8] = 0;
+ names = W_CacheLumpNum(names_lump = W_GetNumForName("PNAMES"));
+ nummappatches = LONG(*((const int *)names));
+ name_p = names+4;
+ patchlookup = malloc(nummappatches*sizeof(*patchlookup)); // killough
+
+ for (i=0 ; i<nummappatches ; i++)
+ {
+ strncpy (name,name_p+i*8, 8);
+ patchlookup[i] = W_CheckNumForName(name);
+ if (patchlookup[i] == -1)
+ {
+ // killough 4/17/98:
+ // Some wads use sprites as wall patches, so repeat check and
+ // look for sprites this time, but only if there were no wall
+ // patches found. This is the same as allowing for both, except
+ // that wall patches always win over sprites, even when they
+ // appear first in a wad. This is a kludgy solution to the wad
+ // lump namespace problem.
+
+ patchlookup[i] = (W_CheckNumForName)(name, ns_sprites);
+
+ if (patchlookup[i] == -1 && devparm)
+ //jff 8/3/98 use logical output routine
+ printf("\nWarning: patch %.8s, index %d does not exist",name,i);
+ }
+ }
+ W_UnlockLumpNum(names_lump); // cph - release the lump
+
+ // Load the map texture definitions from textures.lmp.
+ // The data is contained in one or two lumps,
+ // TEXTURE1 for shareware, plus TEXTURE2 for commercial.
+
+ maptex = maptex1 = W_CacheLumpNum(maptex_lump[0] = W_GetNumForName("TEXTURE1"));
+ numtextures1 = LONG(*maptex);
+ maxoff = W_LumpLength(maptex_lump[0]);
+ directory = maptex+1;
+
+ if (W_CheckNumForName("TEXTURE2") != -1)
+ {
+ maptex2 = W_CacheLumpNum(maptex_lump[1] = W_GetNumForName("TEXTURE2"));
+ numtextures2 = LONG(*maptex2);
+ maxoff2 = W_LumpLength(maptex_lump[1]);
+ }
+ else
+ {
+ maptex2 = NULL;
+ numtextures2 = 0;
+ maxoff2 = 0;
+ }
+ numtextures = numtextures1 + numtextures2;
+
+ // killough 4/9/98: make column offsets 32-bit;
+ // clean up malloc-ing to use sizeof
+
+ textures = Z_Malloc(numtextures*sizeof*textures, PU_STATIC, 0);
+ textureheight = Z_Malloc(numtextures*sizeof*textureheight, PU_STATIC, 0);
+
+ totalwidth = 0;
+
+ for (i=0 ; i<numtextures ; i++, directory++)
+ {
+ if (i == numtextures1)
+ {
+ // Start looking in second texture file.
+ maptex = maptex2;
+ maxoff = maxoff2;
+ directory = maptex+1;
+ }
+
+ offset = LONG(*directory);
+
+ if (offset > maxoff)
+ I_Error("R_InitTextures: Bad texture directory");
+
+ mtexture = (maptexture_t *) ( (byte *)maptex + offset);
+
+ texture = textures[i] =
+ Z_Malloc(sizeof(texture_t) +
+ sizeof(texpatch_t)*(SHORT(mtexture->patchcount)-1),
+ PU_STATIC, 0);
+
+ texture->width = SHORT(mtexture->width);
+ texture->height = SHORT(mtexture->height);
+ texture->patchcount = SHORT(mtexture->patchcount);
+
+ /* Mattias EngdegÄrd emailed me of the following explenation of
+ * why memcpy doesnt work on some systems:
+ * "I suppose it is the mad unaligned allocation
+ * going on (and which gcc in some way manages to cope with
+ * through the __attribute__ ((packed))), and which it forgets
+ * when optimizing memcpy (to a single word move) since it appears
+ * to be aligned. Technically a gcc bug, but I can't blame it when
+ * it's stressed with that amount of
+ * non-standard nonsense."
+ * So in short the unaligned struct confuses gcc's optimizer so
+ * i took the memcpy out alltogether to avoid future problems-Jess
+ */
+ /* The above was #ifndef SPARC, but i got a mail from
+ * Putera Joseph F NPRI <PuteraJF@Npt.NUWC.Navy.Mil> containing:
+ * I had to use the memcpy function on a sparc machine. The
+ * other one would give me a core dump.
+ * cph - I find it hard to believe that sparc memcpy is broken,
+ * but I don't believe the pointers to memcpy have to be aligned
+ * either. Use fast memcpy on other machines anyway.
+ */
+ /*
+ proff - I took this out, because Oli Kraus (olikraus@yahoo.com) told
+ me the memcpy produced a buserror. Since this function isn't time-
+ critical I'm using the for loop now.
+ */
+ /*
+ #ifndef GCC
+ memcpy(texture->name, mtexture->name, sizeof(texture->name));
+ #else
+ */
+ {
+ unsigned int j;
+ for(j=0;j<sizeof(texture->name);j++)
+ texture->name[j]=mtexture->name[j];
+ }
+ /* #endif */
+
+ mpatch = mtexture->patches;
+ patch = texture->patches;
+
+ for (j=0 ; j<texture->patchcount ; j++, mpatch++, patch++)
+ {
+ patch->originx = SHORT(mpatch->originx);
+ patch->originy = SHORT(mpatch->originy);
+ patch->patch = patchlookup[SHORT(mpatch->patch)];
+ if (patch->patch == -1)
+ {
+ //jff 8/3/98 use logical output routine
+ printf("\nR_InitTextures: Missing patch %d in texture %s",
+ SHORT(mpatch->patch), texture->name); // killough 4/17/98
+ ++errors;
+ }
+ }
+
+ texture->columnofs = NULL; texture->columnlump = NULL;
+
+ for (j=1; j*2 <= texture->width; j<<=1)
+ ;
+ texture->widthmask = j-1;
+ textureheight[i] = texture->height<<FRACBITS;
+
+ totalwidth += texture->width;
+ }
+
+ free(patchlookup); // killough
+
+ for (i=0; i<2; i++) // cph - release the TEXTUREx lumps
+ if (maptex_lump[i] != -1)
+ W_UnlockLumpNum(maptex_lump[i]);
+
+ if (errors)
+ I_Error("R_InitTextures: %d errors", errors);
+
+ // Precalculate whatever possible.
+ if (devparm) // cph - If in development mode, generate now so all errors are found at once
+ for (i=0 ; i<numtextures ; i++)
+ R_GenerateLookup(i, &errors);
+
+ if (errors)
+ I_Error("R_InitTextures: %d errors", errors);
+
+ // Create translation table for global animation.
+ // killough 4/9/98: make column offsets 32-bit;
+ // clean up malloc-ing to use sizeof
+
+ texturetranslation =
+ Z_Malloc((numtextures+1)*sizeof*texturetranslation, PU_STATIC, 0);
+
+ for (i=0 ; i<numtextures ; i++)
+ texturetranslation[i] = i;
+
+ // killough 1/31/98: Initialize texture hash table
+ for (i = 0; i<numtextures; i++)
+ textures[i]->index = -1;
+ while (--i >= 0)
+ {
+ int j = W_LumpNameHash(textures[i]->name) % (unsigned) numtextures;
+ textures[i]->next = textures[j]->index; // Prepend to chain
+ textures[j]->index = i;
+ }
+}
+
+//
+// R_InitFlats
+//
+void R_InitFlats(void)
+{
+ int i;
+
+ firstflat = W_GetNumForName("F_START") + 1;
+ lastflat = W_GetNumForName("F_END") - 1;
+ numflats = lastflat - firstflat + 1;
+
+ // Create translation table for global animation.
+ // killough 4/9/98: make column offsets 32-bit;
+ // clean up malloc-ing to use sizeof
+
+ flattranslation =
+ Z_Malloc((numflats+1)*sizeof(*flattranslation), PU_STATIC, 0);
+
+ for (i=0 ; i<numflats ; i++)
+ flattranslation[i] = i;
+}
+
+//
+// R_InitSpriteLumps
+// Finds the width and hoffset of all sprites in the wad,
+// so the sprite does not need to be cached completely
+// just for having the header info ready during rendering.
+//
+void R_InitSpriteLumps(void)
+{
+ int i;
+ const patch_t *patch;
+
+ firstspritelump = W_GetNumForName("S_START") + 1;
+ lastspritelump = W_GetNumForName("S_END") - 1;
+ numspritelumps = lastspritelump - firstspritelump + 1;
+
+ // killough 4/9/98: make columnd offsets 32-bit;
+ // clean up malloc-ing to use sizeof
+
+ spritewidth = Z_Malloc(numspritelumps*sizeof*spritewidth, PU_STATIC, 0);
+ spriteoffset = Z_Malloc(numspritelumps*sizeof*spriteoffset, PU_STATIC, 0);
+ spritetopoffset =
+ Z_Malloc(numspritelumps*sizeof*spritetopoffset, PU_STATIC, 0);
+
+ for (i=0 ; i< numspritelumps ; i++)
+ {
+ patch = W_CacheLumpNum(firstspritelump+i);
+ spritewidth[i] = SHORT(patch->width)<<FRACBITS;
+ spriteoffset[i] = SHORT(patch->leftoffset)<<FRACBITS;
+ spritetopoffset[i] = SHORT(patch->topoffset)<<FRACBITS;
+ W_UnlockLumpNum(firstspritelump+i);
+ }
+}
+
+//
+// R_InitColormaps
+//
+// killough 3/20/98: rewritten to allow dynamic colormaps
+// and to remove unnecessary 256-byte alignment
+//
+// killough 4/4/98: Add support for C_START/C_END markers
+//
+
+void R_InitColormaps(void)
+{
+ int i;
+ firstcolormaplump = W_GetNumForName("C_START");
+ lastcolormaplump = W_GetNumForName("C_END");
+ numcolormaps = lastcolormaplump - firstcolormaplump;
+ colormaps = Z_Malloc(sizeof(*colormaps) * numcolormaps, PU_STATIC, 0);
+ colormaps[0] = (lighttable_t *)W_CacheLumpName("COLORMAP");
+ for (i=1; i<numcolormaps; i++)
+ colormaps[i] = (lighttable_t *)W_CacheLumpNum(i+firstcolormaplump);
+ // cph - always lock
+}
+
+// killough 4/4/98: get colormap number from name
+// killough 4/11/98: changed to return -1 for illegal names
+// killough 4/17/98: changed to use ns_colormaps tag
+
+int R_ColormapNumForName(const char *name)
+{
+ register int i = 0;
+ if (strncasecmp(name,"COLORMAP",8)) // COLORMAP predefined to return 0
+ if ((i = (W_CheckNumForName)(name, ns_colormaps)) != -1)
+ i -= firstcolormaplump;
+ return i;
+}
+
+//
+// R_InitTranMap
+//
+// Initialize translucency filter map
+//
+// By Lee Killough 2/21/98
+//
+
+struct _cache {
+ unsigned char pct;
+ unsigned char playpal[256];
+} cache;
+
+int tran_filter_pct = 66; // filter percent
+
+#define TSC 12 /* number of fixed point digits in filter percent */
+
+void R_InitTranMap(int progress)
+{
+ int lump = W_CheckNumForName("TRANMAP");
+
+ // If a tranlucency filter map lump is present, use it
+ if (lump != -1) // Set a pointer to the translucency filter maps.
+ main_tranmap = W_CacheLumpNum(lump); // killough 4/11/98
+ else
+ { // Compose a default transparent filter map based on PLAYPAL.
+ const byte *playpal = W_CacheLumpName("PLAYPAL");
+ byte *my_tranmap;
+
+ int cachefd = open(GAMEBASE"tranmap.dat",O_RDONLY);
+
+ main_tranmap = my_tranmap = Z_Malloc(256*256, PU_STATIC, 0); // killough 4/11/98
+
+ // Use cached translucency filter if it's available
+
+ if ((cachefd<0) ? cachefd = open(GAMEBASE"tranmap.dat",O_WRONLY | O_CREAT) , 1 :
+ read(cachefd, &cache, sizeof(cache)) != sizeof(cache) ||
+ cache.pct != tran_filter_pct ||
+ memcmp(cache.playpal, playpal, sizeof cache.playpal) ||
+ read(cachefd, my_tranmap, 256*256) != 256*256 ) // killough 4/11/98
+ {
+
+ long *stackdeath=malloc(256*7*sizeof(long)); // This was a bunch of static varibles, way too big for rockbox
+ long *pal[3], *tot, *pal_w1[3];
+ pal[0]=&stackdeath[0];
+ pal[1]=&stackdeath[256];
+ pal[2]=&stackdeath[256*2];
+ tot=&stackdeath[256*3];
+ pal_w1[0]=&stackdeath[256*4];
+ pal_w1[1]=&stackdeath[256*5];
+ pal_w1[2]=&stackdeath[256*6];
+ long w1 = ((unsigned long) tran_filter_pct<<TSC)/100;
+ long w2 = (1l<<TSC)-w1;
+
+ if (progress)
+ printf("Please wait: Tranmap build");
+ // First, convert playpal into long int type, and transpose array,
+ // for fast inner-loop calculations. Precompute tot array.
+
+ {
+ register int i = 255;
+ register const unsigned char *p = playpal+255*3;
+ do
+ {
+ register long t,d;
+ pal_w1[0][i] = (pal[0][i] = t = p[0]) * w1;
+ d = t*t;
+ pal_w1[1][i] = (pal[1][i] = t = p[1]) * w1;
+ d += t*t;
+ pal_w1[2][i] = (pal[2][i] = t = p[2]) * w1;
+ d += t*t;
+ p -= 3;
+ tot[i] = d << (TSC-1);
+ } while (--i>=0);
+ }
+
+ // Next, compute all entries using minimum arithmetic.
+
+ {
+ int i,j;
+ byte *tp = my_tranmap;
+ for (i=0;i<256;i++)
+ {
+ long r1 = pal[0][i] * w2;
+ long g1 = pal[1][i] * w2;
+ long b1 = pal[2][i] * w2;
+ if (!(i & 31) && progress)
+ //jff 8/3/98 use logical output routine
+ printf(" Computing: %d", 256/32-i/32);
+ for (j=0;j<256;j++,tp++)
+ {
+ register int color = 255;
+ register long err;
+ long r = pal_w1[0][j] + r1;
+ long g = pal_w1[1][j] + g1;
+ long b = pal_w1[2][j] + b1;
+ long best = LONG_MAX;
+ do
+ if ((err = tot[color] - pal[0][color]*r
+ - pal[1][color]*g - pal[2][color]*b) < best)
+ best = err, *tp = color;
+ while (--color >= 0);
+ }
+ }
+ }
+
+ free(stackdeath); // Free this beast
+
+ if (cachefd) // write out the cached translucency map
+ {
+ cache.pct = tran_filter_pct;
+ memcpy(cache.playpal, playpal, 256);
+ lseek(cachefd, 0, SEEK_SET);
+ write(cachefd, &cache, sizeof cache);
+ write(cachefd,main_tranmap, 256*256);
+ // CPhipps - leave close for a few lines...
+ }
+
+ }
+
+ if (cachefd) // killough 11/98: fix filehandle leak
+ close(cachefd);
+
+ W_UnlockLumpName("PLAYPAL");
+ }
+}
+
+//
+// R_InitData
+// Locates all the lumps
+// that will be used by all views
+// Must be called after W_Init.
+//
+void R_InitData (void)
+{
+ R_InitTextures ();
+ printf ("\nInitTextures");
+ R_InitFlats ();
+ printf ("\nInitFlats");
+ R_InitSpriteLumps ();
+ printf ("\nInitSprites");
+ if (general_translucency) // killough 3/1/98
+ R_InitTranMap(1);
+ R_InitColormaps ();
+ printf ("\nInitColormaps");
+}
+
+//
+// R_FlatNumForName
+// Retrieval, get a flat number for a flat name.
+//
+// killough 4/17/98: changed to use ns_flats namespace
+//
+
+int R_FlatNumForName(const char *name) // killough -- const added
+{
+ int i = (W_CheckNumForName)(name, ns_flats);
+ if (i == -1)
+ I_Error("R_FlatNumForName: %s not found", name);
+ return i - firstflat;
+}
+
+//
+// R_CheckTextureNumForName
+// Check whether texture is available.
+// Filter out NoTexture indicator.
+//
+// Rewritten by Lee Killough to use hash table for fast lookup. Considerably
+// reduces the time needed to start new levels. See w_wad.c for comments on
+// the hashing algorithm, which is also used for lump searches.
+//
+// killough 1/21/98, 1/31/98
+//
+
+int R_CheckTextureNumForName(const char *name)
+{
+ int i = 0;
+ if (*name != '-') // "NoTexture" marker.
+ {
+ i = textures[W_LumpNameHash(name) % (unsigned) numtextures]->index;
+ while (i >= 0 && strncasecmp(textures[i]->name,name,8))
+ i = textures[i]->next;
+ }
+ return i;
+}
+
+//
+// R_TextureNumForName
+// Calls R_CheckTextureNumForName,
+// aborts with error message.
+//
+
+int R_TextureNumForName(const char *name) // const added -- killough
+{
+ int i = R_CheckTextureNumForName(name);
+ if (i == -1)
+ I_Error("R_TextureNumForName: %s not found", name);
+ return i;
+}
+
+//
+// R_PrecacheLevel
+// Preloads all relevant graphics for the level.
+//
+// Totally rewritten by Lee Killough to use less memory,
+// to avoid using alloca(), and to improve performance.
+// cph - new wad lump handling, calls cache functions but acquires no locks
+
+void R_PrecacheLevel(void)
+{
+ register int i;
+ register byte *hitlist;
+
+ if (demoplayback)
+ return;
+
+ {
+ size_t size = numflats > numsprites ? numflats : numsprites;
+ hitlist = malloc((size_t)numtextures > size ? (unsigned)numtextures : size);
+ }
+ // Precache flats.
+
+ memset(hitlist, 0, numflats);
+
+ for (i = numsectors; --i >= 0; )
+ hitlist[sectors[i].floorpic] = hitlist[sectors[i].ceilingpic] = 1;
+
+ for (i = numflats; --i >= 0; )
+ if (hitlist[i])
+ (W_CacheLumpNum)(firstflat + i, 0);
+
+ // Precache textures.
+
+ memset(hitlist, 0, numtextures);
+
+ for (i = numsides; --i >= 0;)
+ hitlist[sides[i].bottomtexture] =
+ hitlist[sides[i].toptexture] =
+ hitlist[sides[i].midtexture] = 1;
+
+ // Sky texture is always present.
+ // Note that F_SKY1 is the name used to
+ // indicate a sky floor/ceiling as a flat,
+ // while the sky texture is stored like
+ // a wall texture, with an episode dependend
+ // name.
+
+ hitlist[skytexture] = 1;
+
+ for (i = numtextures; --i >= 0; )
+ if (hitlist[i])
+ {
+ texture_t *texture = textures[i];
+ int j = texture->patchcount;
+ while (--j >= 0)
+ (W_CacheLumpNum)(texture->patches[j].patch, 0);
+ }
+
+ // Precache sprites.
+ memset(hitlist, 0, numsprites);
+
+ {
+ thinker_t *th;
+ for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
+ if (th->function == P_MobjThinker)
+ hitlist[((mobj_t *)th)->sprite] = 1;
+ }
+
+ for (i=numsprites; --i >= 0;)
+ if (hitlist[i])
+ {
+ int j = sprites[i].numframes;
+ while (--j >= 0)
+ {
+ short *sflump = sprites[i].spriteframes[j].lump;
+ int k = 7;
+ do
+ (W_CacheLumpNum)(firstspritelump + sflump[k], 0);
+ while (--k >= 0);
+ }
+ }
+ free(hitlist);
+}
+
+// Proff - Added for OpenGL
+void R_SetPatchNum(patchnum_t *patchnum, const char *name)
+{
+ patch_t *patch;
+
+ patch = (patch_t *) W_CacheLumpName(name);
+ patchnum->width = patch->width;
+ patchnum->height = patch->height;
+ patchnum->leftoffset = patch->leftoffset;
+ patchnum->topoffset = patch->topoffset;
+ patchnum->lumpnum = W_GetNumForName(name);
+ W_UnlockLumpName(name);
+}