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

📄 p_maputl.c

📁 使用Doom引擎开发的著名游戏《毁灭巫师》的源代码。
💻 C
📖 第 1 页 / 共 2 页
字号:
//**************************************************************************//**//** p_maputl.c : Heretic 2 : Raven Software, Corp.//**//** $RCSfile: p_maputl.c,v $//** $Revision: 1.11 $//** $Date: 95/10/04 02:39:28 $//** $Author: paul $//**//**************************************************************************#include "h2def.h"#include "p_local.h"static mobj_t *RoughBlockCheck(mobj_t *mo, int index);/*===================== P_AproxDistance== Gives an estimation of distance (not exact)====================*/fixed_t P_AproxDistance (fixed_t dx, fixed_t dy){	dx = abs(dx);	dy = abs(dy);	if (dx < dy)		return dx+dy-(dx>>1);	return dx+dy-(dy>>1);}/*==================== P_PointOnLineSide== Returns 0 or 1==================*/int P_PointOnLineSide (fixed_t x, fixed_t y, line_t *line){	fixed_t dx,dy;	fixed_t left, right;	if (!line->dx)	{		if (x <= line->v1->x)			return line->dy > 0;		return line->dy < 0;	}	if (!line->dy)	{		if (y <= line->v1->y)			return line->dx < 0;		return line->dx > 0;	}	dx = (x - line->v1->x);	dy = (y - line->v1->y);	left = FixedMul ( line->dy>>FRACBITS , dx );	right = FixedMul ( dy , line->dx>>FRACBITS );	if (right < left)		return 0;               // front side	return 1;                       // back side}/*=================== P_BoxOnLineSide== Considers the line to be infinite= Returns side 0 or 1, -1 if box crosses the line=================*/int P_BoxOnLineSide (fixed_t *tmbox, line_t *ld){	int             p1, p2;	switch (ld->slopetype)	{	case ST_HORIZONTAL:		p1 = tmbox[BOXTOP] > ld->v1->y;		p2 = tmbox[BOXBOTTOM] > ld->v1->y;		if (ld->dx < 0)		{			p1 ^= 1;			p2 ^= 1;		}		break;	case ST_VERTICAL:		p1 = tmbox[BOXRIGHT] < ld->v1->x;		p2 = tmbox[BOXLEFT] < ld->v1->x;		if (ld->dy < 0)		{			p1 ^= 1;			p2 ^= 1;		}		break;	case ST_POSITIVE:		p1 = P_PointOnLineSide (tmbox[BOXLEFT], tmbox[BOXTOP], ld);		p2 = P_PointOnLineSide (tmbox[BOXRIGHT], tmbox[BOXBOTTOM], ld);		break;	case ST_NEGATIVE:		p1 = P_PointOnLineSide (tmbox[BOXRIGHT], tmbox[BOXTOP], ld);		p2 = P_PointOnLineSide (tmbox[BOXLEFT], tmbox[BOXBOTTOM], ld);		break;	}	if (p1 == p2)		return p1;	return -1;}/*==================== P_PointOnDivlineSide== Returns 0 or 1==================*/int P_PointOnDivlineSide (fixed_t x, fixed_t y, divline_t *line){	fixed_t dx,dy;	fixed_t left, right;	if (!line->dx)	{		if (x <= line->x)			return line->dy > 0;		return line->dy < 0;	}	if (!line->dy)	{		if (y <= line->y)			return line->dx < 0;		return line->dx > 0;	}	dx = (x - line->x);	dy = (y - line->y);// try to quickly decide by looking at sign bits	if ( (line->dy ^ line->dx ^ dx ^ dy)&0x80000000 )	{		if ( (line->dy ^ dx) & 0x80000000 )			return 1;       // (left is negative)		return 0;	}	left = FixedMul ( line->dy>>8, dx>>8 );	right = FixedMul ( dy>>8 , line->dx>>8 );	if (right < left)		return 0;               // front side	return 1;                       // back side}/*================ P_MakeDivline===============*/void P_MakeDivline (line_t *li, divline_t *dl){	dl->x = li->v1->x;	dl->y = li->v1->y;	dl->dx = li->dx;	dl->dy = li->dy;}/*================= P_InterceptVector== Returns the fractional intercept point along the first divline== This is only called by the addthings and addlines traversers===============*/fixed_t P_InterceptVector (divline_t *v2, divline_t *v1){#if 1	fixed_t frac, num, den;	den = FixedMul (v1->dy>>8,v2->dx) - FixedMul(v1->dx>>8,v2->dy);	if (den == 0)		return 0;//              I_Error ("P_InterceptVector: parallel");	num = FixedMul ( (v1->x - v2->x)>>8 ,v1->dy) +		FixedMul ( (v2->y - v1->y)>>8 , v1->dx);	frac = FixedDiv (num , den);	return frac;#elsefloat   frac, num, den, v1x,v1y,v1dx,v1dy,v2x,v2y,v2dx,v2dy;	v1x = (float)v1->x/FRACUNIT;	v1y = (float)v1->y/FRACUNIT;	v1dx = (float)v1->dx/FRACUNIT;	v1dy = (float)v1->dy/FRACUNIT;	v2x = (float)v2->x/FRACUNIT;	v2y = (float)v2->y/FRACUNIT;	v2dx = (float)v2->dx/FRACUNIT;	v2dy = (float)v2->dy/FRACUNIT;	den = v1dy*v2dx - v1dx*v2dy;	if (den == 0)		return 0;       // parallel	num = (v1x - v2x)*v1dy + (v2y - v1y)*v1dx;	frac = num / den;	return frac*FRACUNIT;#endif}/*==================== P_LineOpening== Sets opentop and openbottom to the window through a two sided line= OPTIMIZE: keep this precalculated==================*/fixed_t opentop, openbottom, openrange;fixed_t lowfloor;void P_LineOpening (line_t *linedef){	sector_t        *front, *back;	if (linedef->sidenum[1] == -1)	{       // single sided line		openrange = 0;		return;	}	front = linedef->frontsector;	back = linedef->backsector;	if (front->ceilingheight < back->ceilingheight)		opentop = front->ceilingheight;	else		opentop = back->ceilingheight;	if (front->floorheight > back->floorheight)	{		openbottom = front->floorheight;		lowfloor = back->floorheight;		tmfloorpic = front->floorpic;	}	else	{		openbottom = back->floorheight;		lowfloor = front->floorheight;		tmfloorpic = back->floorpic;	}	openrange = opentop - openbottom;}/*===============================================================================						THING POSITION SETTING===============================================================================*//*===================== P_UnsetThingPosition== Unlinks a thing from block map and sectors====================*/void P_UnsetThingPosition (mobj_t *thing){	int                             blockx, blocky;	if ( ! (thing->flags & MF_NOSECTOR) )	{       // inert things don't need to be in blockmap// unlink from subsector		if (thing->snext)			thing->snext->sprev = thing->sprev;		if (thing->sprev)			thing->sprev->snext = thing->snext;		else			thing->subsector->sector->thinglist = thing->snext;	}	if ( ! (thing->flags & MF_NOBLOCKMAP) )	{       // inert things don't need to be in blockmap// unlink from block map		if (thing->bnext)			thing->bnext->bprev = thing->bprev;		if (thing->bprev)			thing->bprev->bnext = thing->bnext;		else		{			blockx = (thing->x - bmaporgx)>>MAPBLOCKSHIFT;			blocky = (thing->y - bmaporgy)>>MAPBLOCKSHIFT;			if (blockx>=0 && blockx < bmapwidth			&& blocky>=0 && blocky <bmapheight)			blocklinks[blocky*bmapwidth+blockx] = thing->bnext;		}	}}/*===================== P_SetThingPosition== Links a thing into both a block and a subsector based on it's x y= Sets thing->subsector properly====================*/void P_SetThingPosition (mobj_t *thing){	subsector_t             *ss;	sector_t                *sec;	int                             blockx, blocky;	mobj_t                  **link;//// link into subsector//	ss = R_PointInSubsector (thing->x,thing->y);	thing->subsector = ss;	if ( ! (thing->flags & MF_NOSECTOR) )	{       // invisible things don't go into the sector links		sec = ss->sector;		thing->sprev = NULL;		thing->snext = sec->thinglist;		if (sec->thinglist)			sec->thinglist->sprev = thing;		sec->thinglist = thing;	}//// link into blockmap//	if ( ! (thing->flags & MF_NOBLOCKMAP) )	{       // inert things don't need to be in blockmap		blockx = (thing->x - bmaporgx)>>MAPBLOCKSHIFT;		blocky = (thing->y - bmaporgy)>>MAPBLOCKSHIFT;		if (blockx>=0 && blockx < bmapwidth && blocky>=0 && blocky <bmapheight)		{			link = &blocklinks[blocky*bmapwidth+blockx];			thing->bprev = NULL;			thing->bnext = *link;			if (*link)				(*link)->bprev = thing;			*link = thing;		}		else		{       // thing is off the map			thing->bnext = thing->bprev = NULL;		}	}}/*===============================================================================						BLOCK MAP ITERATORSFor each line/thing in the given mapblock, call the passed 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===================*/boolean P_BlockLinesIterator (int x, int y, boolean(*func)(line_t*) ){	int                     offset;	short           *list;	line_t          *ld;	int i;	polyblock_t *polyLink;	seg_t **tempSeg;	extern polyblock_t **PolyBlockMap;	if (x < 0 || y<0 || x>=bmapwidth || y>=bmapheight)		return true;	offset = y*bmapwidth+x;	polyLink = PolyBlockMap[offset];	while(polyLink)	{		if(polyLink->polyobj)		{			if(polyLink->polyobj->validcount != validcount)			{				polyLink->polyobj->validcount = validcount;				tempSeg = polyLink->polyobj->segs;				for(i = 0; i < polyLink->polyobj->numsegs; i++, tempSeg++)				{					if((*tempSeg)->linedef->validcount == validcount)					{						continue;					}					(*tempSeg)->linedef->validcount = validcount;					if(!func((*tempSeg)->linedef))					{						return false;					}				}			}		}		polyLink = polyLink->next;	}	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===================*/boolean P_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_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==================*/boolean PIT_AddLineIntercepts (line_t *ld){	int                     s1, s2;	fixed_t         frac;	divline_t       dl;// avoid precision problems with two routines

⌨️ 快捷键说明

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