diff options
Diffstat (limited to 'src/util.cc')
-rw-r--r-- | src/util.cc | 948 |
1 files changed, 450 insertions, 498 deletions
diff --git a/src/util.cc b/src/util.cc index 7d795828..4928a294 100644 --- a/src/util.cc +++ b/src/util.cc @@ -3,7 +3,6 @@ /* Purpose: Angband utilities -BEN- */ #include "util.hpp" -#include "util.h" #include "cli_comm.hpp" #include "cmd3.hpp" @@ -18,22 +17,140 @@ #include "player_race.hpp" #include "player_race_mod.hpp" #include "player_type.hpp" -#include "tables.h" #include "tables.hpp" #include "timer_type.hpp" -#include "variable.h" #include "variable.hpp" #include "xtra1.hpp" +#include "z-form.hpp" #include <boost/algorithm/string/predicate.hpp> #include <chrono> +#include <cstdio> +#include <fcntl.h> +#include <fmt/format.h> #include <sstream> #include <thread> +#ifdef SET_UID +#include <pwd.h> +#endif + using boost::algorithm::iequals; +using boost::algorithm::equals; +using boost::algorithm::starts_with; using std::this_thread::sleep_for; using std::chrono::milliseconds; + +enum class display_option_t { + IMMEDIATE, + DELAY, +}; + +/* + * Read a number at a specific location on the screen + * + * Allow numbers of any size and save the last keypress. + */ +static std::tuple<u32b, char> get_number(u32b def, u32b max, int y, int x, display_option_t display_option) +{ + auto display_number = [x, y](u32b i) + { + prt(fmt::format("{}", i), y, x); + }; + + /* Player has not typed anything yet */ + bool no_keys = true; + + /* Begin the input with default */ + u32b res = def; + + /* Display? */ + switch (display_option) + { + case display_option_t::IMMEDIATE: + // Show current value immediately + display_number(res); + break; + case display_option_t::DELAY: + // Don't show + break; + } + + /* Get a command count */ + while (true) + { + /* Get a new keypress */ + char key = inkey(); + + /* Simple editing (delete or backspace) */ + if ((key == 0x7F) || (key == KTRL('H'))) + { + /* Override the default */ + no_keys = false; + + /* Delete a digit */ + res = res / 10; + + display_number(res); + } + + /* Actual numeric data */ + else if (key >= '0' && key <= '9') + { + /* Override the default */ + if (no_keys) + { + no_keys = false; + res = 0; + } + + /* Don't overflow */ + if (((u32b)(0 - 1) - D2I(key)) / 10 < res) + { + /* Warn */ + bell(); + + /* Limit */ + res = (max + 1 == 0) ? (u32b)(0 - 1) : max; + } + + /* Stop count at maximum */ + else if (res * 10 + D2I(key) > max) + { + /* Warn */ + bell(); + + /* Limit */ + res = max; + } + + /* Increase count */ + else + { + /* Incorporate that digit */ + res = res * 10 + D2I(key); + } + + /* Show current count */ + display_number(res); + } + + /* Escape cancels */ + else if (key == ESCAPE) + { + return { 0, key }; + } + + /* Exit on "unusable" input */ + else + { + return { res, key }; + } + } +} + + /* * Find a default user name from the system. */ @@ -94,11 +211,11 @@ std::string user_name() * But leading tilde symbols must be handled in a special way * Replace "~/" by the home directory of the current user */ -errr path_parse(char *buf, int max, cptr file) +errr path_parse(char *buf, int max, const char *file) { - cptr u, s; - struct passwd *pw; - + const char *u; + const char *s; + struct passwd *pw; /* Assume no result */ buf[0] = '\0'; @@ -154,7 +271,7 @@ errr path_parse(char *buf, int max, cptr file) * This requires no special processing on simple machines, * except for verifying the size of the filename. */ -errr path_parse(char *buf, int max, cptr file) +errr path_parse(char *buf, int max, const char *file) { /* Accept the filename */ strnfmt(buf, max, "%s", file); @@ -180,7 +297,7 @@ errr path_parse(char *buf, int max, cptr file) * Note that this function yields a path which must be "parsed" * using the "parse" function above. */ -errr path_build(char *buf, int max, cptr path, cptr file) +errr path_build(char *buf, int max, const char *path, const char *file) { /* Special file */ if (file[0] == '~') @@ -190,7 +307,7 @@ errr path_build(char *buf, int max, cptr path, cptr file) } /* Absolute file, on "normal" systems */ - else if (prefix(file, PATH_SEP) && !streq(PATH_SEP, "")) + else if (starts_with(file, PATH_SEP) && !equals(PATH_SEP, "")) { /* Use the file itself */ strnfmt(buf, max, "%s", file); @@ -218,7 +335,7 @@ errr path_build(char *buf, int max, cptr path, cptr file) /* * Hack -- replacement for "fopen()" */ -FILE *my_fopen(cptr file, cptr mode) +FILE *my_fopen(const char *file, const char *mode) { char buf[1024]; @@ -255,11 +372,11 @@ errr my_fclose(FILE *fff) * * Process tabs, strip internal non-printables */ -errr my_fgets(FILE *fff, char *buf, huge n) +errr my_fgets(FILE *fff, char *buf, unsigned long n) { - huge i = 0; + unsigned long i = 0; - while (TRUE) + while (true) { int c = fgetc(fff); @@ -336,7 +453,7 @@ errr my_fgets(FILE *fff, char *buf, huge n) /* * Hack -- attempt to delete a file */ -errr fd_kill(cptr file) +errr fd_kill(const char *file) { char buf[1024]; @@ -354,7 +471,7 @@ errr fd_kill(cptr file) /* * Hack -- attempt to move a file */ -errr fd_move(cptr file, cptr what) +errr fd_move(const char *file, const char *what) { char buf[1024]; char aux[1024]; @@ -381,7 +498,7 @@ errr fd_move(cptr file, cptr what) * Note that we assume that the file should be "binary" * */ -int fd_make(cptr file, int mode) +int fd_make(const char *file, int mode) { char buf[1024]; @@ -401,7 +518,7 @@ return (open(buf, O_CREAT | O_EXCL | O_WRONLY | O_BINARY, mode)); * * Note that we assume that the file should be "binary" */ -int fd_open(cptr file, int flags) +int fd_open(const char *file, int flags) { char buf[1024]; @@ -418,7 +535,7 @@ return (open(buf, flags | O_BINARY, 0)); /* * Hack -- attempt to seek on a file descriptor */ -errr fd_seek(int fd, huge n) +errr fd_seek(int fd, unsigned long n) { s32b p; @@ -432,7 +549,7 @@ errr fd_seek(int fd, huge n) if (p < 0) return (1); /* Failure */ - if ((huge)p != n) return (1); + if ((unsigned long)p != n) return (1); /* Success */ return (0); @@ -442,7 +559,7 @@ errr fd_seek(int fd, huge n) /* * Hack -- attempt to read data from a file descriptor */ -errr fd_read(int fd, char *buf, huge n) +errr fd_read(int fd, char *buf, unsigned long n) { /* Verify the fd */ if (fd < 0) return ( -1); @@ -465,7 +582,7 @@ errr fd_read(int fd, char *buf, huge n) #endif /* Read the final piece */ - if ((huge)read(fd, buf, n) != n) return (1); + if ((unsigned long)read(fd, buf, n) != n) return (1); /* Success */ return (0); @@ -475,7 +592,7 @@ errr fd_read(int fd, char *buf, huge n) /* * Hack -- Attempt to write data to a file descriptor */ -errr fd_write(int fd, cptr buf, huge n) +errr fd_write(int fd, const char *buf, unsigned long n) { /* Verify the fd */ if (fd < 0) return ( -1); @@ -498,7 +615,7 @@ errr fd_write(int fd, cptr buf, huge n) #endif /* Write the final piece */ - if ((huge)write(fd, buf, n) != n) return (1); + if ((unsigned long)write(fd, buf, n) != n) return (1); /* Success */ return (0); @@ -567,20 +684,11 @@ errr fd_close(int fd) */ -/* -* Move the cursor -*/ -void move_cursor(int row, int col) -{ - Term_gotoxy(col, row); -} - - /* * Convert a decimal to a single digit octal number */ -static char octify(uint i) +static char octify(unsigned int i) { return (hexsym[i % 8]); } @@ -588,7 +696,7 @@ static char octify(uint i) /* * Convert a decimal to a single digit hex number */ -static char hexify(uint i) +static char hexify(unsigned int i) { return (hexsym[i % 16]); } @@ -615,25 +723,25 @@ static int dehex(char c) } -static void trigger_text_to_ascii(char **bufptr, cptr *strptr) +static void trigger_text_to_ascii(char **bufptr, const char **strptr) { char *s = *bufptr; - cptr str = *strptr; - bool_ mod_status[MAX_MACRO_MOD]; + const char *str = *strptr; + bool mod_status[MAX_MACRO_MOD]; int i, len = 0; int shiftstatus = 0; - cptr key_code; + const char *key_code; if (macro_template == NULL) return; for (i = 0; macro_modifier_chr[i]; i++) - mod_status[i] = FALSE; + mod_status[i] = false; str++; /* Examine modifier keys */ - while (1) + while (true) { for (i = 0; macro_modifier_chr[i]; i++) { @@ -643,7 +751,7 @@ static void trigger_text_to_ascii(char **bufptr, cptr *strptr) } if (!macro_modifier_chr[i]) break; str += len; - mod_status[i] = TRUE; + mod_status[i] = true; if ('S' == macro_modifier_chr[i]) shiftstatus = 1; } @@ -701,8 +809,7 @@ static void trigger_text_to_ascii(char **bufptr, cptr *strptr) *s++ = (char)13; *bufptr = s; - *strptr = str; /* where **strptr == ']' */ - return; + *strptr = str; } @@ -713,7 +820,7 @@ static void trigger_text_to_ascii(char **bufptr, cptr *strptr) * parsing "\xFF" into a (signed) char. Whoever thought of making * the "sign" of a "char" undefined is a complete moron. Oh well. */ -void text_to_ascii(char *buf, cptr str) +void text_to_ascii(char *buf, const char *str) { char *s = buf; @@ -838,16 +945,16 @@ void text_to_ascii(char *buf, cptr str) } -bool_ trigger_ascii_to_text(char **bufptr, cptr *strptr) +static bool trigger_ascii_to_text(char **bufptr, const char **strptr) { char *s = *bufptr; - cptr str = *strptr; + const char *str = *strptr; char key_code[100]; int i; - cptr tmp; + const char *tmp; if (macro_template == NULL) - return FALSE; + return false; *s++ = '\\'; *s++ = '['; @@ -874,11 +981,11 @@ bool_ trigger_ascii_to_text(char **bufptr, cptr *strptr) key_code[j] = '\0'; break; default: - if (ch != *str) return FALSE; + if (ch != *str) return false; str++; } } - if (*str++ != (char)13) return FALSE; + if (*str++ != (char)13) return false; for (i = 0; i < max_macrotrigger; i++) { @@ -887,7 +994,7 @@ bool_ trigger_ascii_to_text(char **bufptr, cptr *strptr) break; } if (i == max_macrotrigger) - return FALSE; + return false; tmp = macro_trigger_name[i]; while (*tmp) *s++ = *tmp++; @@ -896,14 +1003,14 @@ bool_ trigger_ascii_to_text(char **bufptr, cptr *strptr) *bufptr = s; *strptr = str; - return TRUE; + return true; } /* * Hack -- convert a string into a printable form */ -void ascii_to_text(char *buf, cptr str) +void ascii_to_text(char *buf, const char *str) { char *s = buf; @@ -1005,13 +1112,13 @@ void ascii_to_text(char *buf, cptr str) /* * Determine if any macros have ever started with a given character. */ -static bool_ macro__use[256]; +static bool macro__use[256]; /* * Find the macro (if any) which exactly matches the given pattern */ -sint macro_find_exact(cptr pat) +int macro_find_exact(const char *pat) { int i; @@ -1025,7 +1132,7 @@ sint macro_find_exact(cptr pat) for (i = 0; i < macro__num; ++i) { /* Skip macros which do not match the pattern */ - if (!streq(macro__pat[i], pat)) continue; + if (!equals(macro__pat[i], pat)) continue; /* Found one */ return (i); @@ -1039,7 +1146,7 @@ sint macro_find_exact(cptr pat) /* * Find the first macro (if any) which contains the given pattern */ -static sint macro_find_check(cptr pat) +static int macro_find_check(const char *pat) { int i; @@ -1053,7 +1160,7 @@ static sint macro_find_check(cptr pat) for (i = 0; i < macro__num; ++i) { /* Skip macros which do not contain the pattern */ - if (!prefix(macro__pat[i], pat)) continue; + if (!starts_with(macro__pat[i], pat)) continue; /* Found one */ return (i); @@ -1067,7 +1174,7 @@ static sint macro_find_check(cptr pat) /* * Find the first macro (if any) which contains the given pattern and more */ -static sint macro_find_maybe(cptr pat) +static int macro_find_maybe(const char *pat) { int i; @@ -1081,10 +1188,10 @@ static sint macro_find_maybe(cptr pat) for (i = 0; i < macro__num; ++i) { /* Skip macros which do not contain the pattern */ - if (!prefix(macro__pat[i], pat)) continue; + if (!starts_with(macro__pat[i], pat)) continue; /* Skip macros which exactly match the pattern XXX XXX */ - if (streq(macro__pat[i], pat)) continue; + if (equals(macro__pat[i], pat)) continue; /* Found one */ return (i); @@ -1098,7 +1205,7 @@ static sint macro_find_maybe(cptr pat) /* * Find the longest macro (if any) which starts with the given pattern */ -static sint macro_find_ready(cptr pat) +static int macro_find_ready(const char *pat) { int i, t, n = -1, s = -1; @@ -1112,7 +1219,7 @@ static sint macro_find_ready(cptr pat) for (i = 0; i < macro__num; ++i) { /* Skip macros which are not contained by the pattern */ - if (!prefix(pat, macro__pat[i])) continue; + if (!starts_with(pat, macro__pat[i])) continue; /* Obtain the length of this macro */ t = strlen(macro__pat[i]); @@ -1144,7 +1251,7 @@ static sint macro_find_ready(cptr pat) * with some kind of "powerful keymap" ability, but this might make it hard * to change the "roguelike" option from inside the game. XXX XXX XXX */ -errr macro_add(cptr pat, cptr act) +errr macro_add(const char *pat, const char *act) { int n; @@ -1177,7 +1284,7 @@ errr macro_add(cptr pat, cptr act) macro__act[n] = strdup(act); /* Efficiency */ - macro__use[(byte)(pat[0])] = TRUE; + macro__use[(byte)(pat[0])] = true; /* Success */ return (0); @@ -1188,7 +1295,7 @@ errr macro_add(cptr pat, cptr act) /* * Local "need flush" variable */ -static bool_ flush_later = FALSE; +static bool flush_later = false; /* @@ -1196,14 +1303,14 @@ static bool_ flush_later = FALSE; * * Do not match any macros until "ascii 30" is found. */ -static bool_ parse_macro = FALSE; +static bool parse_macro = false; /* * Local variable -- we are inside a "macro trigger" * * Strip all keypresses until a low ascii value is found. */ -static bool_ parse_under = FALSE; +static bool parse_under = false; /* @@ -1216,7 +1323,7 @@ static bool_ parse_under = FALSE; void flush() { /* Do it later */ - flush_later = TRUE; + flush_later = true; } @@ -1275,17 +1382,18 @@ static char inkey_aux() char ch; - cptr pat, act; + const char *pat; + const char *act; char buf[1024]; /* Wait for a keypress */ - (Term_inkey(&ch, TRUE, TRUE)); + Term_inkey(&ch, true, true); /* End "macro action" */ - if (ch == 30) parse_macro = FALSE; + if (ch == 30) parse_macro = false; /* Inside "macro action" */ if (ch == 30) return (ch); @@ -1310,7 +1418,7 @@ static char inkey_aux() /* Wait for a macro, or a timeout */ - while (TRUE) + while (true) { /* Check for pending macro */ k = macro_find_maybe(buf); @@ -1319,7 +1427,7 @@ static char inkey_aux() if (k < 0) break; /* Check for (and remove) a pending key */ - if (0 == Term_inkey(&ch, FALSE, TRUE)) + if (0 == Term_inkey(&ch, false, true)) { /* Append the key */ buf[p++] = ch; @@ -1358,7 +1466,7 @@ static char inkey_aux() } /* Wait for (and remove) a pending key */ - Term_inkey(&ch, TRUE, TRUE); + Term_inkey(&ch, true, true); /* Return the key */ return (ch); @@ -1380,7 +1488,7 @@ static char inkey_aux() /* Begin "macro action" */ - parse_macro = TRUE; + parse_macro = true; /* Push the "end of macro action" key */ if (Term_key_push(30)) return (0); @@ -1413,34 +1521,34 @@ static char inkey_aux() * trigger any macros, and cannot be bypassed by the Borg. It is used * in Angband to handle "keymaps". */ -static cptr inkey_next = NULL; +static const char *inkey_next = NULL; -bool_ inkey_flag = FALSE; +bool inkey_flag = false; /* * Get a keypress from the user. * * This function recognizes a few "global parameters". These are variables -* which, if set to TRUE before calling this function, will have an effect -* on this function, and which are always reset to FALSE by this function +* which, if set to true before calling this function, will have an effect +* on this function, and which are always reset to false by this function * before this function returns. Thus they function just like normal * parameters, except that most calls to this function can ignore them. * -* If "inkey_scan" is TRUE, then we will immediately return "zero" if no +* If "inkey_scan" is true, then we will immediately return "zero" if no * keypress is available, instead of waiting for a keypress. * -* If "inkey_base" is TRUE, then all macro processing will be bypassed. -* If "inkey_base" and "inkey_scan" are both TRUE, then this function will +* If "inkey_base" is true, then all macro processing will be bypassed. +* If "inkey_base" and "inkey_scan" are both true, then this function will * not return immediately, but will wait for a keypress for as long as the * normal macro matching code would, allowing the direct entry of macro * triggers. The "inkey_base" flag is extremely dangerous! * -* If "inkey_flag" is TRUE, then we will assume that we are waiting for a +* If "inkey_flag" is true, then we will assume that we are waiting for a * normal command, and we will only show the cursor if "hilite_player" is -* TRUE (or if the player is in a store), instead of always showing the +* true (or if the player is in a store), instead of always showing the * cursor. The various "main-xxx.c" files should avoid saving the game -* in response to a "menu item" request unless "inkey_flag" is TRUE, to +* in response to a "menu item" request unless "inkey_flag" is true, to * prevent savefile corruption. * * If we are waiting for a keypress, and no keypress is ready, then we will @@ -1472,30 +1580,20 @@ bool_ inkey_flag = FALSE; * * Hack -- Note the use of "inkey_next" to allow "keymaps" to be processed. */ -static char inkey_real(bool_ inkey_scan) +static char inkey_real(bool inkey_scan) { - int v; - - char kk; - - char ch = 0; - - bool_ done = FALSE; - - term *old = Term; - /* Hack -- Use the "inkey_next" pointer */ if (inkey_next && *inkey_next) { /* Get next character, and advance */ - ch = *inkey_next++; + char ch = *inkey_next++; /* Cancel the various "global parameters" */ - inkey_base = inkey_flag = inkey_scan = FALSE; + inkey_base = inkey_flag = inkey_scan = false; /* Accept result */ macro_recorder_add(ch); - return (ch); + return ch; } /* Forget pointer */ @@ -1503,166 +1601,158 @@ static char inkey_real(bool_ inkey_scan) /* Access cursor state */ - Term_get_cursor(&v); - - /* Show the cursor if waiting, except sometimes in "command" mode */ - if (!inkey_scan && (!inkey_flag || options->hilite_player || character_icky)) - { - /* Show the cursor */ - Term_set_cursor(1); - } - - - /* Hack -- Activate main screen */ - Term_activate(angband_term[0]); + char ch = '\0'; + Term_with_saved_cursor_visbility([&ch, &inkey_scan]() { - - /* Get a key */ - while (!ch) - { - /* Hack -- Handle "inkey_scan" */ - if (!inkey_base && inkey_scan && - (0 != Term_inkey(&kk, FALSE, FALSE))) - { - break; - } - - - /* Hack -- Flush output once when no key ready */ - if (!done && (0 != Term_inkey(&kk, FALSE, FALSE))) + /* Show the cursor if waiting, except sometimes in "command" mode */ + if (!inkey_scan && (!inkey_flag || options->hilite_player || character_icky)) { - /* Hack -- activate proper term */ - Term_activate(old); - - /* Flush output */ - Term_fresh(); - - /* Hack -- activate main screen */ - Term_activate(angband_term[0]); - - /* Only once */ - done = TRUE; + Term_show_cursor(); } - - /* Hack -- Handle "inkey_base" */ - if (inkey_base) - { - int w = 0; - - /* Wait forever */ - if (!inkey_scan) + /* Hack -- Activate main screen */ + auto old = Term; + Term_with_active(angband_term[0], [&ch, &old, &inkey_scan]() { + /* Have with flushed the output? */ + bool flushed = false; + /* Get a key */ + while (!ch) { - /* Wait for (and remove) a pending key */ - if (0 == Term_inkey(&ch, TRUE, TRUE)) - { - /* Done */ - break; - } + char kk; - /* Oops */ - break; - } - - /* Wait */ - while (TRUE) - { - /* Check for (and remove) a pending key */ - if (0 == Term_inkey(&ch, FALSE, TRUE)) + /* Hack -- Handle "inkey_scan" */ + if (!inkey_base && inkey_scan && + (0 != Term_inkey(&kk, false, false))) { - /* Done */ break; } - /* No key ready */ - else - { - /* Increase "wait" */ - w += 10; - /* Excessive delay */ - if (w >= 100) break; + /* Hack -- Flush output once when no key ready */ + if (!flushed && (0 != Term_inkey(&kk, false, false))) + { + /* Hack -- activate proper term */ + Term_with_active(old, []() { + Term_fresh(); + }); - /* Delay */ - sleep_for(milliseconds(w)); + /* Only once */ + flushed = true; } - } - /* Done */ - break; - } + /* Hack -- Handle "inkey_base" */ + if (inkey_base) + { + int w = 0; - /* Get a key (see above) */ - ch = inkey_aux(); + /* Wait forever */ + if (!inkey_scan) + { + /* Wait for (and remove) a pending key */ + if (0 == Term_inkey(&ch, true, true)) + { + /* Done */ + break; + } + + /* Oops */ + break; + } + /* Wait */ + while (true) + { + /* Check for (and remove) a pending key */ + if (0 == Term_inkey(&ch, false, true)) + { + /* Done */ + break; + } + + /* No key ready */ + else + { + /* Increase "wait" */ + w += 10; + + /* Excessive delay */ + if (w >= 100) break; + + /* Delay */ + sleep_for(milliseconds(w)); + } + } - /* Handle "control-right-bracket" */ - if ((ch == 29) || ((!options->rogue_like_commands) && (ch == KTRL('D')))) - { - /* Strip this key */ - ch = 0; + /* Done */ + break; + } - /* Do an html dump */ - do_cmd_html_dump(); - /* Continue */ - continue; - } + /* Get a key (see above) */ + ch = inkey_aux(); - /* Treat back-quote as escape */ - if (ch == '`') ch = ESCAPE; + /* Handle "control-right-bracket" */ + if ((ch == 29) || ((!options->rogue_like_commands) && (ch == KTRL('D')))) + { + /* Strip this key */ + ch = 0; + /* Do an html dump */ + do_cmd_html_dump(); - /* End "macro trigger" */ - if (parse_under && (ch <= 32)) - { - /* Strip this key */ - ch = 0; + /* Continue */ + continue; + } - /* End "macro trigger" */ - parse_under = FALSE; - } + /* Treat back-quote as escape */ + if (ch == '`') ch = ESCAPE; - /* Handle "control-caret" */ - if (ch == 30) - { - /* Strip this key */ - ch = 0; - } - /* Handle "control-underscore" */ - else if (ch == 31) - { - /* Strip this key */ - ch = 0; + /* End "macro trigger" */ + if (parse_under && (ch <= 32)) + { + /* Strip this key */ + ch = 0; - /* Begin "macro trigger" */ - parse_under = TRUE; - } + /* End "macro trigger" */ + parse_under = false; + } - /* Inside "macro trigger" */ - else if (parse_under) - { - /* Strip this key */ - ch = 0; - } - } + /* Handle "control-caret" */ + if (ch == 30) + { + /* Strip this key */ + ch = 0; + } - /* Hack -- restore the term */ - Term_activate(old); + /* Handle "control-underscore" */ + else if (ch == 31) + { + /* Strip this key */ + ch = 0; + /* Begin "macro trigger" */ + parse_under = true; + } - /* Restore the cursor */ - Term_set_cursor(v); + /* Inside "macro trigger" */ + else if (parse_under) + { + /* Strip this key */ + ch = 0; + } + } + }); - /* Cancel the various "global parameters" */ - inkey_base = inkey_flag = FALSE; + }); + /* Cancel the various "global parameters" */ + inkey_base = inkey_flag = false; /* Return the keypress */ macro_recorder_add(ch); @@ -1670,11 +1760,11 @@ static char inkey_real(bool_ inkey_scan) } char inkey() { - return inkey_real(FALSE); + return inkey_real(false); } char inkey_scan() { - return inkey_real(TRUE); + return inkey_real(true); } /* @@ -1688,7 +1778,7 @@ static void msg_flush(int x) Term_putstr(x, 0, -1, a, "-more-"); /* Get an acceptable keypress */ - while (1) + while (true) { int cmd = inkey(); if (options->quick_messages) break; @@ -1702,7 +1792,7 @@ static void msg_flush(int x) } /* Display a message */ -void display_message(int x, int y, int split, byte color, cptr t) +void display_message(int x, int y, int split, byte color, const char *t) { int i = 0, j = 0; @@ -1756,7 +1846,7 @@ void display_message(int x, int y, int split, byte color, cptr t) * XXX XXX XXX Note that "msg_print(NULL)" will clear the top line * even if no messages are pending. This is probably a hack. */ -void cmsg_print(byte color, cptr msg) +void cmsg_print(byte color, const char *msg) { auto &messages = game->messages; @@ -1783,7 +1873,7 @@ void cmsg_print(byte color, cptr msg) msg_flush(p); /* Forget it */ - msg_flag = FALSE; + msg_flag = false; /* Reset */ p = 0; @@ -1877,7 +1967,7 @@ void cmsg_print(byte color, cptr msg) } /* Remember the message */ - msg_flag = TRUE; + msg_flag = true; /* Remember the position */ p += n + 1; @@ -1892,11 +1982,16 @@ void cmsg_print(byte color, std::string const &msg) } /* Hack -- for compatibility and easy sake */ -void msg_print(cptr msg) +void msg_print(const char *msg) { cmsg_print(TERM_WHITE, msg); } +void msg_print(std::string const &msg) +{ + cmsg_print(TERM_WHITE, msg.c_str()); +} + /* * Hack -- prevent "accidents" in "screen_save()" or "screen_load()" @@ -1917,10 +2012,18 @@ void screen_save() /* Save the screen (if legal) */ if (screen_depth++ == 0) Term_save(); - /* Increase "icky" depth */ - character_icky++; + /* Enter "icky" mode */ + character_icky = true; } +void screen_save_no_flush() +{ + /* Enter "icky" mode */ + character_icky = true; + + /* Save the screen */ + Term_save(); +} /* * Load the screen, and decrease the "icky" depth. @@ -1935,15 +2038,24 @@ void screen_load() /* Load the screen (if legal) */ if (--screen_depth == 0) Term_load(); - /* Decrease "icky" depth */ - character_icky--; + /* Leave "icky" mode */ + character_icky = false; +} + +void screen_load_no_flush() +{ + /* Restore the screen */ + Term_load(); + + /* Leave "icky" mode */ + character_icky = false; } /* * Display a formatted message, using "vstrnfmt()" and "msg_print()". */ -void msg_format(cptr fmt, ...) +void msg_format(const char *fmt, ...) { va_list vp; @@ -1962,7 +2074,7 @@ void msg_format(cptr fmt, ...) cmsg_print(TERM_WHITE, buf); } -void cmsg_format(byte color, cptr fmt, ...) +void cmsg_format(byte color, const char *fmt, ...) { va_list vp; @@ -1981,7 +2093,7 @@ void cmsg_format(byte color, cptr fmt, ...) cmsg_print(color, buf); } -void c_put_str(byte attr, cptr str, int row, int col) +void c_put_str(byte attr, const char *str, int row, int col) { Term_putstr(col, row, -1, attr, str); } @@ -1991,7 +2103,7 @@ void c_put_str(byte attr, std::string const &str, int row, int col) Term_putstr(col, row, -1, attr, str.c_str()); } -void put_str(cptr str, int row, int col) +void put_str(const char *str, int row, int col) { Term_putstr(col, row, -1, TERM_WHITE, str); } @@ -2006,7 +2118,7 @@ void put_str(std::string const &str, int row, int col) * Display a string on the screen using an attribute, and clear * to the end of the line. */ -void c_prt(byte attr, cptr str, int row, int col) +void c_prt(byte attr, const char *str, int row, int col) { /* Clear line, position cursor */ Term_erase(col, row, 255); @@ -2020,7 +2132,7 @@ void c_prt(byte attr, std::string const &s, int row, int col) c_prt(attr, s.c_str(), row, col); } -void prt(cptr str, int row, int col) +void prt(const char *str, int row, int col) { c_prt(TERM_WHITE, str, row, col); } @@ -2044,7 +2156,7 @@ void prt(std::string const &s, int row, int col) * This function will correctly handle any width up to the maximum legal * value of 256, though it works best for a standard 80 character width. */ -void text_out_to_screen(byte a, cptr str) +void text_out_to_screen(byte a, const char *str) { int x, y; @@ -2052,7 +2164,7 @@ void text_out_to_screen(byte a, cptr str) int wrap; - cptr s; + const char *s; /* Obtain the size */ @@ -2154,7 +2266,7 @@ void text_out_to_screen(byte a, cptr str) * You must be careful to end all file output with a newline character * to "flush" the stored line position. */ -void text_out_to_file(byte a, cptr str) +void text_out_to_file(byte a, const char *str) { /* Current position on the line */ static int pos = 0; @@ -2163,7 +2275,7 @@ void text_out_to_file(byte a, cptr str) int wrap = 75; /* Current location within "str" */ - cptr s = str; + const char *s = str; /* Unused parameter */ a; @@ -2258,9 +2370,6 @@ void text_out_to_file(byte a, cptr str) /* Skip whitespace */ while (*s == ' ') s++; } - - /* We are done */ - return; } @@ -2268,7 +2377,12 @@ void text_out_to_file(byte a, cptr str) * Output text to the screen or to a file depending on the selected * text_out hook. */ -void text_out(cptr str) +void text_out(const char *str) +{ + text_out_c(TERM_WHITE, str); +} + +void text_out(std::string const &str) { text_out_c(TERM_WHITE, str); } @@ -2278,12 +2392,15 @@ void text_out(cptr str) * Output text to the screen (in color) or to a file depending on the * selected hook. */ -void text_out_c(byte a, cptr str) +void text_out_c(byte a, const char *str) { text_out_hook(a, str); } - +void text_out_c(byte a, std::string const &str) +{ + text_out_c(a, str.c_str()); +} /* @@ -2316,7 +2433,7 @@ static char complete_buf[100]; static int complete_command(char *buf, int clen, int mlen) { int i, j = 1, max = clen; - bool_ gotone = FALSE; + bool gotone = false; /* Forget the characters after the end of the string. */ complete_buf[clen] = '\0'; @@ -2334,7 +2451,7 @@ static int complete_command(char *buf, int clen, int mlen) if (!gotone) { sprintf(buf, "%.*s", mlen, cli_ptr->comm); - gotone = TRUE; + gotone = true; } /* For later matches, simply notice how much of buf it * matches. */ @@ -2379,12 +2496,12 @@ bool askfor_aux(std::string *buf, std::size_t max_len) * Pressing RETURN right away accepts the default entry. * Normal chars clear the default and append the char. * Backspace clears the default or deletes the final char. -* ESCAPE clears the buffer and the window and returns FALSE. -* RETURN accepts the current buffer contents and returns TRUE. +* ESCAPE clears the buffer and the window and returns false. +* RETURN accepts the current buffer contents and returns true. */ -static bool_ askfor_aux_complete = FALSE; +static bool askfor_aux_complete = false; -bool_ askfor_aux(char *buf, int len) +bool askfor_aux(char *buf, int len) { int y, x; @@ -2394,7 +2511,7 @@ bool_ askfor_aux(char *buf, int len) int wid, hgt; - bool_ done = FALSE; + bool done = false; /* Locate the cursor */ @@ -2439,13 +2556,13 @@ bool_ askfor_aux(char *buf, int len) { case ESCAPE: k = 0; - done = TRUE; + done = true; break; case '\n': case '\r': k = strlen(buf); - done = TRUE; + done = true; break; case '\t': @@ -2493,17 +2610,17 @@ bool_ askfor_aux(char *buf, int len) } /* Aborted */ - if (i == ESCAPE) return (FALSE); + if (i == ESCAPE) return false; /* Success */ - return (TRUE); + return true; } -bool_ askfor_aux_with_completion(char *buf, int len) +bool askfor_aux_with_completion(char *buf, int len) { - askfor_aux_complete = TRUE; - bool_ res = askfor_aux(buf, len); - askfor_aux_complete = FALSE; + askfor_aux_complete = true; + bool res = askfor_aux(buf, len); + askfor_aux_complete = false; return res; } @@ -2515,11 +2632,11 @@ bool_ askfor_aux_with_completion(char *buf, int len) * Note that the initial contents of the string is used as * the default response, so be sure to "clear" it if needed. * -* We clear the input, and return FALSE, on "ESCAPE". +* We clear the input, and return false, on "ESCAPE". */ -bool_ get_string(cptr prompt, char *buf, int len) +bool get_string(const char *prompt, char *buf, int len) { - bool_ res; + bool res; /* Paranoia XXX XXX XXX */ msg_print(NULL); @@ -2545,7 +2662,7 @@ bool_ get_string(cptr prompt, char *buf, int len) * * Note that "[y/n]" is appended to the prompt. */ -bool_ get_check(cptr prompt) +bool get_check(const char *prompt) { int i; @@ -2561,7 +2678,7 @@ bool_ get_check(cptr prompt) prt(buf, 0, 0); /* Get an acceptable answer */ - while (TRUE) + while (true) { i = inkey(); if (options->quick_messages) break; @@ -2574,10 +2691,16 @@ bool_ get_check(cptr prompt) prt("", 0, 0); /* Normal negation */ - if ((i != 'Y') && (i != 'y')) return (FALSE); + if ((i != 'Y') && (i != 'y')) return false; /* Success */ - return (TRUE); + return true; +} + + +bool get_check(std::string const &prompt) +{ + return get_check(prompt.c_str()); } @@ -2586,9 +2709,9 @@ bool_ get_check(cptr prompt) * * The "prompt" should take the form "Command: " * -* Returns TRUE unless the character is "Escape" +* Returns true unless the character is "Escape" */ -bool_ get_com(cptr prompt, char *command) +bool get_com(const char *prompt, char *command) { /* Paranoia XXX XXX XXX */ msg_print(NULL); @@ -2603,10 +2726,10 @@ bool_ get_com(cptr prompt, char *command) prt("", 0, 0); /* Handle "cancel" */ - if (*command == ESCAPE) return (FALSE); + if (*command == ESCAPE) return false; /* Success */ - return (TRUE); + return true; } @@ -2615,7 +2738,7 @@ bool_ get_com(cptr prompt, char *command) * * Hack -- allow "command_arg" to specify a quantity */ -s32b get_quantity(cptr prompt, s32b max) +s32b get_quantity(const char *prompt, s32b max) { s32b amt; int aamt; @@ -2724,7 +2847,7 @@ char request_command_ignore_keymaps[MAX_IGNORE_KEYMAPS]; * Mega-Hack -- flag set by do_cmd_{inven,equip}() to allow keymaps in * auto-command mode. */ -bool_ request_command_inven_mode = FALSE; +bool request_command_inven_mode = false; /* @@ -2755,7 +2878,7 @@ void request_command(int shopping) int mode; - cptr act; + const char *act; /* Keymap mode */ @@ -2772,7 +2895,7 @@ void request_command(int shopping) /* Get command */ - while (1) + while (true) { /* Hack -- auto-commands */ if (command_new) @@ -2793,17 +2916,17 @@ void request_command(int shopping) } /* Mega-Hack -- turn off this flag immediately */ - request_command_inven_mode = FALSE; + request_command_inven_mode = false; } /* Get a keypress in "command" mode */ else { /* Hack -- no flush needed */ - msg_flag = FALSE; + msg_flag = false; /* Activate "command mode" */ - inkey_flag = TRUE; + inkey_flag = true; /* Get a command */ cmd = inkey(); @@ -2818,58 +2941,9 @@ void request_command(int shopping) { int old_arg = command_arg; - /* Reset */ - command_arg = 0; - - /* Begin the input */ prt("Count: ", 0, 0); - - /* Get a command count */ - while (1) - { - /* Get a new keypress */ - cmd = inkey(); - - /* Simple editing (delete or backspace) */ - if ((cmd == 0x7F) || (cmd == KTRL('H'))) - { - /* Delete a digit */ - command_arg = command_arg / 10; - - /* Show current count */ - prt(format("Count: %d", command_arg), 0, 0); - } - - /* Actual numeric data */ - else if (cmd >= '0' && cmd <= '9') - { - /* Stop count at 9999 */ - if (command_arg >= 1000) - { - /* Warn */ - bell(); - - /* Limit */ - command_arg = 9999; - } - - /* Increase count */ - else - { - /* Incorporate that digit */ - command_arg = command_arg * 10 + D2I(cmd); - } - - /* Show current count */ - prt(format("Count: %d", command_arg), 0, 0); - } - - /* Exit on "unusable" input */ - else - { - break; - } - } + std::tie(command_arg, cmd) = + get_number(0, 9999, 0, 7, display_option_t::DELAY); /* Hack -- Handle "zero" */ if (command_arg == 0) @@ -2878,7 +2952,7 @@ void request_command(int shopping) command_arg = 99; /* Show current count */ - prt(format("Count: %d", command_arg), 0, 0); + prt(fmt::format("Count: {}", command_arg), 0, 0); } /* Hack -- Handle "old_arg" */ @@ -2888,14 +2962,14 @@ void request_command(int shopping) command_arg = old_arg; /* Show current count */ - prt(format("Count: %d", command_arg), 0, 0); + prt(fmt::format("Count: {}", command_arg), 0, 0); } /* Hack -- white-space means "enter command now" */ if ((cmd == ' ') || (cmd == '\n') || (cmd == '\r')) { /* Get a real command */ - bool_ temp = get_com("Command: ", &cmd_char); + bool temp = get_com("Command: ", &cmd_char); cmd = cmd_char; if (!temp) @@ -2988,7 +3062,10 @@ void request_command(int shopping) object_type *o_ptr = &p_ptr->inventory[i]; /* Skip non-objects */ - if (!o_ptr->k_idx) continue; + if (!o_ptr->k_ptr) + { + continue; + } /* No inscription */ if (o_ptr->inscription.empty()) @@ -3032,7 +3109,7 @@ void request_command(int shopping) /* * Check a char for "vowel-hood" */ -bool_ is_a_vowel(int ch) +bool is_a_vowel(int ch) { switch (ch) { @@ -3046,10 +3123,10 @@ bool_ is_a_vowel(int ch) case 'I': case 'O': case 'U': - return (TRUE); + return true; } - return (FALSE); + return false; } @@ -3067,9 +3144,9 @@ int get_keymap_dir(char ch) int mode; - cptr act; + const char *act; - cptr s; + const char *s; /* Already a direction? */ @@ -3130,21 +3207,22 @@ void repeat_push(int what) } -bool_ repeat_pull(int *what) +bool repeat_pull(int *what) { /* All out of keys */ - if (repeat__idx == repeat__cnt) return (FALSE); + if (repeat__idx == repeat__cnt) return false; /* Grab the next key, advance */ *what = repeat__key[repeat__idx++]; /* Success */ - return (TRUE); + return true; } -void repeat_check() +void repeat_check(s16b *command_ptr) { - int what; + assert(command_ptr); + auto &command_cmd = *command_ptr; /* Ignore some commands */ if (command_cmd == ESCAPE) return; @@ -3159,6 +3237,7 @@ void repeat_check() repeat__idx = 0; /* Get the command */ + int what; if (repeat_pull(&what)) { /* Save the command */ @@ -3173,115 +3252,16 @@ void repeat_check() repeat__cnt = 0; repeat__idx = 0; - what = command_cmd; - /* Save this command */ - repeat_push(what); - } -} - - -/* - * Read a number at a specific location on the screen - * - * Allow numbers of any size and save the last keypress. - */ -static u32b get_number(u32b def, u32b max, int y, int x, char *cmd) -{ - u32b res = def; - - /* Player has not typed anything yet */ - bool_ no_keys = TRUE; - - /* Begin the input with default */ - prt(format("%lu", def), y, x); - - /* Get a command count */ - while (1) - { - /* Get a new keypress */ - *cmd = inkey(); - - /* Simple editing (delete or backspace) */ - if ((*cmd == 0x7F) || (*cmd == KTRL('H'))) - { - /* Override the default */ - no_keys = FALSE; - - /* Delete a digit */ - res = res / 10; - - prt(format("%lu", res), y, x); - } - - /* Actual numeric data */ - else if (*cmd >= '0' && *cmd <= '9') - { - /* Override the default */ - if (no_keys) - { - no_keys = FALSE; - res = 0; - } - - /* Don't overflow */ - if (((u32b)(0 - 1) - D2I(*cmd)) / 10 < res) - { - /* Warn */ - bell(); - - /* Limit */ - res = (max + 1 == 0) ? (u32b)(0 - 1) : max; - } - - /* Stop count at maximum */ - else if (res * 10 + D2I(*cmd) > max) - { - /* Warn */ - bell(); - - /* Limit */ - res = max; - } - - /* Increase count */ - else - { - /* Incorporate that digit */ - res = res * 10 + D2I(*cmd); - } - - /* Show current count */ - prt(format("%lu", res), y, x); - } - - /* Escape cancels */ - else if (*cmd == ESCAPE) - { - res = 0; - break; - } - - /* Exit on "unusable" input */ - else - { - break; - } + repeat_push(command_cmd); } - - return res; } /* * Allow the user to select multiple items without pressing '0' */ -void get_count(int number, int max) +s16b get_count(int number, int max) { - char cmd; - - /* Use the default */ - command_arg = number; - /* Hack -- Optional flush */ if (options->flush_command) { @@ -3295,9 +3275,11 @@ void get_count(int number, int max) prt("How many?", 0, 0); /* Actually get a number */ - command_arg = get_number(command_arg, max, 0, 10, &cmd); + auto [res, cmd] = get_number(number, max, 0, 10, display_option_t::IMMEDIATE); prt("", 0, 0); + + return res; } byte count_bits(u32b array) @@ -3327,7 +3309,7 @@ void strlower(char *buf) * must exactly match (look out for commas and the like!), or else 0 is * returned. Case doesn't matter. -GSN- */ -int test_monster_name(cptr name) +int test_monster_name(const char *name) { auto const &r_info = game->edit_data.r_info; @@ -3342,7 +3324,7 @@ int test_monster_name(cptr name) return (0); } -int test_mego_name(cptr needle) +int test_mego_name(const char *needle) { const auto &re_info = game->edit_data.re_info; @@ -3360,24 +3342,22 @@ int test_mego_name(cptr needle) /* * Given item name as string, return the index in k_info array. Name - * must exactly match (look out for commas and the like!), or else 0 is + * must exactly match (look out for commas and the like!), or else -1 is * returned. Case doesn't matter. -DG- */ - -int test_item_name(cptr needle) +int test_item_name(const char *needle) { auto const &k_info = game->edit_data.k_info; - for (std::size_t i = 0; i < k_info.size(); i++) + for (auto const &k_entry: k_info) { - auto const &name = k_info[i].name; - if (name && iequals(needle, name)) + if (iequals(needle, k_entry.second->name)) { - return i; + return k_entry.first; } } - return 0; + return -1; } /* @@ -3454,23 +3434,21 @@ std::string get_player_race_name(int pr, int ps) /* * Ask to select an item in a list */ -int ask_menu(cptr ask, const std::vector<std::string> &items) +int ask_menu(const char *ask, const std::vector<std::string> &items) { int ret = -1, i, start = 0; char c; int size = static_cast<int>(items.size()); // Convert to int to avoid warnings - /* Enter "icky" mode */ - character_icky = TRUE; - /* Save the screen */ - Term_save(); + screen_save_no_flush(); - while (TRUE) + while (true) { /* Display list */ - Term_load(); - Term_save(); + screen_load_no_flush(); + screen_save_no_flush(); + prt(ask, 0, 0); for (i = start; (i < size) && (i < start + 20); i++) { @@ -3519,38 +3497,12 @@ int ask_menu(cptr ask, const std::vector<std::string> &items) } } - /* Load the screen */ - Term_load(); - - /* Leave "icky" mode */ - character_icky = FALSE; + screen_load_no_flush(); return ret; } /* - * Determine if string "t" is a prefix of string "s" - */ -bool_ prefix(cptr s, cptr t) -{ - /* Paranoia */ - if (!s || !t) - { - return FALSE; - } - - /* Scan "t" */ - while (*t) - { - /* Compare content and length */ - if (*t++ != *s++) return (FALSE); - } - - /* Matched, we have a prefix */ - return (TRUE); -} - -/* * Displays a box */ void draw_box(int y, int x, int h, int w) @@ -3581,7 +3533,7 @@ void draw_box(int y, int x, int h, int w) /* * Displays a scrollable boxed list with a selected item */ -void display_list(int y, int x, int h, int w, cptr title, std::vector<std::string> const &list, std::size_t begin, std::size_t sel, byte sel_color) +void display_list(int y, int x, int h, int w, const char *title, std::vector<std::string> const &list, std::size_t begin, std::size_t sel, byte sel_color) { draw_box(y, x, h, w); c_put_str(TERM_L_BLUE, title, y, x + ((w - strlen(title)) / 2)); |