📄 am_map.c
字号:
if(cheat_kills[ShowKillsCount] == ev->data1 && netgame && deathmatch) { ShowKillsCount++; if(ShowKillsCount == 5) { ShowKillsCount = 0; rc = false; ShowKills ^= 1; } } else { ShowKillsCount = 0; } } else if (ev->type == ev_keyup) { rc = false; switch (ev->data1) { case AM_PANRIGHTKEY: if (!followplayer) m_paninc.x = 0; break; case AM_PANLEFTKEY: if (!followplayer) m_paninc.x = 0; break; case AM_PANUPKEY: if (!followplayer) m_paninc.y = 0; break; case AM_PANDOWNKEY: if (!followplayer) m_paninc.y = 0; break; case AM_ZOOMOUTKEY: case AM_ZOOMINKEY: mtof_zoommul = FRACUNIT; ftom_zoommul = FRACUNIT; break; } } return rc;}void AM_changeWindowScale(void){ // Change the scaling multipliers scale_mtof = FixedMul(scale_mtof, mtof_zoommul); scale_ftom = FixedDiv(FRACUNIT, scale_mtof); if (scale_mtof < min_scale_mtof) AM_minOutWindowScale(); else if (scale_mtof > max_scale_mtof) AM_maxOutWindowScale(); else AM_activateNewScale();}void AM_doFollowPlayer(void){ if (f_oldloc.x != plr->mo->x || f_oldloc.y != plr->mo->y) {// m_x = FTOM(MTOF(plr->mo->x - m_w/2));// m_y = FTOM(MTOF(plr->mo->y - m_h/2));// m_x = plr->mo->x - m_w/2;// m_y = plr->mo->y - m_h/2; m_x = FTOM(MTOF(plr->mo->x)) - m_w/2; m_y = FTOM(MTOF(plr->mo->y)) - m_h/2; m_x2 = m_x + m_w; m_y2 = m_y + m_h; // do the parallax parchment scrolling./* dmapx = (MTOF(plr->mo->x)-MTOF(f_oldloc.x)); //fixed point dmapy = (MTOF(f_oldloc.y)-MTOF(plr->mo->y)); if(f_oldloc.x == MAXINT) //to eliminate an error when the user first dmapx=0; //goes into the automap. mapxstart += dmapx; mapystart += dmapy; while(mapxstart >= finit_width) mapxstart -= finit_width; while(mapxstart < 0) mapxstart += finit_width; while(mapystart >= finit_height) mapystart -= finit_height; while(mapystart < 0) mapystart += finit_height;*/ f_oldloc.x = plr->mo->x; f_oldloc.y = plr->mo->y; }}// Ripped out for Heretic/*void AM_updateLightLev(void){ static nexttic = 0;//static int litelevels[] = { 0, 3, 5, 6, 6, 7, 7, 7 }; static int litelevels[] = { 0, 4, 7, 10, 12, 14, 15, 15 }; static int litelevelscnt = 0; // Change light level if (amclock>nexttic) { lightlev = litelevels[litelevelscnt++]; if (litelevelscnt == sizeof(litelevels)/sizeof(int)) litelevelscnt = 0; nexttic = amclock + 6 - (amclock % 6); }}*/void AM_Ticker (void){ if (!automapactive) return; amclock++; if (followplayer) AM_doFollowPlayer(); // Change the zoom if necessary if (ftom_zoommul != FRACUNIT) AM_changeWindowScale(); // Change x,y location if (m_paninc.x || m_paninc.y) AM_changeWindowLoc(); // Update light level// AM_updateLightLev();}void AM_clearFB(int color){ int i, j; int dmapx; int dmapy; if(followplayer) { dmapx = (MTOF(plr->mo->x)-MTOF(oldplr.x)); //fixed point dmapy = (MTOF(oldplr.y)-MTOF(plr->mo->y)); oldplr.x = plr->mo->x; oldplr.y = plr->mo->y;// if(f_oldloc.x == MAXINT) //to eliminate an error when the user first// dmapx=0; //goes into the automap. mapxstart += dmapx>>1; mapystart += dmapy>>1; while(mapxstart >= finit_width) mapxstart -= finit_width; while(mapxstart < 0) mapxstart += finit_width; while(mapystart >= finit_height) mapystart -= finit_height; while(mapystart < 0) mapystart += finit_height; } else { mapxstart += (MTOF(m_paninc.x)>>1); mapystart -= (MTOF(m_paninc.y)>>1); if(mapxstart >= finit_width) mapxstart -= finit_width; if(mapxstart < 0) mapxstart += finit_width; if(mapystart >= finit_height) mapystart -= finit_height; if(mapystart < 0) mapystart += finit_height; } //blit the automap background to the screen. j=mapystart*finit_width; for(i = 0; i < SCREENHEIGHT-SBARHEIGHT; i++) { memcpy(screen+i*finit_width, maplump+j+mapxstart, finit_width-mapxstart); memcpy(screen+i*finit_width+finit_width-mapxstart, maplump+j, mapxstart); j += finit_width; if(j >= finit_height*finit_width) j=0; }// memcpy(screen, maplump, finit_width*finit_height);// memset(fb, color, f_w*f_h);}// Based on Cohen-Sutherland clipping algorithm but with a slightly// faster reject and precalculated slopes. If I need the speed, will// hash algorithm to the common cases.boolean AM_clipMline(mline_t *ml, fline_t *fl){ enum { LEFT=1, RIGHT=2, BOTTOM=4, TOP=8 }; register outcode1 = 0, outcode2 = 0, outside; fpoint_t tmp; int dx, dy;#define DOOUTCODE(oc, mx, my) \ (oc) = 0; \ if ((my) < 0) (oc) |= TOP; \ else if ((my) >= f_h) (oc) |= BOTTOM; \ if ((mx) < 0) (oc) |= LEFT; \ else if ((mx) >= f_w) (oc) |= RIGHT // do trivial rejects and outcodes if (ml->a.y > m_y2) outcode1 = TOP; 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 I need for speedvoid AM_drawFline(fline_t *fl, int color){ register int x, y, dx, dy, sx, sy, ax, ay, d; //static fuck = 0; switch(color) { case WALLCOLORS: DrawWuLine(fl->a.x, fl->a.y, fl->b.x, fl->b.y, &antialias[0][0], 8, 3); break; case FDWALLCOLORS: DrawWuLine(fl->a.x, fl->a.y, fl->b.x, fl->b.y, &antialias[1][0], 8, 3); break; case CDWALLCOLORS: DrawWuLine(fl->a.x, fl->a.y, fl->b.x, fl->b.y, &antialias[2][0], 8, 3); break; default: { // 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) { //fprintf(stderr, "fuck %d \r", fuck++); return; } #define DOT(xx,yy,cc) fb[(yy)*f_w+(xx)]=(cc) //the MACRO! 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) { DOT(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) { DOT(x, y, color); if (y == fl->b.y) return; if (d >= 0) { x += sx; d -= ay; } y += sy; d += ax; } } } }}/* Wu antialiased line drawer. * (X0,Y0),(X1,Y1) = line to draw * BaseColor = color # of first color in block used for antialiasing, the * 100% intensity version of the drawing color * NumLevels = size of color block, with BaseColor+NumLevels-1 being the * 0% intensity version of the drawing color * IntensityBits = log base 2 of NumLevels; the # of bits used to describe * the intensity of the drawing color. 2**IntensityBits==NumLevels */void PUTDOT(short xx,short yy,byte *cc, byte *cm){ static int oldyy; static int oldyyshifted; byte *oldcc=cc; if(xx < 32) cc += 7-(xx>>2); else if(xx > (finit_width - 32)) cc += 7-((finit_width-xx) >> 2);// if(cc==oldcc) //make sure that we don't double fade the corners.// { if(yy < 32) cc += 7-(yy>>2); else if(yy > (finit_height - 32)) cc += 7-((finit_height-yy) >> 2);// } if(cc > cm && cm != NULL) { cc = cm; } else if(cc > oldcc+6) // don't let the color escape from the fade table... { cc=oldcc+6; } if(yy == oldyy+1) { oldyy++; oldyyshifted += 320; } else if(yy == oldyy-1) { oldyy--; oldyyshifted -= 320; } else if(yy != oldyy) { oldyy = yy; oldyyshifted = yy*320; } fb[oldyyshifted+xx] = *(cc);// fb[(yy)*f_w+(xx)]=*(cc);}void DrawWuLine(int X0, int Y0, int X1, int Y1, byte *BaseColor, int NumLevels, unsigned short IntensityBits){ unsigned short IntensityShift, ErrorAdj, ErrorAcc; unsigned short ErrorAccTemp, Weighting, WeightingComplementMask; short DeltaX, DeltaY, Temp, XDir; /* Make sure the line runs top to bottom */ if (Y0 > Y1) { Temp = Y0; Y0 = Y1; Y1 = Temp; Temp = X0; X0 = X1; X1 = Temp; } /* Draw the initial pixel, which is always exactly intersected by the line and so needs no weighting */ PUTDOT(X0, Y0, &BaseColor[0], NULL); if ((DeltaX = X1 - X0) >= 0) { XDir = 1; } else { XDir = -1; DeltaX = -DeltaX; /* make DeltaX positive */ } /* Special-case horizontal, vertical, and diagonal lines, which require no weighting because they go right through the center of every pixel */ if ((DeltaY = Y1 - Y0) == 0) { /* Horizontal line */ while (DeltaX-- != 0) { X0 += XDir; PUTDOT(X0, Y0, &BaseColor[0], NULL); } return; } if (DeltaX == 0) { /* Vertical line */ do { Y0++; PUTDOT(X0, Y0, &BaseColor[0], NULL); } while (--DeltaY != 0); return; } //diagonal line. if (DeltaX == DeltaY) { do { X0 += XDir; Y0++; PUTDOT(X0, Y0, &BaseColor[0], NULL); } while (--DeltaY != 0); return; } /* Line is not horizontal, diagonal, or vertical */ ErrorAcc = 0; /* initialize the line error accumulator to 0 */ /* # of bits by which to shift ErrorAcc to get intensity level */ IntensityShift = 16 - IntensityBits; /* Mask used to flip all bits in an intensity weighting, producing the result (1 - intensity weighting) */ WeightingComplementMask = NumLevels - 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -