diff --git a/src/am_map.c b/src/am_map.c index 7dfbf4ba4..b2c7de442 100644 --- a/src/am_map.c +++ b/src/am_map.c @@ -160,6 +160,7 @@ static boolean am_stopped = true; static INT32 f_x, f_y; // location of window on screen (always zero for both) static INT32 f_w, f_h; // size of window on screen (always the screen width and height respectively) +static boolean m_keydown[4]; // which window panning keys are being pressed down? static mpoint_t m_paninc; // how far the window pans each tic (map coords) static fixed_t mtof_zoommul; // how far the window zooms in each tic (map coords) static fixed_t ftom_zoommul; // how far the window zooms in each tic (fb coords) @@ -205,6 +206,7 @@ static boolean followplayer = true; // specifies whether to follow the player ar typedef void (*AMDRAWFLINEFUNC) (const fline_t *fl, INT32 color); static AMDRAWFLINEFUNC AM_drawFline; +static void AM_drawPixel(INT32 xx, INT32 yy, INT32 cc); static void AM_drawFline_soft(const fline_t *fl, INT32 color); static void AM_activateNewScale(void) @@ -344,22 +346,22 @@ static void AM_initVariables(void) old_m_h = m_h; } +// +// Called when the screen size changes. +// +static void AM_FrameBufferInit(void) +{ + f_x = f_y = 0; + f_w = vid.width; + f_h = vid.height; +} + // // should be called at the start of every level // right now, i figure it out myself // static void AM_LevelInit(void) { - f_x = f_y = 0; - f_w = vid.width; - f_h = vid.height; - - AM_drawFline = AM_drawFline_soft; -#ifdef HWRENDER - if (rendermode == render_opengl) - AM_drawFline = HWR_drawAMline; -#endif - AM_findMinMaxBoundaries(); scale_mtof = FixedDiv(min_scale_mtof*10, 7*FRACUNIT); if (scale_mtof > max_scale_mtof) @@ -381,7 +383,7 @@ void AM_Stop(void) * * \sa AM_Stop */ -static inline void AM_Start(void) +void AM_Start(void) { static INT32 lastlevel = -1; @@ -390,8 +392,12 @@ static inline void AM_Start(void) am_stopped = false; if (lastlevel != gamemap || am_recalc) // screen size changed { - AM_LevelInit(); - lastlevel = gamemap; + AM_FrameBufferInit(); + if (lastlevel != gamemap) + { + AM_LevelInit(); + lastlevel = gamemap; + } am_recalc = false; } AM_initVariables(); @@ -417,6 +423,28 @@ static void AM_maxOutWindowScale(void) AM_activateNewScale(); } +// +// set window panning +// +static void AM_setWindowPanning(void) +{ + // up and down + if (m_keydown[2]) // pan up + m_paninc.y = FTOM(F_PANINC); + else if (m_keydown[3]) // pan down + m_paninc.y = -FTOM(F_PANINC); + else + m_paninc.y = 0; + + // left and right + if (m_keydown[0]) // pan right + m_paninc.x = FTOM(F_PANINC); + else if (m_keydown[1]) // pan left + m_paninc.x = -FTOM(F_PANINC); + else + m_paninc.x = 0; +} + /** Responds to user inputs in automap mode. * * \param ev Event to possibly respond to. @@ -449,35 +477,49 @@ boolean AM_Responder(event_t *ev) { case AM_PANRIGHTKEY: // pan right if (!followplayer) - m_paninc.x = FTOM(F_PANINC); + { + m_keydown[0] = true; + AM_setWindowPanning(); + } else rc = false; break; case AM_PANLEFTKEY: // pan left if (!followplayer) - m_paninc.x = -FTOM(F_PANINC); + { + m_keydown[1] = true; + AM_setWindowPanning(); + } else rc = false; break; case AM_PANUPKEY: // pan up if (!followplayer) - m_paninc.y = FTOM(F_PANINC); + { + m_keydown[2] = true; + AM_setWindowPanning(); + } else rc = false; break; case AM_PANDOWNKEY: // pan down if (!followplayer) - m_paninc.y = -FTOM(F_PANINC); + { + m_keydown[3] = true; + AM_setWindowPanning(); + } else rc = false; break; case AM_ZOOMOUTKEY: // zoom out mtof_zoommul = M_ZOOMOUT; ftom_zoommul = M_ZOOMIN; + AM_setWindowPanning(); break; case AM_ZOOMINKEY: // zoom in mtof_zoommul = M_ZOOMIN; ftom_zoommul = M_ZOOMOUT; + AM_setWindowPanning(); break; case AM_TOGGLEKEY: AM_Stop(); @@ -491,6 +533,7 @@ boolean AM_Responder(event_t *ev) } else AM_restoreScaleAndLoc(); + AM_setWindowPanning(); break; case AM_FOLLOWKEY: followplayer = !followplayer; @@ -510,14 +553,32 @@ boolean AM_Responder(event_t *ev) switch (ev->data1) { case AM_PANRIGHTKEY: + if (!followplayer) + { + m_keydown[0] = false; + AM_setWindowPanning(); + } + break; case AM_PANLEFTKEY: if (!followplayer) - m_paninc.x = 0; + { + m_keydown[1] = false; + AM_setWindowPanning(); + } break; case AM_PANUPKEY: + if (!followplayer) + { + m_keydown[2] = false; + AM_setWindowPanning(); + } + break; case AM_PANDOWNKEY: if (!followplayer) - m_paninc.y = 0; + { + m_keydown[3] = false; + AM_setWindowPanning(); + } break; case AM_ZOOMOUTKEY: case AM_ZOOMINKEY: @@ -718,6 +779,17 @@ static boolean AM_clipMline(const mline_t *ml, fline_t *fl) } #undef DOOUTCODE +// +// Draws a pixel. +// +static void AM_drawPixel(INT32 xx, INT32 yy, INT32 cc) +{ + UINT8 *dest = screens[0]; + if (xx < 0 || yy < 0 || xx >= vid.width || yy >= vid.height) + return; // off the screen + dest[(yy*vid.width) + xx] = cc; +} + // // Classic Bresenham w/ whatever optimizations needed for speed // @@ -739,8 +811,6 @@ static void AM_drawFline_soft(const fline_t *fl, INT32 color) } #endif - #define PUTDOT(xx,yy,cc) V_DrawFill(xx,yy,1,1,cc|V_NOSCALESTART); - dx = fl->b.x - fl->a.x; ax = 2 * (dx < 0 ? -dx : dx); sx = dx < 0 ? -1 : 1; @@ -757,7 +827,7 @@ static void AM_drawFline_soft(const fline_t *fl, INT32 color) d = ay - ax/2; for (;;) { - PUTDOT(x, y, color) + AM_drawPixel(x, y, color); if (x == fl->b.x) return; if (d >= 0) @@ -774,7 +844,7 @@ static void AM_drawFline_soft(const fline_t *fl, INT32 color) d = ax - ay/2; for (;;) { - PUTDOT(x, y, color) + AM_drawPixel(x, y, color); if (y == fl->b.y) return; if (d >= 0) @@ -786,8 +856,6 @@ static void AM_drawFline_soft(const fline_t *fl, INT32 color) d += ax; } } - - #undef PUTDOT } // @@ -1100,6 +1168,12 @@ void AM_Drawer(void) if (!automapactive) return; + AM_drawFline = AM_drawFline_soft; +#ifdef HWRENDER + if (rendermode == render_opengl) + AM_drawFline = HWR_drawAMline; +#endif + AM_clearFB(BACKGROUND); if (draw_grid) AM_drawGrid(GRIDCOLORS); AM_drawWalls(); diff --git a/src/am_map.h b/src/am_map.h index 462bb3d6d..0560207bb 100644 --- a/src/am_map.h +++ b/src/am_map.h @@ -38,6 +38,9 @@ void AM_Ticker(void); // Called by main loop, instead of view drawer if automap is active. void AM_Drawer(void); +// Enables the automap. +void AM_Start(void); + // Called to force the automap to quit if the level is completed while it is up. void AM_Stop(void); diff --git a/src/screen.c b/src/screen.c index 5bb304c08..fcf6c6b0b 100644 --- a/src/screen.c +++ b/src/screen.c @@ -360,10 +360,13 @@ void SCR_Recalc(void) vid.fsmalldupy = vid.smalldupy*FRACUNIT; #endif - // toggle off automap because some screensize-dependent values will + // toggle off (then back on) the automap because some screensize-dependent values will // be calculated next time the automap is activated. if (automapactive) - AM_Stop(); + { + am_recalc = true; + AM_Start(); + } // set the screen[x] ptrs on the new vidbuffers V_Init();