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

📄 am_map.c

📁 游戏类程序源代码---WinDoom 3D源程序.zip
💻 C
📖 第 1 页 / 共 3 页
字号:
	// may be partially inside box
	// find an outside point
	if (outcode1)
	    outside = outcode1;
	else
	    outside = outcode2;
	
	// clip to each side
	if (outside & TOP)
	{
	    dy = fl->a.y - fl->b.y;
	    dx = fl->b.x - fl->a.x;
	    tmp.x = fl->a.x + (dx*(fl->a.y))/dy;
	    tmp.y = 0;
	}
	else if (outside & BOTTOM)
	{
	    dy = fl->a.y - fl->b.y;
	    dx = fl->b.x - fl->a.x;
	    tmp.x = fl->a.x + (dx*(fl->a.y-f_h))/dy;
	    tmp.y = f_h-1;
	}
	else if (outside & RIGHT)
	{
	    dy = fl->b.y - fl->a.y;
	    dx = fl->b.x - fl->a.x;
	    tmp.y = fl->a.y + (dy*(f_w-1 - fl->a.x))/dx;
	    tmp.x = f_w-1;
	}
	else if (outside & LEFT)
	{
	    dy = fl->b.y - fl->a.y;
	    dx = fl->b.x - fl->a.x;
	    tmp.y = fl->a.y + (dy*(-fl->a.x))/dx;
	    tmp.x = 0;
	}

	if (outside == outcode1)
	{
	    fl->a = tmp;
	    DOOUTCODE(outcode1, fl->a.x, fl->a.y);
	}
	else
	{
	    fl->b = tmp;
	    DOOUTCODE(outcode2, fl->b.x, fl->b.y);
	}
	
	if (outcode1 & outcode2)
	    return false; // trivially outside
    }

    return true;
}
#undef DOOUTCODE


//
// Classic Bresenham w/ whatever optimizations needed for speed
//
void
AM_drawFline
( fline_t*	fl,
  int		color,
  PBUFFER RenderBuffer) // DQ
//void
//AM_drawFline
//( fline_t*	fl,
//  int		color )
{
    register int x;
    register int y;
    register int dx;
    register int dy;
    register int sx;
    register int sy;
    register int ax;
    register int ay;
    register int d;

	 BYTE * Buffer;	// DQ
	 long * YLookup; // DQ
    
    static fuck = 0;

    // For debugging only
    if (      fl->a.x < 0 || fl->a.x >= f_w
	   || fl->a.y < 0 || fl->a.y >= f_h
	   || fl->b.x < 0 || fl->b.x >= f_w
	   || fl->b.y < 0 || fl->b.y >= f_h)
    {
	sprintf(MsgText, "fuck %d \r", fuck++);
    WriteDebug(MsgText);
	return;
    }

	 Buffer = RenderBuffer->Buffer;
	 YLookup = RenderBuffer->YLookup;

//    sprintf(MsgText, "Drawline from %d,%d to %d,%d : color %d...\n", fl->a.x,fl->a.y, fl->b.x,fl->b.y, color);
//    WriteDebug(MsgText);

// DQ removed def of PUTDOT, to remove use of "fb"
//#define PUTDOT(xx,yy,cc) fb[(yy)*f_w+(xx)]=(cc)

    dx = fl->b.x - fl->a.x;
    ax = 2 * (dx<0 ? -dx : dx);
    sx = dx<0 ? -1 : 1;

    dy = fl->b.y - fl->a.y;
    ay = 2 * (dy<0 ? -dy : dy);
    sy = dy<0 ? -1 : 1;

    x = fl->a.x;
    y = fl->a.y;

    if (ax > ay)
    {
	d = ay - ax/2;
	while (1)
	{
		// DQ start addition
		*(Buffer + YLookup[y] + x) = color;
		// DQ end addition
	    //PUTDOT(x,y,color);	// DQ removed
	    if (x == fl->b.x) return;
	    if (d>=0)
	    {
		y += sy;
		d -= ax;
	    }
	    x += sx;
	    d += ay;
	}
    }
    else
    {
	d = ax - ay/2;
	while (1)
	{
		// DQ start addition
		*(Buffer + YLookup[y] + x) = color;
		// DQ end addition
	    // PUTDOT(x, y, color);	// DQ removed
	    if (y == fl->b.y) return;
	    if (d >= 0)
	    {
		x += sx;
		d -= ay;
	    }
	    y += sy;
	    d += ax;
	}
    }
}


//
// Clip lines, draw visible part sof lines.
//
void AM_drawMline( mline_t *ml,int color, PBUFFER RenderBuffer) // DQ
//void AM_drawMline( mline_t *ml,int color)
   {
    static fline_t fl;

    if (AM_clipMline(ml, &fl))
        AM_drawFline(&fl, color, RenderBuffer/*DQ*/); // draws it on frame buffer using fb coords
   }



