From 68fed677ac9fd5fe2b24b7eb2837dbe2dab10320 Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Tue, 8 Jun 2021 13:26:40 +0700 Subject: [PATCH] automap overlay and rotate modes (based on Crispy Doom) (#216) * add automap overlay mode * add automap rotate mode * add zoom automap with mouse wheel * remove automaprotate toggle * set mapangle in AM_Ticker * initialize zoomlevel on all maps so that a 4096 units square map would just fit in (from Crispy Doom) * revert 320->SCREENWITDH change * change STlib_updatePercent 'refresh' check * cleanup and add comment * move map title position calculation to the next block --- Source/am_map.c | 234 +++++++++++++++++++++++++++++++++++++++++----- Source/d_deh.c | 8 ++ Source/d_deh.h | 6 ++ Source/d_englsh.h | 6 ++ Source/d_french.h | 6 ++ Source/d_main.c | 12 ++- Source/doomstat.h | 2 + Source/g_game.c | 2 + Source/g_game.h | 2 + Source/hu_stuff.c | 13 ++- Source/m_menu.c | 35 +++++-- Source/m_misc.c | 28 ++++++ Source/r_main.c | 2 +- Source/r_segs.c | 2 +- Source/st_lib.c | 4 +- Source/st_stuff.c | 2 +- 16 files changed, 326 insertions(+), 38 deletions(-) diff --git a/Source/am_map.c b/Source/am_map.c index c5dc4316..43b57207 100644 --- a/Source/am_map.c +++ b/Source/am_map.c @@ -86,6 +86,8 @@ extern int key_map_clear; // | extern int key_map_grid; // phares // [FG] automap joystick button extern int joybautomap; +extern int key_map_overlay; +extern int key_map_rotate; // scale on entry #define INITSCALEMTOF (int)(.2*FRACUNIT) @@ -99,6 +101,10 @@ extern int joybautomap; // pulls out to 0.5x in 1 second #define M_ZOOMOUT ((int) (FRACUNIT/1.02)) +// [crispy] zoom faster with the mouse wheel +#define M2_ZOOMIN ((int) (1.08*FRACUNIT)) +#define M2_ZOOMOUT ((int) (FRACUNIT/1.08)) + // translates between frame-buffer and map distances // [FG] fix int overflow that causes map and grid lines to disappear #define FTOM(x) ((((int64_t)(x)<<16)*scale_ftom)>>16) @@ -220,6 +226,8 @@ int automap_grid = 0; boolean automapactive = false; +boolean automapoverlay = false; + // location of window on screen static int f_x; static int f_y; @@ -288,6 +296,17 @@ int followplayer = 1; // specifies whether to follow the player around static boolean stopped = true; +// [crispy] automap rotate mode needs these early on +boolean automaprotate = false; +void AM_rotate(int64_t *x, int64_t *y, angle_t a); +static void AM_rotatePoint(mpoint_t *pt); +static mpoint_t mapcenter; +static angle_t mapangle; + +// [FG] prev/next weapon keys and buttons +extern int mousebprevweapon; +extern int mousebnextweapon; + // // AM_getIslope() // @@ -457,14 +476,22 @@ void AM_findMinMaxBoundaries(void) // void AM_changeWindowLoc(void) { + int64_t incx, incy; + if (m_paninc.x || m_paninc.y) { followplayer = 0; f_oldloc.x = D_MAXINT; } - m_x += m_paninc.x; - m_y += m_paninc.y; + incx = m_paninc.x; + incy = m_paninc.y; + if (automaprotate) + { + AM_rotate(&incx, &incy, -mapangle); + } + m_x += incx; + m_y += incy; if (m_x + m_w/2 > max_x) m_x = max_x - m_w/2; @@ -600,7 +627,15 @@ void AM_LevelInit(void) f_h = (SCREENHEIGHT-ST_HEIGHT) << hires; AM_findMinMaxBoundaries(); - scale_mtof = FixedDiv(min_scale_mtof, (int) (0.7*FRACUNIT)); + + // [crispy] initialize zoomlevel on all maps so that a 4096 units + // square map would just fit in (MAP01 is 3376x3648 units) + { + fixed_t a = FixedDiv(f_w, (max_w>>FRACBITS < 2048) ? 2*(max_w>>FRACBITS) : 4096); + fixed_t b = FixedDiv(f_h, (max_h>>FRACBITS < 2048) ? 2*(max_h>>FRACBITS) : 4096); + scale_mtof = FixedDiv(a < b ? a : b, (int) (0.7*FRACUNIT)); + } + if (scale_mtof > max_scale_mtof) scale_mtof = min_scale_mtof; scale_ftom = FixedDiv(FRACUNIT, scale_mtof); @@ -720,6 +755,23 @@ boolean AM_Responder rc = true; } } + // [crispy] zoom automap with the mouse (wheel) + else if (ev->type == ev_mouse && !menuactive) + { + if (mousebprevweapon >= 0 && ev->data1 & (1 << mousebprevweapon)) + { + mtof_zoommul = M2_ZOOMOUT; + ftom_zoommul = M2_ZOOMIN; + rc = true; + } + else + if (mousebnextweapon >= 0 && ev->data1 & (1 << mousebnextweapon)) + { + mtof_zoommul = M2_ZOOMIN; + ftom_zoommul = M2_ZOOMOUT; + rc = true; + } + } else if (ev->type == ev_keydown) { rc = true; @@ -797,6 +849,23 @@ boolean AM_Responder plr->message = s_AMSTR_MARKSCLEARED; // ^ } // | else // phares + if (ch == key_map_overlay) + { + automapoverlay = !automapoverlay; + if (automapoverlay) + plr->message = s_AMSTR_OVERLAYON; + else + plr->message = s_AMSTR_OVERLAYOFF; + } + else if (ch == key_map_rotate) + { + automaprotate = !automaprotate; + if (automaprotate) + plr->message = s_AMSTR_ROTATEON; + else + plr->message = s_AMSTR_ROTATEOFF; + } + else { rc = false; } @@ -847,6 +916,13 @@ void AM_changeWindowScale(void) scale_mtof = FixedMul(scale_mtof, mtof_zoommul); scale_ftom = FixedDiv(FRACUNIT, scale_mtof); + // [crispy] reset after zooming with the mouse wheel + if (ftom_zoommul == M2_ZOOMIN || ftom_zoommul == M2_ZOOMOUT) + { + mtof_zoommul = FRACUNIT; + ftom_zoommul = FRACUNIT; + } + if (scale_mtof < min_scale_mtof) AM_minOutWindowScale(); else if (scale_mtof > max_scale_mtof) @@ -911,7 +987,17 @@ void AM_Ticker (void) // Change x,y location if (m_paninc.x || m_paninc.y) + { AM_changeWindowLoc(); + } + + // [crispy] required for AM_rotatePoint() + if (automaprotate) + { + mapcenter.x = m_x + m_w / 2; + mapcenter.y = m_y + m_h / 2; + mapangle = ANG90 - viewangle; + } } @@ -1191,35 +1277,67 @@ void AM_drawGrid(int color) // Figure out start of vertical gridlines start = m_x; + if (automaprotate) + { + start -= m_h / 2; + } if ((start-bmaporgx)%(MAPBLOCKUNITS<y; l.b.x = lines[i].v2->x; l.b.y = lines[i].v2->y; + if (automaprotate) + { + AM_rotatePoint(&l.a); + AM_rotatePoint(&l.b); + } // if line has been seen or IDDT has been used if (ddt_cheating || (lines[i].flags & ML_MAPPED)) { @@ -1498,6 +1621,27 @@ void AM_rotate *x = tmpx; } +// [crispy] rotate point around map center +// adapted from prboom-plus/src/am_map.c:898-920 +static void AM_rotatePoint(mpoint_t *pt) +{ + int64_t tmpx; + const angle_t actualangle = ANG90 - viewangle; + + pt->x -= mapcenter.x; + pt->y -= mapcenter.y; + + tmpx = (int64_t)FixedMul(pt->x, finecosine[actualangle>>ANGLETOFINESHIFT]) + - (int64_t)FixedMul(pt->y, finesine[actualangle>>ANGLETOFINESHIFT]) + + mapcenter.x; + + pt->y = (int64_t)FixedMul(pt->x, finesine[actualangle>>ANGLETOFINESHIFT]) + + (int64_t)FixedMul(pt->y, finecosine[actualangle>>ANGLETOFINESHIFT]) + + mapcenter.y; + + pt->x = tmpx; +} + // // AM_drawLineCharacter() // @@ -1520,6 +1664,11 @@ void AM_drawLineCharacter int i; mline_t l; + if (automaprotate) + { + angle += mapangle; + } + for (i=0;imo->x; + pt.y = plr->mo->y; + if (automaprotate) + { + AM_rotatePoint(&pt); + } + if (ddt_cheating) AM_drawLineCharacter ( @@ -1582,8 +1739,8 @@ void AM_drawPlayers(void) 0, plr->mo->angle, mapcolor_sngl, //jff color - plr->mo->x, - plr->mo->y + pt.x, + pt.y ); else AM_drawLineCharacter @@ -1593,8 +1750,8 @@ void AM_drawPlayers(void) 0, plr->mo->angle, mapcolor_sngl, //jff color - plr->mo->x, - plr->mo->y); + pt.x, + pt.y); return; } @@ -1603,6 +1760,13 @@ void AM_drawPlayers(void) their_color++; p = &players[i]; + pt.x = p->mo->x; + pt.y = p->mo->y; + if (automaprotate) + { + AM_rotatePoint(&pt); + } + // killough 9/29/98: use !demoplayback so internal demos are no different if ( (deathmatch && !demoplayback) && p != plr) continue; @@ -1622,8 +1786,8 @@ void AM_drawPlayers(void) 0, p->mo->angle, color, - p->mo->x, - p->mo->y + pt.x, + pt.y ); } } @@ -1642,6 +1806,7 @@ void AM_drawThings { int i; mobj_t* t; + mpoint_t pt; // for all sectors for (i=0;imo) + { + t = t->snext; + continue; + } + + pt.x = t->x; + pt.y = t->y; + if (automaprotate) + { + AM_rotatePoint(&pt); + } + //jff 1/5/98 case over doomednum of thing being drawn if (mapcolor_rkey || mapcolor_ykey || mapcolor_bkey) { @@ -1663,8 +1842,8 @@ void AM_drawThings 16<angle, mapcolor_rkey!=-1? mapcolor_rkey : mapcolor_sprt, - t->x, - t->y + pt.x, + pt.y ); t = t->snext; continue; @@ -1676,8 +1855,8 @@ void AM_drawThings 16<angle, mapcolor_ykey!=-1? mapcolor_ykey : mapcolor_sprt, - t->x, - t->y + pt.x, + pt.y ); t = t->snext; continue; @@ -1689,8 +1868,8 @@ void AM_drawThings 16<angle, mapcolor_bkey!=-1? mapcolor_bkey : mapcolor_sprt, - t->x, - t->y + pt.x, + pt.y ); t = t->snext; continue; @@ -1731,19 +1910,31 @@ void AM_drawThings void AM_drawMarks(void) { int i; + mpoint_t pt; + for (i=0;i0 && // hud optioned on hud_displayed && // hud on from fullscreen key scaledviewheight==SCREENHEIGHT &&// fullscreen mode is active - !automapactive // automap is not active + (!automapactive || automapoverlay) ) { HU_MoveHud(); // insure HUD display coords are correct @@ -1440,6 +1443,12 @@ void HU_Ticker(void) { char *s; + // [crispy] move map title to the bottom + if (automapoverlay && screenblocks >= 11) + w_title.y = HU_TITLEY + ST_HEIGHT; + else + w_title.y = HU_TITLEY; + if (map_level_stats) { sprintf(hud_lstatk, "K: %d/%d", plr->killcount, totalkills); diff --git a/Source/m_menu.c b/Source/m_menu.c index 02017c2a..5c83de32 100644 --- a/Source/m_menu.c +++ b/Source/m_menu.c @@ -2591,12 +2591,13 @@ static int G_GotoNextLevel(void) #define X_BUTTON 301 #define Y_BUTTON 3 -// Definitions of the (in this case) four key binding screens. +// Definitions of the (in this case) five key binding screens. setup_menu_t keys_settings1[]; setup_menu_t keys_settings2[]; setup_menu_t keys_settings3[]; setup_menu_t keys_settings4[]; +setup_menu_t keys_settings5[]; // The table which gets you from one screen table to the next. @@ -2606,6 +2607,7 @@ setup_menu_t* keys_settings[] = keys_settings2, keys_settings3, keys_settings4, + keys_settings5, NULL }; @@ -2768,17 +2770,30 @@ setup_menu_t keys_settings4[] = // Key Binding screen strings {"CLEAR MARKS",S_KEY ,m_map ,KB_X,KB_Y+ 9*8,{&key_map_clear}}, {"FULL/ZOOM" ,S_KEY ,m_map ,KB_X,KB_Y+10*8,{&key_map_gobig}}, {"GRID" ,S_KEY ,m_map ,KB_X,KB_Y+11*8,{&key_map_grid}}, - - {"CHATTING" ,S_SKIP|S_TITLE,m_null,KB_X,KB_Y+12*8}, - {"BEGIN CHAT" ,S_KEY ,m_scrn,KB_X,KB_Y+13*8,{&key_chat}}, - {"PLAYER 1" ,S_KEY ,m_scrn,KB_X,KB_Y+14*8,{&destination_keys[0]}}, - {"PLAYER 2" ,S_KEY ,m_scrn,KB_X,KB_Y+15*8,{&destination_keys[1]}}, - {"PLAYER 3" ,S_KEY ,m_scrn,KB_X,KB_Y+16*8,{&destination_keys[2]}}, - {"PLAYER 4" ,S_KEY ,m_scrn,KB_X,KB_Y+17*8,{&destination_keys[3]}}, - {"BACKSPACE" ,S_KEY ,m_scrn,KB_X,KB_Y+18*8,{&key_backspace}}, - {"ENTER" ,S_KEY ,m_scrn,KB_X,KB_Y+19*8,{&key_enter}}, + {"OVERLAY" ,S_KEY ,m_map ,KB_X,KB_Y+12*8,{&key_map_overlay}}, + {"ROTATE" ,S_KEY ,m_map ,KB_X,KB_Y+13*8,{&key_map_rotate}}, {"<- PREV" ,S_SKIP|S_PREV,m_null,KB_PREV,KB_Y+20*8, {keys_settings3}}, + {"NEXT ->",S_SKIP|S_NEXT,m_null,KB_NEXT,KB_Y+20*8, {keys_settings5}}, + + // Final entry + + {0,S_SKIP|S_END,m_null} + +}; + +setup_menu_t keys_settings5[] = +{ + {"CHATTING" ,S_SKIP|S_TITLE,m_null,KB_X,KB_Y}, + {"BEGIN CHAT" ,S_KEY ,m_scrn,KB_X,KB_Y+1*8,{&key_chat}}, + {"PLAYER 1" ,S_KEY ,m_scrn,KB_X,KB_Y+2*8,{&destination_keys[0]}}, + {"PLAYER 2" ,S_KEY ,m_scrn,KB_X,KB_Y+3*8,{&destination_keys[1]}}, + {"PLAYER 3" ,S_KEY ,m_scrn,KB_X,KB_Y+4*8,{&destination_keys[2]}}, + {"PLAYER 4" ,S_KEY ,m_scrn,KB_X,KB_Y+5*8,{&destination_keys[3]}}, + {"BACKSPACE" ,S_KEY ,m_scrn,KB_X,KB_Y+6*8,{&key_backspace}}, + {"ENTER" ,S_KEY ,m_scrn,KB_X,KB_Y+7*8,{&key_enter}}, + + {"<- PREV" ,S_SKIP|S_PREV,m_null,KB_PREV,KB_Y+20*8, {keys_settings4}}, // Final entry diff --git a/Source/m_misc.c b/Source/m_misc.c index bd983883..98e7e291 100644 --- a/Source/m_misc.c +++ b/Source/m_misc.c @@ -937,6 +937,20 @@ default_t defaults[] = { "key to toggle grid display over automap" }, + { + "key_map_overlay", + (config_t *) &key_map_overlay, NULL, + {'o'}, {0,255}, number, ss_keys, wad_no, + "key to toggle overlay mode" + }, + + { + "key_map_rotate", + (config_t *) &key_map_rotate, NULL, + {'r'}, {0,255}, number, ss_keys, wad_no, + "key to toggle rotate mode" + }, + { "key_reverse", (config_t *) &key_reverse, NULL, @@ -1548,6 +1562,20 @@ default_t defaults[] = { "1 to show level time widget" }, + { + "automapoverlay", + (config_t *) &automapoverlay, NULL, + {0}, {0,1}, number, ss_auto, wad_no, + "1 to enable automap overlay mode" + }, + + { + "automaprotate", + (config_t *) &automaprotate, NULL, + {0}, {0,1}, number, ss_auto, wad_no, + "1 to enable automap rotate mode" + }, + //jff 1/7/98 end additions for automap //jff 2/16/98 defaults for color ranges in hud and status diff --git a/Source/r_main.c b/Source/r_main.c index cbc9fa51..f26f3b88 100644 --- a/Source/r_main.c +++ b/Source/r_main.c @@ -694,7 +694,7 @@ void R_RenderPlayerView (player_t* player) R_RenderBSPNode (numnodes-1); // [FG] update automap while playing - if (automapactive) + if (automapactive && !automapoverlay) return; // Check for new console commands. diff --git a/Source/r_segs.c b/Source/r_segs.c index fafbc10a..64760f8d 100644 --- a/Source/r_segs.c +++ b/Source/r_segs.c @@ -396,7 +396,7 @@ void R_StoreWallRange(const int start, const int stop) linedef->flags |= ML_MAPPED; // [FG] update automap while playing - if (automapactive) + if (automapactive && !automapoverlay) return; // calculate rw_distance for scale calculation diff --git a/Source/st_lib.c b/Source/st_lib.c index cdf744ea..9fda812a 100644 --- a/Source/st_lib.c +++ b/Source/st_lib.c @@ -221,7 +221,9 @@ void STlib_updatePercent char *outrng, //jff 2/16/98 add color translation to digit output int refresh ) { - if (refresh || *per->n.on) // killough 2/21/98: fix percents not updated; + // Remove the check for 'refresh' because this causes percent symbols to always appear + // in automap overlay mode. + if (*per->n.on) // killough 2/21/98: fix percents not updated; { if (!sts_always_red) // also support gray-only percents V_DrawPatchTranslated diff --git a/Source/st_stuff.c b/Source/st_stuff.c index 0e5158a1..09d618a9 100644 --- a/Source/st_stuff.c +++ b/Source/st_stuff.c @@ -838,7 +838,7 @@ void ST_diffDraw(void) void ST_Drawer(boolean fullscreen, boolean refresh) { - st_statusbaron = !fullscreen || automapactive; + st_statusbaron = !fullscreen || (automapactive && !automapoverlay); st_firsttime = st_firsttime || refresh; ST_doPaletteStuff(); // Do red-/gold-shifts from damage/items