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 *)malloc (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);
239 // I_Error ("R_GenerateLookup: column without a patch");
240 if (patchcount[x] > 1)
242 collump[x] = -1; // use the cached block
243 colofs[x] = texturecompositesize[texnum];
244 if (texturecompositesize[texnum] > 0x10000-texture->height)
245 I_Error ("R_GenerateLookup: texture %i is >64k",texnum);
246 texturecompositesize[texnum] += texture->height;
261 byte *R_GetColumn (int tex, int col)
265 col &= texturewidthmask[tex];
266 lump = texturecolumnlump[tex][col];
267 ofs = texturecolumnofs[tex][col];
269 return (byte *)W_CacheLumpNum(lump,PU_CACHE)+ofs;
270 if (!texturecomposite[tex])
271 R_GenerateComposite (tex);
272 return texturecomposite[tex] + ofs;
281 = Initializes the texture list with the textures from the world map
286 void R_InitTextures (void)
288 maptexture_t *mtexture;
293 int *maptex, *maptex2, *maptex1;
294 char name[9], *names, *name_p;
298 int offset, maxoff, maxoff2;
299 int numtextures1, numtextures2;
303 // load the patch names from pnames.lmp
306 names = W_CacheLumpName ("PNAMES", PU_STATIC);
307 nummappatches = LONG ( *((int *)names) );
309 patchlookup = (int *)malloc(nummappatches*sizeof(*patchlookup));
310 for (i=0 ; i<nummappatches ; i++)
312 strncpy (name,name_p+i*8, 8);
313 patchlookup[i] = W_CheckNumForName (name);
318 // load the map texture definitions from textures.lmp
320 maptex = maptex1 = W_CacheLumpName ("TEXTURE1", PU_STATIC);
321 numtextures1 = LONG(*maptex);
322 maxoff = W_LumpLength (W_GetNumForName ("TEXTURE1"));
323 directory = maptex+1;
325 if (W_CheckNumForName ("TEXTURE2") != -1)
327 maptex2 = W_CacheLumpName ("TEXTURE2", PU_STATIC);
328 numtextures2 = LONG(*maptex2);
329 maxoff2 = W_LumpLength (W_GetNumForName ("TEXTURE2"));
337 numtextures = numtextures1 + numtextures2;
339 textures = Z_Malloc (numtextures*4, PU_STATIC, 0);
340 texturecolumnlump = Z_Malloc (numtextures*4, PU_STATIC, 0);
341 texturecolumnofs = Z_Malloc (numtextures*4, PU_STATIC, 0);
342 texturecomposite = Z_Malloc (numtextures*4, PU_STATIC, 0);
343 texturecompositesize = Z_Malloc (numtextures*4, PU_STATIC, 0);
344 texturewidthmask = Z_Malloc (numtextures*4, PU_STATIC, 0);
345 textureheight = Z_Malloc (numtextures*4, PU_STATIC, 0);
349 for (i=0 ; i<numtextures ; i++, directory++)
351 if (i == numtextures1)
352 { // start looking in second texture file
355 directory = maptex+1;
358 offset = LONG(*directory);
360 I_Error ("R_InitTextures: bad texture directory");
361 mtexture = (maptexture_t *) ( (byte *)maptex + offset);
362 texture = textures[i] = Z_Malloc (sizeof(texture_t)
363 + sizeof(texpatch_t)*(SHORT(mtexture->patchcount)-1), PU_STATIC,
365 texture->width = SHORT(mtexture->width);
366 texture->height = SHORT(mtexture->height);
367 texture->patchcount = SHORT(mtexture->patchcount);
368 memcpy (texture->name, mtexture->name, sizeof(texture->name));
369 mpatch = &mtexture->patches[0];
370 patch = &texture->patches[0];
371 for (j=0 ; j<texture->patchcount ; j++, mpatch++, patch++)
373 patch->originx = SHORT(mpatch->originx);
374 patch->originy = SHORT(mpatch->originy);
375 patch->patch = patchlookup[SHORT(mpatch->patch)];
376 if (patch->patch == -1)
378 "R_InitTextures: Missing patch in texture %s",texture->name);
380 texturecolumnlump[i] = Z_Malloc (texture->width*2, PU_STATIC,0);
381 texturecolumnofs[i] = Z_Malloc (texture->width*2, PU_STATIC,0);
383 while (j*2 <= texture->width)
385 texturewidthmask[i] = j-1;
386 textureheight[i] = texture->height<<FRACBITS;
388 totalwidth += texture->width;
396 // precalculate whatever possible
398 for (i=0 ; i<numtextures ; i++)
400 R_GenerateLookup (i);
401 if(!(i&31)) ST_Progress();
405 // translation table for global animation
407 texturetranslation = Z_Malloc ((numtextures+1)*4, PU_STATIC, 0);
408 for (i=0 ; i<numtextures ; i++)
409 texturetranslation[i] = i;
423 void R_InitFlats (void)
427 firstflat = W_GetNumForName ("F_START") + 1;
428 lastflat = W_GetNumForName ("F_END") - 1;
429 numflats = lastflat - firstflat + 1;
431 // translation table for global animation
432 flattranslation = Z_Malloc ((numflats+1)*4, PU_STATIC, 0);
433 for (i=0 ; i<numflats ; i++)
434 flattranslation[i] = i;
443 = Finds the width and hoffset of all sprites in the wad, so the sprite doesn't
444 = need to be cached just for the header during rendering
448 void R_InitSpriteLumps (void)
453 firstspritelump = W_GetNumForName ("S_START") + 1;
454 lastspritelump = W_GetNumForName ("S_END") - 1;
455 numspritelumps = lastspritelump - firstspritelump + 1;
456 spritewidth = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
457 spriteoffset = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
458 spritetopoffset = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
460 for (i=0 ; i< numspritelumps ; i++)
462 if (!(i&127)) ST_Progress();
463 patch = W_CacheLumpNum (firstspritelump+i, PU_CACHE);
464 spritewidth[i] = SHORT(patch->width)<<FRACBITS;
465 spriteoffset[i] = SHORT(patch->leftoffset)<<FRACBITS;
466 spritetopoffset[i] = SHORT(patch->topoffset)<<FRACBITS;
479 void R_InitColormaps (void)
483 // load in the light tables
484 // 256 byte align tables
486 lump = W_GetNumForName("COLORMAP");
487 length = W_LumpLength (lump) + 255;
488 colormaps = Z_Malloc (length, PU_STATIC, 0);
489 colormaps = (byte *)( ((int)colormaps + 255)&~0xff);
490 W_ReadLump (lump,colormaps);
499 = Locates all the lumps that will be used by all views
500 = Must be called after W_Init
504 void R_InitData (void)
512 //=============================================================================
522 int R_FlatNumForName (char *name)
527 i = W_CheckNumForName (name);
531 memcpy (namet, name,8);
532 I_Error ("R_FlatNumForName: %s not found",namet);
534 return i - firstflat;
541 = R_CheckTextureNumForName
546 int R_CheckTextureNumForName (char *name)
550 if (name[0] == '-') // no texture marker
554 //printf( "%s\n", name );
555 for (i=0 ; i<numtextures ; i++)
557 //printf( "%d %s\n", i, textures[i]->name );
558 if (!strncasecmp (textures[i]->name, name, 8) )
569 = R_TextureNumForName
574 int R_TextureNumForName (char *name)
579 i = R_CheckTextureNumForName (name);
583 printf("R_TextureNumForName: %s not found! Assuming shareware wad.\n",
587 I_Error ("R_TextureNumForName: %s not found",name);
600 = Preloads all relevent graphics for the level
604 int flatmemory, texturememory, spritememory;
606 void R_PrecacheLevel (void)
609 char *texturepresent;
622 flatpresent = (char*)malloc(numflats);
623 memset (flatpresent,0,numflats);
624 for (i=0 ; i<numsectors ; i++)
626 flatpresent[sectors[i].floorpic] = 1;
627 flatpresent[sectors[i].ceilingpic] = 1;
631 for (i=0 ; i<numflats ; i++)
634 lump = firstflat + i;
635 flatmemory += lumpinfo[lump].size;
636 W_CacheLumpNum(lump, PU_CACHE);
642 texturepresent = (char*) malloc(numtextures);
643 memset (texturepresent,0, numtextures);
645 for (i=0 ; i<numsides ; i++)
647 texturepresent[sides[i].toptexture] = 1;
648 texturepresent[sides[i].midtexture] = 1;
649 texturepresent[sides[i].bottomtexture] = 1;
652 texturepresent[Sky1Texture] = 1;
653 texturepresent[Sky2Texture] = 1;
656 for (i=0 ; i<numtextures ; i++)
658 if (!texturepresent[i])
660 texture = textures[i];
661 for (j=0 ; j<texture->patchcount ; j++)
663 lump = texture->patches[j].patch;
664 texturememory += lumpinfo[lump].size;
665 W_CacheLumpNum(lump , PU_CACHE);
672 spritepresent = (char*)malloc(numsprites);
673 memset (spritepresent,0, numsprites);
675 for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
677 if (th->function == P_MobjThinker)
678 spritepresent[((mobj_t *)th)->sprite] = 1;
682 for (i=0 ; i<numsprites ; i++)
684 if (!spritepresent[i])
686 for (j=0 ; j<sprites[i].numframes ; j++)
688 sf = &sprites[i].spriteframes[j];
689 for (k=0 ; k<8 ; k++)
691 lump = firstspritelump + sf->lump[k];
692 spritememory += lumpinfo[lump].size;
693 W_CacheLumpNum(lump , PU_CACHE);
698 free (texturepresent);
699 free (spritepresent);