//
// Draws flat (floor/ceiling tile) aligned grid lines.
//
void AM_drawGrid(int color, PBUFFER RenderBuffer) // DQ
//void AM_drawGrid(int color)
   {
    fixed_t x, y;
    fixed_t start, end;
    mline_t ml;

//    WriteDebug("Drawing grid...\n");

    // Figure out start of vertical gridlines
//    sprintf(MsgText, "m_x = %d : bmaporgx = %d : bmaporgy = %d\n", m_x>>FRACBITS, bmaporgx>>FRACBITS, bmaporgy>>FRACBITS);
//    WriteDebug(MsgText);
    start = m_x;
    if ((start-bmaporgx)%(MAPBLOCKUNITS<<FRACBITS))
	    start += (MAPBLOCKUNITS<<FRACBITS) - ((start-bmaporgx)%(MAPBLOCKUNITS<<FRACBITS));
    end = m_x + m_w;
//    sprintf(MsgText, "start %d, end %d\n", start>>FRACBITS, end>>FRACBITS);
//    WriteDebug(MsgText);

    // draw vertical gridlines
    ml.a.y = m_y;
    ml.b.y = m_y+m_h;
//    sprintf(MsgText, "m_y = %d, m_h = %d\n", m_y>>FRACBITS, m_h>>FRACBITS);
//    WriteDebug(MsgText);
    for (x = start; x < end; x += (MAPBLOCKUNITS<<FRACBITS))
        {
         ml.a.x = x;
         ml.b.x = x;
         AM_drawMline(&ml, color, RenderBuffer/*DQ*/);
        }

    // Figure out start of horizontal gridlines
    start = m_y;
    if ((start-bmaporgy)%(MAPBLOCKUNITS<<FRACBITS))
	start += (MAPBLOCKUNITS<<FRACBITS)
	    - ((start-bmaporgy)%(MAPBLOCKUNITS<<FRACBITS));
    end = m_y + m_h;

    // draw horizontal gridlines
    ml.a.x = m_x;
    ml.b.x = m_x + m_w;
    for (y=start; y<end; y+=(MAPBLOCKUNITS<<FRACBITS))
    {
	ml.a.y = y;
	ml.b.y = y;
	AM_drawMline(&ml, color, RenderBuffer/*DQ*/);
    }

}

//
// Determines visible lines, draws them.
// This is LineDef based, not LineSeg based.
//
void AM_drawWalls(PBUFFER RenderBuffer) // DQ
//void AM_drawWalls(void)
{
    int i;
    static mline_t l;

    for (i=0;i<numlines;i++)
    {
	l.a.x = lines[i].v1->x;
	l.a.y = lines[i].v1->y;
	l.b.x = lines[i].v2->x;
	l.b.y = lines[i].v2->y;
	if (cheating || (lines[i].flags & ML_MAPPED))
	{
	    if ((lines[i].flags & LINE_NEVERSEE) && !cheating)
		continue;
	    if (!lines[i].backsector)
	    {
		AM_drawMline(&l, WALLCOLORS+lightlev, RenderBuffer/*DQ*/);
	    }
	    else
	    {
		if (lines[i].special == 39)
		{ // teleporters
		    AM_drawMline(&l, WALLCOLORS+WALLRANGE/2, RenderBuffer/*DQ*/);
		}
		else if (lines[i].flags & ML_SECRET) // secret door
		{
		    if (cheating) AM_drawMline(&l, SECRETWALLCOLORS + lightlev, RenderBuffer/*DQ*/);
		    else AM_drawMline(&l, WALLCOLORS+lightlev, RenderBuffer/*DQ*/);
		}
		else if (lines[i].backsector->floorheight
			   != lines[i].frontsector->floorheight) {
		    AM_drawMline(&l, FDWALLCOLORS + lightlev, RenderBuffer/*DQ*/); // floor level change
		}
		else if (lines[i].backsector->ceilingheight
			   != lines[i].frontsector->ceilingheight) {
		    AM_drawMline(&l, CDWALLCOLORS+lightlev, RenderBuffer/*DQ*/); // ceiling level change
		}
		else if (cheating) {
		    AM_drawMline(&l, TSWALLCOLORS+lightlev, RenderBuffer/*DQ*/);
		}
	    }
	}
	else if (plr->powers[pw_allmap])
	{
	    if (!(lines[i].flags & LINE_NEVERSEE)) AM_drawMline(&l, GRAYS+3, RenderBuffer/*DQ*/);
	}
    }
}


//
// Rotation in 2D.
// Used to rotate player arrow line character.
//
void
AM_rotate
( fixed_t*	x,
  fixed_t*	y,
  angle_t	a )
{
    fixed_t tmpx;

    tmpx =
	FixedMul(*x,finecosine[a>>ANGLETOFINESHIFT])
	- FixedMul(*y,finesine[a>>ANGLETOFINESHIFT]);
    
    *y   =
	FixedMul(*x,finesine[a>>ANGLETOFINESHIFT])
	+ FixedMul(*y,finecosine[a>>ANGLETOFINESHIFT]);

    *x = tmpx;
}

void AM_drawLineCharacter( mline_t*	lineguy, 
								  int lineguylines, 
								  fixed_t scale, 
								  angle_t angle, 
								  int color, 
								  fixed_t	x, 
								  fixed_t	y,
								  PBUFFER RenderBuffer) // DQ
