r_data.c (11909B)
1 #include <stdlib.h> 2 #include <alloca.h> 3 4 #include "m_swap.h" 5 #include "i_system.h" 6 #include "z_zone.h" 7 #include "w_wad.h" 8 #include "doomdef.h" 9 #include "r_local.h" 10 #include "p_local.h" 11 #include "doomstat.h" 12 #include "r_data.h" 13 14 typedef struct { 15 short originx; 16 short originy; 17 short patch; 18 short stepdir; 19 short colormap; 20 } mappatch_t; 21 22 typedef struct { 23 char name[8]; 24 boolean masked; 25 short width; 26 short height; 27 char columndirectory[4]; /* obsolete btw */ 28 short patchcount; 29 mappatch_t patches[1]; 30 } maptexture_t; 31 32 typedef struct { 33 int originx; 34 int originy; 35 int patch; 36 } texpatch_t; 37 38 typedef struct { 39 char name[8]; 40 short width; 41 short height; 42 short patchcount; 43 texpatch_t patches[1]; 44 } texture_t; 45 46 int firstflat; 47 int lastflat; 48 int numflats; 49 int firstpatch; 50 int lastpatch; 51 int numpatches; 52 int firstspritelump; 53 int lastspritelump; 54 int numspritelumps; 55 int numtextures; 56 int flatmemory; 57 int texturememory; 58 int spritememory; 59 texture_t** textures_g; 60 int* texturewidthmask_g; 61 fixed_t* textureheight_g; 62 int* texturecompositesize_g; 63 short** texturecolumnlump_g; 64 unsigned short** texturecolumnofs_g; 65 byte** texturecomposite_g; 66 int* flattranslation; 67 int* texturetranslation; 68 fixed_t* spritewidth; 69 fixed_t* spriteoffset; 70 fixed_t* spritetopoffset; 71 lighttable_t *colormaps; 72 73 void 74 R_DrawColumnInCache(column_t* patch, byte* cache, int originy, int cacheheight) 75 { 76 byte* source; 77 int count, position; 78 79 while (patch->topdelta != 0xff) { 80 source = (byte *)patch + 3; 81 count = patch->length; 82 position = originy + patch->topdelta; 83 if (position < 0) { 84 count += position; 85 position = 0; 86 } 87 if (position + count > cacheheight) 88 count = cacheheight - position; 89 if (count > 0) 90 memcpy (cache + position, source, count); 91 patch = (column_t *)( (byte *)patch + patch->length + 4); 92 } 93 } 94 95 void 96 R_GenerateComposite(int texnum) 97 { 98 byte* block; 99 texture_t* texture; 100 texpatch_t* patch; 101 patch_t* realpatch; 102 column_t* patchcol; 103 short* collump; 104 unsigned short* colofs; 105 int x, x1, x2, i; 106 107 texture = textures_g[texnum]; 108 block = Z_Malloc(texturecompositesize_g[texnum], PU_STATIC, &texturecomposite_g[texnum]); 109 collump = texturecolumnlump_g[texnum]; 110 colofs = texturecolumnofs_g[texnum]; 111 patch = texture->patches; 112 for (i = 0, patch = texture->patches; i < texture->patchcount; ++i, ++patch) { 113 realpatch = W_CacheLumpNum(patch->patch, PU_CACHE); 114 x1 = patch->originx; 115 x2 = x1 + realpatch->width; 116 if (x1 < 0) 117 x = 0; 118 else x = x1; 119 if (x2 > texture->width) 120 x2 = texture->width; 121 for (; x < x2; ++x) { 122 if (collump[x] >= 0) 123 continue; 124 patchcol = (column_t *)((byte *)realpatch + realpatch->columnofs[x-x1]); 125 R_DrawColumnInCache (patchcol, block + colofs[x], patch->originy, texture->height); 126 } 127 } 128 Z_ChangeTag(block, PU_CACHE); 129 } 130 131 void 132 R_GenerateLookup(int texnum) 133 { 134 texture_t* texture; 135 byte* patchcount; 136 texpatch_t* patch; 137 patch_t* realpatch; 138 short* collump; 139 unsigned short* colofs; 140 int x, x1, x2, i; 141 142 texture = textures_g[texnum]; 143 texturecomposite_g[texnum] = 0; 144 texturecompositesize_g[texnum] = 0; 145 collump = texturecolumnlump_g[texnum]; 146 colofs = texturecolumnofs_g[texnum]; 147 patchcount = (byte*)alloca(texture->width); 148 memset(patchcount, 0, texture->width); 149 patch = texture->patches; 150 for (i = 0, patch = texture->patches; i < texture->patchcount; ++i, ++patch) { 151 realpatch = W_CacheLumpNum (patch->patch, PU_CACHE); 152 x1 = patch->originx; 153 x2 = x1 + realpatch->width; 154 if (x1 < 0) 155 x = 0; 156 else x = x1; 157 if (x2 > texture->width) 158 x2 = texture->width; 159 for (; x < x2 ; ++x) { 160 ++patchcount[x]; 161 collump[x] = patch->patch; 162 colofs[x] = realpatch->columnofs[x-x1]+3; 163 } 164 } 165 for (x = 0; x < texture->width; ++x) { 166 if (!patchcount[x]) { 167 printf ("R_GenerateLookup: column without a patch (%s)\n", texture->name); 168 return; 169 } 170 if (patchcount[x] > 1) { 171 collump[x] = -1; 172 colofs[x] = texturecompositesize_g[texnum]; 173 if (texturecompositesize_g[texnum] > 0x10000-texture->height) 174 I_Error ("R_GenerateLookup: texture %i is >64k", texnum); 175 texturecompositesize_g[texnum] += texture->height; 176 } 177 } 178 } 179 180 byte* 181 R_GetColumn(int tex, int col) 182 { 183 int lump, ofs; 184 185 col &= texturewidthmask_g[tex]; 186 lump = texturecolumnlump_g[tex][col]; 187 ofs = texturecolumnofs_g[tex][col]; 188 if (lump > 0) 189 return (byte*)W_CacheLumpNum(lump,PU_CACHE)+ofs; 190 if (!texturecomposite_g[tex]) 191 R_GenerateComposite (tex); 192 return texturecomposite_g[tex] + ofs; 193 } 194 195 void 196 R_InitTextures() 197 { 198 maptexture_t* mtexture; 199 texture_t* texture; 200 mappatch_t* mpatch; 201 texpatch_t* patch; 202 int* maptex, *maptex1, *maptex2, *patchlookup, *directory; 203 char* names, *name_p; 204 char name[9]; 205 int i, j, totalwidth, num_mappatches, offset, maxoff, maxoff2, numtextures1, numtextures2, temp1, temp2, temp3; 206 207 name[8] = 0; 208 names = W_CacheLumpName("PNAMES", PU_STATIC); 209 num_mappatches = *((int*)names); 210 name_p = names+4; 211 patchlookup = alloca(num_mappatches*sizeof(*patchlookup)); 212 for (i = 0; i < num_mappatches; ++i) { 213 strncpy(name, name_p+i*8, 8); 214 patchlookup[i] = W_CheckNumForName(name); 215 } 216 Z_Free(names); 217 maptex = maptex1 = W_CacheLumpName("TEXTURE1", PU_STATIC); 218 numtextures1 = *maptex; 219 maxoff = W_LumpLength(W_GetNumForName ("TEXTURE1")); 220 directory = maptex+1; 221 if (W_CheckNumForName("TEXTURE2") == -1) { 222 maptex2 = NULL; 223 numtextures2 = 0; 224 maxoff2 = 0; 225 } else { 226 maptex2 = W_CacheLumpName("TEXTURE2", PU_STATIC); 227 numtextures2 = *maptex2; 228 maxoff2 = W_LumpLength(W_GetNumForName ("TEXTURE2")); 229 } 230 numtextures = numtextures1 + numtextures2; 231 textures_g = Z_Malloc(numtextures * sizeof(void*), PU_STATIC, 0); 232 texturecolumnlump_g = Z_Malloc(numtextures * sizeof(void*), PU_STATIC, 0); 233 texturecolumnofs_g = Z_Malloc(numtextures * sizeof(void*), PU_STATIC, 0); 234 texturecomposite_g = Z_Malloc(numtextures * sizeof(void*), PU_STATIC, 0); 235 texturecompositesize_g = Z_Malloc(numtextures * sizeof(void*), PU_STATIC, 0); 236 texturewidthmask_g = Z_Malloc(numtextures * sizeof(void*), PU_STATIC, 0); 237 textureheight_g = Z_Malloc(numtextures * sizeof(void*), PU_STATIC, 0); 238 totalwidth = 0; 239 temp1 = W_GetNumForName ("S_START"); 240 temp2 = W_GetNumForName ("S_END") - 1; 241 temp3 = ((temp2-temp1+63)/64) + ((numtextures+63)/64); 242 printf("["); 243 for (i = 0; i < temp3; ++i) 244 printf(" "); 245 printf(" ]"); 246 for (i = 0; i < temp3; ++i) 247 printf("\x8"); 248 printf("\x8\x8\x8\x8\x8\x8\x8\x8\x8\x8"); 249 for (i = 0; i < numtextures; ++i, ++directory) { 250 if (!(i & 63)) 251 printf("."); 252 if (i == numtextures1) { 253 maptex = maptex2; 254 maxoff = maxoff2; 255 directory = maptex+1; 256 } 257 offset = *directory; 258 if (offset > maxoff) 259 I_Error("R_InitTextures: bad texture directory"); 260 mtexture = (maptexture_t*)((byte*)maptex + offset); 261 texture = textures_g[i] = Z_Malloc(sizeof(texture_t) + sizeof(texpatch_t)*(mtexture->patchcount-1), PU_STATIC, 0); 262 texture->width = mtexture->width; 263 texture->height = mtexture->height; 264 texture->patchcount = mtexture->patchcount; 265 memcpy(texture->name, mtexture->name, sizeof(texture->name)); 266 mpatch = &mtexture->patches[0]; 267 patch = &texture->patches[0]; 268 for (j = 0; j < texture->patchcount; ++j, ++mpatch, ++patch) { 269 patch->originx = mpatch->originx; 270 patch->originy = mpatch->originy; 271 patch->patch = patchlookup[mpatch->patch]; 272 if (patch->patch == -1) 273 I_Error("R_InitTextures: Missing patch in texture %s", texture->name); 274 } 275 texturecolumnlump_g[i] = Z_Malloc(texture->width * 2, PU_STATIC,0); 276 texturecolumnofs_g[i] = Z_Malloc(texture->width * 2, PU_STATIC,0); 277 for (j = 1; j * 2 <= texture->width; j <<= 1); 278 texturewidthmask_g[i] = j-1; 279 textureheight_g[i] = texture->height<<FRACBITS; 280 totalwidth += texture->width; 281 } 282 Z_Free(maptex1); 283 if (maptex2) 284 Z_Free(maptex2); 285 for (i = 0; i < numtextures; ++i) 286 R_GenerateLookup(i); 287 texturetranslation = Z_Malloc((numtextures+1) * 4, PU_STATIC, 0); 288 for (i = 0; i < numtextures; ++i) 289 texturetranslation[i] = i; 290 } 291 292 void 293 R_InitFlats() 294 { 295 int i; 296 297 firstflat = W_GetNumForName ("F_START") + 1; 298 lastflat = W_GetNumForName ("F_END") - 1; 299 numflats = lastflat - firstflat + 1; 300 flattranslation = Z_Malloc((numflats+1) * 4, PU_STATIC, 0); 301 for (i = 0; i < numflats; ++i) 302 flattranslation[i] = i; 303 } 304 305 void 306 R_InitSpriteLumps() 307 { 308 patch_t* patch; 309 int i; 310 311 firstspritelump = W_GetNumForName("S_START") + 1; 312 lastspritelump = W_GetNumForName("S_END") - 1; 313 numspritelumps = lastspritelump - firstspritelump + 1; 314 spritewidth = Z_Malloc(numspritelumps * sizeof(*spritewidth), PU_STATIC, 0); 315 spriteoffset = Z_Malloc(numspritelumps * sizeof(*spriteoffset), PU_STATIC, 0); 316 spritetopoffset = Z_Malloc(numspritelumps * sizeof(*spritetopoffset), PU_STATIC, 0); 317 for (i = 0; i < numspritelumps; ++i) { 318 if (!(i & 63)) 319 printf ("."); 320 patch = W_CacheLumpNum(firstspritelump+i, PU_CACHE); 321 spritewidth[i] = patch->width<<FRACBITS; 322 spriteoffset[i] = patch->leftoffset<<FRACBITS; 323 spritetopoffset[i] = patch->topoffset<<FRACBITS; 324 } 325 } 326 327 void 328 R_InitColormaps() 329 { 330 int lump, length; 331 332 lump = W_GetNumForName("COLORMAP"); 333 length = W_LumpLength (lump) + 255; 334 colormaps = Z_Malloc (length, PU_STATIC, 0); 335 colormaps = (byte*)(((long)colormaps + 255)&~0xff); 336 W_ReadLump(lump, colormaps); 337 } 338 339 void 340 R_InitData() 341 { 342 R_InitTextures(); 343 printf("\nInitTextures"); 344 R_InitFlats(); 345 printf("\nInitFlats"); 346 R_InitSpriteLumps(); 347 printf("\nInitSprites"); 348 R_InitColormaps(); 349 printf("\nInitColormaps"); 350 } 351 352 int 353 R_FlatNumForName(char* name) 354 { 355 char namet[9]; 356 int i; 357 358 i = W_CheckNumForName(name); 359 if (i == -1) { 360 namet[8] = 0; 361 memcpy(namet, name,8); 362 I_Error("R_FlatNumForName: %s not found", namet); 363 } 364 return i - firstflat; 365 } 366 367 int 368 R_CheckTextureNumForName(char *name) 369 { 370 int i; 371 372 if (name[0] == '-') 373 return 0; 374 for (i = 0; i < numtextures; ++i) 375 if (!strncasecmp(textures_g[i]->name, name, 8)) 376 return i; 377 return -1; 378 } 379 380 int 381 R_TextureNumForName(char* name) 382 { 383 int i; 384 385 i = R_CheckTextureNumForName(name); 386 if (i == -1) 387 I_Error("R_TextureNumForName: %s not found", name); 388 return i; 389 } 390 391 void 392 R_PrecacheLevel() 393 { 394 texture_t* texture; 395 thinker_t* th; 396 spriteframe_t* sf; 397 char* flatpresent, *texturepresent, *spritepresent; 398 int i, j, k, lump; 399 400 if (demoplayback) 401 return; 402 flatpresent = alloca(numflats); 403 memset(flatpresent,0,numflats); 404 for (i = 0; i < numsectors; ++i) { 405 flatpresent[sectors[i].floorpic] = 1; 406 flatpresent[sectors[i].ceilingpic] = 1; 407 } 408 flatmemory = 0; 409 for (i = 0; i < numflats; ++i) { 410 if (flatpresent[i]) { 411 lump = firstflat + i; 412 flatmemory += lumpinfo_g[lump].size; 413 W_CacheLumpNum(lump, PU_CACHE); 414 } 415 } 416 texturepresent = alloca(numtextures); 417 memset (texturepresent,0, numtextures); 418 for (i = 0; i < numsides; ++i) { 419 texturepresent[sides[i].toptexture] = 1; 420 texturepresent[sides[i].midtexture] = 1; 421 texturepresent[sides[i].bottomtexture] = 1; 422 } 423 texturepresent[skytexture] = 1; 424 texturememory = 0; 425 for (i = 0; i < numtextures; ++i) { 426 if (!texturepresent[i]) 427 continue; 428 texture = textures_g[i]; 429 for (j = 0; j < texture->patchcount; ++j) { 430 lump = texture->patches[j].patch; 431 texturememory += lumpinfo_g[lump].size; 432 W_CacheLumpNum(lump , PU_CACHE); 433 } 434 } 435 spritepresent = alloca(numsprites); 436 memset (spritepresent,0, numsprites); 437 for (th = thinkercap.next ; th != &thinkercap ; th=th->next) 438 if (th->function.acp1 == (actionf_p1)P_MobjThinker) 439 spritepresent[((mobj_t *)th)->sprite] = 1; 440 spritememory = 0; 441 for (i = 0; i < numsprites; ++i) { 442 if (!spritepresent[i]) 443 continue; 444 for (j = 0; j < sprites[i].numframes; ++j) { 445 sf = &sprites[i].spriteframes[j]; 446 for (k = 0; k < 8; ++k) { 447 lump = firstspritelump + sf->lump[k]; 448 spritememory += lumpinfo_g[lump].size; 449 W_CacheLumpNum(lump , PU_CACHE); 450 } 451 } 452 } 453 }