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
18 // Revision 1.1 2000/02/29 18:21:05 stegerg
19 // Doom port based on ADoomPPC. Read README.AROS!
23 // Do all the WAD I/O, get map description,
24 // set up initial state and misc. LUTs.
26 //-----------------------------------------------------------------------------
32 /* #include <math.h> */
52 void P_SpawnMapThing (mapthing_t
* mthing
);
56 // MAP related Lookup tables.
57 // Store VERTEXES, LINEDEFS, SIDEDEFS, etc.
69 subsector_t
* subsectors
;
82 // Created from axis aligned bounding box
83 // of the map, a rectangular array of
85 // Used to speed up collision detection
86 // by spatial subdivision in 2D.
90 int bmapheight
; // size in mapblocks
91 short* blockmap
; // int for larger maps
92 // offsets in blockmap are from here
94 // origin of block map
102 // For fast sight rejection.
103 // Speeds up enemy AI by skipping detailed
104 // LineOf Sight calculation.
105 // Without special effect, this could be
106 // used as a PVS lookup as well.
111 // Maintain single and multi player starting spots.
112 #define MAX_DEATHMATCH_STARTS 10
114 mapthing_t deathmatchstarts
[MAX_DEATHMATCH_STARTS
];
115 mapthing_t
* deathmatch_p
;
116 mapthing_t playerstarts
[MAXPLAYERS
];
125 void P_LoadVertexes (int lump
)
132 // Determine number of lumps:
133 // total lump length / vertex record length.
134 numvertexes
= W_LumpLength (lump
) / sizeof(mapvertex_t
);
136 // Allocate zone memory for buffer.
137 vertexes
= Z_Malloc (numvertexes
*sizeof(vertex_t
),PU_LEVEL
,0);
139 // Load data into cache.
140 data
= W_CacheLumpNum (lump
,PU_STATIC
);
142 ml
= (mapvertex_t
*)data
;
145 // Copy and convert vertex coordinates,
146 // internal representation as fixed.
147 for (i
=0 ; i
<numvertexes
; i
++, li
++, ml
++)
149 li
->x
= SWAPSHORT(ml
->x
)<<FRACBITS
;
150 li
->y
= SWAPSHORT(ml
->y
)<<FRACBITS
;
153 // Free buffer memory.
162 void P_LoadSegs (int lump
)
172 numsegs
= W_LumpLength (lump
) / sizeof(mapseg_t
);
173 segs
= Z_Malloc (numsegs
*sizeof(seg_t
),PU_LEVEL
,0);
174 memset (segs
, 0, numsegs
*sizeof(seg_t
));
175 data
= W_CacheLumpNum (lump
,PU_STATIC
);
177 ml
= (mapseg_t
*)data
;
179 for (i
=0 ; i
<numsegs
; i
++, li
++, ml
++)
181 li
->v1
= &vertexes
[SWAPSHORT(ml
->v1
)];
182 li
->v2
= &vertexes
[SWAPSHORT(ml
->v2
)];
184 li
->angle
= (SWAPSHORT(ml
->angle
))<<16;
185 li
->offset
= (SWAPSHORT(ml
->offset
))<<16;
186 linedef
= SWAPSHORT(ml
->linedef
);
187 ldef
= &lines
[linedef
];
189 side
= SWAPSHORT(ml
->side
);
190 li
->sidedef
= &sides
[ldef
->sidenum
[side
]];
191 li
->frontsector
= sides
[ldef
->sidenum
[side
]].sector
;
192 if (ldef
-> flags
& ML_TWOSIDED
)
193 li
->backsector
= sides
[ldef
->sidenum
[side
^1]].sector
;
205 void P_LoadSubsectors (int lump
)
212 numsubsectors
= W_LumpLength (lump
) / sizeof(mapsubsector_t
);
213 subsectors
= Z_Malloc (numsubsectors
*sizeof(subsector_t
),PU_LEVEL
,0);
214 data
= W_CacheLumpNum (lump
,PU_STATIC
);
216 ms
= (mapsubsector_t
*)data
;
217 memset (subsectors
,0, numsubsectors
*sizeof(subsector_t
));
220 for (i
=0 ; i
<numsubsectors
; i
++, ss
++, ms
++)
222 ss
->numlines
= SWAPSHORT(ms
->numsegs
);
223 ss
->firstline
= SWAPSHORT(ms
->firstseg
);
234 void P_LoadSectors (int lump
)
241 numsectors
= W_LumpLength (lump
) / sizeof(mapsector_t
);
242 sectors
= Z_Malloc (numsectors
*sizeof(sector_t
),PU_LEVEL
,0);
243 memset (sectors
, 0, numsectors
*sizeof(sector_t
));
244 data
= W_CacheLumpNum (lump
,PU_STATIC
);
246 ms
= (mapsector_t
*)data
;
248 for (i
=0 ; i
<numsectors
; i
++, ss
++, ms
++)
250 ss
->floorheight
= SWAPSHORT(ms
->floorheight
)<<FRACBITS
;
251 ss
->ceilingheight
= SWAPSHORT(ms
->ceilingheight
)<<FRACBITS
;
252 ss
->floorpic
= R_FlatNumForName(ms
->floorpic
);
253 ss
->ceilingpic
= R_FlatNumForName(ms
->ceilingpic
);
254 ss
->lightlevel
= SWAPSHORT(ms
->lightlevel
);
255 ss
->special
= SWAPSHORT(ms
->special
);
256 ss
->tag
= SWAPSHORT(ms
->tag
);
257 ss
->thinglist
= NULL
;
267 void P_LoadNodes (int lump
)
276 numnodes
= W_LumpLength (lump
) / sizeof(mapnode_t
);
277 nodes
= Z_Malloc (numnodes
*sizeof(node_t
),PU_LEVEL
,0);
278 data
= W_CacheLumpNum (lump
,PU_STATIC
);
280 mn
= (mapnode_t
*)data
;
283 for (i
=0 ; i
<numnodes
; i
++, no
++, mn
++)
285 no
->x
= SWAPSHORT(mn
->x
)<<FRACBITS
;
286 no
->y
= SWAPSHORT(mn
->y
)<<FRACBITS
;
287 no
->dx
= SWAPSHORT(mn
->dx
)<<FRACBITS
;
288 no
->dy
= SWAPSHORT(mn
->dy
)<<FRACBITS
;
289 for (j
=0 ; j
<2 ; j
++)
291 no
->children
[j
] = SWAPSHORT(mn
->children
[j
]);
292 for (k
=0 ; k
<4 ; k
++)
293 no
->bbox
[j
][k
] = SWAPSHORT(mn
->bbox
[j
][k
])<<FRACBITS
;
304 void P_LoadThings (int lump
)
312 data
= W_CacheLumpNum (lump
,PU_STATIC
);
313 numthings
= W_LumpLength (lump
) / sizeof(mapthing_t
);
315 mt
= (mapthing_t
*)data
;
316 for (i
=0 ; i
<numthings
; i
++, mt
++)
320 // Do not spawn cool, new monsters if !commercial
321 if ( gamemode
!= commercial
)
325 case 68: // Arachnotron
327 case 88: // Boss Brain
328 case 89: // Boss Shooter
329 case 69: // Hell Knight
331 case 71: // Pain Elemental
332 case 65: // Former Human Commando
342 // Do spawn all other stuff.
343 mt
->x
= SWAPSHORT(mt
->x
);
344 mt
->y
= SWAPSHORT(mt
->y
);
345 mt
->angle
= SWAPSHORT(mt
->angle
);
346 mt
->type
= SWAPSHORT(mt
->type
);
347 mt
->options
= SWAPSHORT(mt
->options
);
349 P_SpawnMapThing (mt
);
358 // Also counts secret lines for intermissions.
360 void P_LoadLineDefs (int lump
)
369 numlines
= W_LumpLength (lump
) / sizeof(maplinedef_t
);
370 lines
= Z_Malloc (numlines
*sizeof(line_t
),PU_LEVEL
,0);
371 memset (lines
, 0, numlines
*sizeof(line_t
));
372 data
= W_CacheLumpNum (lump
,PU_STATIC
);
374 mld
= (maplinedef_t
*)data
;
376 for (i
=0 ; i
<numlines
; i
++, mld
++, ld
++)
378 ld
->flags
= SWAPSHORT(mld
->flags
);
379 ld
->special
= SWAPSHORT(mld
->special
);
380 ld
->tag
= SWAPSHORT(mld
->tag
);
381 v1
= ld
->v1
= &vertexes
[SWAPSHORT(mld
->v1
)];
382 v2
= ld
->v2
= &vertexes
[SWAPSHORT(mld
->v2
)];
383 ld
->dx
= v2
->x
- v1
->x
;
384 ld
->dy
= v2
->y
- v1
->y
;
387 ld
->slopetype
= ST_VERTICAL
;
389 ld
->slopetype
= ST_HORIZONTAL
;
392 if (FixedDiv (ld
->dy
, ld
->dx
) > 0)
393 ld
->slopetype
= ST_POSITIVE
;
395 ld
->slopetype
= ST_NEGATIVE
;
400 ld
->bbox
[BOXLEFT
] = v1
->x
;
401 ld
->bbox
[BOXRIGHT
] = v2
->x
;
405 ld
->bbox
[BOXLEFT
] = v2
->x
;
406 ld
->bbox
[BOXRIGHT
] = v1
->x
;
411 ld
->bbox
[BOXBOTTOM
] = v1
->y
;
412 ld
->bbox
[BOXTOP
] = v2
->y
;
416 ld
->bbox
[BOXBOTTOM
] = v2
->y
;
417 ld
->bbox
[BOXTOP
] = v1
->y
;
420 ld
->sidenum
[0] = SWAPSHORT(mld
->sidenum
[0]);
421 ld
->sidenum
[1] = SWAPSHORT(mld
->sidenum
[1]);
423 if (ld
->sidenum
[0] != -1)
424 ld
->frontsector
= sides
[ld
->sidenum
[0]].sector
;
428 if (ld
->sidenum
[1] != -1)
429 ld
->backsector
= sides
[ld
->sidenum
[1]].sector
;
441 void P_LoadSideDefs (int lump
)
448 numsides
= W_LumpLength (lump
) / sizeof(mapsidedef_t
);
449 sides
= Z_Malloc (numsides
*sizeof(side_t
),PU_LEVEL
,0);
450 memset (sides
, 0, numsides
*sizeof(side_t
));
451 data
= W_CacheLumpNum (lump
,PU_STATIC
);
453 msd
= (mapsidedef_t
*)data
;
455 for (i
=0 ; i
<numsides
; i
++, msd
++, sd
++)
457 sd
->textureoffset
= SWAPSHORT(msd
->textureoffset
)<<FRACBITS
;
458 sd
->rowoffset
= SWAPSHORT(msd
->rowoffset
)<<FRACBITS
;
459 sd
->toptexture
= R_TextureNumForName(msd
->toptexture
);
460 sd
->bottomtexture
= R_TextureNumForName(msd
->bottomtexture
);
461 sd
->midtexture
= R_TextureNumForName(msd
->midtexture
);
462 sd
->sector
= §ors
[SWAPSHORT(msd
->sector
)];
472 void P_LoadBlockMap (int lump
)
477 blockmaplump
= W_CacheLumpNum (lump
,PU_LEVEL
);
478 blockmap
= blockmaplump
+4;
479 count
= W_LumpLength (lump
)/2;
481 for (i
=0 ; i
<count
; i
++)
482 blockmaplump
[i
] = SWAPSHORT(blockmaplump
[i
]);
484 bmaporgx
= blockmaplump
[0]<<FRACBITS
;
485 bmaporgy
= blockmaplump
[1]<<FRACBITS
;
486 bmapwidth
= blockmaplump
[2];
487 bmapheight
= blockmaplump
[3];
489 // clear out mobj chains
490 count
= sizeof(*blocklinks
)* bmapwidth
*bmapheight
;
491 blocklinks
= Z_Malloc (count
,PU_LEVEL
, 0);
492 memset (blocklinks
, 0, count
);
499 // Builds sector line lists and subsector sector numbers.
500 // Finds block bounding boxes for sectors.
502 void P_GroupLines (void)
515 // look up sector number for each subsector
517 for (i
=0 ; i
<numsubsectors
; i
++, ss
++)
519 seg
= &segs
[ss
->firstline
];
520 ss
->sector
= seg
->sidedef
->sector
;
523 // count number of lines in each sector
526 for (i
=0 ; i
<numlines
; i
++, li
++)
529 li
->frontsector
->linecount
++;
531 if (li
->backsector
&& li
->backsector
!= li
->frontsector
)
533 li
->backsector
->linecount
++;
538 // build line tables for each sector
539 linebuffer
= Z_Malloc (total
*4, PU_LEVEL
, 0);
541 for (i
=0 ; i
<numsectors
; i
++, sector
++)
544 sector
->lines
= linebuffer
;
546 for (j
=0 ; j
<numlines
; j
++, li
++)
548 if (li
->frontsector
== sector
|| li
->backsector
== sector
)
551 M_AddToBox (bbox
, li
->v1
->x
, li
->v1
->y
);
552 M_AddToBox (bbox
, li
->v2
->x
, li
->v2
->y
);
555 if (linebuffer
- sector
->lines
!= sector
->linecount
)
556 I_Error ("P_GroupLines: miscounted");
558 // set the degenmobj_t to the middle of the bounding box
559 sector
->soundorg
.x
= (bbox
[BOXRIGHT
]+bbox
[BOXLEFT
])/2;
560 sector
->soundorg
.y
= (bbox
[BOXTOP
]+bbox
[BOXBOTTOM
])/2;
562 // adjust bounding box to map blocks
563 block
= (bbox
[BOXTOP
]-bmaporgy
+MAXRADIUS
)>>MAPBLOCKSHIFT
;
564 block
= block
>= bmapheight
? bmapheight
-1 : block
;
565 sector
->blockbox
[BOXTOP
]=block
;
567 block
= (bbox
[BOXBOTTOM
]-bmaporgy
-MAXRADIUS
)>>MAPBLOCKSHIFT
;
568 block
= block
< 0 ? 0 : block
;
569 sector
->blockbox
[BOXBOTTOM
]=block
;
571 block
= (bbox
[BOXRIGHT
]-bmaporgx
+MAXRADIUS
)>>MAPBLOCKSHIFT
;
572 block
= block
>= bmapwidth
? bmapwidth
-1 : block
;
573 sector
->blockbox
[BOXRIGHT
]=block
;
575 block
= (bbox
[BOXLEFT
]-bmaporgx
-MAXRADIUS
)>>MAPBLOCKSHIFT
;
576 block
= block
< 0 ? 0 : block
;
577 sector
->blockbox
[BOXLEFT
]=block
;
597 totalkills
= totalitems
= totalsecret
= wminfo
.maxfrags
= 0;
598 wminfo
.partime
= 180;
599 for (i
=0 ; i
<MAXPLAYERS
; i
++)
601 players
[i
].killcount
= players
[i
].secretcount
602 = players
[i
].itemcount
= 0;
605 // Initial height of PointOfView
606 // will be set by player think.
607 players
[consoleplayer
].viewz
= 1;
609 // Make sure all sounds are stopped before Z_FreeTags.
616 Z_FreeTags (PU_LEVEL
, MAXINT
);
617 Z_FileDumpHeap (debugfile
);
621 Z_FreeTags (PU_LEVEL
, PU_PURGELEVEL
-1);
624 // UNUSED W_Profile ();
627 // if working with a devlopment map, reload it
631 if ( gamemode
== commercial
)
634 sprintf (lumpname
,"map0%i", map
);
636 sprintf (lumpname
,"map%i", map
);
641 lumpname
[1] = '0' + episode
;
643 lumpname
[3] = '0' + map
;
647 lumpnum
= W_GetNumForName (lumpname
);
651 // note: most of this ordering is important
652 P_LoadBlockMap (lumpnum
+ML_BLOCKMAP
);
653 P_LoadVertexes (lumpnum
+ML_VERTEXES
);
654 P_LoadSectors (lumpnum
+ML_SECTORS
);
655 P_LoadSideDefs (lumpnum
+ML_SIDEDEFS
);
657 P_LoadLineDefs (lumpnum
+ML_LINEDEFS
);
658 P_LoadSubsectors (lumpnum
+ML_SSECTORS
);
659 P_LoadNodes (lumpnum
+ML_NODES
);
660 P_LoadSegs (lumpnum
+ML_SEGS
);
662 rejectmatrix
= W_CacheLumpNum (lumpnum
+ML_REJECT
,PU_LEVEL
);
666 deathmatch_p
= deathmatchstarts
;
667 P_LoadThings (lumpnum
+ML_THINGS
);
669 // if deathmatch, randomly spawn the active players
672 for (i
=0 ; i
<MAXPLAYERS
; i
++)
675 players
[i
].mo
= NULL
;
676 G_DeathMatchSpawnPlayer (i
);
681 // clear special respawning que
682 iquehead
= iquetail
= 0;
684 // set up world state
687 // build subsector connect matrix
688 // UNUSED P_ConnectSubsectors ();
694 //printf ("free memory: 0x%x\n", Z_FreeMemory());
707 R_InitSprites (sprnames
);