//void AM_drawLineCharacter( mline_t*	lineguy, int lineguylines, fixed_t scale, angle_t angle, int color, fixed_t	x, fixed_t	y )
   {
    int		i;
    mline_t	l;

    for (i = 0;i < lineguylines;i++)
       {
        l.a.x = lineguy[i].a.x;
        l.a.y = lineguy[i].a.y;

        if (scale)
           {
            l.a.x = FixedMul(scale, l.a.x);
            l.a.y = FixedMul(scale, l.a.y);
           }

        if (angle)
            AM_rotate(&l.a.x, &l.a.y, angle);

        l.a.x += x;
        l.a.y += y;

        l.b.x = lineguy[i].b.x;
        l.b.y = lineguy[i].b.y;

        if (scale)
           {
            l.b.x = FixedMul(scale, l.b.x);
            l.b.y = FixedMul(scale, l.b.y);
           }

        if (angle)
            AM_rotate(&l.b.x, &l.b.y, angle);
	
        l.b.x += x;
        l.b.y += y;

        AM_drawMline(&l, color, RenderBuffer/*DQ*/);
       }
   }

void AM_drawPlayers(PBUFFER RenderBuffer)
//void AM_drawPlayers(void)
{
    int		i;
    player_t*	p;
    static int 	their_colors[] = { GREENS, GRAYS, BROWNS, REDS };
    int		their_color = -1;
    int		color;

    if (!netgame)
    {
	if (cheating)
	    AM_drawLineCharacter
		(cheat_player_arrow, NUMCHEATPLYRLINES, 0,
		 plr->mo->angle, WHITE, plr->mo->x, plr->mo->y, RenderBuffer/*DQ*/);
	else
	    AM_drawLineCharacter
		(player_arrow, NUMPLYRLINES, 0, plr->mo->angle,
		 WHITE, plr->mo->x, plr->mo->y, RenderBuffer/*DQ*/);
	return;
    }

    for (i=0;i<MAXPLAYERS;i++)
    {
	their_color++;
	p = &players[i];

	if ( (deathmatch && !singledemo) && p != plr)
	    continue;

	if (!playeringame[i])
	    continue;

	if (p->powers[pw_invisibility])
	    color = 246; // *close* to black
	else
	    color = their_colors[their_color];
	
	AM_drawLineCharacter
	    (player_arrow, NUMPLYRLINES, 0, p->mo->angle,
	     color, p->mo->x, p->mo->y, RenderBuffer/*DQ*/);
    }

}

void
AM_drawThings
( int	colors,
  int 	colorrange, 
  PBUFFER RenderBuffer)	// DQ
//void
//AM_drawThings
//( int	colors,
//  int 	colorrange)
{
    int		i;
    mobj_t*	t;

    for (i=0;i<numsectors;i++)
    {
	t = sectors[i].thinglist;
	while (t)
	{
	    AM_drawLineCharacter
		(thintriangle_guy, NUMTHINTRIANGLEGUYLINES,
		 16<<FRACBITS, t->angle, colors+lightlev, t->x, t->y, RenderBuffer/*DQ*/);
	    t = t->snext;
	}
    }
}

void AM_drawMarks(PBUFFER RenderBuffer)
//void AM_drawMarks(void)
{
    int i, fx, fy, w, h;

    for (i=0;i<AM_NUMMARKPOINTS;i++)
    {
	if (markpoints[i].x != -1)
	{
	    //      w = SHORT(marknums[i]->width);
	    //      h = SHORT(marknums[i]->height);
	    w = 5; // because something's wrong with the wad, i guess
	    h = 6; // because something's wrong with the wad, i guess
	    fx = CXMTOF(markpoints[i].x);
	    fy = CYMTOF(markpoints[i].y);
	    if (fx >= f_x && fx <= f_w - w && fy >= f_y && fy <= f_h - h)
		V_DrawPatch(fx, fy, RenderBuffer/*DQ FB*/, marknums[i]);
	}
    }

}

void AM_drawCrosshair(int color, PBUFFER RenderBuffer/*DQ*/)
{
	*(RenderBuffer->Buffer + RenderBuffer->YLookup[(f_h+1)/2] + f_w/2) = color; // DQ
	// DQ removed
    //fb[(f_w*(f_h+1))/2] = color; // single point for now
}

void AM_Drawer (PBUFFER RenderBuffer) // DQ
//void AM_Drawer (void)
   {
    if (!automapactive)
        return;

    AM_clearFB(BACKGROUND, RenderBuffer/*DQ*/);
    if (grid)
        AM_drawGrid(GRIDCOLORS, RenderBuffer/*DQ*/);
    AM_drawWalls(RenderBuffer/*DQ*/);
    AM_drawPlayers(RenderBuffer/*DQ*/);
    if (cheating==2)
        AM_drawThings(THINGCOLORS, THINGRANGE, RenderBuffer/*DQ*/);
    AM_drawCrosshair(XHAIRCOLORS, RenderBuffer/*DQ*/);

    AM_drawMarks(RenderBuffer/*DQ*/);

    V_MarkRect(f_x, f_y, f_w, f_h);
   }

⌨️ 快捷键说明

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