diff options
Diffstat (limited to 'src/p_setup.c')
-rw-r--r-- | src/p_setup.c | 1688 |
1 files changed, 1688 insertions, 0 deletions
diff --git a/src/p_setup.c b/src/p_setup.c new file mode 100644 index 0000000..5247cb9 --- /dev/null +++ b/src/p_setup.c | |||
@@ -0,0 +1,1688 @@ | |||
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 | * Copyright 2005, 2006 by | ||
12 | * Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License | ||
16 | * as published by the Free Software Foundation; either version 2 | ||
17 | * of the License, or (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
27 | * 02111-1307, USA. | ||
28 | * | ||
29 | * DESCRIPTION: | ||
30 | * Do all the WAD I/O, get map description, | ||
31 | * set up initial state and misc. LUTs. | ||
32 | * | ||
33 | *-----------------------------------------------------------------------------*/ | ||
34 | |||
35 | #include <math.h> | ||
36 | |||
37 | #include "doomstat.h" | ||
38 | #include "m_bbox.h" | ||
39 | #include "m_argv.h" | ||
40 | #include "g_game.h" | ||
41 | #include "w_wad.h" | ||
42 | #include "r_main.h" | ||
43 | #include "r_things.h" | ||
44 | #include "p_maputl.h" | ||
45 | #include "p_map.h" | ||
46 | #include "p_setup.h" | ||
47 | #include "p_spec.h" | ||
48 | #include "p_tick.h" | ||
49 | #include "p_enemy.h" | ||
50 | #include "s_sound.h" | ||
51 | #include "lprintf.h" //jff 10/6/98 for debug outputs | ||
52 | #include "v_video.h" | ||
53 | #include "r_demo.h" | ||
54 | #include "r_fps.h" | ||
55 | |||
56 | // | ||
57 | // MAP related Lookup tables. | ||
58 | // Store VERTEXES, LINEDEFS, SIDEDEFS, etc. | ||
59 | // | ||
60 | |||
61 | int numvertexes; | ||
62 | vertex_t *vertexes; | ||
63 | |||
64 | int numsegs; | ||
65 | seg_t *segs; | ||
66 | |||
67 | int numsectors; | ||
68 | sector_t *sectors; | ||
69 | |||
70 | int numsubsectors; | ||
71 | subsector_t *subsectors; | ||
72 | |||
73 | int numnodes; | ||
74 | node_t *nodes; | ||
75 | |||
76 | int numlines; | ||
77 | line_t *lines; | ||
78 | |||
79 | int numsides; | ||
80 | side_t *sides; | ||
81 | |||
82 | |||
83 | //////////////////////////////////////////////////////////////////////////////////////////// | ||
84 | // figgi 08/21/00 -- constants and globals for glBsp support | ||
85 | #define gNd2 0x32644E67 // figgi -- suppport for new GL_VERT format v2.0 | ||
86 | #define gNd3 0x33644E67 | ||
87 | #define gNd4 0x34644E67 | ||
88 | #define gNd5 0x35644E67 | ||
89 | #define ZNOD 0x444F4E5A | ||
90 | #define ZGLN 0x4E4C475A | ||
91 | #define GL_VERT_OFFSET 4 | ||
92 | |||
93 | int firstglvertex = 0; | ||
94 | int nodesVersion = 0; | ||
95 | boolean forceOldBsp = false; | ||
96 | |||
97 | // figgi 08/21/00 -- glSegs | ||
98 | typedef struct | ||
99 | { | ||
100 | unsigned short v1; // start vertex (16 bit) | ||
101 | unsigned short v2; // end vertex (16 bit) | ||
102 | unsigned short linedef; // linedef, or -1 for minisegs | ||
103 | short side; // side on linedef: 0 for right, 1 for left | ||
104 | unsigned short partner; // corresponding partner seg, or -1 on one-sided walls | ||
105 | } glseg_t; | ||
106 | |||
107 | // fixed 32 bit gl_vert format v2.0+ (glBsp 1.91) | ||
108 | typedef struct | ||
109 | { | ||
110 | fixed_t x,y; | ||
111 | } mapglvertex_t; | ||
112 | |||
113 | enum | ||
114 | { | ||
115 | ML_GL_LABEL=0, // A separator name, GL_ExMx or GL_MAPxx | ||
116 | ML_GL_VERTS, // Extra Vertices | ||
117 | ML_GL_SEGS, // Segs, from linedefs & minisegs | ||
118 | ML_GL_SSECT, // SubSectors, list of segs | ||
119 | ML_GL_NODES // GL BSP nodes | ||
120 | }; | ||
121 | //////////////////////////////////////////////////////////////////////////////////////////// | ||
122 | |||
123 | |||
124 | // BLOCKMAP | ||
125 | // Created from axis aligned bounding box | ||
126 | // of the map, a rectangular array of | ||
127 | // blocks of size ... | ||
128 | // Used to speed up collision detection | ||
129 | // by spatial subdivision in 2D. | ||
130 | // | ||
131 | // Blockmap size. | ||
132 | |||
133 | int bmapwidth, bmapheight; // size in mapblocks | ||
134 | |||
135 | // killough 3/1/98: remove blockmap limit internally: | ||
136 | long *blockmap; // was short -- killough | ||
137 | |||
138 | // offsets in blockmap are from here | ||
139 | long *blockmaplump; // was short -- killough | ||
140 | |||
141 | fixed_t bmaporgx, bmaporgy; // origin of block map | ||
142 | |||
143 | mobj_t **blocklinks; // for thing chains | ||
144 | |||
145 | // | ||
146 | // REJECT | ||
147 | // For fast sight rejection. | ||
148 | // Speeds up enemy AI by skipping detailed | ||
149 | // LineOf Sight calculation. | ||
150 | // Without the special effect, this could | ||
151 | // be used as a PVS lookup as well. | ||
152 | // | ||
153 | |||
154 | static int rejectlump = -1;// cph - store reject lump num if cached | ||
155 | const byte *rejectmatrix; // cph - const* | ||
156 | |||
157 | // Maintain single and multi player starting spots. | ||
158 | |||
159 | // 1/11/98 killough: Remove limit on deathmatch starts | ||
160 | mapthing_t *deathmatchstarts; // killough | ||
161 | size_t num_deathmatchstarts; // killough | ||
162 | |||
163 | mapthing_t *deathmatch_p; | ||
164 | mapthing_t playerstarts[MAXPLAYERS]; | ||
165 | |||
166 | // | ||
167 | // P_CheckForZDoomNodes | ||
168 | // | ||
169 | |||
170 | static boolean P_CheckForZDoomNodes(int lumpnum, int gl_lumpnum) | ||
171 | { | ||
172 | const void *data; | ||
173 | |||
174 | data = W_CacheLumpNum(lumpnum + ML_NODES); | ||
175 | if (*(const int *)data == ZNOD) | ||
176 | I_Error("P_CheckForZDoomNodes: ZDoom nodes not supported yet"); | ||
177 | |||
178 | data = W_CacheLumpNum(lumpnum + ML_SSECTORS); | ||
179 | if (*(const int *)data == ZGLN) | ||
180 | I_Error("P_CheckForZDoomNodes: ZDoom GL nodes not supported yet"); | ||
181 | |||
182 | return false; | ||
183 | } | ||
184 | |||
185 | // | ||
186 | // P_GetNodesVersion | ||
187 | // | ||
188 | |||
189 | static void P_GetNodesVersion(int lumpnum, int gl_lumpnum) | ||
190 | { | ||
191 | const void *data; | ||
192 | |||
193 | data = W_CacheLumpNum(gl_lumpnum+ML_GL_VERTS); | ||
194 | if ( (gl_lumpnum > lumpnum) && (forceOldBsp == false) && (compatibility_level >= prboom_2_compatibility) ) { | ||
195 | if (*(const int *)data == gNd2) { | ||
196 | data = W_CacheLumpNum(gl_lumpnum+ML_GL_SEGS); | ||
197 | if (*(const int *)data == gNd3) { | ||
198 | nodesVersion = gNd3; | ||
199 | lprintf(LO_DEBUG, "P_GetNodesVersion: found version 3 nodes\n"); | ||
200 | I_Error("P_GetNodesVersion: version 3 nodes not supported\n"); | ||
201 | } else { | ||
202 | nodesVersion = gNd2; | ||
203 | lprintf(LO_DEBUG, "P_GetNodesVersion: found version 2 nodes\n"); | ||
204 | } | ||
205 | } | ||
206 | if (*(const int *)data == gNd4) { | ||
207 | nodesVersion = gNd4; | ||
208 | lprintf(LO_DEBUG, "P_GetNodesVersion: found version 4 nodes\n"); | ||
209 | I_Error("P_GetNodesVersion: version 4 nodes not supported\n"); | ||
210 | } | ||
211 | if (*(const int *)data == gNd5) { | ||
212 | nodesVersion = gNd5; | ||
213 | lprintf(LO_DEBUG, "P_GetNodesVersion: found version 5 nodes\n"); | ||
214 | I_Error("P_GetNodesVersion: version 5 nodes not supported\n"); | ||
215 | } | ||
216 | } else { | ||
217 | nodesVersion = 0; | ||
218 | lprintf(LO_DEBUG,"P_GetNodesVersion: using normal BSP nodes\n"); | ||
219 | if (P_CheckForZDoomNodes(lumpnum, gl_lumpnum)) | ||
220 | I_Error("P_GetNodesVersion: ZDoom nodes not supported yet"); | ||
221 | } | ||
222 | } | ||
223 | |||
224 | // | ||
225 | // P_LoadVertexes | ||
226 | // | ||
227 | // killough 5/3/98: reformatted, cleaned up | ||
228 | // | ||
229 | static void P_LoadVertexes (int lump) | ||
230 | { | ||
231 | const mapvertex_t *data; // cph - const | ||
232 | int i; | ||
233 | |||
234 | // Determine number of lumps: | ||
235 | // total lump length / vertex record length. | ||
236 | numvertexes = W_LumpLength(lump) / sizeof(mapvertex_t); | ||
237 | |||
238 | // Allocate zone memory for buffer. | ||
239 | vertexes = Z_Malloc(numvertexes*sizeof(vertex_t),PU_LEVEL,0); | ||
240 | |||
241 | // Load data into cache. | ||
242 | // cph 2006/07/29 - cast to mapvertex_t here, making the loop below much neater | ||
243 | data = (const mapvertex_t *)W_CacheLumpNum(lump); | ||
244 | |||
245 | // Copy and convert vertex coordinates, | ||
246 | // internal representation as fixed. | ||
247 | for (i=0; i<numvertexes; i++) | ||
248 | { | ||
249 | vertexes[i].x = SHORT(data[i].x)<<FRACBITS; | ||
250 | vertexes[i].y = SHORT(data[i].y)<<FRACBITS; | ||
251 | } | ||
252 | |||
253 | // Free buffer memory. | ||
254 | W_UnlockLumpNum(lump); | ||
255 | } | ||
256 | |||
257 | /******************************************* | ||
258 | * Name : P_LoadVertexes2 * | ||
259 | * modified : 09/18/00, adapted for PrBoom * | ||
260 | * author : figgi * | ||
261 | * what : support for gl nodes * | ||
262 | *******************************************/ | ||
263 | |||
264 | // figgi -- FIXME: Automap showes wrong zoom boundaries when starting game | ||
265 | // when P_LoadVertexes2 is used with classic BSP nodes. | ||
266 | |||
267 | static void P_LoadVertexes2(int lump, int gllump) | ||
268 | { | ||
269 | const byte *gldata; | ||
270 | int i; | ||
271 | const mapvertex_t* ml; | ||
272 | |||
273 | firstglvertex = W_LumpLength(lump) / sizeof(mapvertex_t); | ||
274 | numvertexes = W_LumpLength(lump) / sizeof(mapvertex_t); | ||
275 | |||
276 | if (gllump >= 0) // check for glVertices | ||
277 | { | ||
278 | gldata = W_CacheLumpNum(gllump); | ||
279 | |||
280 | if (nodesVersion == gNd2) // 32 bit GL_VERT format (16.16 fixed) | ||
281 | { | ||
282 | const mapglvertex_t* mgl; | ||
283 | |||
284 | numvertexes += (W_LumpLength(gllump) - GL_VERT_OFFSET)/sizeof(mapglvertex_t); | ||
285 | vertexes = Z_Malloc (numvertexes*sizeof(vertex_t),PU_LEVEL,0); | ||
286 | mgl = (const mapglvertex_t *) (gldata + GL_VERT_OFFSET); | ||
287 | |||
288 | for (i = firstglvertex; i < numvertexes; i++) | ||
289 | { | ||
290 | vertexes[i].x = mgl->x; | ||
291 | vertexes[i].y = mgl->y; | ||
292 | mgl++; | ||
293 | } | ||
294 | } | ||
295 | else | ||
296 | { | ||
297 | numvertexes += W_LumpLength(gllump)/sizeof(mapvertex_t); | ||
298 | vertexes = Z_Malloc (numvertexes*sizeof(vertex_t),PU_LEVEL,0); | ||
299 | ml = (const mapvertex_t *)gldata; | ||
300 | |||
301 | for (i = firstglvertex; i < numvertexes; i++) | ||
302 | { | ||
303 | vertexes[i].x = SHORT(ml->x)<<FRACBITS; | ||
304 | vertexes[i].y = SHORT(ml->y)<<FRACBITS; | ||
305 | ml++; | ||
306 | } | ||
307 | } | ||
308 | W_UnlockLumpNum(gllump); | ||
309 | } | ||
310 | |||
311 | ml = (const mapvertex_t*) W_CacheLumpNum(lump); | ||
312 | |||
313 | for (i=0; i < firstglvertex; i++) | ||
314 | { | ||
315 | vertexes[i].x = SHORT(ml->x)<<FRACBITS; | ||
316 | vertexes[i].y = SHORT(ml->y)<<FRACBITS; | ||
317 | ml++; | ||
318 | } | ||
319 | W_UnlockLumpNum(lump); | ||
320 | } | ||
321 | |||
322 | |||
323 | /******************************************* | ||
324 | * created : 08/13/00 * | ||
325 | * modified : 09/18/00, adapted for PrBoom * | ||
326 | * author : figgi * | ||
327 | * what : basic functions needed for * | ||
328 | * computing gl nodes * | ||
329 | *******************************************/ | ||
330 | |||
331 | static int checkGLVertex(int num) | ||
332 | { | ||
333 | if (num & 0x8000) | ||
334 | num = (num&0x7FFF)+firstglvertex; | ||
335 | return num; | ||
336 | } | ||
337 | |||
338 | |||
339 | static float GetDistance(int dx, int dy) | ||
340 | { | ||
341 | float fx = (float)(dx)/FRACUNIT, fy = (float)(dy)/FRACUNIT; | ||
342 | return (float)sqrt(fx*fx + fy*fy); | ||
343 | } | ||
344 | |||
345 | |||
346 | static int GetOffset(vertex_t *v1, vertex_t *v2) | ||
347 | { | ||
348 | float a, b; | ||
349 | int r; | ||
350 | a = (float)(v1->x - v2->x) / (float)FRACUNIT; | ||
351 | b = (float)(v1->y - v2->y) / (float)FRACUNIT; | ||
352 | r = (int)(sqrt(a*a+b*b) * (float)FRACUNIT); | ||
353 | return r; | ||
354 | } | ||
355 | |||
356 | |||
357 | |||
358 | // | ||
359 | // P_LoadSegs | ||
360 | // | ||
361 | // killough 5/3/98: reformatted, cleaned up | ||
362 | |||
363 | static void P_LoadSegs (int lump) | ||
364 | { | ||
365 | int i; | ||
366 | const mapseg_t *data; // cph - const | ||
367 | |||
368 | numsegs = W_LumpLength(lump) / sizeof(mapseg_t); | ||
369 | segs = Z_Calloc(numsegs,sizeof(seg_t),PU_LEVEL,0); | ||
370 | data = (const mapseg_t *)W_CacheLumpNum(lump); // cph - wad lump handling updated | ||
371 | |||
372 | if ((!data) || (!numsegs)) | ||
373 | I_Error("P_LoadSegs: no segs in level"); | ||
374 | |||
375 | for (i=0; i<numsegs; i++) | ||
376 | { | ||
377 | seg_t *li = segs+i; | ||
378 | const mapseg_t *ml = data + i; | ||
379 | unsigned short v1, v2; | ||
380 | |||
381 | int side, linedef; | ||
382 | line_t *ldef; | ||
383 | |||
384 | li->iSegID = i; // proff 11/05/2000: needed for OpenGL | ||
385 | |||
386 | v1 = (unsigned short)SHORT(ml->v1); | ||
387 | v2 = (unsigned short)SHORT(ml->v2); | ||
388 | li->v1 = &vertexes[v1]; | ||
389 | li->v2 = &vertexes[v2]; | ||
390 | |||
391 | li->miniseg = false; // figgi -- there are no minisegs in classic BSP nodes | ||
392 | li->length = GetDistance(li->v2->x - li->v1->x, li->v2->y - li->v1->y); | ||
393 | li->angle = (SHORT(ml->angle))<<16; | ||
394 | li->offset =(SHORT(ml->offset))<<16; | ||
395 | linedef = (unsigned short)SHORT(ml->linedef); | ||
396 | ldef = &lines[linedef]; | ||
397 | li->linedef = ldef; | ||
398 | side = SHORT(ml->side); | ||
399 | li->sidedef = &sides[ldef->sidenum[side]]; | ||
400 | |||
401 | /* cph 2006/09/30 - our frontsector can be the second side of the | ||
402 | * linedef, so must check for NO_INDEX in case we are incorrectly | ||
403 | * referencing the back of a 1S line */ | ||
404 | if (ldef->sidenum[side] != NO_INDEX) | ||
405 | li->frontsector = sides[ldef->sidenum[side]].sector; | ||
406 | else { | ||
407 | li->frontsector = 0; | ||
408 | lprintf(LO_WARN, "P_LoadSegs: front of seg %i has no sidedef\n", i); | ||
409 | } | ||
410 | |||
411 | if (ldef->flags & ML_TWOSIDED && ldef->sidenum[side^1]!=NO_INDEX) | ||
412 | li->backsector = sides[ldef->sidenum[side^1]].sector; | ||
413 | else | ||
414 | li->backsector = 0; | ||
415 | } | ||
416 | |||
417 | W_UnlockLumpNum(lump); // cph - release the data | ||
418 | } | ||
419 | |||
420 | |||
421 | |||
422 | /******************************************* | ||
423 | * Name : P_LoadGLSegs * | ||
424 | * created : 08/13/00 * | ||
425 | * modified : 09/18/00, adapted for PrBoom * | ||
426 | * author : figgi * | ||
427 | * what : support for gl nodes * | ||
428 | *******************************************/ | ||
429 | static void P_LoadGLSegs(int lump) | ||
430 | { | ||
431 | int i; | ||
432 | const glseg_t *ml; | ||
433 | line_t *ldef; | ||
434 | |||
435 | numsegs = W_LumpLength(lump) / sizeof(glseg_t); | ||
436 | segs = Z_Malloc(numsegs * sizeof(seg_t), PU_LEVEL, 0); | ||
437 | memset(segs, 0, numsegs * sizeof(seg_t)); | ||
438 | ml = (const glseg_t*)W_CacheLumpNum(lump); | ||
439 | |||
440 | if ((!ml) || (!numsegs)) | ||
441 | I_Error("P_LoadGLSegs: no glsegs in level"); | ||
442 | |||
443 | for(i = 0; i < numsegs; i++) | ||
444 | { // check for gl-vertices | ||
445 | segs[i].v1 = &vertexes[checkGLVertex(SHORT(ml->v1))]; | ||
446 | segs[i].v2 = &vertexes[checkGLVertex(SHORT(ml->v2))]; | ||
447 | segs[i].iSegID = i; | ||
448 | |||
449 | if(ml->linedef != (unsigned short)-1) // skip minisegs | ||
450 | { | ||
451 | ldef = &lines[ml->linedef]; | ||
452 | segs[i].linedef = ldef; | ||
453 | segs[i].miniseg = false; | ||
454 | segs[i].angle = R_PointToAngle2(segs[i].v1->x,segs[i].v1->y,segs[i].v2->x,segs[i].v2->y); | ||
455 | |||
456 | segs[i].sidedef = &sides[ldef->sidenum[ml->side]]; | ||
457 | segs[i].length = GetDistance(segs[i].v2->x - segs[i].v1->x, segs[i].v2->y - segs[i].v1->y); | ||
458 | segs[i].frontsector = sides[ldef->sidenum[ml->side]].sector; | ||
459 | if (ldef->flags & ML_TWOSIDED) | ||
460 | segs[i].backsector = sides[ldef->sidenum[ml->side^1]].sector; | ||
461 | else | ||
462 | segs[i].backsector = 0; | ||
463 | |||
464 | if (ml->side) | ||
465 | segs[i].offset = GetOffset(segs[i].v1, ldef->v2); | ||
466 | else | ||
467 | segs[i].offset = GetOffset(segs[i].v1, ldef->v1); | ||
468 | } | ||
469 | else | ||
470 | { | ||
471 | segs[i].miniseg = true; | ||
472 | segs[i].angle = 0; | ||
473 | segs[i].offset = 0; | ||
474 | segs[i].length = 0; | ||
475 | segs[i].linedef = NULL; | ||
476 | segs[i].sidedef = NULL; | ||
477 | segs[i].frontsector = NULL; | ||
478 | segs[i].backsector = NULL; | ||
479 | } | ||
480 | ml++; | ||
481 | } | ||
482 | W_UnlockLumpNum(lump); | ||
483 | } | ||
484 | |||
485 | // | ||
486 | // P_LoadSubsectors | ||
487 | // | ||
488 | // killough 5/3/98: reformatted, cleaned up | ||
489 | |||
490 | static void P_LoadSubsectors (int lump) | ||
491 | { | ||
492 | /* cph 2006/07/29 - make data a const mapsubsector_t *, so the loop below is simpler & gives no constness warnings */ | ||
493 | const mapsubsector_t *data; | ||
494 | int i; | ||
495 | |||
496 | numsubsectors = W_LumpLength (lump) / sizeof(mapsubsector_t); | ||
497 | subsectors = Z_Calloc(numsubsectors,sizeof(subsector_t),PU_LEVEL,0); | ||
498 | data = (const mapsubsector_t *)W_CacheLumpNum(lump); | ||
499 | |||
500 | if ((!data) || (!numsubsectors)) | ||
501 | I_Error("P_LoadSubsectors: no subsectors in level"); | ||
502 | |||
503 | for (i=0; i<numsubsectors; i++) | ||
504 | { | ||
505 | subsectors[i].numlines = (unsigned short)SHORT(data[i].numsegs ); | ||
506 | subsectors[i].firstline = (unsigned short)SHORT(data[i].firstseg); | ||
507 | } | ||
508 | |||
509 | W_UnlockLumpNum(lump); // cph - release the data | ||
510 | } | ||
511 | |||
512 | // | ||
513 | // P_LoadSectors | ||
514 | // | ||
515 | // killough 5/3/98: reformatted, cleaned up | ||
516 | |||
517 | static void P_LoadSectors (int lump) | ||
518 | { | ||
519 | const byte *data; // cph - const* | ||
520 | int i; | ||
521 | |||
522 | numsectors = W_LumpLength (lump) / sizeof(mapsector_t); | ||
523 | sectors = Z_Calloc (numsectors,sizeof(sector_t),PU_LEVEL,0); | ||
524 | data = W_CacheLumpNum (lump); // cph - wad lump handling updated | ||
525 | |||
526 | for (i=0; i<numsectors; i++) | ||
527 | { | ||
528 | sector_t *ss = sectors + i; | ||
529 | const mapsector_t *ms = (const mapsector_t *) data + i; | ||
530 | |||
531 | ss->iSectorID=i; // proff 04/05/2000: needed for OpenGL | ||
532 | ss->floorheight = SHORT(ms->floorheight)<<FRACBITS; | ||
533 | ss->ceilingheight = SHORT(ms->ceilingheight)<<FRACBITS; | ||
534 | ss->floorpic = R_FlatNumForName(ms->floorpic); | ||
535 | ss->ceilingpic = R_FlatNumForName(ms->ceilingpic); | ||
536 | ss->lightlevel = SHORT(ms->lightlevel); | ||
537 | ss->special = SHORT(ms->special); | ||
538 | ss->oldspecial = SHORT(ms->special); | ||
539 | ss->tag = SHORT(ms->tag); | ||
540 | ss->thinglist = NULL; | ||
541 | ss->touching_thinglist = NULL; // phares 3/14/98 | ||
542 | |||
543 | ss->nextsec = -1; //jff 2/26/98 add fields to support locking out | ||
544 | ss->prevsec = -1; // stair retriggering until build completes | ||
545 | |||
546 | // killough 3/7/98: | ||
547 | ss->floor_xoffs = 0; | ||
548 | ss->floor_yoffs = 0; // floor and ceiling flats offsets | ||
549 | ss->ceiling_xoffs = 0; | ||
550 | ss->ceiling_yoffs = 0; | ||
551 | ss->heightsec = -1; // sector used to get floor and ceiling height | ||
552 | ss->floorlightsec = -1; // sector used to get floor lighting | ||
553 | // killough 3/7/98: end changes | ||
554 | |||
555 | // killough 4/11/98 sector used to get ceiling lighting: | ||
556 | ss->ceilinglightsec = -1; | ||
557 | |||
558 | // killough 4/4/98: colormaps: | ||
559 | ss->bottommap = ss->midmap = ss->topmap = 0; | ||
560 | |||
561 | // killough 10/98: sky textures coming from sidedefs: | ||
562 | ss->sky = 0; | ||
563 | } | ||
564 | |||
565 | W_UnlockLumpNum(lump); // cph - release the data | ||
566 | } | ||
567 | |||
568 | |||
569 | // | ||
570 | // P_LoadNodes | ||
571 | // | ||
572 | // killough 5/3/98: reformatted, cleaned up | ||
573 | |||
574 | static void P_LoadNodes (int lump) | ||
575 | { | ||
576 | const byte *data; // cph - const* | ||
577 | int i; | ||
578 | |||
579 | numnodes = W_LumpLength (lump) / sizeof(mapnode_t); | ||
580 | nodes = Z_Malloc (numnodes*sizeof(node_t),PU_LEVEL,0); | ||
581 | data = W_CacheLumpNum (lump); // cph - wad lump handling updated | ||
582 | |||
583 | if ((!data) || (!numnodes)) | ||
584 | { | ||
585 | // allow trivial maps | ||
586 | if (numsubsectors == 1) | ||
587 | lprintf(LO_INFO, | ||
588 | "P_LoadNodes: trivial map (no nodes, one subsector)\n"); | ||
589 | else | ||
590 | I_Error("P_LoadNodes: no nodes in level"); | ||
591 | } | ||
592 | |||
593 | for (i=0; i<numnodes; i++) | ||
594 | { | ||
595 | node_t *no = nodes + i; | ||
596 | const mapnode_t *mn = (const mapnode_t *) data + i; | ||
597 | int j; | ||
598 | |||
599 | no->x = SHORT(mn->x)<<FRACBITS; | ||
600 | no->y = SHORT(mn->y)<<FRACBITS; | ||
601 | no->dx = SHORT(mn->dx)<<FRACBITS; | ||
602 | no->dy = SHORT(mn->dy)<<FRACBITS; | ||
603 | |||
604 | for (j=0 ; j<2 ; j++) | ||
605 | { | ||
606 | int k; | ||
607 | no->children[j] = SHORT(mn->children[j]); | ||
608 | for (k=0 ; k<4 ; k++) | ||
609 | no->bbox[j][k] = SHORT(mn->bbox[j][k])<<FRACBITS; | ||
610 | } | ||
611 | } | ||
612 | |||
613 | W_UnlockLumpNum(lump); // cph - release the data | ||
614 | } | ||
615 | |||
616 | |||
617 | /* | ||
618 | * P_LoadThings | ||
619 | * | ||
620 | * killough 5/3/98: reformatted, cleaned up | ||
621 | * cph 2001/07/07 - don't write into the lump cache, especially non-idepotent | ||
622 | * changes like byte order reversals. Take a copy to edit. | ||
623 | */ | ||
624 | |||
625 | static void P_LoadThings (int lump) | ||
626 | { | ||
627 | int i, numthings = W_LumpLength (lump) / sizeof(mapthing_t); | ||
628 | const mapthing_t *data = W_CacheLumpNum (lump); | ||
629 | |||
630 | if ((!data) || (!numthings)) | ||
631 | I_Error("P_LoadThings: no things in level"); | ||
632 | |||
633 | for (i=0; i<numthings; i++) | ||
634 | { | ||
635 | mapthing_t mt = data[i]; | ||
636 | |||
637 | mt.x = SHORT(mt.x); | ||
638 | mt.y = SHORT(mt.y); | ||
639 | mt.angle = SHORT(mt.angle); | ||
640 | mt.type = SHORT(mt.type); | ||
641 | mt.options = SHORT(mt.options); | ||
642 | |||
643 | if (!P_IsDoomnumAllowed(mt.type)) | ||
644 | continue; | ||
645 | |||
646 | // Do spawn all other stuff. | ||
647 | P_SpawnMapThing(&mt); | ||
648 | } | ||
649 | |||
650 | W_UnlockLumpNum(lump); // cph - release the data | ||
651 | } | ||
652 | |||
653 | // | ||
654 | // P_LoadLineDefs | ||
655 | // Also counts secret lines for intermissions. | ||
656 | // ^^^ | ||
657 | // ??? killough ??? | ||
658 | // Does this mean secrets used to be linedef-based, rather than sector-based? | ||
659 | // | ||
660 | // killough 4/4/98: split into two functions, to allow sidedef overloading | ||
661 | // | ||
662 | // killough 5/3/98: reformatted, cleaned up | ||
663 | |||
664 | static void P_LoadLineDefs (int lump) | ||
665 | { | ||
666 | const byte *data; // cph - const* | ||
667 | int i; | ||
668 | |||
669 | numlines = W_LumpLength (lump) / sizeof(maplinedef_t); | ||
670 | lines = Z_Calloc (numlines,sizeof(line_t),PU_LEVEL,0); | ||
671 | data = W_CacheLumpNum (lump); // cph - wad lump handling updated | ||
672 | |||
673 | for (i=0; i<numlines; i++) | ||
674 | { | ||
675 | const maplinedef_t *mld = (const maplinedef_t *) data + i; | ||
676 | line_t *ld = lines+i; | ||
677 | vertex_t *v1, *v2; | ||
678 | |||
679 | ld->flags = (unsigned short)SHORT(mld->flags); | ||
680 | ld->special = SHORT(mld->special); | ||
681 | ld->tag = SHORT(mld->tag); | ||
682 | v1 = ld->v1 = &vertexes[(unsigned short)SHORT(mld->v1)]; | ||
683 | v2 = ld->v2 = &vertexes[(unsigned short)SHORT(mld->v2)]; | ||
684 | ld->dx = v2->x - v1->x; | ||
685 | ld->dy = v2->y - v1->y; | ||
686 | |||
687 | ld->tranlump = -1; // killough 4/11/98: no translucency by default | ||
688 | |||
689 | ld->slopetype = !ld->dx ? ST_VERTICAL : !ld->dy ? ST_HORIZONTAL : | ||
690 | FixedDiv(ld->dy, ld->dx) > 0 ? ST_POSITIVE : ST_NEGATIVE; | ||
691 | |||
692 | if (v1->x < v2->x) | ||
693 | { | ||
694 | ld->bbox[BOXLEFT] = v1->x; | ||
695 | ld->bbox[BOXRIGHT] = v2->x; | ||
696 | } | ||
697 | else | ||
698 | { | ||
699 | ld->bbox[BOXLEFT] = v2->x; | ||
700 | ld->bbox[BOXRIGHT] = v1->x; | ||
701 | } | ||
702 | if (v1->y < v2->y) | ||
703 | { | ||
704 | ld->bbox[BOXBOTTOM] = v1->y; | ||
705 | ld->bbox[BOXTOP] = v2->y; | ||
706 | } | ||
707 | else | ||
708 | { | ||
709 | ld->bbox[BOXBOTTOM] = v2->y; | ||
710 | ld->bbox[BOXTOP] = v1->y; | ||
711 | } | ||
712 | |||
713 | /* calculate sound origin of line to be its midpoint */ | ||
714 | //e6y: fix sound origin for large levels | ||
715 | // no need for comp_sound test, these are only used when comp_sound = 0 | ||
716 | ld->soundorg.x = ld->bbox[BOXLEFT] / 2 + ld->bbox[BOXRIGHT] / 2; | ||
717 | ld->soundorg.y = ld->bbox[BOXTOP] / 2 + ld->bbox[BOXBOTTOM] / 2; | ||
718 | |||
719 | ld->iLineID=i; // proff 04/05/2000: needed for OpenGL | ||
720 | ld->sidenum[0] = SHORT(mld->sidenum[0]); | ||
721 | ld->sidenum[1] = SHORT(mld->sidenum[1]); | ||
722 | |||
723 | { | ||
724 | /* cph 2006/09/30 - fix sidedef errors right away. | ||
725 | * cph 2002/07/20 - these errors are fatal if not fixed, so apply them | ||
726 | * in compatibility mode - a desync is better than a crash! */ | ||
727 | int j; | ||
728 | |||
729 | for (j=0; j < 2; j++) | ||
730 | { | ||
731 | if (ld->sidenum[j] != NO_INDEX && ld->sidenum[j] >= numsides) { | ||
732 | ld->sidenum[j] = NO_INDEX; | ||
733 | lprintf(LO_WARN, "P_LoadLineDefs: linedef %d has out-of-range sidedef number\n",numlines-i-1); | ||
734 | } | ||
735 | } | ||
736 | |||
737 | // killough 11/98: fix common wad errors (missing sidedefs): | ||
738 | |||
739 | if (ld->sidenum[0] == NO_INDEX) { | ||
740 | ld->sidenum[0] = 0; // Substitute dummy sidedef for missing right side | ||
741 | // cph - print a warning about the bug | ||
742 | lprintf(LO_WARN, "P_LoadLineDefs: linedef %d missing first sidedef\n",numlines-i-1); | ||
743 | } | ||
744 | |||
745 | if ((ld->sidenum[1] == NO_INDEX) && (ld->flags & ML_TWOSIDED)) { | ||
746 | ld->flags &= ~ML_TWOSIDED; // Clear 2s flag for missing left side | ||
747 | // cph - print a warning about the bug | ||
748 | lprintf(LO_WARN, "P_LoadLineDefs: linedef %d has two-sided flag set, but no second sidedef\n",numlines-i-1); | ||
749 | } | ||
750 | } | ||
751 | |||
752 | // killough 4/4/98: support special sidedef interpretation below | ||
753 | if (ld->sidenum[0] != NO_INDEX && ld->special) | ||
754 | sides[*ld->sidenum].special = ld->special; | ||
755 | } | ||
756 | |||
757 | W_UnlockLumpNum(lump); // cph - release the lump | ||
758 | } | ||
759 | |||
760 | // killough 4/4/98: delay using sidedefs until they are loaded | ||
761 | // killough 5/3/98: reformatted, cleaned up | ||
762 | |||
763 | static void P_LoadLineDefs2(int lump) | ||
764 | { | ||
765 | int i = numlines; | ||
766 | register line_t *ld = lines; | ||
767 | for (;i--;ld++) | ||
768 | { | ||
769 | ld->frontsector = sides[ld->sidenum[0]].sector; //e6y: Can't be NO_INDEX here | ||
770 | ld->backsector = ld->sidenum[1]!=NO_INDEX ? sides[ld->sidenum[1]].sector : 0; | ||
771 | switch (ld->special) | ||
772 | { // killough 4/11/98: handle special types | ||
773 | int lump, j; | ||
774 | |||
775 | case 260: // killough 4/11/98: translucent 2s textures | ||
776 | lump = sides[*ld->sidenum].special; // translucency from sidedef | ||
777 | if (!ld->tag) // if tag==0, | ||
778 | ld->tranlump = lump; // affect this linedef only | ||
779 | else | ||
780 | for (j=0;j<numlines;j++) // if tag!=0, | ||
781 | if (lines[j].tag == ld->tag) // affect all matching linedefs | ||
782 | lines[j].tranlump = lump; | ||
783 | break; | ||
784 | } | ||
785 | } | ||
786 | } | ||
787 | |||
788 | // | ||
789 | // P_LoadSideDefs | ||
790 | // | ||
791 | // killough 4/4/98: split into two functions | ||
792 | |||
793 | static void P_LoadSideDefs (int lump) | ||
794 | { | ||
795 | numsides = W_LumpLength(lump) / sizeof(mapsidedef_t); | ||
796 | sides = Z_Calloc(numsides,sizeof(side_t),PU_LEVEL,0); | ||
797 | } | ||
798 | |||
799 | // killough 4/4/98: delay using texture names until | ||
800 | // after linedefs are loaded, to allow overloading. | ||
801 | // killough 5/3/98: reformatted, cleaned up | ||
802 | |||
803 | static void P_LoadSideDefs2(int lump) | ||
804 | { | ||
805 | const byte *data = W_CacheLumpNum(lump); // cph - const*, wad lump handling updated | ||
806 | int i; | ||
807 | |||
808 | for (i=0; i<numsides; i++) | ||
809 | { | ||
810 | register const mapsidedef_t *msd = (const mapsidedef_t *) data + i; | ||
811 | register side_t *sd = sides + i; | ||
812 | register sector_t *sec; | ||
813 | |||
814 | sd->textureoffset = SHORT(msd->textureoffset)<<FRACBITS; | ||
815 | sd->rowoffset = SHORT(msd->rowoffset)<<FRACBITS; | ||
816 | |||
817 | { /* cph 2006/09/30 - catch out-of-range sector numbers; use sector 0 instead */ | ||
818 | unsigned short sector_num = SHORT(msd->sector); | ||
819 | if (sector_num >= numsectors) { | ||
820 | lprintf(LO_WARN,"P_LoadSideDefs2: sidedef %i has out-of-range sector num %u\n", i, sector_num); | ||
821 | sector_num = 0; | ||
822 | } | ||
823 | sd->sector = sec = §ors[sector_num]; | ||
824 | } | ||
825 | |||
826 | // killough 4/4/98: allow sidedef texture names to be overloaded | ||
827 | // killough 4/11/98: refined to allow colormaps to work as wall | ||
828 | // textures if invalid as colormaps but valid as textures. | ||
829 | switch (sd->special) | ||
830 | { | ||
831 | case 242: // variable colormap via 242 linedef | ||
832 | sd->bottomtexture = | ||
833 | (sec->bottommap = R_ColormapNumForName(msd->bottomtexture)) < 0 ? | ||
834 | sec->bottommap = 0, R_TextureNumForName(msd->bottomtexture): 0 ; | ||
835 | sd->midtexture = | ||
836 | (sec->midmap = R_ColormapNumForName(msd->midtexture)) < 0 ? | ||
837 | sec->midmap = 0, R_TextureNumForName(msd->midtexture) : 0 ; | ||
838 | sd->toptexture = | ||
839 | (sec->topmap = R_ColormapNumForName(msd->toptexture)) < 0 ? | ||
840 | sec->topmap = 0, R_TextureNumForName(msd->toptexture) : 0 ; | ||
841 | break; | ||
842 | |||
843 | case 260: // killough 4/11/98: apply translucency to 2s normal texture | ||
844 | sd->midtexture = strncasecmp("TRANMAP", msd->midtexture, 8) ? | ||
845 | (sd->special = W_CheckNumForName(msd->midtexture)) < 0 || | ||
846 | W_LumpLength(sd->special) != 65536 ? | ||
847 | sd->special=0, R_TextureNumForName(msd->midtexture) : | ||
848 | (sd->special++, 0) : (sd->special=0); | ||
849 | sd->toptexture = R_TextureNumForName(msd->toptexture); | ||
850 | sd->bottomtexture = R_TextureNumForName(msd->bottomtexture); | ||
851 | break; | ||
852 | |||
853 | default: // normal cases | ||
854 | sd->midtexture = R_SafeTextureNumForName(msd->midtexture, i); | ||
855 | sd->toptexture = R_SafeTextureNumForName(msd->toptexture, i); | ||
856 | sd->bottomtexture = R_SafeTextureNumForName(msd->bottomtexture, i); | ||
857 | break; | ||
858 | } | ||
859 | } | ||
860 | |||
861 | W_UnlockLumpNum(lump); // cph - release the lump | ||
862 | } | ||
863 | |||
864 | // | ||
865 | // jff 10/6/98 | ||
866 | // New code added to speed up calculation of internal blockmap | ||
867 | // Algorithm is order of nlines*(ncols+nrows) not nlines*ncols*nrows | ||
868 | // | ||
869 | |||
870 | #define blkshift 7 /* places to shift rel position for cell num */ | ||
871 | #define blkmask ((1<<blkshift)-1)/* mask for rel position within cell */ | ||
872 | #define blkmargin 0 /* size guardband around map used */ | ||
873 | // jff 10/8/98 use guardband>0 | ||
874 | // jff 10/12/98 0 ok with + 1 in rows,cols | ||
875 | |||
876 | typedef struct linelist_t // type used to list lines in each block | ||
877 | { | ||
878 | long num; | ||
879 | struct linelist_t *next; | ||
880 | } linelist_t; | ||
881 | |||
882 | // | ||
883 | // Subroutine to add a line number to a block list | ||
884 | // It simply returns if the line is already in the block | ||
885 | // | ||
886 | |||
887 | static void AddBlockLine | ||
888 | ( | ||
889 | linelist_t **lists, | ||
890 | int *count, | ||
891 | int *done, | ||
892 | int blockno, | ||
893 | long lineno | ||
894 | ) | ||
895 | { | ||
896 | linelist_t *l; | ||
897 | |||
898 | if (done[blockno]) | ||
899 | return; | ||
900 | |||
901 | l = malloc(sizeof(linelist_t)); | ||
902 | l->num = lineno; | ||
903 | l->next = lists[blockno]; | ||
904 | lists[blockno] = l; | ||
905 | count[blockno]++; | ||
906 | done[blockno] = 1; | ||
907 | } | ||
908 | |||
909 | // | ||
910 | // Actually construct the blockmap lump from the level data | ||
911 | // | ||
912 | // This finds the intersection of each linedef with the column and | ||
913 | // row lines at the left and bottom of each blockmap cell. It then | ||
914 | // adds the line to all block lists touching the intersection. | ||
915 | // | ||
916 | |||
917 | static void P_CreateBlockMap(void) | ||
918 | { | ||
919 | int xorg,yorg; // blockmap origin (lower left) | ||
920 | int nrows,ncols; // blockmap dimensions | ||
921 | linelist_t **blocklists=NULL; // array of pointers to lists of lines | ||
922 | int *blockcount=NULL; // array of counters of line lists | ||
923 | int *blockdone=NULL; // array keeping track of blocks/line | ||
924 | int NBlocks; // number of cells = nrows*ncols | ||
925 | long linetotal=0; // total length of all blocklists | ||
926 | int i,j; | ||
927 | int map_minx=INT_MAX; // init for map limits search | ||
928 | int map_miny=INT_MAX; | ||
929 | int map_maxx=INT_MIN; | ||
930 | int map_maxy=INT_MIN; | ||
931 | |||
932 | // scan for map limits, which the blockmap must enclose | ||
933 | |||
934 | for (i=0;i<numvertexes;i++) | ||
935 | { | ||
936 | fixed_t t; | ||
937 | |||
938 | if ((t=vertexes[i].x) < map_minx) | ||
939 | map_minx = t; | ||
940 | else if (t > map_maxx) | ||
941 | map_maxx = t; | ||
942 | if ((t=vertexes[i].y) < map_miny) | ||
943 | map_miny = t; | ||
944 | else if (t > map_maxy) | ||
945 | map_maxy = t; | ||
946 | } | ||
947 | map_minx >>= FRACBITS; // work in map coords, not fixed_t | ||
948 | map_maxx >>= FRACBITS; | ||
949 | map_miny >>= FRACBITS; | ||
950 | map_maxy >>= FRACBITS; | ||
951 | |||
952 | // set up blockmap area to enclose level plus margin | ||
953 | |||
954 | xorg = map_minx-blkmargin; | ||
955 | yorg = map_miny-blkmargin; | ||
956 | ncols = (map_maxx+blkmargin-xorg+1+blkmask)>>blkshift; //jff 10/12/98 | ||
957 | nrows = (map_maxy+blkmargin-yorg+1+blkmask)>>blkshift; //+1 needed for | ||
958 | NBlocks = ncols*nrows; //map exactly 1 cell | ||
959 | |||
960 | // create the array of pointers on NBlocks to blocklists | ||
961 | // also create an array of linelist counts on NBlocks | ||
962 | // finally make an array in which we can mark blocks done per line | ||
963 | |||
964 | // CPhipps - calloc's | ||
965 | blocklists = calloc(NBlocks,sizeof(linelist_t *)); | ||
966 | blockcount = calloc(NBlocks,sizeof(int)); | ||
967 | blockdone = malloc(NBlocks*sizeof(int)); | ||
968 | |||
969 | // initialize each blocklist, and enter the trailing -1 in all blocklists | ||
970 | // note the linked list of lines grows backwards | ||
971 | |||
972 | for (i=0;i<NBlocks;i++) | ||
973 | { | ||
974 | blocklists[i] = malloc(sizeof(linelist_t)); | ||
975 | blocklists[i]->num = -1; | ||
976 | blocklists[i]->next = NULL; | ||
977 | blockcount[i]++; | ||
978 | } | ||
979 | |||
980 | // For each linedef in the wad, determine all blockmap blocks it touches, | ||
981 | // and add the linedef number to the blocklists for those blocks | ||
982 | |||
983 | for (i=0;i<numlines;i++) | ||
984 | { | ||
985 | int x1 = lines[i].v1->x>>FRACBITS; // lines[i] map coords | ||
986 | int y1 = lines[i].v1->y>>FRACBITS; | ||
987 | int x2 = lines[i].v2->x>>FRACBITS; | ||
988 | int y2 = lines[i].v2->y>>FRACBITS; | ||
989 | int dx = x2-x1; | ||
990 | int dy = y2-y1; | ||
991 | int vert = !dx; // lines[i] slopetype | ||
992 | int horiz = !dy; | ||
993 | int spos = (dx^dy) > 0; | ||
994 | int sneg = (dx^dy) < 0; | ||
995 | int bx,by; // block cell coords | ||
996 | int minx = x1>x2? x2 : x1; // extremal lines[i] coords | ||
997 | int maxx = x1>x2? x1 : x2; | ||
998 | int miny = y1>y2? y2 : y1; | ||
999 | int maxy = y1>y2? y1 : y2; | ||
1000 | |||
1001 | // no blocks done for this linedef yet | ||
1002 | |||
1003 | memset(blockdone,0,NBlocks*sizeof(int)); | ||
1004 | |||
1005 | // The line always belongs to the blocks containing its endpoints | ||
1006 | |||
1007 | bx = (x1-xorg)>>blkshift; | ||
1008 | by = (y1-yorg)>>blkshift; | ||
1009 | AddBlockLine(blocklists,blockcount,blockdone,by*ncols+bx,i); | ||
1010 | bx = (x2-xorg)>>blkshift; | ||
1011 | by = (y2-yorg)>>blkshift; | ||
1012 | AddBlockLine(blocklists,blockcount,blockdone,by*ncols+bx,i); | ||
1013 | |||
1014 | |||
1015 | // For each column, see where the line along its left edge, which | ||
1016 | // it contains, intersects the Linedef i. Add i to each corresponding | ||
1017 | // blocklist. | ||
1018 | |||
1019 | if (!vert) // don't interesect vertical lines with columns | ||
1020 | { | ||
1021 | for (j=0;j<ncols;j++) | ||
1022 | { | ||
1023 | // intersection of Linedef with x=xorg+(j<<blkshift) | ||
1024 | // (y-y1)*dx = dy*(x-x1) | ||
1025 | // y = dy*(x-x1)+y1*dx; | ||
1026 | |||
1027 | int x = xorg+(j<<blkshift); // (x,y) is intersection | ||
1028 | int y = (dy*(x-x1))/dx+y1; | ||
1029 | int yb = (y-yorg)>>blkshift; // block row number | ||
1030 | int yp = (y-yorg)&blkmask; // y position within block | ||
1031 | |||
1032 | if (yb<0 || yb>nrows-1) // outside blockmap, continue | ||
1033 | continue; | ||
1034 | |||
1035 | if (x<minx || x>maxx) // line doesn't touch column | ||
1036 | continue; | ||
1037 | |||
1038 | // The cell that contains the intersection point is always added | ||
1039 | |||
1040 | AddBlockLine(blocklists,blockcount,blockdone,ncols*yb+j,i); | ||
1041 | |||
1042 | // if the intersection is at a corner it depends on the slope | ||
1043 | // (and whether the line extends past the intersection) which | ||
1044 | // blocks are hit | ||
1045 | |||
1046 | if (yp==0) // intersection at a corner | ||
1047 | { | ||
1048 | if (sneg) // \ - blocks x,y-, x-,y | ||
1049 | { | ||
1050 | if (yb>0 && miny<y) | ||
1051 | AddBlockLine(blocklists,blockcount,blockdone,ncols*(yb-1)+j,i); | ||
1052 | if (j>0 && minx<x) | ||
1053 | AddBlockLine(blocklists,blockcount,blockdone,ncols*yb+j-1,i); | ||
1054 | } | ||
1055 | else if (spos) // / - block x-,y- | ||
1056 | { | ||
1057 | if (yb>0 && j>0 && minx<x) | ||
1058 | AddBlockLine(blocklists,blockcount,blockdone,ncols*(yb-1)+j-1,i); | ||
1059 | } | ||
1060 | else if (horiz) // - - block x-,y | ||
1061 | { | ||
1062 | if (j>0 && minx<x) | ||
1063 | AddBlockLine(blocklists,blockcount,blockdone,ncols*yb+j-1,i); | ||
1064 | } | ||
1065 | } | ||
1066 | else if (j>0 && minx<x) // else not at corner: x-,y | ||
1067 | AddBlockLine(blocklists,blockcount,blockdone,ncols*yb+j-1,i); | ||
1068 | } | ||
1069 | } | ||
1070 | |||
1071 | // For each row, see where the line along its bottom edge, which | ||
1072 | // it contains, intersects the Linedef i. Add i to all the corresponding | ||
1073 | // blocklists. | ||
1074 | |||
1075 | if (!horiz) | ||
1076 | { | ||
1077 | for (j=0;j<nrows;j++) | ||
1078 | { | ||
1079 | // intersection of Linedef with y=yorg+(j<<blkshift) | ||
1080 | // (x,y) on Linedef i satisfies: (y-y1)*dx = dy*(x-x1) | ||
1081 | // x = dx*(y-y1)/dy+x1; | ||
1082 | |||
1083 | int y = yorg+(j<<blkshift); // (x,y) is intersection | ||
1084 | int x = (dx*(y-y1))/dy+x1; | ||
1085 | int xb = (x-xorg)>>blkshift; // block column number | ||
1086 | int xp = (x-xorg)&blkmask; // x position within block | ||
1087 | |||
1088 | if (xb<0 || xb>ncols-1) // outside blockmap, continue | ||
1089 | continue; | ||
1090 | |||
1091 | if (y<miny || y>maxy) // line doesn't touch row | ||
1092 | continue; | ||
1093 | |||
1094 | // The cell that contains the intersection point is always added | ||
1095 | |||
1096 | AddBlockLine(blocklists,blockcount,blockdone,ncols*j+xb,i); | ||
1097 | |||
1098 | // if the intersection is at a corner it depends on the slope | ||
1099 | // (and whether the line extends past the intersection) which | ||
1100 | // blocks are hit | ||
1101 | |||
1102 | if (xp==0) // intersection at a corner | ||
1103 | { | ||
1104 | if (sneg) // \ - blocks x,y-, x-,y | ||
1105 | { | ||
1106 | if (j>0 && miny<y) | ||
1107 | AddBlockLine(blocklists,blockcount,blockdone,ncols*(j-1)+xb,i); | ||
1108 | if (xb>0 && minx<x) | ||
1109 | AddBlockLine(blocklists,blockcount,blockdone,ncols*j+xb-1,i); | ||
1110 | } | ||
1111 | else if (vert) // | - block x,y- | ||
1112 | { | ||
1113 | if (j>0 && miny<y) | ||
1114 | AddBlockLine(blocklists,blockcount,blockdone,ncols*(j-1)+xb,i); | ||
1115 | } | ||
1116 | else if (spos) // / - block x-,y- | ||
1117 | { | ||
1118 | if (xb>0 && j>0 && miny<y) | ||
1119 | AddBlockLine(blocklists,blockcount,blockdone,ncols*(j-1)+xb-1,i); | ||
1120 | } | ||
1121 | } | ||
1122 | else if (j>0 && miny<y) // else not on a corner: x,y- | ||
1123 | AddBlockLine(blocklists,blockcount,blockdone,ncols*(j-1)+xb,i); | ||
1124 | } | ||
1125 | } | ||
1126 | } | ||
1127 | |||
1128 | // Add initial 0 to all blocklists | ||
1129 | // count the total number of lines (and 0's and -1's) | ||
1130 | |||
1131 | memset(blockdone,0,NBlocks*sizeof(int)); | ||
1132 | for (i=0,linetotal=0;i<NBlocks;i++) | ||
1133 | { | ||
1134 | AddBlockLine(blocklists,blockcount,blockdone,i,0); | ||
1135 | linetotal += blockcount[i]; | ||
1136 | } | ||
1137 | |||
1138 | // Create the blockmap lump | ||
1139 | |||
1140 | blockmaplump = Z_Malloc(sizeof(*blockmaplump) * (4+NBlocks+linetotal), | ||
1141 | PU_LEVEL, 0); | ||
1142 | // blockmap header | ||
1143 | |||
1144 | blockmaplump[0] = bmaporgx = xorg << FRACBITS; | ||
1145 | blockmaplump[1] = bmaporgy = yorg << FRACBITS; | ||
1146 | blockmaplump[2] = bmapwidth = ncols; | ||
1147 | blockmaplump[3] = bmapheight = nrows; | ||
1148 | |||
1149 | // offsets to lists and block lists | ||
1150 | |||
1151 | for (i=0;i<NBlocks;i++) | ||
1152 | { | ||
1153 | linelist_t *bl = blocklists[i]; | ||
1154 | long offs = blockmaplump[4+i] = // set offset to block's list | ||
1155 | (i? blockmaplump[4+i-1] : 4+NBlocks) + (i? blockcount[i-1] : 0); | ||
1156 | |||
1157 | // add the lines in each block's list to the blockmaplump | ||
1158 | // delete each list node as we go | ||
1159 | |||
1160 | while (bl) | ||
1161 | { | ||
1162 | linelist_t *tmp = bl->next; | ||
1163 | blockmaplump[offs++] = bl->num; | ||
1164 | free(bl); | ||
1165 | bl = tmp; | ||
1166 | } | ||
1167 | } | ||
1168 | |||
1169 | // free all temporary storage | ||
1170 | |||
1171 | free (blocklists); | ||
1172 | free (blockcount); | ||
1173 | free (blockdone); | ||
1174 | } | ||
1175 | |||
1176 | // jff 10/6/98 | ||
1177 | // End new code added to speed up calculation of internal blockmap | ||
1178 | |||
1179 | // | ||
1180 | // P_LoadBlockMap | ||
1181 | // | ||
1182 | // killough 3/1/98: substantially modified to work | ||
1183 | // towards removing blockmap limit (a wad limitation) | ||
1184 | // | ||
1185 | // killough 3/30/98: Rewritten to remove blockmap limit, | ||
1186 | // though current algorithm is brute-force and unoptimal. | ||
1187 | // | ||
1188 | |||
1189 | static void P_LoadBlockMap (int lump) | ||
1190 | { | ||
1191 | long count; | ||
1192 | |||
1193 | if (M_CheckParm("-blockmap") || W_LumpLength(lump)<8 || (count = W_LumpLength(lump)/2) >= 0x10000) //e6y | ||
1194 | P_CreateBlockMap(); | ||
1195 | else | ||
1196 | { | ||
1197 | long i; | ||
1198 | // cph - const*, wad lump handling updated | ||
1199 | const short *wadblockmaplump = W_CacheLumpNum(lump); | ||
1200 | blockmaplump = Z_Malloc(sizeof(*blockmaplump) * count, PU_LEVEL, 0); | ||
1201 | |||
1202 | // killough 3/1/98: Expand wad blockmap into larger internal one, | ||
1203 | // by treating all offsets except -1 as unsigned and zero-extending | ||
1204 | // them. This potentially doubles the size of blockmaps allowed, | ||
1205 | // because Doom originally considered the offsets as always signed. | ||
1206 | |||
1207 | blockmaplump[0] = SHORT(wadblockmaplump[0]); | ||
1208 | blockmaplump[1] = SHORT(wadblockmaplump[1]); | ||
1209 | blockmaplump[2] = (long)(SHORT(wadblockmaplump[2])) & 0xffff; | ||
1210 | blockmaplump[3] = (long)(SHORT(wadblockmaplump[3])) & 0xffff; | ||
1211 | |||
1212 | for (i=4 ; i<count ; i++) | ||
1213 | { | ||
1214 | short t = SHORT(wadblockmaplump[i]); // killough 3/1/98 | ||
1215 | blockmaplump[i] = t == -1 ? -1l : (long) t & 0xffff; | ||
1216 | } | ||
1217 | |||
1218 | W_UnlockLumpNum(lump); // cph - unlock the lump | ||
1219 | |||
1220 | bmaporgx = blockmaplump[0]<<FRACBITS; | ||
1221 | bmaporgy = blockmaplump[1]<<FRACBITS; | ||
1222 | bmapwidth = blockmaplump[2]; | ||
1223 | bmapheight = blockmaplump[3]; | ||
1224 | } | ||
1225 | |||
1226 | // clear out mobj chains - CPhipps - use calloc | ||
1227 | blocklinks = Z_Calloc (bmapwidth*bmapheight,sizeof(*blocklinks),PU_LEVEL,0); | ||
1228 | blockmap = blockmaplump+4; | ||
1229 | } | ||
1230 | |||
1231 | // | ||
1232 | // P_LoadReject - load the reject table, padding it if it is too short | ||
1233 | // totallines must be the number returned by P_GroupLines() | ||
1234 | // an underflow will be padded with zeroes, or a doom.exe z_zone header | ||
1235 | // | ||
1236 | // this function incorporates e6y's RejectOverrunAddInt code: | ||
1237 | // e6y: REJECT overrun emulation code | ||
1238 | // It's emulated successfully if the size of overflow no more than 16 bytes. | ||
1239 | // No more desync on teeth-32.wad\teeth-32.lmp. | ||
1240 | // http://www.doomworld.com/vb/showthread.php?s=&threadid=35214 | ||
1241 | |||
1242 | static void P_LoadReject(int lumpnum, int totallines) | ||
1243 | { | ||
1244 | unsigned int length, required; | ||
1245 | byte *newreject; | ||
1246 | |||
1247 | // dump any old cached reject lump, then cache the new one | ||
1248 | if (rejectlump != -1) | ||
1249 | W_UnlockLumpNum(rejectlump); | ||
1250 | rejectlump = lumpnum + ML_REJECT; | ||
1251 | rejectmatrix = W_CacheLumpNum(rejectlump); | ||
1252 | |||
1253 | required = (numsectors * numsectors + 7) / 8; | ||
1254 | length = W_LumpLength(rejectlump); | ||
1255 | |||
1256 | if (length >= required) | ||
1257 | return; // nothing to do | ||
1258 | |||
1259 | // allocate a new block and copy the reject table into it; zero the rest | ||
1260 | // PU_LEVEL => will be freed on level exit | ||
1261 | newreject = Z_Malloc(required, PU_LEVEL, NULL); | ||
1262 | rejectmatrix = (const byte *)memmove(newreject, rejectmatrix, length); | ||
1263 | memset(newreject + length, 0, required - length); | ||
1264 | // unlock the original lump, it is no longer needed | ||
1265 | W_UnlockLumpNum(rejectlump); | ||
1266 | rejectlump = -1; | ||
1267 | |||
1268 | if (demo_compatibility) | ||
1269 | { | ||
1270 | // merged in RejectOverrunAddInt(), and the 4 calls to it, here | ||
1271 | unsigned int rejectpad[4] = { | ||
1272 | 0, // size, will be filled in using totallines | ||
1273 | 0, // part of the header of a doom.exe z_zone block | ||
1274 | 50, // DOOM_CONST_PU_LEVEL | ||
1275 | 0x1d4a11 // DOOM_CONST_ZONEID | ||
1276 | }; | ||
1277 | unsigned int i, pad = 0, *src = rejectpad; | ||
1278 | byte *dest = newreject + length; | ||
1279 | |||
1280 | rejectpad[0] = ((totallines*4+3)&~3)+24; // doom.exe zone header size | ||
1281 | |||
1282 | // copy at most 16 bytes from rejectpad | ||
1283 | // emulating a 32-bit, little-endian architecture (can't memmove) | ||
1284 | for (i = 0; i < required - length && i < 16; i++) { // 16 hard-coded | ||
1285 | if (!(i&3)) // get the next 4 bytes to copy when i=0,4,8,12 | ||
1286 | pad = *src++; | ||
1287 | *dest++ = pad & 0xff; // store lowest-significant byte | ||
1288 | pad >>= 8; // rotate the next byte down | ||
1289 | } | ||
1290 | } | ||
1291 | lprintf(LO_WARN, "P_LoadReject: REJECT too short (%u<%u) - padded\n", | ||
1292 | length, required); | ||
1293 | } | ||
1294 | |||
1295 | // | ||
1296 | // P_GroupLines | ||
1297 | // Builds sector line lists and subsector sector numbers. | ||
1298 | // Finds block bounding boxes for sectors. | ||
1299 | // | ||
1300 | // killough 5/3/98: reformatted, cleaned up | ||
1301 | // cph 18/8/99: rewritten to avoid O(numlines * numsectors) section | ||
1302 | // It makes things more complicated, but saves seconds on big levels | ||
1303 | // figgi 09/18/00 -- adapted for gl-nodes | ||
1304 | |||
1305 | // cph - convenient sub-function | ||
1306 | static void P_AddLineToSector(line_t* li, sector_t* sector) | ||
1307 | { | ||
1308 | fixed_t *bbox = (void*)sector->blockbox; | ||
1309 | |||
1310 | sector->lines[sector->linecount++] = li; | ||
1311 | M_AddToBox (bbox, li->v1->x, li->v1->y); | ||
1312 | M_AddToBox (bbox, li->v2->x, li->v2->y); | ||
1313 | } | ||
1314 | |||
1315 | // modified to return totallines (needed by P_LoadReject) | ||
1316 | static int P_GroupLines (void) | ||
1317 | { | ||
1318 | register line_t *li; | ||
1319 | register sector_t *sector; | ||
1320 | int i,j, total = numlines; | ||
1321 | |||
1322 | // figgi | ||
1323 | for (i=0 ; i<numsubsectors ; i++) | ||
1324 | { | ||
1325 | seg_t *seg = &segs[subsectors[i].firstline]; | ||
1326 | subsectors[i].sector = NULL; | ||
1327 | for(j=0; j<subsectors[i].numlines; j++) | ||
1328 | { | ||
1329 | if(seg->sidedef) | ||
1330 | { | ||
1331 | subsectors[i].sector = seg->sidedef->sector; | ||
1332 | break; | ||
1333 | } | ||
1334 | seg++; | ||
1335 | } | ||
1336 | if(subsectors[i].sector == NULL) | ||
1337 | I_Error("P_GroupLines: Subsector a part of no sector!\n"); | ||
1338 | } | ||
1339 | |||
1340 | // count number of lines in each sector | ||
1341 | for (i=0,li=lines; i<numlines; i++, li++) | ||
1342 | { | ||
1343 | li->frontsector->linecount++; | ||
1344 | if (li->backsector && li->backsector != li->frontsector) | ||
1345 | { | ||
1346 | li->backsector->linecount++; | ||
1347 | total++; | ||
1348 | } | ||
1349 | } | ||
1350 | |||
1351 | { // allocate line tables for each sector | ||
1352 | line_t **linebuffer = Z_Malloc(total*sizeof(line_t *), PU_LEVEL, 0); | ||
1353 | |||
1354 | // e6y: REJECT overrun emulation code | ||
1355 | // moved to P_LoadReject | ||
1356 | |||
1357 | for (i=0, sector = sectors; i<numsectors; i++, sector++) | ||
1358 | { | ||
1359 | sector->lines = linebuffer; | ||
1360 | linebuffer += sector->linecount; | ||
1361 | sector->linecount = 0; | ||
1362 | M_ClearBox(sector->blockbox); | ||
1363 | } | ||
1364 | } | ||
1365 | |||
1366 | // Enter those lines | ||
1367 | for (i=0,li=lines; i<numlines; i++, li++) | ||
1368 | { | ||
1369 | P_AddLineToSector(li, li->frontsector); | ||
1370 | if (li->backsector && li->backsector != li->frontsector) | ||
1371 | P_AddLineToSector(li, li->backsector); | ||
1372 | } | ||
1373 | |||
1374 | for (i=0, sector = sectors; i<numsectors; i++, sector++) | ||
1375 | { | ||
1376 | fixed_t *bbox = (void*)sector->blockbox; // cph - For convenience, so | ||
1377 | // I can sue the old code unchanged | ||
1378 | int block; | ||
1379 | |||
1380 | // set the degenmobj_t to the middle of the bounding box | ||
1381 | if (comp[comp_sound]) | ||
1382 | { | ||
1383 | sector->soundorg.x = (bbox[BOXRIGHT]+bbox[BOXLEFT])/2; | ||
1384 | sector->soundorg.y = (bbox[BOXTOP]+bbox[BOXBOTTOM])/2; | ||
1385 | } | ||
1386 | else | ||
1387 | { | ||
1388 | //e6y: fix sound origin for large levels | ||
1389 | sector->soundorg.x = bbox[BOXRIGHT]/2+bbox[BOXLEFT]/2; | ||
1390 | sector->soundorg.y = bbox[BOXTOP]/2+bbox[BOXBOTTOM]/2; | ||
1391 | } | ||
1392 | |||
1393 | // adjust bounding box to map blocks | ||
1394 | block = (bbox[BOXTOP]-bmaporgy+MAXRADIUS)>>MAPBLOCKSHIFT; | ||
1395 | block = block >= bmapheight ? bmapheight-1 : block; | ||
1396 | sector->blockbox[BOXTOP]=block; | ||
1397 | |||
1398 | block = (bbox[BOXBOTTOM]-bmaporgy-MAXRADIUS)>>MAPBLOCKSHIFT; | ||
1399 | block = block < 0 ? 0 : block; | ||
1400 | sector->blockbox[BOXBOTTOM]=block; | ||
1401 | |||
1402 | block = (bbox[BOXRIGHT]-bmaporgx+MAXRADIUS)>>MAPBLOCKSHIFT; | ||
1403 | block = block >= bmapwidth ? bmapwidth-1 : block; | ||
1404 | sector->blockbox[BOXRIGHT]=block; | ||
1405 | |||
1406 | block = (bbox[BOXLEFT]-bmaporgx-MAXRADIUS)>>MAPBLOCKSHIFT; | ||
1407 | block = block < 0 ? 0 : block; | ||
1408 | sector->blockbox[BOXLEFT]=block; | ||
1409 | } | ||
1410 | |||
1411 | return total; // this value is needed by the reject overrun emulation code | ||
1412 | } | ||
1413 | |||
1414 | // | ||
1415 | // killough 10/98 | ||
1416 | // | ||
1417 | // Remove slime trails. | ||
1418 | // | ||
1419 | // Slime trails are inherent to Doom's coordinate system -- i.e. there is | ||
1420 | // nothing that a node builder can do to prevent slime trails ALL of the time, | ||
1421 | // because it's a product of the integer coodinate system, and just because | ||
1422 | // two lines pass through exact integer coordinates, doesn't necessarily mean | ||
1423 | // that they will intersect at integer coordinates. Thus we must allow for | ||
1424 | // fractional coordinates if we are to be able to split segs with node lines, | ||
1425 | // as a node builder must do when creating a BSP tree. | ||
1426 | // | ||
1427 | // A wad file does not allow fractional coordinates, so node builders are out | ||
1428 | // of luck except that they can try to limit the number of splits (they might | ||
1429 | // also be able to detect the degree of roundoff error and try to avoid splits | ||
1430 | // with a high degree of roundoff error). But we can use fractional coordinates | ||
1431 | // here, inside the engine. It's like the difference between square inches and | ||
1432 | // square miles, in terms of granularity. | ||
1433 | // | ||
1434 | // For each vertex of every seg, check to see whether it's also a vertex of | ||
1435 | // the linedef associated with the seg (i.e, it's an endpoint). If it's not | ||
1436 | // an endpoint, and it wasn't already moved, move the vertex towards the | ||
1437 | // linedef by projecting it using the law of cosines. Formula: | ||
1438 | // | ||
1439 | // 2 2 2 2 | ||
1440 | // dx x0 + dy x1 + dx dy (y0 - y1) dy y0 + dx y1 + dx dy (x0 - x1) | ||
1441 | // {---------------------------------, ---------------------------------} | ||
1442 | // 2 2 2 2 | ||
1443 | // dx + dy dx + dy | ||
1444 | // | ||
1445 | // (x0,y0) is the vertex being moved, and (x1,y1)-(x1+dx,y1+dy) is the | ||
1446 | // reference linedef. | ||
1447 | // | ||
1448 | // Segs corresponding to orthogonal linedefs (exactly vertical or horizontal | ||
1449 | // linedefs), which comprise at least half of all linedefs in most wads, don't | ||
1450 | // need to be considered, because they almost never contribute to slime trails | ||
1451 | // (because then any roundoff error is parallel to the linedef, which doesn't | ||
1452 | // cause slime). Skipping simple orthogonal lines lets the code finish quicker. | ||
1453 | // | ||
1454 | // Please note: This section of code is not interchangable with TeamTNT's | ||
1455 | // code which attempts to fix the same problem. | ||
1456 | // | ||
1457 | // Firelines (TM) is a Rezistered Trademark of MBF Productions | ||
1458 | // | ||
1459 | |||
1460 | static void P_RemoveSlimeTrails(void) // killough 10/98 | ||
1461 | { | ||
1462 | byte *hit = calloc(1, numvertexes); // Hitlist for vertices | ||
1463 | int i; | ||
1464 | for (i=0; i<numsegs; i++) // Go through each seg | ||
1465 | { | ||
1466 | const line_t *l; | ||
1467 | |||
1468 | if (segs[i].miniseg == true) //figgi -- skip minisegs | ||
1469 | return; | ||
1470 | |||
1471 | l = segs[i].linedef; // The parent linedef | ||
1472 | if (l->dx && l->dy) // We can ignore orthogonal lines | ||
1473 | { | ||
1474 | vertex_t *v = segs[i].v1; | ||
1475 | do | ||
1476 | if (!hit[v - vertexes]) // If we haven't processed vertex | ||
1477 | { | ||
1478 | hit[v - vertexes] = 1; // Mark this vertex as processed | ||
1479 | if (v != l->v1 && v != l->v2) // Exclude endpoints of linedefs | ||
1480 | { // Project the vertex back onto the parent linedef | ||
1481 | int_64_t dx2 = (l->dx >> FRACBITS) * (l->dx >> FRACBITS); | ||
1482 | int_64_t dy2 = (l->dy >> FRACBITS) * (l->dy >> FRACBITS); | ||
1483 | int_64_t dxy = (l->dx >> FRACBITS) * (l->dy >> FRACBITS); | ||
1484 | int_64_t s = dx2 + dy2; | ||
1485 | int x0 = v->x, y0 = v->y, x1 = l->v1->x, y1 = l->v1->y; | ||
1486 | v->x = (int)((dx2 * x0 + dy2 * x1 + dxy * (y0 - y1)) / s); | ||
1487 | v->y = (int)((dy2 * y0 + dx2 * y1 + dxy * (x0 - x1)) / s); | ||
1488 | } | ||
1489 | } // Obsfucated C contest entry: :) | ||
1490 | while ((v != segs[i].v2) && (v = segs[i].v2)); | ||
1491 | } | ||
1492 | } | ||
1493 | free(hit); | ||
1494 | } | ||
1495 | |||
1496 | // | ||
1497 | // P_SetupLevel | ||
1498 | // | ||
1499 | // killough 5/3/98: reformatted, cleaned up | ||
1500 | |||
1501 | void P_SetupLevel(int episode, int map, int playermask, skill_t skill) | ||
1502 | { | ||
1503 | int i; | ||
1504 | char lumpname[9]; | ||
1505 | int lumpnum; | ||
1506 | |||
1507 | char gl_lumpname[9]; | ||
1508 | int gl_lumpnum; | ||
1509 | |||
1510 | R_StopAllInterpolations(); | ||
1511 | |||
1512 | totallive = totalkills = totalitems = totalsecret = wminfo.maxfrags = 0; | ||
1513 | wminfo.partime = 180; | ||
1514 | |||
1515 | for (i=0; i<MAXPLAYERS; i++) | ||
1516 | players[i].killcount = players[i].secretcount = players[i].itemcount = 0; | ||
1517 | |||
1518 | // Initial height of PointOfView will be set by player think. | ||
1519 | players[consoleplayer].viewz = 1; | ||
1520 | |||
1521 | // Make sure all sounds are stopped before Z_FreeTags. | ||
1522 | S_Start(); | ||
1523 | |||
1524 | Z_FreeTags(PU_LEVEL, PU_PURGELEVEL-1); | ||
1525 | if (rejectlump != -1) { // cph - unlock the reject table | ||
1526 | W_UnlockLumpNum(rejectlump); | ||
1527 | rejectlump = -1; | ||
1528 | } | ||
1529 | |||
1530 | #ifdef GL_DOOM | ||
1531 | // proff 11/99: clean the memory from textures etc. | ||
1532 | gld_CleanMemory(); | ||
1533 | #endif | ||
1534 | |||
1535 | P_InitThinkers(); | ||
1536 | |||
1537 | // if working with a devlopment map, reload it | ||
1538 | // W_Reload (); killough 1/31/98: W_Reload obsolete | ||
1539 | |||
1540 | // find map name | ||
1541 | if (gamemode == commercial) | ||
1542 | { | ||
1543 | sprintf(lumpname, "map%02d", map); // killough 1/24/98: simplify | ||
1544 | sprintf(gl_lumpname, "gl_map%02d", map); // figgi | ||
1545 | } | ||
1546 | else | ||
1547 | { | ||
1548 | sprintf(lumpname, "E%dM%d", episode, map); // killough 1/24/98: simplify | ||
1549 | sprintf(gl_lumpname, "GL_E%iM%i", episode, map); // figgi | ||
1550 | } | ||
1551 | |||
1552 | lumpnum = W_GetNumForName(lumpname); | ||
1553 | gl_lumpnum = W_CheckNumForName(gl_lumpname); // figgi | ||
1554 | |||
1555 | leveltime = 0; totallive = 0; | ||
1556 | |||
1557 | // note: most of this ordering is important | ||
1558 | |||
1559 | // killough 3/1/98: P_LoadBlockMap call moved down to below | ||
1560 | // killough 4/4/98: split load of sidedefs into two parts, | ||
1561 | // to allow texture names to be used in special linedefs | ||
1562 | |||
1563 | // refuse to load Hexen-format maps, avoid segfaults | ||
1564 | if ((i = lumpnum + ML_BLOCKMAP + 1) < numlumps | ||
1565 | && !strncasecmp(lumpinfo[i].name, "BEHAVIOR", 8)) | ||
1566 | I_Error("P_SetupLevel: %s: Hexen format not supported", lumpname); | ||
1567 | |||
1568 | #if 1 | ||
1569 | // figgi 10/19/00 -- check for gl lumps and load them | ||
1570 | P_GetNodesVersion(lumpnum,gl_lumpnum); | ||
1571 | |||
1572 | if (nodesVersion > 0) | ||
1573 | P_LoadVertexes2 (lumpnum+ML_VERTEXES,gl_lumpnum+ML_GL_VERTS); | ||
1574 | else | ||
1575 | P_LoadVertexes (lumpnum+ML_VERTEXES); | ||
1576 | P_LoadSectors (lumpnum+ML_SECTORS); | ||
1577 | P_LoadSideDefs (lumpnum+ML_SIDEDEFS); | ||
1578 | P_LoadLineDefs (lumpnum+ML_LINEDEFS); | ||
1579 | P_LoadSideDefs2 (lumpnum+ML_SIDEDEFS); | ||
1580 | P_LoadLineDefs2 (lumpnum+ML_LINEDEFS); | ||
1581 | P_LoadBlockMap (lumpnum+ML_BLOCKMAP); | ||
1582 | |||
1583 | if (nodesVersion > 0) | ||
1584 | { | ||
1585 | P_LoadSubsectors(gl_lumpnum + ML_GL_SSECT); | ||
1586 | P_LoadNodes(gl_lumpnum + ML_GL_NODES); | ||
1587 | P_LoadGLSegs(gl_lumpnum + ML_GL_SEGS); | ||
1588 | } | ||
1589 | else | ||
1590 | { | ||
1591 | P_LoadSubsectors(lumpnum + ML_SSECTORS); | ||
1592 | P_LoadNodes(lumpnum + ML_NODES); | ||
1593 | P_LoadSegs(lumpnum + ML_SEGS); | ||
1594 | } | ||
1595 | |||
1596 | #else | ||
1597 | |||
1598 | P_LoadVertexes (lumpnum+ML_VERTEXES); | ||
1599 | P_LoadSectors (lumpnum+ML_SECTORS); | ||
1600 | P_LoadSideDefs (lumpnum+ML_SIDEDEFS); // killough 4/4/98 | ||
1601 | P_LoadLineDefs (lumpnum+ML_LINEDEFS); // | | ||
1602 | P_LoadSideDefs2 (lumpnum+ML_SIDEDEFS); // | | ||
1603 | P_LoadLineDefs2 (lumpnum+ML_LINEDEFS); // killough 4/4/98 | ||
1604 | P_LoadBlockMap (lumpnum+ML_BLOCKMAP); // killough 3/1/98 | ||
1605 | P_LoadSubsectors(lumpnum+ML_SSECTORS); | ||
1606 | P_LoadNodes (lumpnum+ML_NODES); | ||
1607 | P_LoadSegs (lumpnum+ML_SEGS); | ||
1608 | |||
1609 | #endif | ||
1610 | |||
1611 | // reject loading and underflow padding separated out into new function | ||
1612 | // P_GroupLines modified to return a number the underflow padding needs | ||
1613 | P_LoadReject(lumpnum, P_GroupLines()); | ||
1614 | |||
1615 | // e6y | ||
1616 | // Correction of desync on dv04-423.lmp/dv.wad | ||
1617 | // http://www.doomworld.com/vb/showthread.php?s=&postid=627257#post627257 | ||
1618 | if (compatibility_level>=lxdoom_1_compatibility || M_CheckParm("-force_remove_slime_trails") > 0) | ||
1619 | P_RemoveSlimeTrails(); // killough 10/98: remove slime trails from wad | ||
1620 | |||
1621 | // Note: you don't need to clear player queue slots -- | ||
1622 | // a much simpler fix is in g_game.c -- killough 10/98 | ||
1623 | |||
1624 | bodyqueslot = 0; | ||
1625 | |||
1626 | /* cph - reset all multiplayer starts */ | ||
1627 | memset(playerstarts,0,sizeof(playerstarts)); | ||
1628 | deathmatch_p = deathmatchstarts; | ||
1629 | for (i = 0; i < MAXPLAYERS; i++) | ||
1630 | players[i].mo = NULL; | ||
1631 | |||
1632 | P_MapStart(); | ||
1633 | |||
1634 | P_LoadThings(lumpnum+ML_THINGS); | ||
1635 | |||
1636 | // if deathmatch, randomly spawn the active players | ||
1637 | if (deathmatch) | ||
1638 | { | ||
1639 | for (i=0; i<MAXPLAYERS; i++) | ||
1640 | if (playeringame[i]) | ||
1641 | { | ||
1642 | players[i].mo = NULL; // not needed? - done before P_LoadThings | ||
1643 | G_DeathMatchSpawnPlayer(i); | ||
1644 | } | ||
1645 | } | ||
1646 | else // if !deathmatch, check all necessary player starts actually exist | ||
1647 | { | ||
1648 | for (i=0; i<MAXPLAYERS; i++) | ||
1649 | if (playeringame[i] && !players[i].mo) | ||
1650 | I_Error("P_SetupLevel: missing player %d start\n", i+1); | ||
1651 | } | ||
1652 | |||
1653 | // killough 3/26/98: Spawn icon landings: | ||
1654 | if (gamemode==commercial) | ||
1655 | P_SpawnBrainTargets(); | ||
1656 | |||
1657 | // clear special respawning que | ||
1658 | iquehead = iquetail = 0; | ||
1659 | |||
1660 | // set up world state | ||
1661 | P_SpawnSpecials(); | ||
1662 | |||
1663 | P_MapEnd(); | ||
1664 | |||
1665 | // preload graphics | ||
1666 | if (precache) | ||
1667 | R_PrecacheLevel(); | ||
1668 | |||
1669 | #ifdef GL_DOOM | ||
1670 | if (V_GetMode() == VID_MODEGL) | ||
1671 | { | ||
1672 | // proff 11/99: calculate all OpenGL specific tables etc. | ||
1673 | gld_PreprocessLevel(); | ||
1674 | } | ||
1675 | #endif | ||
1676 | |||
1677 | R_SmoothPlaying_Reset(NULL); // e6y | ||
1678 | } | ||
1679 | |||
1680 | // | ||
1681 | // P_Init | ||
1682 | // | ||
1683 | void P_Init (void) | ||
1684 | { | ||
1685 | P_InitSwitchList(); | ||
1686 | P_InitPicAnims(); | ||
1687 | R_InitSprites(sprnames); | ||
1688 | } | ||