From f70f84aee76461cd8679ca22b172394e8ffd9b6c Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 12 Oct 2023 01:18:55 -0700 Subject: [PATCH] not PR #1102 - map refresh during #terrain This fixes the part of pull request #1102 by entrez dealing with the map refresh side of things. It was pulled out of a much larger patch that also deals with terminal window resize for tty. Using ^R when getpos() is in operation, whether actually picking a position for something or browsing the map during #terrain or post detection magic, it was reconstructing the known map and positioning the cursor on the hero instead redrawing the selected terrain subset or detected objects/monsters/whatever. There's already a routine to redraw the current view of the map without recalculating it, but it wasn't being used for ^R during getpos operation. --- include/display.h | 8 ++++++++ include/extern.h | 3 ++- src/display.c | 47 ++++++++++++++++++++++++++++++++++------------- src/do_name.c | 16 ++++++++++++++-- win/tty/wintty.c | 2 +- 5 files changed, 59 insertions(+), 17 deletions(-) diff --git a/include/display.h b/include/display.h index 1b4d887ae..600e979cb 100644 --- a/include/display.h +++ b/include/display.h @@ -1033,6 +1033,14 @@ enum glyph_offsets { #define MG_FEMALE 0x02000 /* represents a female mon or statue of one */ #define MG_BADXY 0x04000 /* bad coordinates were passed */ +/* docrt(): re-draw whole screen; docrt_flags(): docrt() with more control */ +enum docrt_flags_bits { + docrtRecalc = 0, /* full docrt(), recalculate what the map should show */ + docrtRefresh = 1, /* redraw_map(), draw what we think the map shows */ + docrtMapOnly = 2, /* ORed with Recalc or Refresh; draw the map but not + * status or perminv */ +}; + typedef struct { xint8 gnew; /* perhaps move this bit into the rm structure. */ glyph_info glyphinfo; diff --git a/include/extern.h b/include/extern.h index 3634ebcb7..ee9befb6b 100644 --- a/include/extern.h +++ b/include/extern.h @@ -445,7 +445,8 @@ extern void see_traps(void); extern void curs_on_u(void); extern int doredraw(void); extern void docrt(void); -extern void redraw_map(void); +extern void docrt_flags(int); +extern void redraw_map(boolean); extern void show_glyph(coordxy, coordxy, int); extern void clear_glyph_buffer(void); extern void row_refresh(coordxy, coordxy, coordxy); diff --git a/src/display.c b/src/display.c index 7b5ef20a3..079c287bf 100644 --- a/src/display.c +++ b/src/display.c @@ -152,6 +152,7 @@ static void t_warn(struct rm *); static int wall_angle(struct rm *); #define remember_topology(x, y) (gl.lastseentyp[x][y] = levl[x][y].typ) +#define _glyph_at(x, y) gg.gbuf[y][x].glyphinfo.glyph /* * See display.h for descriptions of tp_sensemon() through @@ -1528,7 +1529,7 @@ see_traps(void) int glyph; for (trap = gf.ftrap; trap; trap = trap->ntrap) { - glyph = glyph_at(trap->tx, trap->ty); + glyph = _glyph_at(trap->tx, trap->ty); if (glyph_is_trap(glyph)) newsym(trap->tx, trap->ty); } @@ -1599,17 +1600,31 @@ doredraw(void) return ECMD_OK; } +/* the main refresh-the-screen routine */ void docrt(void) +{ + docrt_flags(docrtRecalc); +} + +/* docrt() with finer control */ +void +docrt_flags(int refresh_flags) { coordxy x, y; register struct rm *lev; + boolean maponly = (refresh_flags & docrtMapOnly) != 0, + redrawonly = (refresh_flags & docrtRefresh) != 0; if (!u.ux || gp.program_state.in_docrt) return; /* display isn't ready yet */ gp.program_state.in_docrt = TRUE; + if (redrawonly) { + redraw_map(FALSE); + goto post_map; + } if (u.uswallow) { swallowed(1); goto post_map; @@ -1618,7 +1633,7 @@ docrt(void) under_water(1); goto post_map; } - if (u.uburied) { + if (u.uburied) { /* [not implemented] */ under_ground(1); goto post_map; } @@ -1648,17 +1663,20 @@ docrt(void) post_map: - /* perm_invent */ - update_inventory(); - - gc.context.botlx = 1; /* force a redraw of the bottom line */ + if (!maponly) { + /* perm_invent */ + update_inventory(); + /* status */ + gc.context.botlx = 1; /* force a redraw of the bottom lines */ + /* note: caller needs to call bot() to actually redraw status */ + } gp.program_state.in_docrt = FALSE; } /* for panning beyond a clipped region; resend the current map data to the interface rather than use docrt()'s regeneration of that data */ void -redraw_map(void) +redraw_map(boolean cursor_on_u) { coordxy x, y; int glyph; @@ -1682,12 +1700,13 @@ redraw_map(void) */ for (y = 0; y < ROWNO; ++y) for (x = 1; x < COLNO; ++x) { - glyph = glyph_at(x, y); /* not levl[x][y].glyph */ - get_bkglyph_and_framecolor(x, y, &bkglyphinfo.glyph, &bkglyphinfo.framecolor); + glyph = _glyph_at(x, y); /* not levl[x][y].glyph */ + get_bkglyph_and_framecolor(x, y, &bkglyphinfo.glyph, + &bkglyphinfo.framecolor); print_glyph(WIN_MAP, x, y, Glyphinfo_at(x, y, glyph), &bkglyphinfo); } - flush_screen(1); + flush_screen(cursor_on_u); #ifndef UNBUFFERED_GLYPHINFO nhUse(glyph); #endif @@ -2023,7 +2042,7 @@ cls(void) return; in_cls = TRUE; display_nhwindow(WIN_MESSAGE, FALSE); /* flush messages */ - gc.context.botlx = 1; /* force update of botl window */ + gc.context.botlx = 1; /* force update of botl window */ clear_nhwindow(WIN_MAP); /* clear physical screen */ clear_glyph_buffer(); /* force gbuf[][].glyph to unexplored */ @@ -2073,7 +2092,8 @@ flush_screen(int cursor_on_u) for (; x <= gg.gbuf_stop[y]; gptr++, x++) { get_bkglyph_and_framecolor(x, y, &bkglyph, &bkglyphinfo.framecolor); if (gptr->gnew - || (gw.wsettings.map_frame_color != NO_COLOR && bkglyphinfo.framecolor != NO_COLOR)) { + || (gw.wsettings.map_frame_color != NO_COLOR + && bkglyphinfo.framecolor != NO_COLOR)) { map_glyphinfo(x, y, bkglyph, 0, &bkglyphinfo); /* won't touch framecolor */ print_glyph(WIN_MAP, x, y, Glyphinfo_at(x, y, gptr->glyph), &bkglyphinfo); @@ -2298,7 +2318,7 @@ glyph_at(coordxy x, coordxy y) { if (x < 0 || y < 0 || x >= COLNO || y >= ROWNO) return cmap_to_glyph(S_room); /* XXX */ - return gg.gbuf[y][x].glyphinfo.glyph; + return gg.gbuf[y][x].glyphinfo.glyph; /* _glyph_at(x,y) */ } #ifdef UNBUFFERED_GLYPHINFO @@ -3671,6 +3691,7 @@ fn_cmap_to_glyph(int cmap) end of the source code seen by the compiler (there are lots of other macros defined above...) */ #undef remember_topology +#undef _glyph_at #undef DETECTED #undef PHYSICALLY_SEEN #undef is_worm_tail diff --git a/src/do_name.c b/src/do_name.c index 8d7b667aa..4a458d448 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -730,9 +730,20 @@ enum hilite_states { static void getpos_refresh(int *hilite_statep) { - if (*hilite_statep == Hilite_Active) + int redrawflags = docrtRefresh; + + if (*hilite_statep == Hilite_Active) { + /* removing SHOWVALID markers; just redraw the map */ (*getpos_hilitefunc)(2); /* tmp_at(DISP_END) */ - docrt(); /* redraw everything */ + redrawflags |= docrtMapOnly; + } else { + /* ^R: player requested that the screen be redrawn; maybe something + * outside of nethack has clobbered it; clear it, redisplay what we + * think the map already shows rather than recalculate that, do a + * full status update, and show perminv, if applicable */ + ; /* just docrtRefresh */ + } + docrt_flags(redrawflags); *hilite_statep = Hilite_Inactive; } @@ -928,6 +939,7 @@ getpos(coord *ccp, boolean force, const char *goal) getpos_help(force, goal); /* ^R: docrt(), hilite_state = Hilite_Inactive */ getpos_refresh(&hilite_state); + curs(WIN_MAP, cx, cy); /* update message window to reflect that we're still targeting */ show_goal_msg = TRUE; } else if (c == gc.Cmd.spkeys[NHKF_GETPOS_SHOWVALID]) { diff --git a/win/tty/wintty.c b/win/tty/wintty.c index 2d00600fc..7f3214425 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -3438,7 +3438,7 @@ tty_cliparound(int x, int y) clipy = clipymax - (LI - 1 - iflags.wc2_statuslines); } if (clipx != oldx || clipy != oldy) { - redraw_map(); /* ask the core to resend the map window's data */ + redraw_map(TRUE); /* ask the core to resend the map window's data */ } } #endif /* CLIPPING */