1 // Emacs style mode select -*- C++ -*-
2 //-----------------------------------------------------------------------------
6 // Copyright (C) 1993-1996 by id Software, Inc.
8 // This source is available for distribution and/or modification
9 // only under the terms of the DOOM Source Code License as
10 // published by id Software. All rights reserved.
12 // The source is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
20 // Do all the WAD I/O, get map description,
21 // set up initial state and misc. LUTs.
23 //-----------------------------------------------------------------------------
26 rcsid
[] = "$Id: p_setup.c,v 1.5 1997/02/03 22:45:12 b1 Exp $";
49 void P_SpawnMapThing (mapthing_t
* mthing
);
53 // MAP related Lookup tables.
54 // Store VERTEXES, LINEDEFS, SIDEDEFS, etc.
66 subsector_t
* subsectors
;
79 // Created from axis aligned bounding box
80 // of the map, a rectangular array of
82 // Used to speed up collision detection
83 // by spatial subdivision in 2D.
87 int bmapheight
; // size in mapblocks
88 short* blockmap
; // int for larger maps
89 // offsets in blockmap are from here
91 // origin of block map
99 // For fast sight rejection.
100 // Speeds up enemy AI by skipping detailed
101 // LineOf Sight calculation.
102 // Without special effect, this could be
103 // used as a PVS lookup as well.
108 // Maintain single and multi player starting spots.
109 #define MAX_DEATHMATCH_STARTS 10
111 mapthing_t deathmatchstarts
[MAX_DEATHMATCH_STARTS
];
112 mapthing_t
* deathmatch_p
;
113 mapthing_t playerstarts
[MAXPLAYERS
];
122 void P_LoadVertexes (int lump
)
129 // Determine number of lumps:
130 // total lump length / vertex record length.
131 numvertexes
= W_LumpLength (lump
) / sizeof(mapvertex_t
);
133 // Allocate zone memory for buffer.
134 vertexes
= Z_Malloc (numvertexes
*sizeof(vertex_t
),PU_LEVEL
,0);
136 // Load data into cache.
137 data
= W_CacheLumpNum (lump
,PU_STATIC
);
139 ml
= (mapvertex_t
*)data
;
142 // Copy and convert vertex coordinates,
143 // internal representation as fixed.
144 for (i
=0 ; i
<numvertexes
; i
++, li
++, ml
++)
146 li
->x
= SHORT(ml
->x
)<<FRACBITS
;
147 li
->y
= SHORT(ml
->y
)<<FRACBITS
;
150 // Free buffer memory.
159 void P_LoadSegs (int lump
)
169 numsegs
= W_LumpLength (lump
) / sizeof(mapseg_t
);
170 segs
= Z_Malloc (numsegs
*sizeof(seg_t
),PU_LEVEL
,0);
171 memset (segs
, 0, numsegs
*sizeof(seg_t
));
172 data
= W_CacheLumpNum (lump
,PU_STATIC
);
174 ml
= (mapseg_t
*)data
;
176 for (i
=0 ; i
<numsegs
; i
++, li
++, ml
++)
178 li
->v1
= &vertexes
[SHORT(ml
->v1
)];
179 li
->v2
= &vertexes
[SHORT(ml
->v2
)];
181 li
->angle
= (SHORT(ml
->angle
))<<16;
182 li
->offset
= (SHORT(ml
->offset
))<<16;
183 linedef
= SHORT(ml
->linedef
);
184 ldef
= &lines
[linedef
];
186 side
= SHORT(ml
->side
);
187 li
->sidedef
= &sides
[ldef
->sidenum
[side
]];
188 li
->frontsector
= sides
[ldef
->sidenum
[side
]].sector
;
189 if (ldef
-> flags
& ML_TWOSIDED
)
190 li
->backsector
= sides
[ldef
->sidenum
[side
^1]].sector
;
202 void P_LoadSubsectors (int lump
)
209 numsubsectors
= W_LumpLength (lump
) / sizeof(mapsubsector_t
);
210 subsectors
= Z_Malloc (numsubsectors
*sizeof(subsector_t
),PU_LEVEL
,0);
211 data
= W_CacheLumpNum (lump
,PU_STATIC
);
213 ms
= (mapsubsector_t
*)data
;
214 memset (subsectors
,0, numsubsectors
*sizeof(subsector_t
));
217 for (i
=0 ; i
<numsubsectors
; i
++, ss
++, ms
++)
219 ss
->numlines
= SHORT(ms
->numsegs
);
220 ss
->firstline
= SHORT(ms
->firstseg
);
231 void P_LoadSectors (int lump
)
238 numsectors
= W_LumpLength (lump
) / sizeof(mapsector_t
);
239 sectors
= Z_Malloc (numsectors
*sizeof(sector_t
),PU_LEVEL
,0);
240 memset (sectors
, 0, numsectors
*sizeof(sector_t
));
241 data
= W_CacheLumpNum (lump
,PU_STATIC
);
243 ms
= (mapsector_t
*)data
;
245 for (i
=0 ; i
<numsectors
; i
++, ss
++, ms
++)
247 ss
->floorheight
= SHORT(ms
->floorheight
)<<FRACBITS
;
248 ss
->ceilingheight
= SHORT(ms
->ceilingheight
)<<FRACBITS
;
249 ss
->floorpic
= R_FlatNumForName(ms
->floorpic
);
250 ss
->ceilingpic
= R_FlatNumForName(ms
->ceilingpic
);
251 ss
->lightlevel
= SHORT(ms
->lightlevel
);
252 ss
->special
= SHORT(ms
->special
);
253 ss
->tag
= SHORT(ms
->tag
);
254 ss
->thinglist
= NULL
;
264 void P_LoadNodes (int lump
)
273 numnodes
= W_LumpLength (lump
) / sizeof(mapnode_t
);
274 nodes
= Z_Malloc (numnodes
*sizeof(node_t
),PU_LEVEL
,0);
275 data
= W_CacheLumpNum (lump
,PU_STATIC
);
277 mn
= (mapnode_t
*)data
;
280 for (i
=0 ; i
<numnodes
; i
++, no
++, mn
++)
282 no
->x
= SHORT(mn
->x
)<<FRACBITS
;
283 no
->y
= SHORT(mn
->y
)<<FRACBITS
;
284 no
->dx
= SHORT(mn
->dx
)<<FRACBITS
;
285 no
->dy
= SHORT(mn
->dy
)<<FRACBITS
;
286 for (j
=0 ; j
<2 ; j
++)
288 no
->children
[j
] = SHORT(mn
->children
[j
]);
289 for (k
=0 ; k
<4 ; k
++)
290 no
->bbox
[j
][k
] = SHORT(mn
->bbox
[j
][k
])<<FRACBITS
;
301 void P_LoadThings (int lump
)
309 data
= W_CacheLumpNum (lump
,PU_STATIC
);
310 numthings
= W_LumpLength (lump
) / sizeof(mapthing_t
);
312 mt
= (mapthing_t
*)data
;
313 for (i
=0 ; i
<numthings
; i
++, mt
++)
317 // Do not spawn cool, new monsters if !commercial
318 if ( gamemode
!= commercial
)
322 case 68: // Arachnotron
324 case 88: // Boss Brain
325 case 89: // Boss Shooter
326 case 69: // Hell Knight
328 case 71: // Pain Elemental
329 case 65: // Former Human Commando
339 // Do spawn all other stuff.
340 mt
->x
= SHORT(mt
->x
);
341 mt
->y
= SHORT(mt
->y
);
342 mt
->angle
= SHORT(mt
->angle
);
343 mt
->type
= SHORT(mt
->type
);
344 mt
->options
= SHORT(mt
->options
);
346 P_SpawnMapThing (mt
);
355 // Also counts secret lines for intermissions.
357 void P_LoadLineDefs (int lump
)
366 numlines
= W_LumpLength (lump
) / sizeof(maplinedef_t
);
367 lines
= Z_Malloc (numlines
*sizeof(line_t
),PU_LEVEL
,0);
368 memset (lines
, 0, numlines
*sizeof(line_t
));
369 data
= W_CacheLumpNum (lump
,PU_STATIC
);
371 mld
= (maplinedef_t
*)data
;
373 for (i
=0 ; i
<numlines
; i
++, mld
++, ld
++)
375 ld
->flags
= SHORT(mld
->flags
);
376 ld
->special
= SHORT(mld
->special
);
377 ld
->tag
= SHORT(mld
->tag
);
378 v1
= ld
->v1
= &vertexes
[SHORT(mld
->v1
)];
379 v2
= ld
->v2
= &vertexes
[SHORT(mld
->v2
)];
380 ld
->dx
= v2
->x
- v1
->x
;
381 ld
->dy
= v2
->y
- v1
->y
;
384 ld
->slopetype
= ST_VERTICAL
;
386 ld
->slopetype
= ST_HORIZONTAL
;
389 if (FixedDiv (ld
->dy
, ld
->dx
) > 0)
390 ld
->slopetype
= ST_POSITIVE
;
392 ld
->slopetype
= ST_NEGATIVE
;
397 ld
->bbox
[BOXLEFT
] = v1
->x
;
398 ld
->bbox
[BOXRIGHT
] = v2
->x
;
402 ld
->bbox
[BOXLEFT
] = v2
->x
;
403 ld
->bbox
[BOXRIGHT
] = v1
->x
;
408 ld
->bbox
[BOXBOTTOM
] = v1
->y
;
409 ld
->bbox
[BOXTOP
] = v2
->y
;
413 ld
->bbox
[BOXBOTTOM
] = v2
->y
;
414 ld
->bbox
[BOXTOP
] = v1
->y
;
417 ld
->sidenum
[0] = SHORT(mld
->sidenum
[0]);
418 ld
->sidenum
[1] = SHORT(mld
->sidenum
[1]);
420 if (ld
->sidenum
[0] != -1)
421 ld
->frontsector
= sides
[ld
->sidenum
[0]].sector
;
425 if (ld
->sidenum
[1] != -1)
426 ld
->backsector
= sides
[ld
->sidenum
[1]].sector
;
438 void P_LoadSideDefs (int lump
)
445 numsides
= W_LumpLength (lump
) / sizeof(mapsidedef_t
);
446 sides
= Z_Malloc (numsides
*sizeof(side_t
),PU_LEVEL
,0);
447 memset (sides
, 0, numsides
*sizeof(side_t
));
448 data
= W_CacheLumpNum (lump
,PU_STATIC
);
450 msd
= (mapsidedef_t
*)data
;
452 for (i
=0 ; i
<numsides
; i
++, msd
++, sd
++)
454 sd
->textureoffset
= SHORT(msd
->textureoffset
)<<FRACBITS
;
455 sd
->rowoffset
= SHORT(msd
->rowoffset
)<<FRACBITS
;
456 sd
->toptexture
= R_TextureNumForName(msd
->toptexture
);
457 sd
->bottomtexture
= R_TextureNumForName(msd
->bottomtexture
);
458 sd
->midtexture
= R_TextureNumForName(msd
->midtexture
);
459 sd
->sector
= §ors
[SHORT(msd
->sector
)];
469 void P_LoadBlockMap (int lump
)
474 blockmaplump
= W_CacheLumpNum (lump
,PU_LEVEL
);
475 blockmap
= blockmaplump
+4;
476 count
= W_LumpLength (lump
)/2;
478 for (i
=0 ; i
<count
; i
++)
479 blockmaplump
[i
] = SHORT(blockmaplump
[i
]);
481 bmaporgx
= blockmaplump
[0]<<FRACBITS
;
482 bmaporgy
= blockmaplump
[1]<<FRACBITS
;
483 bmapwidth
= blockmaplump
[2];
484 bmapheight
= blockmaplump
[3];
486 // clear out mobj chains
487 count
= sizeof(*blocklinks
)* bmapwidth
*bmapheight
;
488 blocklinks
= Z_Malloc (count
,PU_LEVEL
, 0);
489 memset (blocklinks
, 0, count
);
496 // Builds sector line lists and subsector sector numbers.
497 // Finds block bounding boxes for sectors.
499 void P_GroupLines (void)
512 // look up sector number for each subsector
514 for (i
=0 ; i
<numsubsectors
; i
++, ss
++)
516 seg
= &segs
[ss
->firstline
];
517 ss
->sector
= seg
->sidedef
->sector
;
520 // count number of lines in each sector
523 for (i
=0 ; i
<numlines
; i
++, li
++)
526 li
->frontsector
->linecount
++;
528 if (li
->backsector
&& li
->backsector
!= li
->frontsector
)
530 li
->backsector
->linecount
++;
535 // build line tables for each sector
536 linebuffer
= Z_Malloc (total
*4, PU_LEVEL
, 0);
538 for (i
=0 ; i
<numsectors
; i
++, sector
++)
541 sector
->lines
= linebuffer
;
543 for (j
=0 ; j
<numlines
; j
++, li
++)
545 if (li
->frontsector
== sector
|| li
->backsector
== sector
)
548 M_AddToBox (bbox
, li
->v1
->x
, li
->v1
->y
);
549 M_AddToBox (bbox
, li
->v2
->x
, li
->v2
->y
);
552 if (linebuffer
- sector
->lines
!= sector
->linecount
)
553 I_Error ("P_GroupLines: miscounted");
555 // set the degenmobj_t to the middle of the bounding box
556 sector
->soundorg
.x
= (bbox
[BOXRIGHT
]+bbox
[BOXLEFT
])/2;
557 sector
->soundorg
.y
= (bbox
[BOXTOP
]+bbox
[BOXBOTTOM
])/2;
559 // adjust bounding box to map blocks
560 block
= (bbox
[BOXTOP
]-bmaporgy
+MAXRADIUS
)>>MAPBLOCKSHIFT
;
561 block
= block
>= bmapheight
? bmapheight
-1 : block
;
562 sector
->blockbox
[BOXTOP
]=block
;
564 block
= (bbox
[BOXBOTTOM
]-bmaporgy
-MAXRADIUS
)>>MAPBLOCKSHIFT
;
565 block
= block
< 0 ? 0 : block
;
566 sector
->blockbox
[BOXBOTTOM
]=block
;
568 block
= (bbox
[BOXRIGHT
]-bmaporgx
+MAXRADIUS
)>>MAPBLOCKSHIFT
;
569 block
= block
>= bmapwidth
? bmapwidth
-1 : block
;
570 sector
->blockbox
[BOXRIGHT
]=block
;
572 block
= (bbox
[BOXLEFT
]-bmaporgx
-MAXRADIUS
)>>MAPBLOCKSHIFT
;
573 block
= block
< 0 ? 0 : block
;
574 sector
->blockbox
[BOXLEFT
]=block
;
594 totalkills
= totalitems
= totalsecret
= wminfo
.maxfrags
= 0;
595 wminfo
.partime
= 180;
596 for (i
=0 ; i
<MAXPLAYERS
; i
++)
598 players
[i
].killcount
= players
[i
].secretcount
599 = players
[i
].itemcount
= 0;
602 // Initial height of PointOfView
603 // will be set by player think.
604 players
[consoleplayer
].viewz
= 1;
606 // Make sure all sounds are stopped before Z_FreeTags.
613 Z_FreeTags (PU_LEVEL
, MAXINT
);
614 Z_FileDumpHeap (debugfile
);
618 Z_FreeTags (PU_LEVEL
, PU_PURGELEVEL
-1);
621 // UNUSED W_Profile ();
624 // if working with a devlopment map, reload it
628 if ( gamemode
== commercial
)
631 sprintf (lumpname
,"map0%i", map
);
633 sprintf (lumpname
,"map%i", map
);
638 lumpname
[1] = '0' + episode
;
640 lumpname
[3] = '0' + map
;
644 lumpnum
= W_GetNumForName (lumpname
);
648 // note: most of this ordering is important
649 P_LoadBlockMap (lumpnum
+ML_BLOCKMAP
);
650 P_LoadVertexes (lumpnum
+ML_VERTEXES
);
651 P_LoadSectors (lumpnum
+ML_SECTORS
);
652 P_LoadSideDefs (lumpnum
+ML_SIDEDEFS
);
654 P_LoadLineDefs (lumpnum
+ML_LINEDEFS
);
655 P_LoadSubsectors (lumpnum
+ML_SSECTORS
);
656 P_LoadNodes (lumpnum
+ML_NODES
);
657 P_LoadSegs (lumpnum
+ML_SEGS
);
659 rejectmatrix
= W_CacheLumpNum (lumpnum
+ML_REJECT
,PU_LEVEL
);
663 deathmatch_p
= deathmatchstarts
;
664 P_LoadThings (lumpnum
+ML_THINGS
);
666 // if deathmatch, randomly spawn the active players
669 for (i
=0 ; i
<MAXPLAYERS
; i
++)
672 players
[i
].mo
= NULL
;
673 G_DeathMatchSpawnPlayer (i
);
678 // clear special respawning que
679 iquehead
= iquetail
= 0;
681 // set up world state
684 // build subsector connect matrix
685 // UNUSED P_ConnectSubsectors ();
691 //printf ("free memory: 0x%x\n", Z_FreeMemory());
704 R_InitSprites (sprnames
);