gzdoom/code/R_data.c

832 lines
18 KiB
C
Raw Normal View History

1998-04-07 00:00:00 +00:00
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// $Id:$
//
// Copyright (C) 1993-1996 by id Software, Inc.
//
// This source is available for distribution and/or modification
// only under the terms of the DOOM Source Code License as
// published by id Software. All rights reserved.
//
// The source is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
// for more details.
//
// $Log:$
//
// Revision 1.3 1997/01/29 20:10
// DESCRIPTION:
// Preparation of data for rendering,
// generation of lookups, caching, retrieval by name.
//
//-----------------------------------------------------------------------------
#include "i_system.h"
#include "z_zone.h"
#include "m_swap.h"
#include "w_wad.h"
#include "doomdef.h"
#include "r_local.h"
#include "p_local.h"
#include "doomstat.h"
#include "r_sky.h"
#include "r_data.h"
1998-07-14 00:00:00 +00:00
#include "v_palett.h"
#include "v_video.h"
1998-04-07 00:00:00 +00:00
//
// 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;
short colormap;
} mappatch_t;
//
// Texture definition.
// A DOOM wall texture is a list of patches
// which are to be combined in a predefined order.
//
typedef struct
{
1998-07-14 00:00:00 +00:00
char name[8];
BOOL masked;
short width;
short height;
void **columndirectory; // OBSOLETE
short patchcount;
1998-04-07 00:00:00 +00:00
mappatch_t patches[1];
} maptexture_t;
// A single patch from a texture definition,
// basically a rectangular area within
// the texture rectangle.
typedef struct
{
// Block origin (allways UL),
1998-07-14 00:00:00 +00:00
// which has already accounted
1998-04-07 00:00:00 +00:00
// for the internal origin of the patch.
int originx;
int originy;
int patch;
} texpatch_t;
// A maptexturedef_t describes a rectangular texture,
// which is composed of one or more mappatch_t structures
// that arrange graphic patches.
typedef struct
{
// Keep name for switch changing, etc.
1998-07-14 00:00:00 +00:00
char name[8];
1998-04-07 00:00:00 +00:00
short width;
short height;
1998-07-14 00:00:00 +00:00
// [RH] Use a hash table similar to the one now used
// in w_wad.c, thus speeding up level loads.
// (possibly quite considerably for larger levels)
int index;
int next;
1998-04-07 00:00:00 +00:00
// All the patches[patchcount]
// are drawn back to front into the cached texture.
short patchcount;
1998-07-14 00:00:00 +00:00
texpatch_t patches[1];
1998-04-07 00:00:00 +00:00
} texture_t;
int firstflat;
int lastflat;
1998-07-14 00:00:00 +00:00
static int numflats;
1998-04-07 00:00:00 +00:00
int firstspritelump;
int lastspritelump;
1998-07-14 00:00:00 +00:00
int numspritelumps;
1998-04-07 00:00:00 +00:00
1998-07-14 00:00:00 +00:00
int numtextures;
1998-04-07 00:00:00 +00:00
texture_t** textures;
1998-07-14 00:00:00 +00:00
static int* texturewidthmask;
static byte* textureheightmask; // [RH] Tutti-Frutti fix
fixed_t* textureheight; // needed for texture pegging
static int* texturecompositesize;
static short** texturecolumnlump;
static unsigned short**texturecolumnofs;
static byte** texturecomposite;
1998-04-07 00:00:00 +00:00
// for global animation
int* flattranslation;
int* texturetranslation;
// needed for pre rendering
fixed_t* spritewidth;
fixed_t* spriteoffset;
fixed_t* spritetopoffset;
1998-07-14 00:00:00 +00:00
//lighttable_t *colormaps;
1998-04-07 00:00:00 +00:00
//
// 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.
//
1998-07-14 00:00:00 +00:00
void R_DrawColumnInCache (column_t *patch, byte *cache, int originy, int cacheheight)
1998-04-07 00:00:00 +00:00
{
1998-07-14 00:00:00 +00:00
while (patch->topdelta != 0xff)
{
int count = patch->length;
int position = originy + patch->topdelta;
1998-04-07 00:00:00 +00:00
if (position < 0)
{
count += position;
position = 0;
}
if (position + count > cacheheight)
count = cacheheight - position;
if (count > 0)
1998-07-14 00:00:00 +00:00
memcpy (cache + position, (byte *)patch + 3, count);
1998-04-07 00:00:00 +00:00
patch = (column_t *)( (byte *)patch + patch->length + 4);
1998-07-14 00:00:00 +00:00
}
1998-04-07 00:00:00 +00:00
}
//
// R_GenerateComposite
// Using the texture definition,
// the composite texture is created from the patches,
// and each column is cached.
//
void R_GenerateComposite (int texnum)
{
byte* block;
texture_t* texture;
texpatch_t* patch;
int i;
column_t* patchcol;
short* collump;
unsigned short* colofs;
texture = textures[texnum];
1998-07-14 00:00:00 +00:00
block = Z_Malloc (texturecompositesize[texnum], PU_STATIC,
1998-04-07 00:00:00 +00:00
&texturecomposite[texnum]);
collump = texturecolumnlump[texnum];
colofs = texturecolumnofs[texnum];
// Composite the columns together.
patch = texture->patches;
1998-07-14 00:00:00 +00:00
for (i = texture->patchcount, patch = texture->patches; i > 0; i--, patch++)
1998-04-07 00:00:00 +00:00
{
1998-07-14 00:00:00 +00:00
patch_t *realpatch = W_CacheLumpNum (patch->patch, PU_CACHE);
int x1 = patch->originx;
int x2 = x1 + SHORT(realpatch->width);
int x = (x1 < 0) ? 0 : x1;
1998-04-07 00:00:00 +00:00
if (x2 > texture->width)
x2 = texture->width;
1998-07-14 00:00:00 +00:00
for ( ; x < x2; x++)
1998-04-07 00:00:00 +00:00
{
// Column does not have multiple patches?
if (collump[x] >= 0)
continue;
patchcol = (column_t *)((byte *)realpatch
+ LONG(realpatch->columnofs[x-x1]));
R_DrawColumnInCache (patchcol,
block + colofs[x],
patch->originy,
texture->height);
}
1998-07-14 00:00:00 +00:00
1998-04-07 00:00:00 +00:00
}
// Now that the texture has been built in column cache,
// it is purgable from zone memory.
Z_ChangeTag (block, PU_CACHE);
}
//
// R_GenerateLookup
//
void R_GenerateLookup (int texnum)
{
texture_t* texture;
byte* patchcount; // patchcount[texture->width]
texpatch_t* patch;
int i;
short* collump;
unsigned short* colofs;
texture = textures[texnum];
// Composited texture not created yet.
texturecomposite[texnum] = 0;
texturecompositesize[texnum] = 0;
collump = texturecolumnlump[texnum];
colofs = texturecolumnofs[texnum];
// 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.
1998-07-14 00:00:00 +00:00
patchcount = (byte *)Z_Malloc (texture->width, PU_STATIC, 0);
1998-04-07 00:00:00 +00:00
memset (patchcount, 0, texture->width);
patch = texture->patches;
1998-07-14 00:00:00 +00:00
for (i = texture->patchcount, patch = texture->patches; i > 0; i--, patch++)
1998-04-07 00:00:00 +00:00
{
1998-07-14 00:00:00 +00:00
patch_t *realpatch = W_CacheLumpNum (patch->patch, PU_CACHE);
int x1 = patch->originx;
int x2 = x1 + SHORT(realpatch->width);
int x = (x1 < 0) ? 0 : x1;
1998-04-07 00:00:00 +00:00
if (x2 > texture->width)
x2 = texture->width;
1998-07-14 00:00:00 +00:00
for ( ; x < x2 ; x++)
1998-04-07 00:00:00 +00:00
{
patchcount[x]++;
1998-07-14 00:00:00 +00:00
collump[x] = (short)patch->patch;
colofs[x] = (short)(LONG(realpatch->columnofs[x-x1])+3);
1998-04-07 00:00:00 +00:00
}
}
1998-07-14 00:00:00 +00:00
for (i = 0; i < texture->width; i++)
1998-04-07 00:00:00 +00:00
{
1998-07-14 00:00:00 +00:00
if (!patchcount[i])
1998-04-07 00:00:00 +00:00
{
1998-07-14 00:00:00 +00:00
char namet[9];
strncpy (namet, texture->name, 8);
namet[8] = 0;
// I_Error ("R_GenerateLookup: column without a patch");
Printf ("R_GenerateLookup: column without a patch (%s)\n", namet);
1998-04-07 00:00:00 +00:00
return;
}
1998-07-14 00:00:00 +00:00
if (patchcount[i] > 1)
1998-04-07 00:00:00 +00:00
{
// Use the cached block.
1998-07-14 00:00:00 +00:00
collump[i] = -1;
colofs[i] = (short)texturecompositesize[texnum];
1998-04-07 00:00:00 +00:00
if (texturecompositesize[texnum] > 0x10000-texture->height)
1998-07-14 00:00:00 +00:00
I_Error ("R_GenerateLookup: texture %i is >64k", texnum);
1998-04-07 00:00:00 +00:00
texturecompositesize[texnum] += texture->height;
}
1998-07-14 00:00:00 +00:00
}
Z_Free (patchcount);
1998-04-07 00:00:00 +00:00
}
//
// R_GetColumn
//
1998-07-14 00:00:00 +00:00
byte *R_GetColumn (int tex, int col)
1998-04-07 00:00:00 +00:00
{
1998-07-14 00:00:00 +00:00
int lump;
int ofs;
1998-04-07 00:00:00 +00:00
col &= texturewidthmask[tex];
lump = texturecolumnlump[tex][col];
ofs = texturecolumnofs[tex][col];
1998-07-14 00:00:00 +00:00
dc_mask = textureheightmask[tex]; // [RH] Tutti-Frutti fix
1998-04-07 00:00:00 +00:00
if (lump > 0)
return (byte *)W_CacheLumpNum(lump,PU_CACHE)+ofs;
if (!texturecomposite[tex])
R_GenerateComposite (tex);
return texturecomposite[tex] + 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;
1998-07-14 00:00:00 +00:00
int i;
1998-04-07 00:00:00 +00:00
int j;
int* maptex;
int* maptex2;
int* maptex1;
int* patchlookup;
int totalwidth;
1998-07-14 00:00:00 +00:00
int nummappatches;
1998-04-07 00:00:00 +00:00
int offset;
int maxoff;
int maxoff2;
1998-07-14 00:00:00 +00:00
int numtextures1;
int numtextures2;
1998-04-07 00:00:00 +00:00
int* directory;
// Load the patch names from pnames.lmp.
{
1998-07-14 00:00:00 +00:00
char *names = W_CacheLumpName ("PNAMES", PU_STATIC);
char *name_p = names+4;
nummappatches = LONG ( *((int *)names) );
patchlookup = Z_Malloc (nummappatches*sizeof(*patchlookup), PU_STATIC, 0);
for (i = 0; i < nummappatches; i++)
patchlookup[i] = W_CheckNumForName (name_p + i * 8);
Z_Free (names);
1998-04-07 00:00:00 +00:00
}
// 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_CacheLumpName ("TEXTURE1", PU_STATIC);
numtextures1 = LONG(*maptex);
maxoff = W_LumpLength (W_GetNumForName ("TEXTURE1"));
directory = maptex+1;
if (W_CheckNumForName ("TEXTURE2") != -1)
{
maptex2 = W_CacheLumpName ("TEXTURE2", PU_STATIC);
numtextures2 = LONG(*maptex2);
maxoff2 = W_LumpLength (W_GetNumForName ("TEXTURE2"));
}
else
{
maptex2 = NULL;
numtextures2 = 0;
maxoff2 = 0;
}
1998-07-14 00:00:00 +00:00
1998-04-07 00:00:00 +00:00
numtextures = numtextures1 + numtextures2;
1998-07-14 00:00:00 +00:00
#define ALLOC(a) a = Z_Malloc (numtextures * sizeof(*a), PU_STATIC, 0);
ALLOC (textures);
ALLOC (texturecolumnlump);
ALLOC (texturecolumnofs);
ALLOC (texturecomposite);
ALLOC (texturecompositesize);
ALLOC (texturewidthmask);
ALLOC (textureheightmask); // [RH] Tutti-Frutti fix
ALLOC (textureheight);
#undef ALLOC
1998-04-07 00:00:00 +00:00
totalwidth = 0;
// Really complex printing shit...
{
1998-07-14 00:00:00 +00:00
int temp3 = (((W_GetNumForName ("S_END") - 1) -
W_GetNumForName ("S_START") + 127) >> 7) +
((numtextures+127) >> 8);
Printf("[");
for (i = temp3; i > 0; i--)
Printf(" ");
Printf(" ]");
for (i = temp3; i > 0; i--)
Printf("\x8");
Printf("\x8\x8\x8\x8\x8\x8\x8\x8\x8\x8");
}
for (i = 0; i < numtextures; i++, directory++)
{
if (!(i&127))
1998-04-07 00:00:00 +00:00
Printf (".");
if (i == numtextures1)
{
// Start looking in second texture file.
maptex = maptex2;
maxoff = maxoff2;
directory = maptex+1;
}
1998-07-14 00:00:00 +00:00
1998-04-07 00:00:00 +00:00
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);
1998-07-14 00:00:00 +00:00
uppercopy (texture->name, mtexture->name);
1998-04-07 00:00:00 +00:00
mpatch = &mtexture->patches[0];
patch = &texture->patches[0];
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)
{
I_Error ("R_InitTextures: Missing patch in texture %s",
texture->name);
}
1998-07-14 00:00:00 +00:00
}
texturecolumnlump[i] = Z_Malloc (texture->width*sizeof(**texturecolumnlump), PU_STATIC,0);
texturecolumnofs[i] = Z_Malloc (texture->width*sizeof(**texturecolumnofs), PU_STATIC,0);
1998-04-07 00:00:00 +00:00
j = 1;
while (j*2 <= texture->width)
j<<=1;
texturewidthmask[i] = j-1;
textureheight[i] = texture->height<<FRACBITS;
1998-07-14 00:00:00 +00:00
// [RH] Tutti-Frutti fix
// Sorry, only power-of-2 tall textures are actually fixed.
j = 1;
while (j < texture->height)
j <<= 1;
textureheightmask[i] = j-1;
1998-04-07 00:00:00 +00:00
totalwidth += texture->width;
}
1998-07-14 00:00:00 +00:00
Z_Free (patchlookup);
1998-04-07 00:00:00 +00:00
Z_Free (maptex1);
if (maptex2)
Z_Free (maptex2);
1998-07-14 00:00:00 +00:00
// [RH] Setup hash chains. Go from back to front so that if
// duplicates are found, the first one gets used instead
// of the last (thus mimicing the original behavior
// of R_CheckTextureNumForName().
for (i = 0; i < numtextures; i++)
textures[i]->index = -1;
for (i = numtextures - 1; i >= 0; i--) {
j = W_LumpNameHash (textures[i]->name) % (unsigned) numtextures;
textures[i]->next = textures[j]->index;
textures[j]->index = i;
}
1998-04-07 00:00:00 +00:00
// Precalculate whatever possible.
1998-07-14 00:00:00 +00:00
for (i = 0; i < numtextures; i++)
1998-04-07 00:00:00 +00:00
R_GenerateLookup (i);
// Create translation table for global animation.
1998-07-14 00:00:00 +00:00
texturetranslation = Z_Malloc ((numtextures+1)*sizeof(*texturetranslation), PU_STATIC, 0);
1998-04-07 00:00:00 +00:00
1998-07-14 00:00:00 +00:00
for (i = 0; i < numtextures; i++)
1998-04-07 00:00:00 +00:00
texturetranslation[i] = i;
1998-07-14 00:00:00 +00:00
1998-04-07 00:00:00 +00:00
}
//
// R_InitFlats
//
void R_InitFlats (void)
{
1998-07-14 00:00:00 +00:00
int i;
1998-04-07 00:00:00 +00:00
firstflat = W_GetNumForName ("F_START") + 1;
lastflat = W_GetNumForName ("F_END") - 1;
numflats = lastflat - firstflat + 1;
// Create translation table for global animation.
1998-07-14 00:00:00 +00:00
flattranslation = Z_Malloc ((numflats+1) * (sizeof(int)), PU_STATIC, 0);
1998-04-07 00:00:00 +00:00
1998-07-14 00:00:00 +00:00
for (i = 0; i < numflats; i++)
1998-04-07 00:00:00 +00:00
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)
{
1998-07-14 00:00:00 +00:00
int i;
1998-04-07 00:00:00 +00:00
patch_t *patch;
firstspritelump = W_GetNumForName ("S_START") + 1;
lastspritelump = W_GetNumForName ("S_END") - 1;
numspritelumps = lastspritelump - firstspritelump + 1;
spritewidth = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
spriteoffset = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
spritetopoffset = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
1998-07-14 00:00:00 +00:00
for (i = 0; i < numspritelumps; i++)
1998-04-07 00:00:00 +00:00
{
1998-07-14 00:00:00 +00:00
if (!(i&127))
1998-04-07 00:00:00 +00:00
Printf (".");
patch = W_CacheLumpNum (firstspritelump+i, PU_CACHE);
spritewidth[i] = SHORT(patch->width)<<FRACBITS;
spriteoffset[i] = SHORT(patch->leftoffset)<<FRACBITS;
spritetopoffset[i] = SHORT(patch->topoffset)<<FRACBITS;
}
}
//
// R_InitColormaps
//
void R_InitColormaps (void)
{
1998-07-14 00:00:00 +00:00
// [RH] This is all done dynamically in v_palette.c
#if 0
1998-04-07 00:00:00 +00:00
int lump, length;
1998-07-14 00:00:00 +00:00
// Load in the light tables,
1998-04-07 00:00:00 +00:00
// 256 byte align tables.
1998-07-14 00:00:00 +00:00
lump = W_GetNumForName("COLORMAP");
length = W_LumpLength (lump) + 255;
colormaps = Z_Malloc (length, PU_STATIC, 0);
colormaps = (byte *)( ((int)colormaps + 255)&~0xff);
W_ReadLump (lump,colormaps);
#endif
1998-04-07 00:00:00 +00:00
}
//
// 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 ();
1998-07-14 00:00:00 +00:00
// Printf ("\nInitTextures");
1998-04-07 00:00:00 +00:00
R_InitFlats ();
1998-07-14 00:00:00 +00:00
// Printf ("\nInitFlats");
1998-04-07 00:00:00 +00:00
R_InitSpriteLumps ();
1998-07-14 00:00:00 +00:00
// Printf (".");
// Printf ("\nInitSprites");
1998-04-07 00:00:00 +00:00
R_InitColormaps ();
1998-07-14 00:00:00 +00:00
// Printf (".");
// Printf ("\nInitColormaps");
1998-04-07 00:00:00 +00:00
}
//
// R_FlatNumForName
// Retrieval, get a flat number for a flat name.
//
1998-07-14 00:00:00 +00:00
int R_FlatNumForName (const char* name)
1998-04-07 00:00:00 +00:00
{
1998-07-14 00:00:00 +00:00
int i = W_CheckNumForName (name);
1998-04-07 00:00:00 +00:00
1998-07-14 00:00:00 +00:00
if (i == -1)
i = W_CheckNumForName ("-NOFLAT-");
1998-04-07 00:00:00 +00:00
1998-07-14 00:00:00 +00:00
if (i == -1) {
char namet[9];
1998-04-07 00:00:00 +00:00
1998-07-14 00:00:00 +00:00
strncpy (namet, name, 8);
namet[8] = 0;
I_Error ("R_FlatNumForName: %s not found", namet);
1998-04-07 00:00:00 +00:00
}
1998-07-14 00:00:00 +00:00
1998-04-07 00:00:00 +00:00
return i - firstflat;
}
//
// R_CheckTextureNumForName
// Check whether texture is available.
// Filter out NoTexture indicator.
//
1998-07-14 00:00:00 +00:00
int R_CheckTextureNumForName (const char *name)
1998-04-07 00:00:00 +00:00
{
1998-07-14 00:00:00 +00:00
char uname[8];
int i;
1998-04-07 00:00:00 +00:00
// "NoTexture" marker.
if (name[0] == '-')
return 0;
1998-07-14 00:00:00 +00:00
// [RH] Use a hash table instead of linear search
uppercopy (uname, name);
i = textures[W_LumpNameHash (uname) % (unsigned) numtextures]->index;
while (i != -1) {
if (!strncmp (textures[i]->name, uname, 8))
break;
i = textures[i]->next;
}
return i;
1998-04-07 00:00:00 +00:00
}
//
// R_TextureNumForName
// Calls R_CheckTextureNumForName,
// aborts with error message.
//
1998-07-14 00:00:00 +00:00
int R_TextureNumForName (const char *name)
1998-04-07 00:00:00 +00:00
{
1998-07-14 00:00:00 +00:00
int i;
1998-04-07 00:00:00 +00:00
i = R_CheckTextureNumForName (name);
1998-07-14 00:00:00 +00:00
if (i==-1) {
char namet[9];
strncpy (namet, name, 8);
namet[8] = 0;
//I_Error ("R_TextureNumForName: %s not found", namet);
// [RH] Return empty texture if it wasn't found.
Printf ("Texture %s not found\n", namet);
return 0;
1998-04-07 00:00:00 +00:00
}
1998-07-14 00:00:00 +00:00
1998-04-07 00:00:00 +00:00
return i;
}
//
// R_PrecacheLevel
// Preloads all relevant graphics for the level.
//
1998-07-14 00:00:00 +00:00
// [RH] Rewrote this using Lee Killough's code in BOOM as an example.
1998-04-07 00:00:00 +00:00
void R_PrecacheLevel (void)
{
1998-07-14 00:00:00 +00:00
byte *hitlist;
int i;
1998-04-07 00:00:00 +00:00
if (demoplayback)
return;
{
1998-07-14 00:00:00 +00:00
int size = (numflats > numsprites) ? numflats : numsprites;
1998-04-07 00:00:00 +00:00
1998-07-14 00:00:00 +00:00
hitlist = Z_Malloc ((numtextures > size) ? numtextures : size, PU_STATIC, NULL);
1998-04-07 00:00:00 +00:00
}
1998-07-14 00:00:00 +00:00
// Precache flats.
memset (hitlist, 0, numflats);
for (i = numsectors - 1; i >= 0; i--)
hitlist[sectors[i].floorpic] = hitlist[sectors[i].ceilingpic] = 1;
1998-04-07 00:00:00 +00:00
1998-07-14 00:00:00 +00:00
for (i = numflats - 1; i >= 0; i--)
if (hitlist[i])
W_CacheLumpNum (firstflat + i, PU_CACHE);
// Precache textures.
memset (hitlist, 0, numtextures);
for (i = numsides - 1; i >= 0; i--)
1998-04-07 00:00:00 +00:00
{
1998-07-14 00:00:00 +00:00
hitlist[sides[i].toptexture] =
hitlist[sides[i].midtexture] =
hitlist[sides[i].bottomtexture] = 1;
1998-04-07 00:00:00 +00:00
}
// 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.
1998-07-14 00:00:00 +00:00
//
// [RH] Possibly two sky textures now.
1998-04-07 00:00:00 +00:00
1998-07-14 00:00:00 +00:00
hitlist[sky1texture] =
hitlist[sky2texture] = 1;
for (i = numtextures - 1; i >= 0; i--) {
if (hitlist[i]) {
int j;
texture_t *texture = textures[i];
for (j = texture->patchcount - 1; j > 0; j--)
W_CacheLumpNum(texture->patches[j].patch, PU_CACHE);
1998-04-07 00:00:00 +00:00
}
}
1998-07-14 00:00:00 +00:00
1998-04-07 00:00:00 +00:00
// Precache sprites.
1998-07-14 00:00:00 +00:00
memset (hitlist, 0, numsprites);
1998-04-07 00:00:00 +00:00
{
1998-07-14 00:00:00 +00:00
thinker_t *th;
for (th = thinkercap.next; th != &thinkercap; th = th->next)
if (th->function.acp1 == (actionf_p1)P_MobjThinker)
hitlist[((mobj_t *)th)->sprite] = 1;
1998-04-07 00:00:00 +00:00
}
1998-07-14 00:00:00 +00:00
for (i = numsprites - 1; i >= 0; i--)
1998-04-07 00:00:00 +00:00
{
1998-07-14 00:00:00 +00:00
if (hitlist[i]) {
int j;
1998-04-07 00:00:00 +00:00
1998-07-14 00:00:00 +00:00
for (j = sprites[i].numframes - 1; j >= 0; j--)
1998-04-07 00:00:00 +00:00
{
1998-07-14 00:00:00 +00:00
short *sflumps = sprites[i].spriteframes[j].lump;
int k;
for (k = 7; k >= 0; k--)
W_CacheLumpNum(firstspritelump + sflumps[k], PU_CACHE);
1998-04-07 00:00:00 +00:00
}
}
}
1998-07-14 00:00:00 +00:00
Z_Free (hitlist);
}