⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 p_maputl.c

📁 Nxdoom真的满好用的
💻 C
📖 第 1 页 / 共 2 页
字号:
	    if (*link)		(*link)->bprev = thing;	    *link = thing;	}	else	{	    // thing is off the map	    thing->bnext = thing->bprev = NULL;	}    }}//// BLOCK MAP ITERATORS// For each line/thing in the given mapblock,// call the passed PIT_* function.// If the function returns false,// exit with false without checking anything else.////// P_BlockLinesIterator// The validcount flags are used to avoid checking lines// that are marked in multiple mapblocks,// so increment validcount before the first call// to P_BlockLinesIterator, then make one or more calls// to it.//booleanP_BlockLinesIterator( int			x,  int			y,  boolean(*func)(line_t*) ){    int			offset;    short*		list;    line_t*		ld;	    if (x<0	|| y<0	|| x>=bmapwidth	|| y>=bmapheight)    {	return true;    }        offset = y*bmapwidth+x;	    offset = *(blockmap+offset);    for ( list = blockmaplump+offset ; *list != -1 ; list++)    {	ld = &lines[*list];	if (ld->validcount == validcount)	    continue; 	// line has already been checked	ld->validcount = validcount;			if ( !func(ld) )	    return false;    }    return true;	// everything was checked}//// P_BlockThingsIterator//booleanP_BlockThingsIterator( int			x,  int			y,  boolean(*func)(mobj_t*) ){    mobj_t*		mobj;	    if ( x<0	 || y<0	 || x>=bmapwidth	 || y>=bmapheight)    {	return true;    }        for (mobj = blocklinks[y*bmapwidth+x] ;	 mobj ;	 mobj = mobj->bnext)    {	if (!func( mobj ) )	    return false;    }    return true;}//// INTERCEPT ROUTINES//intercept_t	intercepts[MAXINTERCEPTS];intercept_t*	intercept_p;divline_t 	trace;boolean 	earlyout;int		ptflags;//// PIT_AddLineIntercepts.// Looks for lines in the given block// that intercept the given trace// to add to the intercepts list.//// A line is crossed if its endpoints// are on opposite sides of the trace.// Returns true if earlyout and a solid line hit.//booleanPIT_AddLineIntercepts (line_t* ld){    int			s1;    int			s2;    fixed_t		frac;    divline_t		dl;	    // avoid precision problems with two routines    if ( trace.dx > FRACUNIT*16	 || trace.dy > FRACUNIT*16	 || trace.dx < -FRACUNIT*16	 || trace.dy < -FRACUNIT*16)    {	s1 = P_PointOnDivlineSide (ld->v1->x, ld->v1->y, &trace);	s2 = P_PointOnDivlineSide (ld->v2->x, ld->v2->y, &trace);    }    else    {	s1 = P_PointOnLineSide (trace.x, trace.y, ld);	s2 = P_PointOnLineSide (trace.x+trace.dx, trace.y+trace.dy, ld);    }        if (s1 == s2)	return true;	// line isn't crossed        // hit the line    P_MakeDivline (ld, &dl);    frac = P_InterceptVector (&trace, &dl);    if (frac < 0)	return true;	// behind source	    // try to early out the check    if (earlyout	&& frac < FRACUNIT	&& !ld->backsector)    {	return false;	// stop checking    }    	    intercept_p->frac = frac;    intercept_p->isaline = true;    intercept_p->d.line = ld;    intercept_p++;    return true;	// continue}//// PIT_AddThingIntercepts//boolean PIT_AddThingIntercepts (mobj_t* thing){    fixed_t		x1;    fixed_t		y1;    fixed_t		x2;    fixed_t		y2;        int			s1;    int			s2;        boolean		tracepositive;    divline_t		dl;        fixed_t		frac;	    tracepositive = (trace.dx ^ trace.dy)>0;		    // check a corner to corner crossection for hit    if (tracepositive)    {	x1 = thing->x - thing->radius;	y1 = thing->y + thing->radius;			x2 = thing->x + thing->radius;	y2 = thing->y - thing->radius;			    }    else    {	x1 = thing->x - thing->radius;	y1 = thing->y - thing->radius;			x2 = thing->x + thing->radius;	y2 = thing->y + thing->radius;			    }        s1 = P_PointOnDivlineSide (x1, y1, &trace);    s2 = P_PointOnDivlineSide (x2, y2, &trace);    if (s1 == s2)	return true;		// line isn't crossed	    dl.x = x1;    dl.y = y1;    dl.dx = x2-x1;    dl.dy = y2-y1;        frac = P_InterceptVector (&trace, &dl);    if (frac < 0)	return true;		// behind source    intercept_p->frac = frac;    intercept_p->isaline = false;    intercept_p->d.thing = thing;    intercept_p++;    return true;		// keep going}//// P_TraverseIntercepts// Returns true if the traverser function returns true// for all lines.// booleanP_TraverseIntercepts( traverser_t	func,  fixed_t	maxfrac ){    int			count;    fixed_t		dist;    intercept_t*	scan;    intercept_t*	in;	    count = intercept_p - intercepts;        in = 0;			// shut up compiler warning	    while (count--)    {	dist = MAXINT;	for (scan = intercepts ; scan<intercept_p ; scan++)	{	    if (scan->frac < dist)	    {		dist = scan->frac;		in = scan;	    }	}		if (dist > maxfrac)	    return true;	// checked everything in range		#if 0  // UNUSED    {	// don't check these yet, there may be others inserted	in = scan = intercepts;	for ( scan = intercepts ; scan<intercept_p ; scan++)	    if (scan->frac > maxfrac)		*in++ = *scan;	intercept_p = in;	return false;    }#endif        if ( !func (in) )	    return false;	// don't bother going farther	in->frac = MAXINT;    }	    return true;		// everything was traversed}//// P_PathTraverse// Traces a line from x1,y1 to x2,y2,// calling the traverser function for each.// Returns true if the traverser function returns true// for all lines.//booleanP_PathTraverse( fixed_t		x1,  fixed_t		y1,  fixed_t		x2,  fixed_t		y2,  int			flags,  boolean (*trav) (intercept_t *)){    fixed_t	xt1;    fixed_t	yt1;    fixed_t	xt2;    fixed_t	yt2;        fixed_t	xstep;    fixed_t	ystep;        fixed_t	partial;        fixed_t	xintercept;    fixed_t	yintercept;        int		mapx;    int		mapy;        int		mapxstep;    int		mapystep;    int		count;		    earlyout = flags & PT_EARLYOUT;		    validcount++;    intercept_p = intercepts;	    if ( ((x1-bmaporgx)&(MAPBLOCKSIZE-1)) == 0)	x1 += FRACUNIT;	// don't side exactly on a line        if ( ((y1-bmaporgy)&(MAPBLOCKSIZE-1)) == 0)	y1 += FRACUNIT;	// don't side exactly on a line    trace.x = x1;    trace.y = y1;    trace.dx = x2 - x1;    trace.dy = y2 - y1;    x1 -= bmaporgx;    y1 -= bmaporgy;    xt1 = x1>>MAPBLOCKSHIFT;    yt1 = y1>>MAPBLOCKSHIFT;    x2 -= bmaporgx;    y2 -= bmaporgy;    xt2 = x2>>MAPBLOCKSHIFT;    yt2 = y2>>MAPBLOCKSHIFT;    if (xt2 > xt1)    {	mapxstep = 1;	partial = FRACUNIT - ((x1>>MAPBTOFRAC)&(FRACUNIT-1));	ystep = FixedDiv (y2-y1,abs(x2-x1));    }    else if (xt2 < xt1)    {	mapxstep = -1;	partial = (x1>>MAPBTOFRAC)&(FRACUNIT-1);	ystep = FixedDiv (y2-y1,abs(x2-x1));    }    else    {	mapxstep = 0;	partial = FRACUNIT;	ystep = 256*FRACUNIT;    }	    yintercept = (y1>>MAPBTOFRAC) + FixedMul (partial, ystep);	    if (yt2 > yt1)    {	mapystep = 1;	partial = FRACUNIT - ((y1>>MAPBTOFRAC)&(FRACUNIT-1));	xstep = FixedDiv (x2-x1,abs(y2-y1));    }    else if (yt2 < yt1)    {	mapystep = -1;	partial = (y1>>MAPBTOFRAC)&(FRACUNIT-1);	xstep = FixedDiv (x2-x1,abs(y2-y1));    }    else    {	mapystep = 0;	partial = FRACUNIT;	xstep = 256*FRACUNIT;    }	    xintercept = (x1>>MAPBTOFRAC) + FixedMul (partial, xstep);        // Step through map blocks.    // Count is present to prevent a round off error    // from skipping the break.    mapx = xt1;    mapy = yt1;	    for (count = 0 ; count < 64 ; count++)    {	if (flags & PT_ADDLINES)	{	    if (!P_BlockLinesIterator (mapx, mapy,PIT_AddLineIntercepts))		return false;	// early out	}		if (flags & PT_ADDTHINGS)	{	    if (!P_BlockThingsIterator (mapx, mapy,PIT_AddThingIntercepts))		return false;	// early out	}			if (mapx == xt2	    && mapy == yt2)	{	    break;	}		if ( (yintercept >> FRACBITS) == mapy)	{	    yintercept += ystep;	    mapx += mapxstep;	}	else if ( (xintercept >> FRACBITS) == mapx)	{	    xintercept += xstep;	    mapy += mapystep;	}		    }    // go through the sorted list    return P_TraverseIntercepts ( trav, FRACUNIT );}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -