📄 am_map.c
字号:
else if (ml->a.y < m_y) outcode1 = BOTTOM; if (ml->b.y > m_y2) outcode2 = TOP; else if (ml->b.y < m_y) outcode2 = BOTTOM; if (outcode1 & outcode2) return false; // trivially outside if (ml->a.x < m_x) outcode1 |= LEFT; else if (ml->a.x > m_x2) outcode1 |= RIGHT; if (ml->b.x < m_x) outcode2 |= LEFT; else if (ml->b.x > m_x2) outcode2 |= RIGHT; if (outcode1 & outcode2) return false; // trivially outside // transform to frame-buffer coordinates. fl->a.x = CXMTOF(ml->a.x); fl->a.y = CYMTOF(ml->a.y); fl->b.x = CXMTOF(ml->b.x); fl->b.y = CYMTOF(ml->b.y); DOOUTCODE(outcode1, fl->a.x, fl->a.y); DOOUTCODE(outcode2, fl->b.x, fl->b.y); if (outcode1 & outcode2) return false; while (outcode1 | outcode2) { // 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_soft ( 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;#ifdef PARANOIA static int 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) { CONS_Printf("line clipping problem %d \r", fuck++); return; }#endif#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) { PUTDOT(x,y,color); if (x == fl->b.x) return; if (d>=0) { y += sy; d -= ax; } x += sx; d += ay; } } else { d = ax - ay/2; while (1) { PUTDOT(x, y, color); if (y == fl->b.y) return; if (d >= 0) { x += sx; d -= ay; } y += sy; d += ax; } }}//// Clip lines, draw visible parts of lines.//void AM_drawMline ( mline_t* ml, int color ){ static fline_t fl; if (AM_clipMline(ml, &fl)) AM_drawFline(&fl, color); // draws it on frame buffer using fb coords}//// Draws flat (floor/ceiling tile) aligned grid lines.//void AM_drawGrid(int color){ fixed_t x, y; fixed_t start, end; mline_t ml; // Figure out start of vertical gridlines start = m_x; if ((start-bmaporgx)%(MAPBLOCKUNITS<<FRACBITS)) start += (MAPBLOCKUNITS<<FRACBITS) - ((start-bmaporgx)%(MAPBLOCKUNITS<<FRACBITS)); end = m_x + m_w; // draw vertical gridlines ml.a.y = m_y; ml.b.y = m_y+m_h; for (x=start; x<end; x+=(MAPBLOCKUNITS<<FRACBITS)) { ml.a.x = x; ml.b.x = x; AM_drawMline(&ml, color); } // 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); }}//// Determines visible lines, draws them.// This is LineDef based, not LineSeg based.//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 (am_cheating || (lines[i].flags & ML_MAPPED)) { if ((lines[i].flags & LINE_NEVERSEE) && !am_cheating) continue; if (!lines[i].backsector) { AM_drawMline(&l, WALLCOLORS+lightlev); } else { switch ( lines[i].special ) { case 39 : // teleporters AM_drawMline(&l, WALLCOLORS+WALLRANGE/2); break; case 26: case 32: AM_drawMline(&l, BLUEKEYCOLOR); break; case 27: case 34: AM_drawMline(&l, YELLOWKEYCOLOR); break; case 28: case 33: AM_drawMline(&l, REDKEYCOLOR); // green for heretic break; default : if (lines[i].flags & ML_SECRET) // secret door { if (am_cheating) AM_drawMline(&l, SECRETWALLCOLORS + lightlev); else AM_drawMline(&l, WALLCOLORS+lightlev); } else if (lines[i].backsector->floorheight != lines[i].frontsector->floorheight) { AM_drawMline(&l, FDWALLCOLORS + lightlev); // floor level change } else if (lines[i].backsector->ceilingheight != lines[i].frontsector->ceilingheight) { AM_drawMline(&l, CDWALLCOLORS+lightlev); // ceiling level change } else if (am_cheating) { AM_drawMline(&l, TSWALLCOLORS+lightlev); } } } } else if (plr->powers[pw_allmap]) { if (!(lines[i].flags & LINE_NEVERSEE)) AM_drawMline(&l, GRAYS+3); } }}//// 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 ){ 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); }}void AM_drawPlayers(void){ int i; player_t* p; int color; if (!multiplayer) { if (am_cheating) AM_drawLineCharacter (cheat_player_arrow, NUMCHEATPLYRLINES, 0, plr->mo->angle, DWHITE, plr->mo->x, plr->mo->y); else AM_drawLineCharacter (player_arrow, NUMPLYRLINES, 0, plr->mo->angle, DWHITE, plr->mo->x, plr->mo->y); return; } // multiplayer for (i=0;i<MAXPLAYERS;i++) { if (!playeringame[i]) continue; p = &players[i]; if ( (cv_deathmatch.value && !singledemo) && p != plr) continue; if (p->powers[pw_invisibility]) color = 246; // *close* to black else { if(p->skincolor==0) color = GREENS; else color = *(translationtables + ((p->skincolor-1)<<8) +GREENS+8); } AM_drawLineCharacter (player_arrow, NUMPLYRLINES, 0, p->mo->angle, color, p->mo->x, p->mo->y); }}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); t = t->snext; } }}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, FB, marknums[i]); } }}void AM_drawCrosshair(int color){ if( rendermode!=render_soft ) { // BP: should be putpixel here return; } if( scr_bpp==1 ) fb[(f_w*(f_h+1))/2] = color; // single point for now else *( (short *)fb + (f_w*(f_h+1))/2) = color;}void AM_Drawer (void){ if (!automapactive) return; AM_clearFB(BACKGROUND); if (grid) AM_drawGrid(GRIDCOLORS); AM_drawWalls(); AM_drawPlayers(); if (am_cheating==2) AM_drawThings(THINGCOLORS, THINGRANGE); AM_drawCrosshair(XHAIRCOLORS); AM_drawMarks(); // mapname { int y; if( cv_scalestatusbar.value ) y = (BASEVIDHEIGHT-ST_HEIGHT-1); else y = (BASEVIDHEIGHT-ST_HEIGHT/vid.dupy-1); V_DrawString( 0, y - V_StringHeight(P_LevelName()), P_LevelName()); } V_MarkRect(f_x, f_y, f_w, f_h);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -