2 //**************************************************************************
4 //** p_setup.c : Heretic 2 : Raven Software, Corp.
11 //**************************************************************************
13 // HEADER FILES ------------------------------------------------------------
22 float AccurateDistance(fixed_t dx,fixed_t dy);
26 // MACROS ------------------------------------------------------------------
28 #define MAPINFO_SCRIPT_NAME "MAPINFO"
31 #define MCMD_LIGHTNING 3
32 #define MCMD_FADETABLE 4
33 #define MCMD_DOUBLESKY 5
34 #define MCMD_CLUSTER 6
35 #define MCMD_WARPTRANS 7
37 #define MCMD_CDTRACK 9
38 #define MCMD_CD_STARTTRACK 10
39 #define MCMD_CD_END1TRACK 11
40 #define MCMD_CD_END2TRACK 12
41 #define MCMD_CD_END3TRACK 13
42 #define MCMD_CD_INTERTRACK 14
43 #define MCMD_CD_TITLETRACK 15
45 #define UNKNOWN_MAP_NAME "DEVELOPMENT MAP"
46 #define DEFAULT_SKY_NAME "SKY1" // "SKY1" not in demo wad - KR
47 #define DEFAULT_SONG_LUMP "DEFSONG"
48 #define DEFAULT_FADE_TABLE "COLORMAP"
50 // TYPES -------------------------------------------------------------------
52 typedef struct mapInfo_s mapInfo_t;
62 fixed_t sky1ScrollDelta;
63 fixed_t sky2ScrollDelta;
70 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
72 void P_SpawnMapThing(mapthing_t *mthing);
74 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
76 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
78 static int QualifyMap(int map);
80 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
82 // PUBLIC DATA DEFINITIONS -------------------------------------------------
85 mapthing_t deathmatchstarts[MAXDEATHMATCHSTARTS], *deathmatch_p;
86 mapthing_t playerstarts[MAX_PLAYER_STARTS][MAXPLAYERS];
94 subsector_t *subsectors;
101 short *blockmaplump; // offsets in blockmap are from here
103 int bmapwidth, bmapheight; // in mapblocks
104 fixed_t bmaporgx, bmaporgy; // origin of block map
105 mobj_t **blocklinks; // for thing chains
106 byte *rejectmatrix; // for fast sight rejection
108 // PRIVATE DATA DEFINITIONS ------------------------------------------------
110 static mapInfo_t MapInfo[99];
111 static char *MapCmdNames[] =
126 "CD_INTERMISSION_TRACK",
130 static int MapCmdIDs[] =
149 static int cd_NonLevelTracks[6]; // Non-level specific song cd track numbers
151 // CODE --------------------------------------------------------------------
161 void P_LoadVertexes (int lump)
168 numvertexes = W_LumpLength (lump) / sizeof(mapvertex_t);
169 vertexes = Z_Malloc (numvertexes*sizeof(vertex_t),PU_LEVEL,0);
170 data = W_CacheLumpNum (lump,PU_STATIC);
172 ml = (mapvertex_t *)data;
174 for (i=0 ; i<numvertexes ; i++, li++, ml++)
176 li->x = SHORT(ml->x)<<FRACBITS;
177 li->y = SHORT(ml->y)<<FRACBITS;
192 void P_LoadSegs (int lump)
201 numsegs = W_LumpLength (lump) / sizeof(mapseg_t);
202 segs = Z_Malloc (numsegs*sizeof(seg_t),PU_LEVEL,0);
203 memset (segs, 0, numsegs*sizeof(seg_t));
204 data = W_CacheLumpNum (lump,PU_STATIC);
206 ml = (mapseg_t *)data;
208 for (i=0 ; i<numsegs ; i++, li++, ml++)
210 li->v1 = &vertexes[SHORT(ml->v1)];
211 li->v2 = &vertexes[SHORT(ml->v2)];
213 li->angle = (SHORT(ml->angle))<<16;
214 li->offset = (SHORT(ml->offset))<<16;
215 linedef = SHORT(ml->linedef);
216 ldef = &lines[linedef];
218 side = SHORT(ml->side);
219 li->sidedef = &sides[ldef->sidenum[side]];
220 li->frontsector = sides[ldef->sidenum[side]].sector;
221 if (ldef-> flags & ML_TWOSIDED)
222 li->backsector = sides[ldef->sidenum[side^1]].sector;
227 // Calculate the length of the segment. We need this for
228 // the texture coordinates. -jk
229 li->len = AccurateDistance( li->v2->x - li->v1->x,
230 li->v2->y - li->v1->y );
246 void P_LoadSubsectors (int lump)
253 numsubsectors = W_LumpLength (lump) / sizeof(mapsubsector_t);
254 subsectors = Z_Malloc (numsubsectors*sizeof(subsector_t),PU_LEVEL,0);
255 data = W_CacheLumpNum (lump,PU_STATIC);
257 ms = (mapsubsector_t *)data;
258 memset (subsectors,0, numsubsectors*sizeof(subsector_t));
260 for (i=0 ; i<numsubsectors ; i++, ss++, ms++)
262 ss->numlines = SHORT(ms->numsegs);
263 ss->firstline = SHORT(ms->firstseg);
278 void P_LoadSectors (int lump)
285 numsectors = W_LumpLength (lump) / sizeof(mapsector_t);
286 sectors = Z_Malloc (numsectors*sizeof(sector_t),PU_LEVEL,0);
287 memset (sectors, 0, numsectors*sizeof(sector_t));
288 data = W_CacheLumpNum (lump,PU_STATIC);
290 ms = (mapsector_t *)data;
293 // Make sure primary lumps are used for flat searching
296 for(i = 0; i < numsectors; i++, ss++, ms++)
298 ss->floorheight = SHORT(ms->floorheight)<<FRACBITS;
299 ss->ceilingheight = SHORT(ms->ceilingheight)<<FRACBITS;
300 ss->floorpic = R_FlatNumForName(ms->floorpic);
301 ss->ceilingpic = R_FlatNumForName(ms->ceilingpic);
302 ss->lightlevel = SHORT(ms->lightlevel);
303 ss->special = SHORT(ms->special);
304 ss->tag = SHORT(ms->tag);
305 ss->thinglist = NULL;
306 ss->seqType = SEQTYPE_STONE; // default seqType
309 ss->flatoffx = ss->flatoffy = 0; // Flat scrolling.
310 ss->skyfix = 0; // Set if needed.
329 void P_LoadNodes (int lump)
336 numnodes = W_LumpLength (lump) / sizeof(mapnode_t);
337 nodes = Z_Malloc (numnodes*sizeof(node_t),PU_LEVEL,0);
338 data = W_CacheLumpNum (lump,PU_STATIC);
340 mn = (mapnode_t *)data;
342 for (i=0 ; i<numnodes ; i++, no++, mn++)
344 no->x = SHORT(mn->x)<<FRACBITS;
345 no->y = SHORT(mn->y)<<FRACBITS;
346 no->dx = SHORT(mn->dx)<<FRACBITS;
347 no->dy = SHORT(mn->dy)<<FRACBITS;
348 for (j=0 ; j<2 ; j++)
350 no->children[j] = SHORT(mn->children[j]);
351 for (k=0 ; k<4 ; k++)
352 no->bbox[j][k] = SHORT(mn->bbox[j][k])<<FRACBITS;
358 //==========================================================================
362 //==========================================================================
364 void P_LoadThings(int lump)
373 data = W_CacheLumpNum(lump, PU_STATIC);
374 numthings = W_LumpLength(lump)/sizeof(mapthing_t);
376 mt = (mapthing_t *)data;
377 for(i = 0; i < numthings; i++, mt++)
379 mt->tid = SHORT(mt->tid);
380 mt->x = SHORT(mt->x);
381 mt->y = SHORT(mt->y);
382 mt->height = SHORT(mt->height);
383 mt->angle = SHORT(mt->angle);
384 mt->type = SHORT(mt->type);
385 mt->options = SHORT(mt->options);
389 P_InitCreatureCorpseQueue(false); // false = do NOT scan for corpses
393 { // Don't need to check deathmatch spots
397 for(i = 0; i < MAXPLAYERS; i++)
399 playerCount += playeringame[i];
401 deathSpotsCount = deathmatch_p-deathmatchstarts;
402 if(deathSpotsCount < playerCount)
404 I_Error("P_LoadThings: Player count (%d) exceeds deathmatch "
405 "spots (%d)", playerCount, deathSpotsCount);
417 void P_LoadLineDefs(int lump)
425 numlines = W_LumpLength(lump)/sizeof(maplinedef_t);
426 lines = Z_Malloc(numlines*sizeof(line_t), PU_LEVEL, 0);
427 memset(lines, 0, numlines*sizeof(line_t));
428 data = W_CacheLumpNum(lump, PU_STATIC);
430 mld = (maplinedef_t *)data;
432 for(i = 0; i < numlines; i++, mld++, ld++)
434 ld->flags = SHORT(mld->flags);
436 // Old line special info ...
437 //ld->special = SHORT(mld->special);
438 //ld->tag = SHORT(mld->tag);
440 // New line special info ...
441 ld->special = mld->special;
442 ld->arg1 = mld->arg1;
443 ld->arg2 = mld->arg2;
444 ld->arg3 = mld->arg3;
445 ld->arg4 = mld->arg4;
446 ld->arg5 = mld->arg5;
448 v1 = ld->v1 = &vertexes[SHORT(mld->v1)];
449 v2 = ld->v2 = &vertexes[SHORT(mld->v2)];
450 ld->dx = v2->x - v1->x;
451 ld->dy = v2->y - v1->y;
453 ld->slopetype = ST_VERTICAL;
455 ld->slopetype = ST_HORIZONTAL;
458 if (FixedDiv (ld->dy , ld->dx) > 0)
459 ld->slopetype = ST_POSITIVE;
461 ld->slopetype = ST_NEGATIVE;
466 ld->bbox[BOXLEFT] = v1->x;
467 ld->bbox[BOXRIGHT] = v2->x;
471 ld->bbox[BOXLEFT] = v2->x;
472 ld->bbox[BOXRIGHT] = v1->x;
476 ld->bbox[BOXBOTTOM] = v1->y;
477 ld->bbox[BOXTOP] = v2->y;
481 ld->bbox[BOXBOTTOM] = v2->y;
482 ld->bbox[BOXTOP] = v1->y;
484 ld->sidenum[0] = SHORT(mld->sidenum[0]);
485 ld->sidenum[1] = SHORT(mld->sidenum[1]);
486 if (ld->sidenum[0] != -1)
487 ld->frontsector = sides[ld->sidenum[0]].sector;
490 if (ld->sidenum[1] != -1)
491 ld->backsector = sides[ld->sidenum[1]].sector;
508 void P_LoadSideDefs (int lump)
515 numsides = W_LumpLength (lump) / sizeof(mapsidedef_t);
516 sides = Z_Malloc (numsides*sizeof(side_t),PU_LEVEL,0);
517 memset (sides, 0, numsides*sizeof(side_t));
518 data = W_CacheLumpNum (lump,PU_STATIC);
520 msd = (mapsidedef_t *)data;
523 // Make sure primary lumps are used for texture searching
526 for(i = 0; i < numsides; i++, msd++, sd++)
528 sd->textureoffset = SHORT(msd->textureoffset)<<FRACBITS;
529 sd->rowoffset = SHORT(msd->rowoffset)<<FRACBITS;
530 sd->toptexture = R_TextureNumForName(msd->toptexture);
531 sd->bottomtexture = R_TextureNumForName(msd->bottomtexture);
532 sd->midtexture = R_TextureNumForName(msd->midtexture);
533 sd->sector = §ors[SHORT(msd->sector)];
550 void P_LoadBlockMap (int lump)
554 blockmaplump = W_CacheLumpNum (lump,PU_LEVEL);
555 blockmap = blockmaplump+4;
556 count = W_LumpLength (lump)/2;
557 for (i=0 ; i<count ; i++)
558 blockmaplump[i] = SHORT(blockmaplump[i]);
560 bmaporgx = blockmaplump[0]<<FRACBITS;
561 bmaporgy = blockmaplump[1]<<FRACBITS;
562 bmapwidth = blockmaplump[2];
563 bmapheight = blockmaplump[3];
565 // clear out mobj chains
566 count = sizeof(*blocklinks)* bmapwidth*bmapheight;
567 blocklinks = Z_Malloc (count,PU_LEVEL, 0);
568 memset (blocklinks, 0, count);
579 = Builds sector line lists and subsector sector numbers
580 = Finds block bounding boxes for sectors
584 void P_GroupLines (void)
595 // look up sector number for each subsector
597 for (i=0 ; i<numsubsectors ; i++, ss++)
599 seg = &segs[ss->firstline];
600 ss->sector = seg->sidedef->sector;
603 // count number of lines in each sector
606 for (i=0 ; i<numlines ; i++, li++)
609 li->frontsector->linecount++;
610 if (li->backsector && li->backsector != li->frontsector)
612 li->backsector->linecount++;
617 // build line tables for each sector
618 linebuffer = Z_Malloc (total*4, PU_LEVEL, 0);
620 for (i=0 ; i<numsectors ; i++, sector++)
623 sector->lines = linebuffer;
625 for (j=0 ; j<numlines ; j++, li++)
627 if (li->frontsector == sector || li->backsector == sector)
630 M_AddToBox (bbox, li->v1->x, li->v1->y);
631 M_AddToBox (bbox, li->v2->x, li->v2->y);
634 if (linebuffer - sector->lines != sector->linecount)
635 I_Error ("P_GroupLines: miscounted");
637 // set the degenmobj_t to the middle of the bounding box
638 sector->soundorg.x = (bbox[BOXRIGHT]+bbox[BOXLEFT])/2;
639 sector->soundorg.y = (bbox[BOXTOP]+bbox[BOXBOTTOM])/2;
641 // adjust bounding box to map blocks
642 block = (bbox[BOXTOP]-bmaporgy+MAXRADIUS)>>MAPBLOCKSHIFT;
643 block = block >= bmapheight ? bmapheight-1 : block;
644 sector->blockbox[BOXTOP]=block;
646 block = (bbox[BOXBOTTOM]-bmaporgy-MAXRADIUS)>>MAPBLOCKSHIFT;
647 block = block < 0 ? 0 : block;
648 sector->blockbox[BOXBOTTOM]=block;
650 block = (bbox[BOXRIGHT]-bmaporgx+MAXRADIUS)>>MAPBLOCKSHIFT;
651 block = block >= bmapwidth ? bmapwidth-1 : block;
652 sector->blockbox[BOXRIGHT]=block;
654 block = (bbox[BOXLEFT]-bmaporgx-MAXRADIUS)>>MAPBLOCKSHIFT;
655 block = block < 0 ? 0 : block;
656 sector->blockbox[BOXLEFT]=block;
663 float AccurateDistance(fixed_t dx,fixed_t dy)
665 float fx = FIX2FLT(dx), fy = FIX2FLT(dy);
667 return (float)sqrt(fx*fx + fy*fy);
671 #define MAX_CC_SIDES 64
673 int detSideFloat(fvertex_t *pnt, fdivline_t *dline)
676 (AY-CY)(BX-AX)-(AX-CX)(BY-AY)
677 s = -----------------------------
680 If s<0 C is left of AB (you can just check the numerator)
681 If s>0 C is right of AB
684 // We'll return false if the point c is on the left side.
685 /* float ax = FIX2FLT(a->x), ay = FIX2FLT(a->y);
686 float bx = FIX2FLT(b->x), by = FIX2FLT(b->y);
687 float cx = FIX2FLT(c->x), cy = FIX2FLT(c->y);*/
688 //float ax = dline->x, ay = dline->y;
689 //float bx = ax + dline->dx, by = ay + dline->dy;
691 // REWRITE using dline->dx and dline->dy for (bx-ax) and (by-ay).
693 //float s = /*(*/(ay-pnt->y)*(bx-ax)-(ax-pnt->x)*(by-ay);//)/l2;
694 float s = (dline->y-pnt->y)*dline->dx-(dline->x-pnt->x)*dline->dy;
701 // Lines start-end and fdiv must intersect.
702 float findIntersectionVertex( fvertex_t *start, fvertex_t *end,
703 fdivline_t *fdiv, fvertex_t *inter )
705 float ax = start->x, ay = start->y, bx = end->x, by = end->y;
706 float cx = fdiv->x, cy = fdiv->y, dx = cx+fdiv->dx, dy = cy+fdiv->dy;
709 (YA-YC)(XD-XC)-(XA-XC)(YD-YC)
710 r = ----------------------------- (eqn 1)
711 (XB-XA)(YD-YC)-(YB-YA)(XD-XC)
714 float r = ((ay-cy)*(dx-cx)-(ax-cx)*(dy-cy)) /
715 ((bx-ax)*(dy-cy)-(by-ay)*(dx-cx));
720 inter->x = ax + r*(bx-ax);
721 inter->y = ay + r*(by-ay);
726 void P_ConvexCarver(subsector_t *ssec, int num, divline_t *list)
728 //extern void OGL_DrawEdges(int num,fvertex_t *list,int,fdivline_t*,int);
730 int numclippers = num+ssec->numlines;
731 fdivline_t *clippers =
732 (fdivline_t*)_alloca(numclippers*sizeof(fdivline_t));
733 int i, k, numedgepoints;
734 fvertex_t *edgepoints;
735 unsigned char sidelist[MAX_CC_SIDES];
740 // Convert the divlines to float, in reverse order.
741 //printf( "%d clippers (%d pls, %d
742 //segs):\n",numclippers,num,ssec->numlines);
743 for(i=0; i<numclippers; i++)
747 clippers[i].x = FIX2FLT(list[num-i-1].x);
748 clippers[i].y = FIX2FLT(list[num-i-1].y);
749 clippers[i].dx = FIX2FLT(list[num-i-1].dx);
750 clippers[i].dy = FIX2FLT(list[num-i-1].dy);
754 seg_t *seg = segs+(ssec->firstline+i-num);
755 clippers[i].x = FIX2FLT(seg->v1->x);
756 clippers[i].y = FIX2FLT(seg->v1->y);
757 clippers[i].dx = FIX2FLT(seg->v2->x - seg->v1->x);
758 clippers[i].dy = FIX2FLT(seg->v2->y - seg->v1->y);
760 //printf( " %d: x=%f y=%f dx=%f
761 //dy=%f\n",i,clippers[i].x,clippers[i].y,clippers[i].dx,clippers[i].dy);
765 // Setup the 'worldwide' polygon.
767 edgepoints = (fvertex_t*)malloc(numedgepoints*sizeof(fvertex_t));
769 edgepoints[0].x = -32768;
770 edgepoints[0].y = 32768;
772 edgepoints[1].x = 32768;
773 edgepoints[1].y = 32768;
775 edgepoints[2].x = 32768;
776 edgepoints[2].y = -32768;
778 edgepoints[3].x = -32768;
779 edgepoints[3].y = -32768;
781 //printf( "carving (with %d clippers):\n",numclippers);
783 // We'll now clip the polygon with each of the divlines. The left side of
784 // each divline is discarded.
785 //OGL_DrawEdges(numedgepoints,edgepoints,numclippers,clippers,-1);
786 for(i=0; i<numclippers; i++)
788 fdivline_t *curclip = clippers+i;
790 //OGL_DrawEdges(numedgepoints,edgepoints,numclippers,clippers,i);
791 // First we'll determine the side of each vertex. Points are allowed
792 // to be on the line.
793 for(k=0; k<numedgepoints; k++)
795 sidelist[k] = detSideFloat(edgepoints+k, curclip);
796 //printf( "%d: %d, ",k,sidelist[k]);
800 for(k=0; k<numedgepoints; k++)
802 int startIdx = k, endIdx = k+1;
804 // Check the end index.
805 if(endIdx == numedgepoints) endIdx = 0; // Wrap-around.
807 // Clipping will happen when the ends are on different sides.
808 if(sidelist[startIdx] != sidelist[endIdx])
811 //printf( " clipping %d - %d\n",startIdx,endIdx);
812 // Find the intersection point of intersecting lines.
813 findIntersectionVertex(edgepoints+startIdx, edgepoints+endIdx,
816 // Add the new vertex. Also modify the sidelist.
818 (fvertex_t*)realloc(edgepoints,(++numedgepoints)*sizeof(fvertex_t));
819 if(numedgepoints >= MAX_CC_SIDES) I_Error("Too many points in
822 // Make room for the new vertex.
823 memmove(edgepoints+endIdx+1, edgepoints+endIdx,
824 (numedgepoints-endIdx-1)*sizeof(fvertex_t));
825 memcpy(edgepoints+endIdx, &newvert, sizeof(newvert));
827 memmove(sidelist+endIdx+1, sidelist+endIdx,
828 numedgepoints-endIdx-1);
829 sidelist[endIdx] = 1;
831 // Skip over the new vertex.
836 // Now we must discard the points that are on the wrong side.
837 for(k=0; k<numedgepoints; k++)
840 memmove(edgepoints+k, edgepoints+k+1,
841 (numedgepoints-k-1)*sizeof(fvertex_t));
842 memmove(sidelist+k, sidelist+k+1, numedgepoints-k-1);
847 //OGL_DrawEdges(numedgepoints,edgepoints,numclippers,clippers,i);
852 //I_Error("All carved away!\n");
853 printf( "All carved away: subsector %p\n", ssec);
854 ssec->numedgeverts = 0;
856 ssec->origedgeverts = 0;
860 // Screen out consecutive identical points.
861 for(i=0; i<numedgepoints; i++)
864 if(previdx < 0) previdx = numedgepoints-1;
865 if(edgepoints[i].x == edgepoints[previdx].x
866 && edgepoints[i].y == edgepoints[previdx].y)
868 // This point (i) must be removed.
869 memmove(edgepoints+i, edgepoints+i+1,
870 sizeof(fvertex_t)*(numedgepoints-i-1));
875 // We need these with dynamic lights.
876 ssec->origedgeverts =
877 (fvertex_t*)Z_Malloc(sizeof(fvertex_t)*numedgepoints, PU_LEVEL, 0);
878 memcpy(ssec->origedgeverts, edgepoints,
879 sizeof(fvertex_t)*numedgepoints);
881 // Find the center point. Do this by first finding the bounding box.
882 //cenx = edgepoints[0].x;
883 //ceny = edgepoints[0].y;
884 ssec->bbox[0].x = ssec->bbox[1].x = edgepoints[0].x;
885 ssec->bbox[0].y = ssec->bbox[1].y = edgepoints[0].y;
886 for(i=1; i<numedgepoints; i++)
888 //printf( " %i: (%f, %f)\n", i, edgepoints[i].x,
890 //cenx += edgepoints[i].x;
891 //ceny += edgepoints[i].y;
892 if(edgepoints[i].x < ssec->bbox[0].x) ssec->bbox[0].x =
894 if(edgepoints[i].y < ssec->bbox[0].y) ssec->bbox[0].y =
896 if(edgepoints[i].x > ssec->bbox[1].x) ssec->bbox[1].x =
898 if(edgepoints[i].y > ssec->bbox[1].y) ssec->bbox[1].y =
901 //cenx /= numedgepoints;
902 //ceny /= numedgepoints;
903 ssec->midpoint.x = (ssec->bbox[1].x+ssec->bbox[0].x)/2;
904 ssec->midpoint.y = (ssec->bbox[1].y+ssec->bbox[0].y)/2;
908 // Make slight adjustments to patch up those ugly, small gaps.
909 for(i=0; i<numedgepoints; i++)
911 float dx = edgepoints[i].x - ssec->midpoint.x,
912 dy = edgepoints[i].y - ssec->midpoint.y;
913 float dlen = (float) sqrt(dx*dx + dy*dy) * 3;
916 edgepoints[i].x += dx/dlen;
917 edgepoints[i].y += dy/dlen;
921 ssec->numedgeverts = numedgepoints;
923 (fvertex_t*)Z_Malloc(sizeof(fvertex_t)*numedgepoints,PU_LEVEL,0);
924 memcpy(ssec->edgeverts, edgepoints, sizeof(fvertex_t)*numedgepoints);
927 // We're done, free the edgepoints memory.
932 void P_CreateFloorsAndCeilings( int bspnode, int numdivlines,
933 divline_t* divlines )
936 divline_t *childlist, *dl;
937 int childlistsize = numdivlines+1;
939 // If this is a subsector we are dealing with, begin carving with the
941 if(bspnode & NF_SUBSECTOR)
944 // We have arrived at a subsector. The divline list contains all
945 // the partition lines that carve out the subsector.
947 //printf( "subsector %d: %d
948 //divlines\n",bspnode&(~NF_SUBSECTOR),numdivlines);
950 int ssidx = bspnode & (~NF_SUBSECTOR);
952 P_ConvexCarver(subsectors+ssidx, numdivlines, divlines);
954 //printf( "subsector %d: %d edgeverts\n", ssidx,
955 //subsectors[ssidx].numedgeverts);
956 // This leaf is done.
960 // Get a pointer to the node.
961 nod = nodes + bspnode;
963 // Allocate a new list for each child.
964 childlist = (divline_t*)malloc(childlistsize*sizeof(divline_t));
966 // Copy the previous lines.
967 if(divlines) memcpy(childlist,divlines,numdivlines*sizeof(divline_t));
969 dl = childlist + numdivlines;
972 // The right child gets the original line (LEFT side clipped).
975 P_CreateFloorsAndCeilings(nod->children[0],childlistsize,childlist);
977 // The left side. We must reverse the line, otherwise the wrong
978 // side would get clipped.
981 P_CreateFloorsAndCeilings(nod->children[1],childlistsize,childlist);
983 // We are finishing with this node, free the allocated list.
992 // We need to check all the linedefs.
993 for(i=0; i<numlines; i++)
995 line_t *line = lines + i;
996 sector_t *front = line->frontsector, *back = line->backsector;
999 if(!front || !back) continue;
1000 // Both the front and back sectors must have the sky ceiling.
1001 if(front->ceilingpic != skyflatnum || back->ceilingpic != skyflatnum)
1003 // Operate on the lower sector.
1004 /*ST_Message("Line %d (f:%d, b:%d).\n", i, front->ceilingheight >>
1006 back->ceilingheight >> FRACBITS);*/
1007 if(front->ceilingheight < back->ceilingheight)
1009 fix = (back->ceilingheight-front->ceilingheight) >> FRACBITS;
1010 if(fix > front->skyfix) front->skyfix = fix;
1012 else if(front->ceilingheight > back->ceilingheight)
1014 fix = (front->ceilingheight-back->ceilingheight) >> FRACBITS;
1015 if(fix > back->skyfix) back->skyfix = fix;
1022 //=============================================================================
1033 extern boolean i_CDMusic;
1035 void P_SetupLevel(int episode, int map, int playermask, skill_t skill)
1044 for(i = 0; i < MAXPLAYERS; i++)
1046 players[i].killcount = players[i].secretcount
1047 = players[i].itemcount = 0;
1049 players[consoleplayer].viewz = 1; // will be set by player think
1051 if(i_CDMusic == false)
1053 S_StartSongName("chess", true); // Waiting-for-level-load song
1056 Z_FreeTags(PU_LEVEL, PU_PURGELEVEL-1);
1067 sprintf(auxName, "%sMAP%02d.WAD", DevMapsDir, map);
1068 W_OpenAuxiliary(auxName);
1070 sprintf(lumpname, "MAP%02d", map);
1071 lumpnum = W_GetNumForName(lumpname);
1073 // Begin processing map lumps
1074 // Note: most of this ordering is important
1076 P_LoadBlockMap(lumpnum+ML_BLOCKMAP);
1077 P_LoadVertexes(lumpnum+ML_VERTEXES);
1078 P_LoadSectors(lumpnum+ML_SECTORS);
1079 P_LoadSideDefs(lumpnum+ML_SIDEDEFS);
1080 P_LoadLineDefs(lumpnum+ML_LINEDEFS);
1081 P_LoadSubsectors(lumpnum+ML_SSECTORS);
1082 P_LoadNodes(lumpnum+ML_NODES);
1083 P_LoadSegs(lumpnum+ML_SEGS);
1086 // We need to carve out the floor/ceiling polygons of each subsector.
1087 // Walk the tree to do this.
1088 //ST_Message( "Floor/ceiling creation: begin at %d, ", ticcount);
1089 P_CreateFloorsAndCeilings(numnodes-1, 0, 0);
1090 // Also check if the sky needs a fix.
1094 rejectmatrix = W_CacheLumpNum(lumpnum+ML_REJECT, PU_LEVEL);
1098 deathmatch_p = deathmatchstarts;
1099 P_LoadThings(lumpnum+ML_THINGS);
1100 PO_Init(lumpnum+ML_THINGS); // Initialize the polyobjs
1101 P_LoadACScripts(lumpnum+ML_BEHAVIOR); // ACS object code
1103 // End of map lump processing
1107 // Close the auxiliary file, but don't free its loaded lumps.
1108 // The next call to W_OpenAuxiliary() will do a full shutdown
1109 // of the current auxiliary WAD (free lumps and info lists).
1110 W_CloseAuxiliaryFile();
1114 // If deathmatch, randomly spawn the active players
1118 for (i=0 ; i<MAXPLAYERS ; i++)
1120 if (playeringame[i])
1121 { // must give a player spot before deathmatchspawn
1122 mobj = P_SpawnMobj (playerstarts[0][i].x<<16,
1123 playerstarts[0][i].y<<16,0, MT_PLAYER_FIGHTER);
1124 players[i].mo = mobj;
1125 G_DeathMatchSpawnPlayer (i);
1126 P_RemoveMobj (mobj);
1129 parm = M_CheckParm("-timer");
1130 if(parm && parm < myargc-1)
1132 TimerGame = atoi(myargv[parm+1])*35*60;
1136 // set up world state
1139 // build subsector connect matrix
1140 // P_ConnectSubsectors ();
1142 // Load colormap and set the fullbright flag
1143 i = P_GetMapFadeTable(gamemap);
1144 W_ReadLump(i, colormaps);
1145 if(i == W_GetNumForName("COLORMAP"))
1147 LevelUseFullBright = true;
1149 OGL_UseWhiteFog(false);
1153 { // Probably fog ... don't use fullbright sprites
1154 LevelUseFullBright = false;
1156 if(i == W_GetNumForName("FOGMAP"))
1158 // Tell the renderer to turn on the fog.
1159 OGL_UseWhiteFog(true);
1168 // Check if the level is a lightning level
1172 SN_StopAllSequences();
1173 S_StartSong(gamemap, true);
1175 //printf ("free memory: 0x%x\n", Z_FreeMemory());
1179 //==========================================================================
1183 //==========================================================================
1185 static void InitMapInfo(void)
1195 // Put defaults into MapInfo[0]
1198 info->warpTrans = 0;
1199 info->nextMap = 1; // Always go to map 1 if not specified
1201 info->sky1Texture = R_TextureNumForName(DEFAULT_SKY_NAME);
1202 info->sky2Texture = info->sky1Texture;
1203 info->sky1ScrollDelta = 0;
1204 info->sky2ScrollDelta = 0;
1205 info->doubleSky = false;
1206 info->lightning = false;
1207 info->fadetable = W_GetNumForName(DEFAULT_FADE_TABLE);
1208 strcpy(info->name, UNKNOWN_MAP_NAME);
1210 // strcpy(info->songLump, DEFAULT_SONG_LUMP);
1211 SC_Open(MAPINFO_SCRIPT_NAME);
1212 while(SC_GetString())
1214 if(SC_Compare("MAP") == false)
1216 SC_ScriptError(NULL);
1219 if(sc_Number < 1 || sc_Number > 99)
1221 SC_ScriptError(NULL);
1225 info = &MapInfo[map];
1227 // Save song lump name
1228 strcpy(songMulch, info->songLump);
1230 // Copy defaults to current map definition
1231 memcpy(info, &MapInfo[0], sizeof(*info));
1233 // Restore song lump name
1234 strcpy(info->songLump, songMulch);
1236 // The warp translation defaults to the map number
1237 info->warpTrans = map;
1239 // Map name must follow the number
1241 strcpy(info->name, sc_String);
1243 // Process optional tokens
1244 while(SC_GetString())
1246 if(SC_Compare("MAP"))
1247 { // Start next map definition
1251 mcmdValue = MapCmdIDs[SC_MustMatchString(MapCmdNames)];
1256 info->cluster = sc_Number;
1258 case MCMD_WARPTRANS:
1260 info->warpTrans = sc_Number;
1264 info->nextMap = sc_Number;
1268 info->cdTrack = sc_Number;
1272 info->sky1Texture = R_TextureNumForName(sc_String);
1274 info->sky1ScrollDelta = sc_Number<<8;
1278 info->sky2Texture = R_TextureNumForName(sc_String);
1280 info->sky2ScrollDelta = sc_Number<<8;
1282 case MCMD_DOUBLESKY:
1283 info->doubleSky = true;
1285 case MCMD_LIGHTNING:
1286 info->lightning = true;
1288 case MCMD_FADETABLE:
1290 info->fadetable = W_GetNumForName(sc_String);
1292 case MCMD_CD_STARTTRACK:
1293 case MCMD_CD_END1TRACK:
1294 case MCMD_CD_END2TRACK:
1295 case MCMD_CD_END3TRACK:
1296 case MCMD_CD_INTERTRACK:
1297 case MCMD_CD_TITLETRACK:
1299 cd_NonLevelTracks[mcmdValue-MCMD_CD_STARTTRACK] =
1304 mapMax = map > mapMax ? map : mapMax;
1310 //==========================================================================
1314 //==========================================================================
1316 int P_GetMapCluster(int map)
1318 return MapInfo[QualifyMap(map)].cluster;
1321 //==========================================================================
1325 //==========================================================================
1327 int P_GetMapCDTrack(int map)
1329 return MapInfo[QualifyMap(map)].cdTrack;
1332 //==========================================================================
1334 // P_GetMapWarpTrans
1336 //==========================================================================
1338 int P_GetMapWarpTrans(int map)
1340 return MapInfo[QualifyMap(map)].warpTrans;
1343 //==========================================================================
1347 //==========================================================================
1349 int P_GetMapNextMap(int map)
1351 return MapInfo[QualifyMap(map)].nextMap;
1354 //==========================================================================
1358 // Returns the actual map number given a warp map number.
1360 //==========================================================================
1362 int P_TranslateMap(int map)
1366 for(i = 1; i < 99; i++) // Make this a macro
1368 if(MapInfo[i].warpTrans == map)
1377 //==========================================================================
1379 // P_GetMapSky1Texture
1381 //==========================================================================
1383 int P_GetMapSky1Texture(int map)
1385 return MapInfo[QualifyMap(map)].sky1Texture;
1388 //==========================================================================
1390 // P_GetMapSky2Texture
1392 //==========================================================================
1394 int P_GetMapSky2Texture(int map)
1396 return MapInfo[QualifyMap(map)].sky2Texture;
1399 //==========================================================================
1403 //==========================================================================
1405 char *P_GetMapName(int map)
1407 return MapInfo[QualifyMap(map)].name;
1410 //==========================================================================
1412 // P_GetMapSky1ScrollDelta
1414 //==========================================================================
1416 fixed_t P_GetMapSky1ScrollDelta(int map)
1418 return MapInfo[QualifyMap(map)].sky1ScrollDelta;
1421 //==========================================================================
1423 // P_GetMapSky2ScrollDelta
1425 //==========================================================================
1427 fixed_t P_GetMapSky2ScrollDelta(int map)
1429 return MapInfo[QualifyMap(map)].sky2ScrollDelta;
1432 //==========================================================================
1434 // P_GetMapDoubleSky
1436 //==========================================================================
1438 boolean P_GetMapDoubleSky(int map)
1440 return MapInfo[QualifyMap(map)].doubleSky;
1443 //==========================================================================
1445 // P_GetMapLightning
1447 //==========================================================================
1449 boolean P_GetMapLightning(int map)
1451 return MapInfo[QualifyMap(map)].lightning;
1454 //==========================================================================
1456 // P_GetMapFadeTable
1458 //==========================================================================
1460 boolean P_GetMapFadeTable(int map)
1462 return MapInfo[QualifyMap(map)].fadetable;
1465 //==========================================================================
1469 //==========================================================================
1471 char *P_GetMapSongLump(int map)
1473 if(!strcasecmp(MapInfo[QualifyMap(map)].songLump, DEFAULT_SONG_LUMP))
1479 return MapInfo[QualifyMap(map)].songLump;
1483 //==========================================================================
1487 //==========================================================================
1489 void P_PutMapSongLump(int map, char *lumpName)
1491 if(map < 1 || map > MapCount)
1495 strcpy(MapInfo[map].songLump, lumpName);
1498 //==========================================================================
1500 // P_GetCDStartTrack
1502 //==========================================================================
1504 int P_GetCDStartTrack(void)
1506 return cd_NonLevelTracks[MCMD_CD_STARTTRACK-MCMD_CD_STARTTRACK];
1509 //==========================================================================
1513 //==========================================================================
1515 int P_GetCDEnd1Track(void)
1517 return cd_NonLevelTracks[MCMD_CD_END1TRACK-MCMD_CD_STARTTRACK];
1520 //==========================================================================
1524 //==========================================================================
1526 int P_GetCDEnd2Track(void)
1528 return cd_NonLevelTracks[MCMD_CD_END2TRACK-MCMD_CD_STARTTRACK];
1531 //==========================================================================
1535 //==========================================================================
1537 int P_GetCDEnd3Track(void)
1539 return cd_NonLevelTracks[MCMD_CD_END3TRACK-MCMD_CD_STARTTRACK];
1542 //==========================================================================
1544 // P_GetCDIntermissionTrack
1546 //==========================================================================
1548 int P_GetCDIntermissionTrack(void)
1550 return cd_NonLevelTracks[MCMD_CD_INTERTRACK-MCMD_CD_STARTTRACK];
1553 //==========================================================================
1555 // P_GetCDTitleTrack
1557 //==========================================================================
1559 int P_GetCDTitleTrack(void)
1561 return cd_NonLevelTracks[MCMD_CD_TITLETRACK-MCMD_CD_STARTTRACK];
1564 //==========================================================================
1568 //==========================================================================
1570 static int QualifyMap(int map)
1572 return (map < 1 || map > MapCount) ? 0 : map;
1575 //==========================================================================
1579 //==========================================================================
1585 P_InitFTAnims(); // Init flat and texture animations
1586 P_InitTerrainTypes();
1588 R_InitSprites(sprnames);
1592 // Special early initializer needed to start sound before R_Init()
1593 void InitMapMusicInfo(void)
1597 for (i=0; i<99; i++)
1599 strcpy(MapInfo[i].songLump, DEFAULT_SONG_LUMP);
1609 printf("My debug stuff ----------------------\n");
1610 printf("gamemap=%d\n",gamemap);
1611 for (i=0; i<10; i++)
1613 printf("i=%d songlump=%s\n",i,MapInfo[i].songLump);