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 = (fdivline_t*)malloc(numclippers*sizeof(fdivline_t));
732 int i, k, numedgepoints;
733 fvertex_t *edgepoints;
734 unsigned char sidelist[MAX_CC_SIDES];
739 // Convert the divlines to float, in reverse order.
740 //printf( "%d clippers (%d pls, %d
741 //segs):\n",numclippers,num,ssec->numlines);
742 for(i=0; i<numclippers; i++)
746 clippers[i].x = FIX2FLT(list[num-i-1].x);
747 clippers[i].y = FIX2FLT(list[num-i-1].y);
748 clippers[i].dx = FIX2FLT(list[num-i-1].dx);
749 clippers[i].dy = FIX2FLT(list[num-i-1].dy);
753 seg_t *seg = segs+(ssec->firstline+i-num);
754 clippers[i].x = FIX2FLT(seg->v1->x);
755 clippers[i].y = FIX2FLT(seg->v1->y);
756 clippers[i].dx = FIX2FLT(seg->v2->x - seg->v1->x);
757 clippers[i].dy = FIX2FLT(seg->v2->y - seg->v1->y);
759 //printf( " %d: x=%f y=%f dx=%f
760 //dy=%f\n",i,clippers[i].x,clippers[i].y,clippers[i].dx,clippers[i].dy);
764 // Setup the 'worldwide' polygon.
766 edgepoints = (fvertex_t*)malloc(numedgepoints*sizeof(fvertex_t));
768 edgepoints[0].x = -32768;
769 edgepoints[0].y = 32768;
771 edgepoints[1].x = 32768;
772 edgepoints[1].y = 32768;
774 edgepoints[2].x = 32768;
775 edgepoints[2].y = -32768;
777 edgepoints[3].x = -32768;
778 edgepoints[3].y = -32768;
780 //printf( "carving (with %d clippers):\n",numclippers);
782 // We'll now clip the polygon with each of the divlines. The left side of
783 // each divline is discarded.
784 //OGL_DrawEdges(numedgepoints,edgepoints,numclippers,clippers,-1);
785 for(i=0; i<numclippers; i++)
787 fdivline_t *curclip = clippers+i;
789 //OGL_DrawEdges(numedgepoints,edgepoints,numclippers,clippers,i);
790 // First we'll determine the side of each vertex. Points are allowed
791 // to be on the line.
792 for(k=0; k<numedgepoints; k++)
794 sidelist[k] = detSideFloat(edgepoints+k, curclip);
795 //printf( "%d: %d, ",k,sidelist[k]);
799 for(k=0; k<numedgepoints; k++)
801 int startIdx = k, endIdx = k+1;
803 // Check the end index.
804 if(endIdx == numedgepoints) endIdx = 0; // Wrap-around.
806 // Clipping will happen when the ends are on different sides.
807 if(sidelist[startIdx] != sidelist[endIdx])
810 //printf( " clipping %d - %d\n",startIdx,endIdx);
811 // Find the intersection point of intersecting lines.
812 findIntersectionVertex(edgepoints+startIdx, edgepoints+endIdx,
815 // Add the new vertex. Also modify the sidelist.
817 (fvertex_t*)realloc(edgepoints,(++numedgepoints)*sizeof(fvertex_t));
818 if(numedgepoints >= MAX_CC_SIDES) I_Error("Too many points in carver.\n");
820 // Make room for the new vertex.
821 memmove(edgepoints+endIdx+1, edgepoints+endIdx,
822 (numedgepoints-endIdx-1)*sizeof(fvertex_t));
823 memcpy(edgepoints+endIdx, &newvert, sizeof(newvert));
825 memmove(sidelist+endIdx+1, sidelist+endIdx,
826 numedgepoints-endIdx-1);
827 sidelist[endIdx] = 1;
829 // Skip over the new vertex.
834 // Now we must discard the points that are on the wrong side.
835 for(k=0; k<numedgepoints; k++)
838 memmove(edgepoints+k, edgepoints+k+1,
839 (numedgepoints-k-1)*sizeof(fvertex_t));
840 memmove(sidelist+k, sidelist+k+1, numedgepoints-k-1);
845 //OGL_DrawEdges(numedgepoints,edgepoints,numclippers,clippers,i);
850 //I_Error("All carved away!\n");
851 printf( "All carved away: subsector %p\n", ssec);
852 ssec->numedgeverts = 0;
854 ssec->origedgeverts = 0;
858 // Screen out consecutive identical points.
859 for(i=0; i<numedgepoints; i++)
862 if(previdx < 0) previdx = numedgepoints-1;
863 if(edgepoints[i].x == edgepoints[previdx].x
864 && edgepoints[i].y == edgepoints[previdx].y)
866 // This point (i) must be removed.
867 memmove(edgepoints+i, edgepoints+i+1,
868 sizeof(fvertex_t)*(numedgepoints-i-1));
873 // We need these with dynamic lights.
874 ssec->origedgeverts =
875 (fvertex_t*)Z_Malloc(sizeof(fvertex_t)*numedgepoints, PU_LEVEL, 0);
876 memcpy(ssec->origedgeverts, edgepoints,
877 sizeof(fvertex_t)*numedgepoints);
879 // Find the center point. Do this by first finding the bounding box.
880 //cenx = edgepoints[0].x;
881 //ceny = edgepoints[0].y;
882 ssec->bbox[0].x = ssec->bbox[1].x = edgepoints[0].x;
883 ssec->bbox[0].y = ssec->bbox[1].y = edgepoints[0].y;
884 for(i=1; i<numedgepoints; i++)
886 //printf( " %i: (%f, %f)\n", i, edgepoints[i].x,
888 //cenx += edgepoints[i].x;
889 //ceny += edgepoints[i].y;
890 if(edgepoints[i].x < ssec->bbox[0].x) ssec->bbox[0].x =
892 if(edgepoints[i].y < ssec->bbox[0].y) ssec->bbox[0].y =
894 if(edgepoints[i].x > ssec->bbox[1].x) ssec->bbox[1].x =
896 if(edgepoints[i].y > ssec->bbox[1].y) ssec->bbox[1].y =
899 //cenx /= numedgepoints;
900 //ceny /= numedgepoints;
901 ssec->midpoint.x = (ssec->bbox[1].x+ssec->bbox[0].x)/2;
902 ssec->midpoint.y = (ssec->bbox[1].y+ssec->bbox[0].y)/2;
906 // Make slight adjustments to patch up those ugly, small gaps.
907 for(i=0; i<numedgepoints; i++)
909 float dx = edgepoints[i].x - ssec->midpoint.x,
910 dy = edgepoints[i].y - ssec->midpoint.y;
911 float dlen = (float) sqrt(dx*dx + dy*dy) * 3;
914 edgepoints[i].x += dx/dlen;
915 edgepoints[i].y += dy/dlen;
919 ssec->numedgeverts = numedgepoints;
921 (fvertex_t*)Z_Malloc(sizeof(fvertex_t)*numedgepoints,PU_LEVEL,0);
922 memcpy(ssec->edgeverts, edgepoints, sizeof(fvertex_t)*numedgepoints);
925 // We're done, free the edgepoints memory.
931 void P_CreateFloorsAndCeilings( int bspnode, int numdivlines,
932 divline_t* divlines )
935 divline_t *childlist, *dl;
936 int childlistsize = numdivlines+1;
938 // If this is a subsector we are dealing with, begin carving with the
940 if(bspnode & NF_SUBSECTOR)
943 // We have arrived at a subsector. The divline list contains all
944 // the partition lines that carve out the subsector.
946 //printf( "subsector %d: %d
947 //divlines\n",bspnode&(~NF_SUBSECTOR),numdivlines);
949 int ssidx = bspnode & (~NF_SUBSECTOR);
951 P_ConvexCarver(subsectors+ssidx, numdivlines, divlines);
953 //printf( "subsector %d: %d edgeverts\n", ssidx,
954 //subsectors[ssidx].numedgeverts);
955 // This leaf is done.
959 // Get a pointer to the node.
960 nod = nodes + bspnode;
962 // Allocate a new list for each child.
963 childlist = (divline_t*)malloc(childlistsize*sizeof(divline_t));
965 // Copy the previous lines.
966 if(divlines) memcpy(childlist,divlines,numdivlines*sizeof(divline_t));
968 dl = childlist + numdivlines;
971 // The right child gets the original line (LEFT side clipped).
974 P_CreateFloorsAndCeilings(nod->children[0],childlistsize,childlist);
976 // The left side. We must reverse the line, otherwise the wrong
977 // side would get clipped.
980 P_CreateFloorsAndCeilings(nod->children[1],childlistsize,childlist);
982 // We are finishing with this node, free the allocated list.
991 // We need to check all the linedefs.
992 for(i=0; i<numlines; i++)
994 line_t *line = lines + i;
995 sector_t *front = line->frontsector, *back = line->backsector;
998 if(!front || !back) continue;
999 // Both the front and back sectors must have the sky ceiling.
1000 if(front->ceilingpic != skyflatnum || back->ceilingpic != skyflatnum)
1002 // Operate on the lower sector.
1003 /*ST_Message("Line %d (f:%d, b:%d).\n", i, front->ceilingheight >>
1005 back->ceilingheight >> FRACBITS);*/
1006 if(front->ceilingheight < back->ceilingheight)
1008 fix = (back->ceilingheight-front->ceilingheight) >> FRACBITS;
1009 if(fix > front->skyfix) front->skyfix = fix;
1011 else if(front->ceilingheight > back->ceilingheight)
1013 fix = (front->ceilingheight-back->ceilingheight) >> FRACBITS;
1014 if(fix > back->skyfix) back->skyfix = fix;
1021 //=============================================================================
1032 extern boolean i_CDMusic;
1034 void P_SetupLevel(int episode, int map, int playermask, skill_t skill)
1043 for(i = 0; i < MAXPLAYERS; i++)
1045 players[i].killcount = players[i].secretcount
1046 = players[i].itemcount = 0;
1048 players[consoleplayer].viewz = 1; // will be set by player think
1050 if(i_CDMusic == false)
1052 S_StartSongName("chess", true); // Waiting-for-level-load song
1055 Z_FreeTags(PU_LEVEL, PU_PURGELEVEL-1);
1066 sprintf(auxName, "%sMAP%02d.WAD", DevMapsDir, map);
1067 W_OpenAuxiliary(auxName);
1069 sprintf(lumpname, "MAP%02d", map);
1070 lumpnum = W_GetNumForName(lumpname);
1072 // Begin processing map lumps
1073 // Note: most of this ordering is important
1075 P_LoadBlockMap(lumpnum+ML_BLOCKMAP);
1076 P_LoadVertexes(lumpnum+ML_VERTEXES);
1077 P_LoadSectors(lumpnum+ML_SECTORS);
1078 P_LoadSideDefs(lumpnum+ML_SIDEDEFS);
1079 P_LoadLineDefs(lumpnum+ML_LINEDEFS);
1080 P_LoadSubsectors(lumpnum+ML_SSECTORS);
1081 P_LoadNodes(lumpnum+ML_NODES);
1082 P_LoadSegs(lumpnum+ML_SEGS);
1085 // We need to carve out the floor/ceiling polygons of each subsector.
1086 // Walk the tree to do this.
1087 //ST_Message( "Floor/ceiling creation: begin at %d, ", ticcount);
1088 P_CreateFloorsAndCeilings(numnodes-1, 0, 0);
1089 // Also check if the sky needs a fix.
1093 rejectmatrix = W_CacheLumpNum(lumpnum+ML_REJECT, PU_LEVEL);
1097 deathmatch_p = deathmatchstarts;
1098 P_LoadThings(lumpnum+ML_THINGS);
1099 PO_Init(lumpnum+ML_THINGS); // Initialize the polyobjs
1100 P_LoadACScripts(lumpnum+ML_BEHAVIOR); // ACS object code
1102 // End of map lump processing
1106 // Close the auxiliary file, but don't free its loaded lumps.
1107 // The next call to W_OpenAuxiliary() will do a full shutdown
1108 // of the current auxiliary WAD (free lumps and info lists).
1109 W_CloseAuxiliaryFile();
1113 // If deathmatch, randomly spawn the active players
1117 for (i=0 ; i<MAXPLAYERS ; i++)
1119 if (playeringame[i])
1120 { // must give a player spot before deathmatchspawn
1121 mobj = P_SpawnMobj (playerstarts[0][i].x<<16,
1122 playerstarts[0][i].y<<16,0, MT_PLAYER_FIGHTER);
1123 players[i].mo = mobj;
1124 G_DeathMatchSpawnPlayer (i);
1125 P_RemoveMobj (mobj);
1128 parm = M_CheckParm("-timer");
1129 if(parm && parm < myargc-1)
1131 TimerGame = atoi(myargv[parm+1])*35*60;
1135 // set up world state
1138 // build subsector connect matrix
1139 // P_ConnectSubsectors ();
1141 // Load colormap and set the fullbright flag
1142 i = P_GetMapFadeTable(gamemap);
1143 W_ReadLump(i, colormaps);
1144 if(i == W_GetNumForName("COLORMAP"))
1146 LevelUseFullBright = true;
1148 OGL_UseWhiteFog(false);
1152 { // Probably fog ... don't use fullbright sprites
1153 LevelUseFullBright = false;
1155 if(i == W_GetNumForName("FOGMAP"))
1157 // Tell the renderer to turn on the fog.
1158 OGL_UseWhiteFog(true);
1167 // Check if the level is a lightning level
1171 SN_StopAllSequences();
1172 S_StartSong(gamemap, true);
1174 //printf ("free memory: 0x%x\n", Z_FreeMemory());
1178 //==========================================================================
1182 //==========================================================================
1184 static void InitMapInfo(void)
1194 // Put defaults into MapInfo[0]
1197 info->warpTrans = 0;
1198 info->nextMap = 1; // Always go to map 1 if not specified
1200 info->sky1Texture = R_TextureNumForName(DEFAULT_SKY_NAME);
1201 info->sky2Texture = info->sky1Texture;
1202 info->sky1ScrollDelta = 0;
1203 info->sky2ScrollDelta = 0;
1204 info->doubleSky = false;
1205 info->lightning = false;
1206 info->fadetable = W_GetNumForName(DEFAULT_FADE_TABLE);
1207 strcpy(info->name, UNKNOWN_MAP_NAME);
1209 // strcpy(info->songLump, DEFAULT_SONG_LUMP);
1210 SC_Open(MAPINFO_SCRIPT_NAME);
1211 while(SC_GetString())
1213 if(SC_Compare("MAP") == false)
1215 SC_ScriptError(NULL);
1218 if(sc_Number < 1 || sc_Number > 99)
1220 SC_ScriptError(NULL);
1224 info = &MapInfo[map];
1226 // Save song lump name
1227 strcpy(songMulch, info->songLump);
1229 // Copy defaults to current map definition
1230 memcpy(info, &MapInfo[0], sizeof(*info));
1232 // Restore song lump name
1233 strcpy(info->songLump, songMulch);
1235 // The warp translation defaults to the map number
1236 info->warpTrans = map;
1238 // Map name must follow the number
1240 strcpy(info->name, sc_String);
1242 // Process optional tokens
1243 while(SC_GetString())
1245 if(SC_Compare("MAP"))
1246 { // Start next map definition
1250 mcmdValue = MapCmdIDs[SC_MustMatchString(MapCmdNames)];
1255 info->cluster = sc_Number;
1257 case MCMD_WARPTRANS:
1259 info->warpTrans = sc_Number;
1263 info->nextMap = sc_Number;
1267 info->cdTrack = sc_Number;
1271 info->sky1Texture = R_TextureNumForName(sc_String);
1273 info->sky1ScrollDelta = sc_Number<<8;
1277 info->sky2Texture = R_TextureNumForName(sc_String);
1279 info->sky2ScrollDelta = sc_Number<<8;
1281 case MCMD_DOUBLESKY:
1282 info->doubleSky = true;
1284 case MCMD_LIGHTNING:
1285 info->lightning = true;
1287 case MCMD_FADETABLE:
1289 info->fadetable = W_GetNumForName(sc_String);
1291 case MCMD_CD_STARTTRACK:
1292 case MCMD_CD_END1TRACK:
1293 case MCMD_CD_END2TRACK:
1294 case MCMD_CD_END3TRACK:
1295 case MCMD_CD_INTERTRACK:
1296 case MCMD_CD_TITLETRACK:
1298 cd_NonLevelTracks[mcmdValue-MCMD_CD_STARTTRACK] =
1303 mapMax = map > mapMax ? map : mapMax;
1309 //==========================================================================
1313 //==========================================================================
1315 int P_GetMapCluster(int map)
1317 return MapInfo[QualifyMap(map)].cluster;
1320 //==========================================================================
1324 //==========================================================================
1326 int P_GetMapCDTrack(int map)
1328 return MapInfo[QualifyMap(map)].cdTrack;
1331 //==========================================================================
1333 // P_GetMapWarpTrans
1335 //==========================================================================
1337 int P_GetMapWarpTrans(int map)
1339 return MapInfo[QualifyMap(map)].warpTrans;
1342 //==========================================================================
1346 //==========================================================================
1348 int P_GetMapNextMap(int map)
1350 return MapInfo[QualifyMap(map)].nextMap;
1353 //==========================================================================
1357 // Returns the actual map number given a warp map number.
1359 //==========================================================================
1361 int P_TranslateMap(int map)
1365 for(i = 1; i < 99; i++) // Make this a macro
1367 if(MapInfo[i].warpTrans == map)
1376 //==========================================================================
1378 // P_GetMapSky1Texture
1380 //==========================================================================
1382 int P_GetMapSky1Texture(int map)
1384 return MapInfo[QualifyMap(map)].sky1Texture;
1387 //==========================================================================
1389 // P_GetMapSky2Texture
1391 //==========================================================================
1393 int P_GetMapSky2Texture(int map)
1395 return MapInfo[QualifyMap(map)].sky2Texture;
1398 //==========================================================================
1402 //==========================================================================
1404 char *P_GetMapName(int map)
1406 return MapInfo[QualifyMap(map)].name;
1409 //==========================================================================
1411 // P_GetMapSky1ScrollDelta
1413 //==========================================================================
1415 fixed_t P_GetMapSky1ScrollDelta(int map)
1417 return MapInfo[QualifyMap(map)].sky1ScrollDelta;
1420 //==========================================================================
1422 // P_GetMapSky2ScrollDelta
1424 //==========================================================================
1426 fixed_t P_GetMapSky2ScrollDelta(int map)
1428 return MapInfo[QualifyMap(map)].sky2ScrollDelta;
1431 //==========================================================================
1433 // P_GetMapDoubleSky
1435 //==========================================================================
1437 boolean P_GetMapDoubleSky(int map)
1439 return MapInfo[QualifyMap(map)].doubleSky;
1442 //==========================================================================
1444 // P_GetMapLightning
1446 //==========================================================================
1448 boolean P_GetMapLightning(int map)
1450 return MapInfo[QualifyMap(map)].lightning;
1453 //==========================================================================
1455 // P_GetMapFadeTable
1457 //==========================================================================
1459 boolean P_GetMapFadeTable(int map)
1461 return MapInfo[QualifyMap(map)].fadetable;
1464 //==========================================================================
1468 //==========================================================================
1470 char *P_GetMapSongLump(int map)
1472 if(!strcasecmp(MapInfo[QualifyMap(map)].songLump, DEFAULT_SONG_LUMP))
1478 return MapInfo[QualifyMap(map)].songLump;
1482 //==========================================================================
1486 //==========================================================================
1488 void P_PutMapSongLump(int map, char *lumpName)
1490 if(map < 1 || map > MapCount)
1494 strcpy(MapInfo[map].songLump, lumpName);
1497 //==========================================================================
1499 // P_GetCDStartTrack
1501 //==========================================================================
1503 int P_GetCDStartTrack(void)
1505 return cd_NonLevelTracks[MCMD_CD_STARTTRACK-MCMD_CD_STARTTRACK];
1508 //==========================================================================
1512 //==========================================================================
1514 int P_GetCDEnd1Track(void)
1516 return cd_NonLevelTracks[MCMD_CD_END1TRACK-MCMD_CD_STARTTRACK];
1519 //==========================================================================
1523 //==========================================================================
1525 int P_GetCDEnd2Track(void)
1527 return cd_NonLevelTracks[MCMD_CD_END2TRACK-MCMD_CD_STARTTRACK];
1530 //==========================================================================
1534 //==========================================================================
1536 int P_GetCDEnd3Track(void)
1538 return cd_NonLevelTracks[MCMD_CD_END3TRACK-MCMD_CD_STARTTRACK];
1541 //==========================================================================
1543 // P_GetCDIntermissionTrack
1545 //==========================================================================
1547 int P_GetCDIntermissionTrack(void)
1549 return cd_NonLevelTracks[MCMD_CD_INTERTRACK-MCMD_CD_STARTTRACK];
1552 //==========================================================================
1554 // P_GetCDTitleTrack
1556 //==========================================================================
1558 int P_GetCDTitleTrack(void)
1560 return cd_NonLevelTracks[MCMD_CD_TITLETRACK-MCMD_CD_STARTTRACK];
1563 //==========================================================================
1567 //==========================================================================
1569 static int QualifyMap(int map)
1571 return (map < 1 || map > MapCount) ? 0 : map;
1574 //==========================================================================
1578 //==========================================================================
1584 P_InitFTAnims(); // Init flat and texture animations
1585 P_InitTerrainTypes();
1587 R_InitSprites(sprnames);
1591 // Special early initializer needed to start sound before R_Init()
1592 void InitMapMusicInfo(void)
1596 for (i=0; i<99; i++)
1598 strcpy(MapInfo[i].songLump, DEFAULT_SONG_LUMP);
1608 printf("My debug stuff ----------------------\n");
1609 printf("gamemap=%d\n",gamemap);
1610 for (i=0; i<10; i++)
1612 printf("i=%d songlump=%s\n",i,MapInfo[i].songLump);