📄 am_map.c
字号:
// 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 + -