8 extern void CheckAbortStartup(void);
10 int firstflat, lastflat, numflats;
11 int firstpatch, lastpatch, numpatches;
12 int firstspritelump, lastspritelump, numspritelumps;
16 int *texturewidthmask;
17 fixed_t *textureheight; // needed for texture pegging
18 int *texturecompositesize;
19 short **texturecolumnlump;
20 unsigned short **texturecolumnofs;
21 byte **texturecomposite;
23 int *flattranslation; // for global animation
24 int *texturetranslation; // for global animation
26 fixed_t *spritewidth; // needed for pre rendering
27 fixed_t *spriteoffset;
28 fixed_t *spritetopoffset;
30 lighttable_t *colormaps;
34 ==============================================================================
38 when a texture is first needed, it counts the number of composite columns
39 required in the texture and allocates space for a column directory and any
40 new columns. The directory will simply point inside other patches if there
41 is only one patch in a given column, but any columns with multiple patches
42 will have new column_ts generated.
44 ==============================================================================
52 = Clip and draw a column from a patch into a cached post
57 void R_DrawColumnInCache (column_t *patch, byte *cache, int originy, int cacheheight)
62 dest = (byte *)cache + 3;
64 while (patch->topdelta != 0xff)
66 source = (byte *)patch + 3;
67 count = patch->length;
68 position = originy + patch->topdelta;
74 if (position + count > cacheheight)
75 count = cacheheight - position;
77 memcpy (cache + position, source, count);
79 patch = (column_t *)( (byte *)patch + patch->length+ 4);
92 void R_GenerateComposite (int texnum)
102 unsigned short *colofs;
104 texture = textures[texnum];
105 block = Z_Malloc (texturecompositesize[texnum], PU_STATIC,
106 &texturecomposite[texnum]);
107 collump = texturecolumnlump[texnum];
108 colofs = texturecolumnofs[texnum];
111 // composite the columns together
113 patch = texture->patches;
115 for (i=0 , patch = texture->patches; i<texture->patchcount ; i++, patch++)
117 realpatch = W_CacheLumpNum (patch->patch, PU_CACHE);
119 x2 = x1 + SHORT(realpatch->width);
125 if (x2 > texture->width)
131 continue; // column does not have multiple patches
132 patchcol = (column_t *)((byte *)realpatch +
133 LONG(realpatch->columnofs[x-x1]));
134 R_DrawColumnInCache (patchcol, block + colofs[x], patch->originy,
140 // now that the texture has been built, it is purgable
141 Z_ChangeTag (block, PU_CACHE);
153 void R_GenerateLookup (int texnum)
156 byte *patchcount; // [texture->width]
162 unsigned short *colofs;
164 texture = textures[texnum];
166 texturecomposite[texnum] = 0; // composited not created yet
167 texturecompositesize[texnum] = 0;
168 collump = texturecolumnlump[texnum];
169 colofs = texturecolumnofs[texnum];
172 // count the number of columns that are covered by more than one patch
173 // fill in the lump / offset, so columns with only a single patch are
176 patchcount = (byte *)alloca (texture->width);
177 memset (patchcount, 0, texture->width);
178 patch = texture->patches;
180 for (i=0 , patch = texture->patches; i<texture->patchcount ; i++, patch++)
182 realpatch = W_CacheLumpNum (patch->patch, PU_CACHE);
184 x2 = x1 + SHORT(realpatch->width);
189 if (x2 > texture->width)
194 collump[x] = patch->patch;
195 colofs[x] = LONG(realpatch->columnofs[x-x1])+3;
199 for (x=0 ; x<texture->width ; x++)
203 printf ("R_GenerateLookup: column without a patch (%s)\n", texture->name);
206 // I_Error ("R_GenerateLookup: column without a patch");
207 if (patchcount[x] > 1)
209 collump[x] = -1; // use the cached block
210 colofs[x] = texturecompositesize[texnum];
211 if (texturecompositesize[texnum] > 0x10000-texture->height)
212 I_Error ("R_GenerateLookup: texture %i is >64k",texnum);
213 texturecompositesize[texnum] += texture->height;
227 byte *R_GetColumn (int tex, int col)
231 col &= texturewidthmask[tex];
232 lump = texturecolumnlump[tex][col];
233 ofs = texturecolumnofs[tex][col];
235 return (byte *)W_CacheLumpNum(lump,PU_CACHE)+ofs;
236 if (!texturecomposite[tex])
237 R_GenerateComposite (tex);
238 return texturecomposite[tex] + ofs;
247 = Initializes the texture list with the textures from the world map
252 void R_InitTextures (void)
254 maptexture_t *mtexture;
259 int *maptex, *maptex2, *maptex1;
260 char name[9], *names, *name_p;
264 int offset, maxoff, maxoff2;
265 int numtextures1, numtextures2;
269 // load the patch names from pnames.lmp
272 names = W_CacheLumpName ("PNAMES", PU_STATIC);
273 nummappatches = LONG ( *((int *)names) );
275 patchlookup = alloca (nummappatches*sizeof(*patchlookup));
276 for (i=0 ; i<nummappatches ; i++)
278 strncpy (name,name_p+i*8, 8);
279 patchlookup[i] = W_CheckNumForName (name);
284 // load the map texture definitions from textures.lmp
286 maptex = maptex1 = W_CacheLumpName ("TEXTURE1", PU_STATIC);
287 numtextures1 = LONG(*maptex);
288 maxoff = W_LumpLength (W_GetNumForName ("TEXTURE1"));
289 directory = maptex+1;
291 if (W_CheckNumForName ("TEXTURE2") != -1)
293 maptex2 = W_CacheLumpName ("TEXTURE2", PU_STATIC);
294 numtextures2 = LONG(*maptex2);
295 maxoff2 = W_LumpLength (W_GetNumForName ("TEXTURE2"));
303 numtextures = numtextures1 + numtextures2;
306 // Init the startup thermometer at this point...
310 spramount = W_GetNumForName("S_END") - W_GetNumForName("S_START") + 1;
311 InitThermo(spramount + numtextures + 6);
314 textures = Z_Malloc (numtextures*4, PU_STATIC, 0);
315 texturecolumnlump = Z_Malloc (numtextures*4, PU_STATIC, 0);
316 texturecolumnofs = Z_Malloc (numtextures*4, PU_STATIC, 0);
317 texturecomposite = Z_Malloc (numtextures*4, PU_STATIC, 0);
318 texturecompositesize = Z_Malloc (numtextures*4, PU_STATIC, 0);
319 texturewidthmask = Z_Malloc (numtextures*4, PU_STATIC, 0);
320 textureheight = Z_Malloc (numtextures*4, PU_STATIC, 0);
324 for (i=0 ; i<numtextures ; i++, directory++)
332 if (i == numtextures1)
333 { // start looking in second texture file
336 directory = maptex+1;
339 offset = LONG(*directory);
341 I_Error ("R_InitTextures: bad texture directory");
342 mtexture = (maptexture_t *) ( (byte *)maptex + offset);
343 texture = textures[i] = Z_Malloc (sizeof(texture_t)
344 + sizeof(texpatch_t)*(SHORT(mtexture->patchcount)-1), PU_STATIC,
346 texture->width = SHORT(mtexture->width);
347 texture->height = SHORT(mtexture->height);
348 texture->patchcount = SHORT(mtexture->patchcount);
349 memcpy (texture->name, mtexture->name, sizeof(texture->name));
350 mpatch = &mtexture->patches[0];
351 patch = &texture->patches[0];
352 for (j=0 ; j<texture->patchcount ; j++, mpatch++, patch++)
354 patch->originx = SHORT(mpatch->originx);
355 patch->originy = SHORT(mpatch->originy);
356 patch->patch = patchlookup[SHORT(mpatch->patch)];
357 if (patch->patch == -1)
359 "R_InitTextures: Missing patch in texture %s",texture->name);
361 texturecolumnlump[i] = Z_Malloc (texture->width*2, PU_STATIC,0);
362 texturecolumnofs[i] = Z_Malloc (texture->width*2, PU_STATIC,0);
364 while (j*2 <= texture->width)
366 texturewidthmask[i] = j-1;
367 textureheight[i] = texture->height<<FRACBITS;
369 totalwidth += texture->width;
377 // precalculate whatever possible
379 for(i = 0; i < numtextures; i++)
386 // translation table for global animation
388 texturetranslation = Z_Malloc ((numtextures+1)*4, PU_STATIC, 0);
389 for (i=0 ; i<numtextures ; i++)
390 texturetranslation[i] = i;
402 void R_InitFlats (void)
406 firstflat = W_GetNumForName ("F_START") + 1;
407 lastflat = W_GetNumForName ("F_END") - 1;
408 numflats = lastflat - firstflat + 1;
410 // translation table for global animation
411 flattranslation = Z_Malloc ((numflats+1)*4, PU_STATIC, 0);
412 for (i=0 ; i<numflats ; i++)
413 flattranslation[i] = i;
422 = Finds the width and hoffset of all sprites in the wad, so the sprite doesn't
423 = need to be cached just for the header during rendering
427 void R_InitSpriteLumps (void)
432 firstspritelump = W_GetNumForName ("S_START") + 1;
433 lastspritelump = W_GetNumForName ("S_END") - 1;
434 numspritelumps = lastspritelump - firstspritelump + 1;
435 spritewidth = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
436 spriteoffset = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
437 spritetopoffset = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
439 for (i=0 ; i< numspritelumps ; i++)
447 patch = W_CacheLumpNum (firstspritelump+i, PU_CACHE);
448 spritewidth[i] = SHORT(patch->width)<<FRACBITS;
449 spriteoffset[i] = SHORT(patch->leftoffset)<<FRACBITS;
450 spritetopoffset[i] = SHORT(patch->topoffset)<<FRACBITS;
463 void R_InitColormaps (void)
467 // load in the light tables
468 // 256 byte align tables
470 lump = W_GetNumForName("COLORMAP");
471 length = W_LumpLength (lump) + 255;
472 colormaps = Z_Malloc (length, PU_STATIC, 0);
473 colormaps = (byte *)( ((int)colormaps + 255)&~0xff);
474 W_ReadLump (lump,colormaps);
483 = Locates all the lumps that will be used by all views
484 = Must be called after W_Init
488 void R_InitData (void)
490 tprintf("\nR_InitTextures ",0);
493 tprintf("R_InitFlats\n",0);
497 tprintf("R_InitSpriteLumps ",0);
498 R_InitSpriteLumps ();
505 //=============================================================================
515 int R_FlatNumForName (char *name)
520 i = W_CheckNumForName (name);
524 memcpy (namet, name,8);
525 I_Error ("R_FlatNumForName: %s not found",namet);
527 return i - firstflat;
534 = R_CheckTextureNumForName
539 int R_CheckTextureNumForName (char *name)
543 if (name[0] == '-') // no texture marker
546 for (i=0 ; i<numtextures ; i++)
547 if (!strncasecmp (textures[i]->name, name, 8) )
557 = R_TextureNumForName
562 int R_TextureNumForName (char *name)
567 i = R_CheckTextureNumForName (name);
569 I_Error ("R_TextureNumForName: %s not found",name);
580 = Preloads all relevent graphics for the level
584 int flatmemory, texturememory, spritememory;
586 void R_PrecacheLevel (void)
589 char *texturepresent;
602 flatpresent = alloca(numflats);
603 memset (flatpresent,0,numflats);
604 for (i=0 ; i<numsectors ; i++)
606 flatpresent[sectors[i].floorpic] = 1;
607 flatpresent[sectors[i].ceilingpic] = 1;
611 for (i=0 ; i<numflats ; i++)
614 lump = firstflat + i;
615 flatmemory += lumpinfo[lump].size;
616 W_CacheLumpNum(lump, PU_CACHE);
622 texturepresent = alloca(numtextures);
623 memset (texturepresent,0, numtextures);
625 for (i=0 ; i<numsides ; i++)
627 texturepresent[sides[i].toptexture] = 1;
628 texturepresent[sides[i].midtexture] = 1;
629 texturepresent[sides[i].bottomtexture] = 1;
632 texturepresent[skytexture] = 1;
635 for (i=0 ; i<numtextures ; i++)
637 if (!texturepresent[i])
639 texture = textures[i];
640 for (j=0 ; j<texture->patchcount ; j++)
642 lump = texture->patches[j].patch;
643 texturememory += lumpinfo[lump].size;
644 W_CacheLumpNum(lump , PU_CACHE);
651 spritepresent = alloca(numsprites);
652 memset (spritepresent,0, numsprites);
654 for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
656 if (th->function == P_MobjThinker)
657 spritepresent[((mobj_t *)th)->sprite] = 1;
661 for (i=0 ; i<numsprites ; i++)
663 if (!spritepresent[i])
665 for (j=0 ; j<sprites[i].numframes ; j++)
667 sf = &sprites[i].spriteframes[j];
668 for (k=0 ; k<8 ; k++)
670 lump = firstspritelump + sf->lump[k];
671 spritememory += lumpinfo[lump].size;
672 W_CacheLumpNum(lump , PU_CACHE);