2 //**************************************************************************
4 //** r_data.c : Heretic 2 : Raven Software, Corp.
11 //**************************************************************************
18 // Moved these structures to r_local.h for RENDER3D.
22 int originx; // block origin (allways UL), which has allready
23 int originy; // accounted for the patch's internal origin
27 // a maptexturedef_t describes a rectangular texture, which is composed of one
28 // or more mappatch_t structures that arrange graphic patches
31 char name[8]; // for switch changing, etc
35 texpatch_t patches[1]; // [patchcount] drawn back to front
36 // into the cached texture
41 int firstflat, lastflat, numflats;
42 int firstpatch, lastpatch, numpatches;
43 int firstspritelump, lastspritelump, numspritelumps;
47 int *texturewidthmask;
48 fixed_t *textureheight; // needed for texture pegging
49 int *texturecompositesize;
50 short **texturecolumnlump;
51 unsigned short **texturecolumnofs;
52 byte **texturecomposite;
54 int *flattranslation; // for global animation
55 int *texturetranslation; // for global animation
57 fixed_t *spritewidth; // needed for pre rendering
58 fixed_t *spriteoffset;
59 fixed_t *spritetopoffset;
61 lighttable_t *colormaps;
65 ==============================================================================
69 when a texture is first needed, it counts the number of composite columns
70 required in the texture and allocates space for a column directory and any
71 new columns. The directory will simply point inside other patches if there
72 is only one patch in a given column, but any columns with multiple patches
73 will have new column_ts generated.
75 ==============================================================================
83 = Clip and draw a column from a patch into a cached post
88 void R_DrawColumnInCache (column_t *patch, byte *cache, int originy, int cacheheight)
93 dest = (byte *)cache + 3;
95 while (patch->topdelta != 0xff)
97 source = (byte *)patch + 3;
98 count = patch->length;
99 position = originy + patch->topdelta;
105 if (position + count > cacheheight)
106 count = cacheheight - position;
108 memcpy (cache + position, source, count);
110 patch = (column_t *)( (byte *)patch + patch->length
119 = R_GenerateComposite
124 void R_GenerateComposite (int texnum)
134 unsigned short *colofs;
136 texture = textures[texnum];
137 block = Z_Malloc (texturecompositesize[texnum], PU_STATIC,
138 &texturecomposite[texnum]);
139 collump = texturecolumnlump[texnum];
140 colofs = texturecolumnofs[texnum];
143 // composite the columns together
145 patch = texture->patches;
147 for (i=0 , patch = texture->patches; i<texture->patchcount ; i++, patch++)
149 realpatch = W_CacheLumpNum (patch->patch, PU_CACHE);
151 x2 = x1 + SHORT(realpatch->width);
157 if (x2 > texture->width)
163 continue; // column does not have multiple patches
164 patchcol = (column_t *)((byte *)realpatch +
165 LONG(realpatch->columnofs[x-x1]));
166 R_DrawColumnInCache (patchcol, block + colofs[x], patch->originy,
172 // now that the texture has been built, it is purgable
173 Z_ChangeTag (block, PU_CACHE);
185 void R_GenerateLookup (int texnum)
188 byte *patchcount; // [texture->width]
194 unsigned short *colofs;
196 texture = textures[texnum];
198 texturecomposite[texnum] = 0; // composited not created yet
199 texturecompositesize[texnum] = 0;
200 collump = texturecolumnlump[texnum];
201 colofs = texturecolumnofs[texnum];
204 // count the number of columns that are covered by more than one patch
205 // fill in the lump / offset, so columns with only a single patch are
208 patchcount = (byte *)alloca (texture->width);
209 memset (patchcount, 0, texture->width);
210 patch = texture->patches;
212 for (i=0 , patch = texture->patches; i<texture->patchcount ; i++, patch++)
214 realpatch = W_CacheLumpNum (patch->patch, PU_CACHE);
216 x2 = x1 + SHORT(realpatch->width);
221 if (x2 > texture->width)
226 collump[x] = patch->patch;
227 colofs[x] = LONG(realpatch->columnofs[x-x1])+3;
231 for (x=0 ; x<texture->width ; x++)
235 ST_Message ("R_GenerateLookup: column without a patch (%s)\n", texture->name);
238 // I_Error ("R_GenerateLookup: column without a patch");
239 if (patchcount[x] > 1)
241 collump[x] = -1; // use the cached block
242 colofs[x] = texturecompositesize[texnum];
243 if (texturecompositesize[texnum] > 0x10000-texture->height)
244 I_Error ("R_GenerateLookup: texture %i is >64k",texnum);
245 texturecompositesize[texnum] += texture->height;
259 byte *R_GetColumn (int tex, int col)
263 col &= texturewidthmask[tex];
264 lump = texturecolumnlump[tex][col];
265 ofs = texturecolumnofs[tex][col];
267 return (byte *)W_CacheLumpNum(lump,PU_CACHE)+ofs;
268 if (!texturecomposite[tex])
269 R_GenerateComposite (tex);
270 return texturecomposite[tex] + ofs;
279 = Initializes the texture list with the textures from the world map
284 void R_InitTextures (void)
286 maptexture_t *mtexture;
291 int *maptex, *maptex2, *maptex1;
292 char name[9], *names, *name_p;
296 int offset, maxoff, maxoff2;
297 int numtextures1, numtextures2;
301 // load the patch names from pnames.lmp
304 names = W_CacheLumpName ("PNAMES", PU_STATIC);
305 nummappatches = LONG ( *((int *)names) );
307 patchlookup = alloca (nummappatches*sizeof(*patchlookup));
308 for (i=0 ; i<nummappatches ; i++)
310 strncpy (name,name_p+i*8, 8);
311 patchlookup[i] = W_CheckNumForName (name);
316 // load the map texture definitions from textures.lmp
318 maptex = maptex1 = W_CacheLumpName ("TEXTURE1", PU_STATIC);
319 numtextures1 = LONG(*maptex);
320 maxoff = W_LumpLength (W_GetNumForName ("TEXTURE1"));
321 directory = maptex+1;
323 if (W_CheckNumForName ("TEXTURE2") != -1)
325 maptex2 = W_CacheLumpName ("TEXTURE2", PU_STATIC);
326 numtextures2 = LONG(*maptex2);
327 maxoff2 = W_LumpLength (W_GetNumForName ("TEXTURE2"));
335 numtextures = numtextures1 + numtextures2;
337 textures = Z_Malloc (numtextures*4, PU_STATIC, 0);
338 texturecolumnlump = Z_Malloc (numtextures*4, PU_STATIC, 0);
339 texturecolumnofs = Z_Malloc (numtextures*4, PU_STATIC, 0);
340 texturecomposite = Z_Malloc (numtextures*4, PU_STATIC, 0);
341 texturecompositesize = Z_Malloc (numtextures*4, PU_STATIC, 0);
342 texturewidthmask = Z_Malloc (numtextures*4, PU_STATIC, 0);
343 textureheight = Z_Malloc (numtextures*4, PU_STATIC, 0);
347 for (i=0 ; i<numtextures ; i++, directory++)
349 if (i == numtextures1)
350 { // start looking in second texture file
353 directory = maptex+1;
356 offset = LONG(*directory);
358 I_Error ("R_InitTextures: bad texture directory");
359 mtexture = (maptexture_t *) ( (byte *)maptex + offset);
360 texture = textures[i] = Z_Malloc (sizeof(texture_t)
361 + sizeof(texpatch_t)*(SHORT(mtexture->patchcount)-1), PU_STATIC,
363 texture->width = SHORT(mtexture->width);
364 texture->height = SHORT(mtexture->height);
365 texture->patchcount = SHORT(mtexture->patchcount);
366 memcpy (texture->name, mtexture->name, sizeof(texture->name));
367 mpatch = &mtexture->patches[0];
368 patch = &texture->patches[0];
369 for (j=0 ; j<texture->patchcount ; j++, mpatch++, patch++)
371 patch->originx = SHORT(mpatch->originx);
372 patch->originy = SHORT(mpatch->originy);
373 patch->patch = patchlookup[SHORT(mpatch->patch)];
374 if (patch->patch == -1)
376 "R_InitTextures: Missing patch in texture %s",texture->name);
378 texturecolumnlump[i] = Z_Malloc (texture->width*2, PU_STATIC,0);
379 texturecolumnofs[i] = Z_Malloc (texture->width*2, PU_STATIC,0);
381 while (j*2 <= texture->width)
383 texturewidthmask[i] = j-1;
384 textureheight[i] = texture->height<<FRACBITS;
386 totalwidth += texture->width;
394 // precalculate whatever possible
396 for (i=0 ; i<numtextures ; i++)
398 R_GenerateLookup (i);
399 if(!(i&31)) ST_Progress();
403 // translation table for global animation
405 texturetranslation = Z_Malloc ((numtextures+1)*4, PU_STATIC, 0);
406 for (i=0 ; i<numtextures ; i++)
407 texturetranslation[i] = i;
419 void R_InitFlats (void)
423 firstflat = W_GetNumForName ("F_START") + 1;
424 lastflat = W_GetNumForName ("F_END") - 1;
425 numflats = lastflat - firstflat + 1;
427 // translation table for global animation
428 flattranslation = Z_Malloc ((numflats+1)*4, PU_STATIC, 0);
429 for (i=0 ; i<numflats ; i++)
430 flattranslation[i] = i;
439 = Finds the width and hoffset of all sprites in the wad, so the sprite doesn't
440 = need to be cached just for the header during rendering
444 void R_InitSpriteLumps (void)
449 firstspritelump = W_GetNumForName ("S_START") + 1;
450 lastspritelump = W_GetNumForName ("S_END") - 1;
451 numspritelumps = lastspritelump - firstspritelump + 1;
452 spritewidth = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
453 spriteoffset = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
454 spritetopoffset = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
456 for (i=0 ; i< numspritelumps ; i++)
458 if (!(i&127)) ST_Progress();
459 patch = W_CacheLumpNum (firstspritelump+i, PU_CACHE);
460 spritewidth[i] = SHORT(patch->width)<<FRACBITS;
461 spriteoffset[i] = SHORT(patch->leftoffset)<<FRACBITS;
462 spritetopoffset[i] = SHORT(patch->topoffset)<<FRACBITS;
475 void R_InitColormaps (void)
479 // load in the light tables
480 // 256 byte align tables
482 lump = W_GetNumForName("COLORMAP");
483 length = W_LumpLength (lump) + 255;
484 colormaps = Z_Malloc (length, PU_STATIC, 0);
485 colormaps = (byte *)( ((int)colormaps + 255)&~0xff);
486 W_ReadLump (lump,colormaps);
495 = Locates all the lumps that will be used by all views
496 = Must be called after W_Init
500 void R_InitData (void)
508 //=============================================================================
518 int R_FlatNumForName (char *name)
523 i = W_CheckNumForName (name);
527 memcpy (namet, name,8);
528 I_Error ("R_FlatNumForName: %s not found",namet);
530 return i - firstflat;
537 = R_CheckTextureNumForName
542 int R_CheckTextureNumForName (char *name)
546 if (name[0] == '-') // no texture marker
550 //printf( "%s\n", name );
551 for (i=0 ; i<numtextures ; i++)
553 //printf( "%d %s\n", i, textures[i]->name );
554 if (!strncasecmp (textures[i]->name, name, 8) )
565 = R_TextureNumForName
570 int R_TextureNumForName (char *name)
575 i = R_CheckTextureNumForName (name);
579 printf("R_TextureNumForName: %s not found! Assuming shareware wad.\n",
583 I_Error ("R_TextureNumForName: %s not found",name);
596 = Preloads all relevent graphics for the level
600 int flatmemory, texturememory, spritememory;
602 void R_PrecacheLevel (void)
605 char *texturepresent;
618 flatpresent = alloca(numflats);
619 memset (flatpresent,0,numflats);
620 for (i=0 ; i<numsectors ; i++)
622 flatpresent[sectors[i].floorpic] = 1;
623 flatpresent[sectors[i].ceilingpic] = 1;
627 for (i=0 ; i<numflats ; i++)
630 lump = firstflat + i;
631 flatmemory += lumpinfo[lump].size;
632 W_CacheLumpNum(lump, PU_CACHE);
638 texturepresent = alloca(numtextures);
639 memset (texturepresent,0, numtextures);
641 for (i=0 ; i<numsides ; i++)
643 texturepresent[sides[i].toptexture] = 1;
644 texturepresent[sides[i].midtexture] = 1;
645 texturepresent[sides[i].bottomtexture] = 1;
648 texturepresent[Sky1Texture] = 1;
649 texturepresent[Sky2Texture] = 1;
652 for (i=0 ; i<numtextures ; i++)
654 if (!texturepresent[i])
656 texture = textures[i];
657 for (j=0 ; j<texture->patchcount ; j++)
659 lump = texture->patches[j].patch;
660 texturememory += lumpinfo[lump].size;
661 W_CacheLumpNum(lump , PU_CACHE);
668 spritepresent = alloca(numsprites);
669 memset (spritepresent,0, numsprites);
671 for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
673 if (th->function == P_MobjThinker)
674 spritepresent[((mobj_t *)th)->sprite] = 1;
678 for (i=0 ; i<numsprites ; i++)
680 if (!spritepresent[i])
682 for (j=0 ; j<sprites[i].numframes ; j++)
684 sf = &sprites[i].spriteframes[j];
685 for (k=0 ; k<8 ; k++)
687 lump = firstspritelump + sf->lump[k];
688 spritememory += lumpinfo[lump].size;
689 W_CacheLumpNum(lump , PU_CACHE);