diff options
Diffstat (limited to 'apps/plugins/doom/r_data.c')
-rw-r--r-- | apps/plugins/doom/r_data.c | 975 |
1 files changed, 975 insertions, 0 deletions
diff --git a/apps/plugins/doom/r_data.c b/apps/plugins/doom/r_data.c new file mode 100644 index 0000000000..aad16e4d95 --- /dev/null +++ b/apps/plugins/doom/r_data.c | |||
@@ -0,0 +1,975 @@ | |||
1 | /* Emacs style mode select -*- C++ -*- | ||
2 | *----------------------------------------------------------------------------- | ||
3 | * | ||
4 | * | ||
5 | * PrBoom a Doom port merged with LxDoom and LSDLDoom | ||
6 | * based on BOOM, a modified and improved DOOM engine | ||
7 | * Copyright (C) 1999 by | ||
8 | * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman | ||
9 | * Copyright (C) 1999-2000 by | ||
10 | * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
25 | * 02111-1307, USA. | ||
26 | * | ||
27 | * DESCRIPTION: | ||
28 | * Preparation of data for rendering, | ||
29 | * generation of lookups, caching, retrieval by name. | ||
30 | * | ||
31 | *-----------------------------------------------------------------------------*/ | ||
32 | |||
33 | #include "doomstat.h" | ||
34 | #include "w_wad.h" | ||
35 | #include "r_main.h" | ||
36 | #include "r_sky.h" | ||
37 | #include "i_system.h" | ||
38 | #include "m_swap.h" | ||
39 | #include "p_tick.h" | ||
40 | //#include "lprintf.h" // jff 08/03/98 - declaration of lprintf | ||
41 | #include "rockmacros.h" | ||
42 | // | ||
43 | // Graphics. | ||
44 | // DOOM graphics for walls and sprites | ||
45 | // is stored in vertical runs of opaque pixels (posts). | ||
46 | // A column is composed of zero or more posts, | ||
47 | // a patch or sprite is composed of zero or more columns. | ||
48 | // | ||
49 | |||
50 | // | ||
51 | // Texture definition. | ||
52 | // Each texture is composed of one or more patches, | ||
53 | // with patches being lumps stored in the WAD. | ||
54 | // The lumps are referenced by number, and patched | ||
55 | // into the rectangular texture space using origin | ||
56 | // and possibly other attributes. | ||
57 | // | ||
58 | |||
59 | typedef struct | ||
60 | { | ||
61 | short originx; | ||
62 | short originy; | ||
63 | short patch; | ||
64 | short stepdir; // unused in Doom but might be used in Phase 2 Boom | ||
65 | short colormap; // unused in Doom but might be used in Phase 2 Boom | ||
66 | } PACKEDATTR mappatch_t; | ||
67 | |||
68 | typedef struct | ||
69 | { | ||
70 | char name[8]; | ||
71 | boolean masked; | ||
72 | short width; | ||
73 | short height; | ||
74 | char pad[4]; // unused in Doom but might be used in Boom Phase 2 | ||
75 | short patchcount; | ||
76 | mappatch_t patches[1]; | ||
77 | } PACKEDATTR maptexture_t; | ||
78 | |||
79 | // A maptexturedef_t describes a rectangular texture, which is composed | ||
80 | // of one or more mappatch_t structures that arrange graphic patches. | ||
81 | |||
82 | // killough 4/17/98: make firstcolormaplump,lastcolormaplump external | ||
83 | int firstcolormaplump, lastcolormaplump; // killough 4/17/98 | ||
84 | |||
85 | int firstflat, lastflat, numflats; | ||
86 | int firstspritelump, lastspritelump, numspritelumps; | ||
87 | int numtextures; | ||
88 | static texture_t **textures; | ||
89 | fixed_t *textureheight; //needed for texture pegging (and TFE fix - killough) | ||
90 | int *flattranslation; // for global animation | ||
91 | int *texturetranslation; | ||
92 | // needed for pre-rendering | ||
93 | fixed_t *spritewidth, *spriteoffset, *spritetopoffset; | ||
94 | |||
95 | // | ||
96 | // MAPTEXTURE_T CACHING | ||
97 | // When a texture is first needed, | ||
98 | // it counts the number of composite columns | ||
99 | // required in the texture and allocates space | ||
100 | // for a column directory and any new columns. | ||
101 | // The directory will simply point inside other patches | ||
102 | // if there is only one patch in a given column, | ||
103 | // but any columns with multiple patches | ||
104 | // will have new column_ts generated. | ||
105 | // | ||
106 | |||
107 | // | ||
108 | // R_DrawColumnInCache | ||
109 | // Clip and draw a column | ||
110 | // from a patch into a cached post. | ||
111 | // | ||
112 | // Rewritten by Lee Killough for performance and to fix Medusa bug | ||
113 | // | ||
114 | |||
115 | void R_DrawColumnInCache(const column_t *patch, byte *cache, | ||
116 | int originy, int cacheheight, byte *marks) | ||
117 | { | ||
118 | while (patch->topdelta != 0xff) | ||
119 | { | ||
120 | int count = patch->length; | ||
121 | int position = originy + patch->topdelta; | ||
122 | |||
123 | if (position < 0) | ||
124 | { | ||
125 | count += position; | ||
126 | position = 0; | ||
127 | } | ||
128 | |||
129 | if (position + count > cacheheight) | ||
130 | count = cacheheight - position; | ||
131 | |||
132 | if (count > 0) | ||
133 | { | ||
134 | memcpy (cache + position, (byte *)patch + 3, count); | ||
135 | |||
136 | // killough 4/9/98: remember which cells in column have been drawn, | ||
137 | // so that column can later be converted into a series of posts, to | ||
138 | // fix the Medusa bug. | ||
139 | |||
140 | memset (marks + position, 0xff, count); | ||
141 | } | ||
142 | |||
143 | patch = (column_t *)((byte *) patch + patch->length + 4); | ||
144 | } | ||
145 | } | ||
146 | |||
147 | // | ||
148 | // R_GenerateComposite | ||
149 | // Using the texture definition, | ||
150 | // the composite texture is created from the patches, | ||
151 | // and each column is cached. | ||
152 | // | ||
153 | // Rewritten by Lee Killough for performance and to fix Medusa bug | ||
154 | |||
155 | void R_GenerateComposite(int texnum) | ||
156 | { | ||
157 | texture_t *texture = textures[texnum]; | ||
158 | byte *block = Z_Malloc(texture->compositesize, PU_STATIC, | ||
159 | (void **)&texture->composite); | ||
160 | // Composite the columns together. | ||
161 | texpatch_t *patch = texture->patches; | ||
162 | short *collump = texture->columnlump; | ||
163 | unsigned *colofs = texture->columnofs; // killough 4/9/98: make 32-bit | ||
164 | int i = texture->patchcount; | ||
165 | // killough 4/9/98: marks to identify transparent regions in merged textures | ||
166 | byte *marks = calloc(texture->width, texture->height), *source; | ||
167 | |||
168 | for (; --i >=0; patch++) | ||
169 | { | ||
170 | const patch_t *realpatch = W_CacheLumpNum(patch->patch); // cph | ||
171 | int x1 = patch->originx, x2 = x1 + SHORT(realpatch->width); | ||
172 | const int *cofs = realpatch->columnofs-x1; | ||
173 | if (x1<0) | ||
174 | x1 = 0; | ||
175 | if (x2 > texture->width) | ||
176 | x2 = texture->width; | ||
177 | for (; x1<x2 ; x1++) | ||
178 | if (collump[x1] == -1) // Column has multiple patches? | ||
179 | // killough 1/25/98, 4/9/98: Fix medusa bug. | ||
180 | R_DrawColumnInCache((column_t*)((byte*)realpatch+LONG(cofs[x1])), | ||
181 | block+colofs[x1],patch->originy,texture->height, | ||
182 | marks + x1 * texture->height); | ||
183 | |||
184 | W_UnlockLumpNum(patch->patch); // cph - unlock the patch lump | ||
185 | } | ||
186 | |||
187 | // killough 4/9/98: Next, convert multipatched columns into true columns, | ||
188 | // to fix Medusa bug while still allowing for transparent regions. | ||
189 | |||
190 | source = malloc(texture->height); // temporary column | ||
191 | for (i=0; i < texture->width; i++) | ||
192 | if (collump[i] == -1) // process only multipatched columns | ||
193 | { | ||
194 | column_t *col = (column_t *)(block + colofs[i] - 3); // cached column | ||
195 | const byte *mark = marks + i * texture->height; | ||
196 | int j = 0; | ||
197 | |||
198 | // save column in temporary so we can shuffle it around | ||
199 | memcpy(source, (byte *) col + 3, texture->height); | ||
200 | |||
201 | for (;;) // reconstruct the column by scanning transparency marks | ||
202 | { | ||
203 | while (j < texture->height && !mark[j]) // skip transparent cells | ||
204 | j++; | ||
205 | if (j >= texture->height) // if at end of column | ||
206 | { | ||
207 | col->topdelta = -1; // end-of-column marker | ||
208 | break; | ||
209 | } | ||
210 | col->topdelta = j; // starting offset of post | ||
211 | for (col->length=0; j < texture->height && mark[j]; j++) | ||
212 | col->length++; // count opaque cells | ||
213 | // copy opaque cells from the temporary back into the column | ||
214 | memcpy((byte *) col + 3, source + col->topdelta, col->length); | ||
215 | col = (column_t *)((byte *) col + col->length + 4); // next post | ||
216 | } | ||
217 | } | ||
218 | free(source); // free temporary column | ||
219 | free(marks); // free transparency marks | ||
220 | |||
221 | // Now that the texture has been built in column cache, | ||
222 | // it is purgable from zone memory. | ||
223 | |||
224 | Z_ChangeTag(block, PU_CACHE); | ||
225 | } | ||
226 | |||
227 | // | ||
228 | // R_GenerateLookup | ||
229 | // | ||
230 | // Rewritten by Lee Killough for performance and to fix Medusa bug | ||
231 | // | ||
232 | |||
233 | static void R_GenerateLookup(int texnum, int *const errors) | ||
234 | { | ||
235 | texture_t *texture = textures[texnum]; | ||
236 | |||
237 | // killough 4/9/98: make column offsets 32-bit; | ||
238 | // clean up malloc-ing to use sizeof | ||
239 | // CPhipps - moved allocing here | ||
240 | short *collump = texture->columnlump = | ||
241 | Z_Malloc(texture->width*sizeof(*texture->columnlump), PU_STATIC,0); | ||
242 | unsigned *colofs = texture->columnofs = | ||
243 | Z_Malloc(texture->width*sizeof(*texture->columnofs), PU_STATIC,0); | ||
244 | |||
245 | // killough 4/9/98: keep count of posts in addition to patches. | ||
246 | // Part of fix for medusa bug for multipatched 2s normals. | ||
247 | |||
248 | struct { | ||
249 | unsigned short patches, posts; | ||
250 | } *count = calloc(sizeof *count, texture->width); | ||
251 | |||
252 | { | ||
253 | int i = texture->patchcount; | ||
254 | const texpatch_t *patch = texture->patches; | ||
255 | |||
256 | while (--i >= 0) | ||
257 | { | ||
258 | int pat = patch->patch; | ||
259 | const patch_t *realpatch = W_CacheLumpNum(pat); | ||
260 | int x1 = patch++->originx, x2 = x1 + SHORT(realpatch->width), x = x1; | ||
261 | const int *cofs = realpatch->columnofs-x1; | ||
262 | |||
263 | if (x2 > texture->width) | ||
264 | x2 = texture->width; | ||
265 | if (x1 < 0) | ||
266 | x = 0; | ||
267 | for ( ; x<x2 ; x++) | ||
268 | { | ||
269 | // killough 4/9/98: keep a count of the number of posts in column, | ||
270 | // to fix Medusa bug while allowing for transparent multipatches. | ||
271 | |||
272 | const column_t *col = (column_t*)((byte*)realpatch+LONG(cofs[x])); | ||
273 | for (;col->topdelta != 0xff; count[x].posts++) | ||
274 | col = (column_t *)((byte *) col + col->length + 4); | ||
275 | count[x].patches++; | ||
276 | collump[x] = pat; | ||
277 | colofs[x] = LONG(cofs[x])+3; | ||
278 | } | ||
279 | |||
280 | W_UnlockLumpNum(pat); | ||
281 | } | ||
282 | } | ||
283 | |||
284 | // Composited texture not created yet. | ||
285 | texture->composite = NULL; | ||
286 | |||
287 | // Now count the number of columns | ||
288 | // that are covered by more than one patch. | ||
289 | // Fill in the lump / offset, so columns | ||
290 | // with only a single patch are all done. | ||
291 | |||
292 | { | ||
293 | int x = texture->width; | ||
294 | int height = texture->height; | ||
295 | int csize = 0; | ||
296 | |||
297 | while (--x >= 0) | ||
298 | { | ||
299 | if (!count[x].patches) // killough 4/9/98 | ||
300 | { | ||
301 | //jff 8/3/98 use logical output routine | ||
302 | printf("\nR_GenerateLookup: Column %d is without a patch in texture %s", | ||
303 | x, texture->name); | ||
304 | if (errors) ++*errors; | ||
305 | else I_Error("R_GenerateLookup: Failed"); | ||
306 | } | ||
307 | if (count[x].patches > 1) // killough 4/9/98 | ||
308 | { | ||
309 | // killough 1/25/98, 4/9/98: | ||
310 | // | ||
311 | // Fix Medusa bug, by adding room for column header | ||
312 | // and trailer bytes for each post in merged column. | ||
313 | // For now, just allocate conservatively 4 bytes | ||
314 | // per post per patch per column, since we don't | ||
315 | // yet know how many posts the merged column will | ||
316 | // require, and it's bounded above by this limit. | ||
317 | |||
318 | collump[x] = -1; // mark lump as multipatched | ||
319 | colofs[x] = csize + 3; // three header bytes in a column | ||
320 | csize += 4*count[x].posts+1; // 1 stop byte plus 4 bytes per post | ||
321 | } | ||
322 | csize += height; // height bytes of texture data | ||
323 | } | ||
324 | texture->compositesize = csize; | ||
325 | } | ||
326 | free(count); // killough 4/9/98 | ||
327 | } | ||
328 | |||
329 | // | ||
330 | // R_GetColumn | ||
331 | // | ||
332 | |||
333 | const byte *R_GetColumn(int tex, int col) | ||
334 | { | ||
335 | const texture_t *texture = textures[tex]; | ||
336 | if (!texture->columnlump) R_GenerateLookup(tex, NULL); | ||
337 | { | ||
338 | int lump = texture->columnlump[col &= texture->widthmask]; | ||
339 | int ofs = texture->columnofs[col]; // cph - WARNING: must be after the above line | ||
340 | // cph - remember the last lump, so we can unlock it if no longer needed, | ||
341 | // or reuse it if possible to reduce lump locking/unlocking | ||
342 | static int lastlump = -1; | ||
343 | static const byte* lastlumpdata; | ||
344 | |||
345 | if ((lump<=0) && (lastlump<=0)) | ||
346 | lump = lastlump; // cph - force equal | ||
347 | |||
348 | if (lump != lastlump) { | ||
349 | // cph - must change the cached lump | ||
350 | if (lastlump>0) | ||
351 | W_UnlockLumpNum(lastlump); | ||
352 | |||
353 | if ((lastlump = lump) > 0) | ||
354 | lastlumpdata = W_CacheLumpNum(lump); | ||
355 | #ifdef RANGECHECK | ||
356 | else | ||
357 | lastlumpdata = NULL; | ||
358 | #endif | ||
359 | } | ||
360 | |||
361 | if (lump > 0) | ||
362 | return lastlumpdata + ofs; | ||
363 | |||
364 | if (!texture->composite) | ||
365 | R_GenerateComposite(tex); | ||
366 | |||
367 | return texture->composite + ofs; | ||
368 | } | ||
369 | } | ||
370 | |||
371 | // | ||
372 | // R_InitTextures | ||
373 | // Initializes the texture list | ||
374 | // with the textures from the world map. | ||
375 | // | ||
376 | |||
377 | void R_InitTextures (void) | ||
378 | { | ||
379 | maptexture_t *mtexture; | ||
380 | texture_t *texture; | ||
381 | mappatch_t *mpatch; | ||
382 | texpatch_t *patch; | ||
383 | int i, j; | ||
384 | int maptex_lump[2] = {-1, -1}; | ||
385 | const int *maptex; | ||
386 | const int *maptex1, *maptex2; | ||
387 | char name[9]; | ||
388 | int names_lump; // cph - new wad lump handling | ||
389 | const char *names; // cph - | ||
390 | const char *name_p;// const*'s | ||
391 | int *patchlookup; | ||
392 | int totalwidth; | ||
393 | int nummappatches; | ||
394 | int offset; | ||
395 | int maxoff, maxoff2; | ||
396 | int numtextures1, numtextures2; | ||
397 | const int *directory; | ||
398 | int errors = 0; | ||
399 | |||
400 | // Load the patch names from pnames.lmp. | ||
401 | name[8] = 0; | ||
402 | names = W_CacheLumpNum(names_lump = W_GetNumForName("PNAMES")); | ||
403 | nummappatches = LONG(*((const int *)names)); | ||
404 | name_p = names+4; | ||
405 | patchlookup = malloc(nummappatches*sizeof(*patchlookup)); // killough | ||
406 | |||
407 | for (i=0 ; i<nummappatches ; i++) | ||
408 | { | ||
409 | strncpy (name,name_p+i*8, 8); | ||
410 | patchlookup[i] = W_CheckNumForName(name); | ||
411 | if (patchlookup[i] == -1) | ||
412 | { | ||
413 | // killough 4/17/98: | ||
414 | // Some wads use sprites as wall patches, so repeat check and | ||
415 | // look for sprites this time, but only if there were no wall | ||
416 | // patches found. This is the same as allowing for both, except | ||
417 | // that wall patches always win over sprites, even when they | ||
418 | // appear first in a wad. This is a kludgy solution to the wad | ||
419 | // lump namespace problem. | ||
420 | |||
421 | patchlookup[i] = (W_CheckNumForName)(name, ns_sprites); | ||
422 | |||
423 | if (patchlookup[i] == -1 && devparm) | ||
424 | //jff 8/3/98 use logical output routine | ||
425 | printf("\nWarning: patch %.8s, index %d does not exist",name,i); | ||
426 | } | ||
427 | } | ||
428 | W_UnlockLumpNum(names_lump); // cph - release the lump | ||
429 | |||
430 | // Load the map texture definitions from textures.lmp. | ||
431 | // The data is contained in one or two lumps, | ||
432 | // TEXTURE1 for shareware, plus TEXTURE2 for commercial. | ||
433 | |||
434 | maptex = maptex1 = W_CacheLumpNum(maptex_lump[0] = W_GetNumForName("TEXTURE1")); | ||
435 | numtextures1 = LONG(*maptex); | ||
436 | maxoff = W_LumpLength(maptex_lump[0]); | ||
437 | directory = maptex+1; | ||
438 | |||
439 | if (W_CheckNumForName("TEXTURE2") != -1) | ||
440 | { | ||
441 | maptex2 = W_CacheLumpNum(maptex_lump[1] = W_GetNumForName("TEXTURE2")); | ||
442 | numtextures2 = LONG(*maptex2); | ||
443 | maxoff2 = W_LumpLength(maptex_lump[1]); | ||
444 | } | ||
445 | else | ||
446 | { | ||
447 | maptex2 = NULL; | ||
448 | numtextures2 = 0; | ||
449 | maxoff2 = 0; | ||
450 | } | ||
451 | numtextures = numtextures1 + numtextures2; | ||
452 | |||
453 | // killough 4/9/98: make column offsets 32-bit; | ||
454 | // clean up malloc-ing to use sizeof | ||
455 | |||
456 | textures = Z_Malloc(numtextures*sizeof*textures, PU_STATIC, 0); | ||
457 | textureheight = Z_Malloc(numtextures*sizeof*textureheight, PU_STATIC, 0); | ||
458 | |||
459 | totalwidth = 0; | ||
460 | |||
461 | for (i=0 ; i<numtextures ; i++, directory++) | ||
462 | { | ||
463 | if (i == numtextures1) | ||
464 | { | ||
465 | // Start looking in second texture file. | ||
466 | maptex = maptex2; | ||
467 | maxoff = maxoff2; | ||
468 | directory = maptex+1; | ||
469 | } | ||
470 | |||
471 | offset = LONG(*directory); | ||
472 | |||
473 | if (offset > maxoff) | ||
474 | I_Error("R_InitTextures: Bad texture directory"); | ||
475 | |||
476 | mtexture = (maptexture_t *) ( (byte *)maptex + offset); | ||
477 | |||
478 | texture = textures[i] = | ||
479 | Z_Malloc(sizeof(texture_t) + | ||
480 | sizeof(texpatch_t)*(SHORT(mtexture->patchcount)-1), | ||
481 | PU_STATIC, 0); | ||
482 | |||
483 | texture->width = SHORT(mtexture->width); | ||
484 | texture->height = SHORT(mtexture->height); | ||
485 | texture->patchcount = SHORT(mtexture->patchcount); | ||
486 | |||
487 | /* Mattias Engdegård emailed me of the following explenation of | ||
488 | * why memcpy doesnt work on some systems: | ||
489 | * "I suppose it is the mad unaligned allocation | ||
490 | * going on (and which gcc in some way manages to cope with | ||
491 | * through the __attribute__ ((packed))), and which it forgets | ||
492 | * when optimizing memcpy (to a single word move) since it appears | ||
493 | * to be aligned. Technically a gcc bug, but I can't blame it when | ||
494 | * it's stressed with that amount of | ||
495 | * non-standard nonsense." | ||
496 | * So in short the unaligned struct confuses gcc's optimizer so | ||
497 | * i took the memcpy out alltogether to avoid future problems-Jess | ||
498 | */ | ||
499 | /* The above was #ifndef SPARC, but i got a mail from | ||
500 | * Putera Joseph F NPRI <PuteraJF@Npt.NUWC.Navy.Mil> containing: | ||
501 | * I had to use the memcpy function on a sparc machine. The | ||
502 | * other one would give me a core dump. | ||
503 | * cph - I find it hard to believe that sparc memcpy is broken, | ||
504 | * but I don't believe the pointers to memcpy have to be aligned | ||
505 | * either. Use fast memcpy on other machines anyway. | ||
506 | */ | ||
507 | /* | ||
508 | proff - I took this out, because Oli Kraus (olikraus@yahoo.com) told | ||
509 | me the memcpy produced a buserror. Since this function isn't time- | ||
510 | critical I'm using the for loop now. | ||
511 | */ | ||
512 | /* | ||
513 | #ifndef GCC | ||
514 | memcpy(texture->name, mtexture->name, sizeof(texture->name)); | ||
515 | #else | ||
516 | */ | ||
517 | { | ||
518 | unsigned int j; | ||
519 | for(j=0;j<sizeof(texture->name);j++) | ||
520 | texture->name[j]=mtexture->name[j]; | ||
521 | } | ||
522 | /* #endif */ | ||
523 | |||
524 | mpatch = mtexture->patches; | ||
525 | patch = texture->patches; | ||
526 | |||
527 | for (j=0 ; j<texture->patchcount ; j++, mpatch++, patch++) | ||
528 | { | ||
529 | patch->originx = SHORT(mpatch->originx); | ||
530 | patch->originy = SHORT(mpatch->originy); | ||
531 | patch->patch = patchlookup[SHORT(mpatch->patch)]; | ||
532 | if (patch->patch == -1) | ||
533 | { | ||
534 | //jff 8/3/98 use logical output routine | ||
535 | printf("\nR_InitTextures: Missing patch %d in texture %s", | ||
536 | SHORT(mpatch->patch), texture->name); // killough 4/17/98 | ||
537 | ++errors; | ||
538 | } | ||
539 | } | ||
540 | |||
541 | texture->columnofs = NULL; texture->columnlump = NULL; | ||
542 | |||
543 | for (j=1; j*2 <= texture->width; j<<=1) | ||
544 | ; | ||
545 | texture->widthmask = j-1; | ||
546 | textureheight[i] = texture->height<<FRACBITS; | ||
547 | |||
548 | totalwidth += texture->width; | ||
549 | } | ||
550 | |||
551 | free(patchlookup); // killough | ||
552 | |||
553 | for (i=0; i<2; i++) // cph - release the TEXTUREx lumps | ||
554 | if (maptex_lump[i] != -1) | ||
555 | W_UnlockLumpNum(maptex_lump[i]); | ||
556 | |||
557 | if (errors) | ||
558 | I_Error("R_InitTextures: %d errors", errors); | ||
559 | |||
560 | // Precalculate whatever possible. | ||
561 | if (devparm) // cph - If in development mode, generate now so all errors are found at once | ||
562 | for (i=0 ; i<numtextures ; i++) | ||
563 | R_GenerateLookup(i, &errors); | ||
564 | |||
565 | if (errors) | ||
566 | I_Error("R_InitTextures: %d errors", errors); | ||
567 | |||
568 | // Create translation table for global animation. | ||
569 | // killough 4/9/98: make column offsets 32-bit; | ||
570 | // clean up malloc-ing to use sizeof | ||
571 | |||
572 | texturetranslation = | ||
573 | Z_Malloc((numtextures+1)*sizeof*texturetranslation, PU_STATIC, 0); | ||
574 | |||
575 | for (i=0 ; i<numtextures ; i++) | ||
576 | texturetranslation[i] = i; | ||
577 | |||
578 | // killough 1/31/98: Initialize texture hash table | ||
579 | for (i = 0; i<numtextures; i++) | ||
580 | textures[i]->index = -1; | ||
581 | while (--i >= 0) | ||
582 | { | ||
583 | int j = W_LumpNameHash(textures[i]->name) % (unsigned) numtextures; | ||
584 | textures[i]->next = textures[j]->index; // Prepend to chain | ||
585 | textures[j]->index = i; | ||
586 | } | ||
587 | } | ||
588 | |||
589 | // | ||
590 | // R_InitFlats | ||
591 | // | ||
592 | void R_InitFlats(void) | ||
593 | { | ||
594 | int i; | ||
595 | |||
596 | firstflat = W_GetNumForName("F_START") + 1; | ||
597 | lastflat = W_GetNumForName("F_END") - 1; | ||
598 | numflats = lastflat - firstflat + 1; | ||
599 | |||
600 | // Create translation table for global animation. | ||
601 | // killough 4/9/98: make column offsets 32-bit; | ||
602 | // clean up malloc-ing to use sizeof | ||
603 | |||
604 | flattranslation = | ||
605 | Z_Malloc((numflats+1)*sizeof(*flattranslation), PU_STATIC, 0); | ||
606 | |||
607 | for (i=0 ; i<numflats ; i++) | ||
608 | flattranslation[i] = i; | ||
609 | } | ||
610 | |||
611 | // | ||
612 | // R_InitSpriteLumps | ||
613 | // Finds the width and hoffset of all sprites in the wad, | ||
614 | // so the sprite does not need to be cached completely | ||
615 | // just for having the header info ready during rendering. | ||
616 | // | ||
617 | void R_InitSpriteLumps(void) | ||
618 | { | ||
619 | int i; | ||
620 | const patch_t *patch; | ||
621 | |||
622 | firstspritelump = W_GetNumForName("S_START") + 1; | ||
623 | lastspritelump = W_GetNumForName("S_END") - 1; | ||
624 | numspritelumps = lastspritelump - firstspritelump + 1; | ||
625 | |||
626 | // killough 4/9/98: make columnd offsets 32-bit; | ||
627 | // clean up malloc-ing to use sizeof | ||
628 | |||
629 | spritewidth = Z_Malloc(numspritelumps*sizeof*spritewidth, PU_STATIC, 0); | ||
630 | spriteoffset = Z_Malloc(numspritelumps*sizeof*spriteoffset, PU_STATIC, 0); | ||
631 | spritetopoffset = | ||
632 | Z_Malloc(numspritelumps*sizeof*spritetopoffset, PU_STATIC, 0); | ||
633 | |||
634 | for (i=0 ; i< numspritelumps ; i++) | ||
635 | { | ||
636 | patch = W_CacheLumpNum(firstspritelump+i); | ||
637 | spritewidth[i] = SHORT(patch->width)<<FRACBITS; | ||
638 | spriteoffset[i] = SHORT(patch->leftoffset)<<FRACBITS; | ||
639 | spritetopoffset[i] = SHORT(patch->topoffset)<<FRACBITS; | ||
640 | W_UnlockLumpNum(firstspritelump+i); | ||
641 | } | ||
642 | } | ||
643 | |||
644 | // | ||
645 | // R_InitColormaps | ||
646 | // | ||
647 | // killough 3/20/98: rewritten to allow dynamic colormaps | ||
648 | // and to remove unnecessary 256-byte alignment | ||
649 | // | ||
650 | // killough 4/4/98: Add support for C_START/C_END markers | ||
651 | // | ||
652 | |||
653 | void R_InitColormaps(void) | ||
654 | { | ||
655 | int i; | ||
656 | firstcolormaplump = W_GetNumForName("C_START"); | ||
657 | lastcolormaplump = W_GetNumForName("C_END"); | ||
658 | numcolormaps = lastcolormaplump - firstcolormaplump; | ||
659 | colormaps = Z_Malloc(sizeof(*colormaps) * numcolormaps, PU_STATIC, 0); | ||
660 | colormaps[0] = (lighttable_t *)W_CacheLumpName("COLORMAP"); | ||
661 | for (i=1; i<numcolormaps; i++) | ||
662 | colormaps[i] = (lighttable_t *)W_CacheLumpNum(i+firstcolormaplump); | ||
663 | // cph - always lock | ||
664 | } | ||
665 | |||
666 | // killough 4/4/98: get colormap number from name | ||
667 | // killough 4/11/98: changed to return -1 for illegal names | ||
668 | // killough 4/17/98: changed to use ns_colormaps tag | ||
669 | |||
670 | int R_ColormapNumForName(const char *name) | ||
671 | { | ||
672 | register int i = 0; | ||
673 | if (strncasecmp(name,"COLORMAP",8)) // COLORMAP predefined to return 0 | ||
674 | if ((i = (W_CheckNumForName)(name, ns_colormaps)) != -1) | ||
675 | i -= firstcolormaplump; | ||
676 | return i; | ||
677 | } | ||
678 | |||
679 | // | ||
680 | // R_InitTranMap | ||
681 | // | ||
682 | // Initialize translucency filter map | ||
683 | // | ||
684 | // By Lee Killough 2/21/98 | ||
685 | // | ||
686 | |||
687 | struct _cache { | ||
688 | unsigned char pct; | ||
689 | unsigned char playpal[256]; | ||
690 | } cache; | ||
691 | |||
692 | int tran_filter_pct = 66; // filter percent | ||
693 | |||
694 | #define TSC 12 /* number of fixed point digits in filter percent */ | ||
695 | |||
696 | void R_InitTranMap(int progress) | ||
697 | { | ||
698 | int lump = W_CheckNumForName("TRANMAP"); | ||
699 | |||
700 | // If a tranlucency filter map lump is present, use it | ||
701 | if (lump != -1) // Set a pointer to the translucency filter maps. | ||
702 | main_tranmap = W_CacheLumpNum(lump); // killough 4/11/98 | ||
703 | else | ||
704 | { // Compose a default transparent filter map based on PLAYPAL. | ||
705 | const byte *playpal = W_CacheLumpName("PLAYPAL"); | ||
706 | byte *my_tranmap; | ||
707 | |||
708 | int cachefd = open(GAMEBASE"tranmap.dat",O_RDONLY); | ||
709 | |||
710 | main_tranmap = my_tranmap = Z_Malloc(256*256, PU_STATIC, 0); // killough 4/11/98 | ||
711 | |||
712 | // Use cached translucency filter if it's available | ||
713 | |||
714 | if ((cachefd<0) ? cachefd = open(GAMEBASE"tranmap.dat",O_WRONLY | O_CREAT) , 1 : | ||
715 | read(cachefd, &cache, sizeof(cache)) != sizeof(cache) || | ||
716 | cache.pct != tran_filter_pct || | ||
717 | memcmp(cache.playpal, playpal, sizeof cache.playpal) || | ||
718 | read(cachefd, my_tranmap, 256*256) != 256*256 ) // killough 4/11/98 | ||
719 | { | ||
720 | |||
721 | long *stackdeath=malloc(256*7*sizeof(long)); // This was a bunch of static varibles, way too big for rockbox | ||
722 | long *pal[3], *tot, *pal_w1[3]; | ||
723 | pal[0]=&stackdeath[0]; | ||
724 | pal[1]=&stackdeath[256]; | ||
725 | pal[2]=&stackdeath[256*2]; | ||
726 | tot=&stackdeath[256*3]; | ||
727 | pal_w1[0]=&stackdeath[256*4]; | ||
728 | pal_w1[1]=&stackdeath[256*5]; | ||
729 | pal_w1[2]=&stackdeath[256*6]; | ||
730 | long w1 = ((unsigned long) tran_filter_pct<<TSC)/100; | ||
731 | long w2 = (1l<<TSC)-w1; | ||
732 | |||
733 | if (progress) | ||
734 | printf("Please wait: Tranmap build"); | ||
735 | // First, convert playpal into long int type, and transpose array, | ||
736 | // for fast inner-loop calculations. Precompute tot array. | ||
737 | |||
738 | { | ||
739 | register int i = 255; | ||
740 | register const unsigned char *p = playpal+255*3; | ||
741 | do | ||
742 | { | ||
743 | register long t,d; | ||
744 | pal_w1[0][i] = (pal[0][i] = t = p[0]) * w1; | ||
745 | d = t*t; | ||
746 | pal_w1[1][i] = (pal[1][i] = t = p[1]) * w1; | ||
747 | d += t*t; | ||
748 | pal_w1[2][i] = (pal[2][i] = t = p[2]) * w1; | ||
749 | d += t*t; | ||
750 | p -= 3; | ||
751 | tot[i] = d << (TSC-1); | ||
752 | } while (--i>=0); | ||
753 | } | ||
754 | |||
755 | // Next, compute all entries using minimum arithmetic. | ||
756 | |||
757 | { | ||
758 | int i,j; | ||
759 | byte *tp = my_tranmap; | ||
760 | for (i=0;i<256;i++) | ||
761 | { | ||
762 | long r1 = pal[0][i] * w2; | ||
763 | long g1 = pal[1][i] * w2; | ||
764 | long b1 = pal[2][i] * w2; | ||
765 | if (!(i & 31) && progress) | ||
766 | //jff 8/3/98 use logical output routine | ||
767 | printf(" Computing: %d", 256/32-i/32); | ||
768 | for (j=0;j<256;j++,tp++) | ||
769 | { | ||
770 | register int color = 255; | ||
771 | register long err; | ||
772 | long r = pal_w1[0][j] + r1; | ||
773 | long g = pal_w1[1][j] + g1; | ||
774 | long b = pal_w1[2][j] + b1; | ||
775 | long best = LONG_MAX; | ||
776 | do | ||
777 | if ((err = tot[color] - pal[0][color]*r | ||
778 | - pal[1][color]*g - pal[2][color]*b) < best) | ||
779 | best = err, *tp = color; | ||
780 | while (--color >= 0); | ||
781 | } | ||
782 | } | ||
783 | } | ||
784 | |||
785 | free(stackdeath); // Free this beast | ||
786 | |||
787 | if (cachefd) // write out the cached translucency map | ||
788 | { | ||
789 | cache.pct = tran_filter_pct; | ||
790 | memcpy(cache.playpal, playpal, 256); | ||
791 | lseek(cachefd, 0, SEEK_SET); | ||
792 | write(cachefd, &cache, sizeof cache); | ||
793 | write(cachefd,main_tranmap, 256*256); | ||
794 | // CPhipps - leave close for a few lines... | ||
795 | } | ||
796 | |||
797 | } | ||
798 | |||
799 | if (cachefd) // killough 11/98: fix filehandle leak | ||
800 | close(cachefd); | ||
801 | |||
802 | W_UnlockLumpName("PLAYPAL"); | ||
803 | } | ||
804 | } | ||
805 | |||
806 | // | ||
807 | // R_InitData | ||
808 | // Locates all the lumps | ||
809 | // that will be used by all views | ||
810 | // Must be called after W_Init. | ||
811 | // | ||
812 | void R_InitData (void) | ||
813 | { | ||
814 | R_InitTextures (); | ||
815 | printf ("\nInitTextures"); | ||
816 | R_InitFlats (); | ||
817 | printf ("\nInitFlats"); | ||
818 | R_InitSpriteLumps (); | ||
819 | printf ("\nInitSprites"); | ||
820 | if (general_translucency) // killough 3/1/98 | ||
821 | R_InitTranMap(1); | ||
822 | R_InitColormaps (); | ||
823 | printf ("\nInitColormaps"); | ||
824 | } | ||
825 | |||
826 | // | ||
827 | // R_FlatNumForName | ||
828 | // Retrieval, get a flat number for a flat name. | ||
829 | // | ||
830 | // killough 4/17/98: changed to use ns_flats namespace | ||
831 | // | ||
832 | |||
833 | int R_FlatNumForName(const char *name) // killough -- const added | ||
834 | { | ||
835 | int i = (W_CheckNumForName)(name, ns_flats); | ||
836 | if (i == -1) | ||
837 | I_Error("R_FlatNumForName: %s not found", name); | ||
838 | return i - firstflat; | ||
839 | } | ||
840 | |||
841 | // | ||
842 | // R_CheckTextureNumForName | ||
843 | // Check whether texture is available. | ||
844 | // Filter out NoTexture indicator. | ||
845 | // | ||
846 | // Rewritten by Lee Killough to use hash table for fast lookup. Considerably | ||
847 | // reduces the time needed to start new levels. See w_wad.c for comments on | ||
848 | // the hashing algorithm, which is also used for lump searches. | ||
849 | // | ||
850 | // killough 1/21/98, 1/31/98 | ||
851 | // | ||
852 | |||
853 | int R_CheckTextureNumForName(const char *name) | ||
854 | { | ||
855 | int i = 0; | ||
856 | if (*name != '-') // "NoTexture" marker. | ||
857 | { | ||
858 | i = textures[W_LumpNameHash(name) % (unsigned) numtextures]->index; | ||
859 | while (i >= 0 && strncasecmp(textures[i]->name,name,8)) | ||
860 | i = textures[i]->next; | ||
861 | } | ||
862 | return i; | ||
863 | } | ||
864 | |||
865 | // | ||
866 | // R_TextureNumForName | ||
867 | // Calls R_CheckTextureNumForName, | ||
868 | // aborts with error message. | ||
869 | // | ||
870 | |||
871 | int R_TextureNumForName(const char *name) // const added -- killough | ||
872 | { | ||
873 | int i = R_CheckTextureNumForName(name); | ||
874 | if (i == -1) | ||
875 | I_Error("R_TextureNumForName: %s not found", name); | ||
876 | return i; | ||
877 | } | ||
878 | |||
879 | // | ||
880 | // R_PrecacheLevel | ||
881 | // Preloads all relevant graphics for the level. | ||
882 | // | ||
883 | // Totally rewritten by Lee Killough to use less memory, | ||
884 | // to avoid using alloca(), and to improve performance. | ||
885 | // cph - new wad lump handling, calls cache functions but acquires no locks | ||
886 | |||
887 | void R_PrecacheLevel(void) | ||
888 | { | ||
889 | register int i; | ||
890 | register byte *hitlist; | ||
891 | |||
892 | if (demoplayback) | ||
893 | return; | ||
894 | |||
895 | { | ||
896 | size_t size = numflats > numsprites ? numflats : numsprites; | ||
897 | hitlist = malloc((size_t)numtextures > size ? (unsigned)numtextures : size); | ||
898 | } | ||
899 | // Precache flats. | ||
900 | |||
901 | memset(hitlist, 0, numflats); | ||
902 | |||
903 | for (i = numsectors; --i >= 0; ) | ||
904 | hitlist[sectors[i].floorpic] = hitlist[sectors[i].ceilingpic] = 1; | ||
905 | |||
906 | for (i = numflats; --i >= 0; ) | ||
907 | if (hitlist[i]) | ||
908 | (W_CacheLumpNum)(firstflat + i, 0); | ||
909 | |||
910 | // Precache textures. | ||
911 | |||
912 | memset(hitlist, 0, numtextures); | ||
913 | |||
914 | for (i = numsides; --i >= 0;) | ||
915 | hitlist[sides[i].bottomtexture] = | ||
916 | hitlist[sides[i].toptexture] = | ||
917 | hitlist[sides[i].midtexture] = 1; | ||
918 | |||
919 | // Sky texture is always present. | ||
920 | // Note that F_SKY1 is the name used to | ||
921 | // indicate a sky floor/ceiling as a flat, | ||
922 | // while the sky texture is stored like | ||
923 | // a wall texture, with an episode dependend | ||
924 | // name. | ||
925 | |||
926 | hitlist[skytexture] = 1; | ||
927 | |||
928 | for (i = numtextures; --i >= 0; ) | ||
929 | if (hitlist[i]) | ||
930 | { | ||
931 | texture_t *texture = textures[i]; | ||
932 | int j = texture->patchcount; | ||
933 | while (--j >= 0) | ||
934 | (W_CacheLumpNum)(texture->patches[j].patch, 0); | ||
935 | } | ||
936 | |||
937 | // Precache sprites. | ||
938 | memset(hitlist, 0, numsprites); | ||
939 | |||
940 | { | ||
941 | thinker_t *th; | ||
942 | for (th = thinkercap.next ; th != &thinkercap ; th=th->next) | ||
943 | if (th->function == P_MobjThinker) | ||
944 | hitlist[((mobj_t *)th)->sprite] = 1; | ||
945 | } | ||
946 | |||
947 | for (i=numsprites; --i >= 0;) | ||
948 | if (hitlist[i]) | ||
949 | { | ||
950 | int j = sprites[i].numframes; | ||
951 | while (--j >= 0) | ||
952 | { | ||
953 | short *sflump = sprites[i].spriteframes[j].lump; | ||
954 | int k = 7; | ||
955 | do | ||
956 | (W_CacheLumpNum)(firstspritelump + sflump[k], 0); | ||
957 | while (--k >= 0); | ||
958 | } | ||
959 | } | ||
960 | free(hitlist); | ||
961 | } | ||
962 | |||
963 | // Proff - Added for OpenGL | ||
964 | void R_SetPatchNum(patchnum_t *patchnum, const char *name) | ||
965 | { | ||
966 | patch_t *patch; | ||
967 | |||
968 | patch = (patch_t *) W_CacheLumpName(name); | ||
969 | patchnum->width = patch->width; | ||
970 | patchnum->height = patch->height; | ||
971 | patchnum->leftoffset = patch->leftoffset; | ||
972 | patchnum->topoffset = patch->topoffset; | ||
973 | patchnum->lumpnum = W_GetNumForName(name); | ||
974 | W_UnlockLumpName(name); | ||
975 | } | ||