From 0a7108679755bb696c18582c3d8c84a7a4db0324 Mon Sep 17 00:00:00 2001 From: Tangles Date: Sun, 23 Apr 2017 00:20:34 +1000 Subject: [PATCH 01/69] fix extcmd entry in curses interface. --- win/curses/cursdial.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/win/curses/cursdial.c b/win/curses/cursdial.c index d155dd3b..e4786a45 100644 --- a/win/curses/cursdial.c +++ b/win/curses/cursdial.c @@ -393,7 +393,7 @@ int curses_ext_cmd() } winy += messageh - 1; - extwin = newwin(1, 25, winy, winx); + extwin = newwin(1, messagew-2, winy, winx); startx = 0; starty = 0; pline("#"); @@ -406,17 +406,20 @@ int curses_ext_cmd() wmove(extwin, starty, startx); waddstr(extwin, "# "); wmove(extwin, starty, startx + 2); - curses_toggle_color_attr(extwin, NONE, A_UNDERLINE, ON); waddstr(extwin, cur_choice); - curses_toggle_color_attr(extwin, NONE, A_UNDERLINE, OFF); wmove(extwin, starty, strlen(cur_choice) + startx + 2); wprintw(extwin, " ", cur_choice); + /* if we have an autocomplete command, AND it matches uniquely */ if (matches == 1) { + curses_toggle_color_attr(extwin, NONE, A_UNDERLINE, ON); wmove(extwin, starty, strlen(cur_choice) + startx + 2); - wprintw(extwin, "%s ", extcmdlist[ret].ef_txt + wprintw(extwin, "%s", extcmdlist[ret].ef_txt + strlen(cur_choice)); + curses_toggle_color_attr(extwin, NONE, A_UNDERLINE, OFF); + mvwprintw(extwin, starty, + strlen(extcmdlist[ret].ef_txt) + 2, " "); } wrefresh(extwin); @@ -432,6 +435,14 @@ int curses_ext_cmd() if ((letter == '\r') || (letter == '\n')) { + if (ret == -1) { + for (count = 0; extcmdlist[count].ef_txt; count++) { + if (!strcasecmp(cur_choice, extcmdlist[count].ef_txt)) { + ret = count; + break; + } + } + } break; } @@ -450,9 +461,14 @@ int curses_ext_cmd() } } + if (letter != '*' && prompt_width < BUFSZ -1) { + cur_choice[prompt_width] = letter; + cur_choice[prompt_width + 1] = '\0'; + ret = -1; + } for (count = 0; extcmdlist[count].ef_txt; count++) { - if (!extcmdlist[count].autocomplete) continue; + if (!extcmdlist[count].autocomplete) continue; if (strlen(extcmdlist[count].ef_txt) > prompt_width) { if (strncasecmp(cur_choice, extcmdlist[count].ef_txt, @@ -461,20 +477,18 @@ int curses_ext_cmd() if ((extcmdlist[count].ef_txt[prompt_width] == lowc(letter)) || letter == '*') { - if ((matches == 0) && (letter != '*')) + if (matches == 0) { ret = count; - cur_choice[prompt_width] = letter; - cur_choice[prompt_width + 1] = '\0'; } matches++; } } } - } - } - + } + } + curses_destroy_win(extwin); return ret; } From 14f89bef8eff84a9c13197a498f46d098a3d7e52 Mon Sep 17 00:00:00 2001 From: Tangles Date: Sun, 23 Apr 2017 00:24:05 +1000 Subject: [PATCH 02/69] Add #ifndef on VAR_PLAYGROUND so it can be defined in makefile. --- include/unixconf.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/unixconf.h b/include/unixconf.h index f7cdcf77..905d7bb8 100644 --- a/include/unixconf.h +++ b/include/unixconf.h @@ -102,8 +102,9 @@ * If you want the static parts of your playground on a read-only file * system, define VAR_PLAYGROUND to be where the variable parts are kept. */ +#ifndef VAR_PLAYGROUND #define VAR_PLAYGROUND "/nh343/var" - +#endif /* * Define DEF_PAGER as your default pager, e.g. "/bin/cat" or "/usr/ucb/more" From 9ce64c10c7f43b1244bed219cb50c6cfde33a785 Mon Sep 17 00:00:00 2001 From: Tangles Date: Sun, 23 Apr 2017 15:30:24 +1000 Subject: [PATCH 03/69] Curses - fix MSGTYPE=STOP Requires player to press TAB, similar to NH4 interface. Changes window borders red to grab attention of even the sleepiest players. --- include/wincurs.h | 7 +++++++ win/curses/cursmain.c | 10 ++++++++-- win/curses/cursmesg.c | 23 +++++++++++++++++------ win/curses/cursmesg.h | 2 ++ win/curses/curswins.c | 18 ++++++++++++++++++ win/curses/curswins.h | 4 ++++ 6 files changed, 56 insertions(+), 8 deletions(-) diff --git a/include/wincurs.h b/include/wincurs.h index 3db6c5a2..f631517d 100644 --- a/include/wincurs.h +++ b/include/wincurs.h @@ -21,6 +21,7 @@ boolean counting; /* Count window is active */ #define NONE -1 #define KEY_ESC 0x1b #define DIALOG_BORDER_COLOR CLR_MAGENTA +#define ALERT_BORDER_COLOR CLR_RED #define SCROLLBAR_COLOR CLR_MAGENTA #define SCROLLBAR_BACK_COLOR CLR_BLACK #define HIGHLIGHT_COLOR CLR_WHITE @@ -178,6 +179,10 @@ extern void curses_puts(winid wid, int attr, const char *text); extern void curses_clear_nhwin(winid wid); +extern void curses_alert_win_border(winid wid, boolean onoff); + +extern void curses_alert_main_borders(boolean onoff); + extern void curses_draw_map(int sx, int sy, int ex, int ey); extern boolean curses_map_borders(int *sx, int *sy, int *ex, int *ey, @@ -279,6 +284,8 @@ extern void curses_cleanup(void); extern void curses_message_win_puts(const char *message, boolean recursed); +extern int curses_block(boolean require_tab); /* for MSGTYPE=STOP */ + extern int curses_more(void); extern void curses_clear_unhighlight_message_window(void); diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index ff2a47c9..c97e28da 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -277,14 +277,20 @@ void curses_display_nhwindow(winid wid, BOOLEAN_P block) { (void) curses_more(); } - + + if ((wid == MESSAGE_WIN) && block) + { + if (u.uhp != -1) (void) curses_block(TRUE); + /* don't bug player with TAB prompt on "Saving..." */ + else (void) curses_more(); + } + if (curses_is_menu(wid) || curses_is_text(wid)) { curses_end_menu(wid, ""); curses_select_menu(wid, PICK_NONE, &selected); return; } - } diff --git a/win/curses/cursmesg.c b/win/curses/cursmesg.c index b64c568d..8446ec02 100644 --- a/win/curses/cursmesg.c +++ b/win/curses/cursmesg.c @@ -153,31 +153,42 @@ void curses_message_win_puts(const char *message, boolean recursed) } -int curses_more() +int curses_block(boolean require_tab) { int height, width, ret; WINDOW *win = curses_get_nhwin(MESSAGE_WIN); curses_get_window_size(MESSAGE_WIN, &height, &width); curses_toggle_color_attr(win, MORECOLOR, NONE, ON); - mvwprintw(win, my, mx, ">>"); + mvwprintw(win, my, mx, require_tab ? "" : ">>"); curses_toggle_color_attr(win, MORECOLOR, NONE, OFF); + if (require_tab) curses_alert_main_borders(TRUE); wrefresh(win); - ret = wgetch(win); + while ((ret = wgetch(win) != '\t') && require_tab); + if (require_tab) curses_alert_main_borders(FALSE); if (height == 1) { curses_clear_unhighlight_message_window(); } else { - mvwprintw(win, my, mx, " "); - scroll_window(MESSAGE_WIN); - turn_lines = 1; + mvwprintw(win, my, mx, " "); + wrefresh(win); + if (!require_tab) + { + scroll_window(MESSAGE_WIN); + turn_lines = 1; + } } return ret; } +int curses_more() +{ + return curses_block(FALSE); +} + /* Clear the message window if one line; otherwise unhighlight old messages */ diff --git a/win/curses/cursmesg.h b/win/curses/cursmesg.h index 344736cd..c1c173af 100644 --- a/win/curses/cursmesg.h +++ b/win/curses/cursmesg.h @@ -6,6 +6,8 @@ void curses_message_win_puts(const char *message, boolean recursed); +int curses_block(boolean require_tab); + int curses_more(void); void curses_clear_unhighlight_message_window(void); diff --git a/win/curses/curswins.c b/win/curses/curswins.c index a4029dc8..25109a4c 100644 --- a/win/curses/curswins.c +++ b/win/curses/curswins.c @@ -561,6 +561,24 @@ void curses_clear_nhwin(winid wid) } } +/* Change colour of window border to alert player to something */ +void curses_alert_win_border(winid wid, boolean onoff) +{ + WINDOW *win = curses_get_nhwin(wid); + if (!curses_window_has_border(wid)) return; + if (onoff) curses_toggle_color_attr(win, ALERT_BORDER_COLOR, NONE, ON); + box(win, 0, 0); + if (onoff) curses_toggle_color_attr(win, ALERT_BORDER_COLOR, NONE, OFF); + wrefresh(win); +} + + +void curses_alert_main_borders(boolean onoff) +{ + curses_alert_win_border(MAP_WIN, onoff); + curses_alert_win_border(MESSAGE_WIN, onoff); + curses_alert_win_border(STATUS_WIN, onoff); +} /* Return true if given wid is a main NetHack window */ diff --git a/win/curses/curswins.h b/win/curses/curswins.h index c41d4983..9a8f2e63 100644 --- a/win/curses/curswins.h +++ b/win/curses/curswins.h @@ -37,6 +37,10 @@ void curses_puts(winid wid, int attr, const char *text); void curses_clear_nhwin(winid wid); +void curses_alert_win_border(winid wid, boolean onoff); + +void curses_alert_main_borders(boolean onoff); + void curses_draw_map(int sx, int sy, int ex, int ey); boolean curses_map_borders(int *sx, int *sy, int *ex, int *ey, int ux, From edf261b824aa0a5371ccff6f50908a9b56390b02 Mon Sep 17 00:00:00 2001 From: Tangles Date: Tue, 25 Apr 2017 16:27:10 +1000 Subject: [PATCH 04/69] curses - splashscrens for dnh and grunt. --- win/curses/cursinit.c | 64 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index 4155a2df..a10624ce 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -14,6 +14,8 @@ #define SLASHEM_CURSES 2 #define UNNETHACK_CURSES 3 #define SPORKHACK_CURSES 4 +#define GRUNTHACK_CURSES 5 +#define DNETHACK_CURSES 6 /* array to save initial terminal colors for later restoration */ @@ -106,7 +108,33 @@ nhrgb orig_hiwhite; #define SPORKHACK_SPLASH_G \ " | | " #define SPORKHACK_SPLASH_H \ -" |_| " +" |_| " + +#define GRUNTHACK_SPLASH_A \ +" ______ _ _ _ _ " +#define GRUNTHACK_SPLASH_B \ +"/ ____) | | | | | | | | " +#define GRUNTHACK_SPLASH_C \ +"| / ___ _ __ _ _ _ __ | |_ | |__| | __ _ ___ | | _" +#define GRUNTHACK_SPLASH_D \ +"| | L \\| '__)| | | || '_ \\ | __)| __ | / _` | / __)| |/ /" +#define GRUNTHACK_SPLASH_E \ +"| l__) || | | |_| || | | || |_ | | | || (_| || (__ | < " +#define GRUNTHACK_SPLASH_F \ +"\\______/|_| \\___,_||_| |_| \\__)|_| |_| \\__,_| \\___)|_|\\_\\" + +#define DNETHACK_SPLASH_A \ +" _ _ _ _ _ _ _ " +#define DNETHACK_SPLASH_B \ +" | || \\ | | | | | | | | | | " +#define DNETHACK_SPLASH_C \ +" __| || \\| | ___ | |_ | |__| | __ _ ___ | | __" +#define DNETHACK_SPLASH_D \ +" / _` || . ` | / _ \\| __|| __ | / _` | / __|| |/ /" +#define DNETHACK_SPLASH_E \ +"| (_| || |\\ || __/| |_ | | | || (_| || (__ | < " +#define DNETHACK_SPLASH_F \ +" \\__,_||_| \\_| \\___| \\__||_| |_| \\__,_| \\___||_|\\_\\" /* Create the "main" nonvolitile windows used by nethack */ @@ -1173,8 +1201,18 @@ void curses_display_splash_window() which_variant = SPORKHACK_CURSES; } - curses_toggle_color_attr(stdscr, CLR_WHITE, A_NORMAL, ON); + if (strncmp("GruntHack", COPYRIGHT_BANNER_A, 9) == 0) + { + which_variant = GRUNTHACK_CURSES; + } + + if (strncmp("dNethack", COPYRIGHT_BANNER_A, 8) == 0) + { + which_variant = DNETHACK_CURSES; + } + + curses_toggle_color_attr(stdscr, CLR_WHITE, A_NORMAL, ON); if (iflags.wc_splash_screen) { switch (which_variant) @@ -1223,6 +1261,28 @@ void curses_display_splash_window() mvaddstr(y_start + 7, x_start, SPORKHACK_SPLASH_H); y_start += 9; break; + case GRUNTHACK_CURSES: + { + mvaddstr(y_start, x_start, GRUNTHACK_SPLASH_A); + mvaddstr(y_start + 1, x_start, GRUNTHACK_SPLASH_B); + mvaddstr(y_start + 2, x_start, GRUNTHACK_SPLASH_C); + mvaddstr(y_start + 3, x_start, GRUNTHACK_SPLASH_D); + mvaddstr(y_start + 4, x_start, GRUNTHACK_SPLASH_E); + mvaddstr(y_start + 5, x_start, GRUNTHACK_SPLASH_F); + y_start += 7; + break; + } + case DNETHACK_CURSES: + { + mvaddstr(y_start, x_start, DNETHACK_SPLASH_A); + mvaddstr(y_start + 1, x_start, DNETHACK_SPLASH_B); + mvaddstr(y_start + 2, x_start, DNETHACK_SPLASH_C); + mvaddstr(y_start + 3, x_start, DNETHACK_SPLASH_D); + mvaddstr(y_start + 4, x_start, DNETHACK_SPLASH_E); + mvaddstr(y_start + 5, x_start, DNETHACK_SPLASH_F); + y_start += 7; + break; + } default: { impossible("which_variant number %d out of range", From 71eea738f76324adfd36f085dfbe939c0fe6ba83 Mon Sep 17 00:00:00 2001 From: Tangles Date: Tue, 25 Apr 2017 16:28:57 +1000 Subject: [PATCH 05/69] curses - fix msgtype-related hang at endgame. --- win/curses/cursmain.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index c97e28da..37c2307f 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -280,8 +280,9 @@ void curses_display_nhwindow(winid wid, BOOLEAN_P block) if ((wid == MESSAGE_WIN) && block) { - if (u.uhp != -1) (void) curses_block(TRUE); - /* don't bug player with TAB prompt on "Saving..." */ + if (u.uhp != -1 && program_state.gameover != 1) + (void) curses_block(TRUE); + /* don't bug player with TAB prompt on "Saving..." or endgame*/ else (void) curses_more(); } From 7aa8af15047183a749c9663be00fa6be61fe17b8 Mon Sep 17 00:00:00 2001 From: Tangles Date: Thu, 27 Apr 2017 22:30:09 +1000 Subject: [PATCH 06/69] Curses - handle long #extcmd entry gracefully. --- win/curses/cursdial.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/win/curses/cursdial.c b/win/curses/cursdial.c index e4786a45..da811b15 100644 --- a/win/curses/cursdial.c +++ b/win/curses/cursdial.c @@ -364,22 +364,29 @@ int curses_character_input_dialog(const char *prompt, const char *choices, CHAR_ int curses_ext_cmd() { int count, letter, prompt_width, startx, starty, winx, winy; - int messageh, messagew; + int messageh, messagew, maxlen = BUFSZ - 1; int ret = -1; char cur_choice[BUFSZ]; int matches = 0; - WINDOW *extwin = NULL; + WINDOW *extwin = NULL, *extwin2 = NULL; if (iflags.extmenu) { return extcmd_via_menu(); } + startx = 0; + starty = 0; if (iflags.wc_popup_dialog) /* Prompt in popup window */ { - startx = 1; - starty = 1; - extwin = curses_create_window(25, 1, UP); + int x0, y0, w, h; /* bounding coords of popup */ + extwin2 = curses_create_window(25, 1, UP); + wrefresh(extwin2); + /* create window inside window to prevent overwriting of border */ + getbegyx(extwin2,y0,x0); + getmaxyx(extwin2,h,w); + extwin = newwin(1, w-2, y0+1, x0+1); + if (w - 4 < maxlen) maxlen = w - 4; } else { @@ -394,8 +401,7 @@ int curses_ext_cmd() winy += messageh - 1; extwin = newwin(1, messagew-2, winy, winx); - startx = 0; - starty = 0; + if (messagew - 4 < maxlen) maxlen = messagew - 4; pline("#"); } @@ -408,7 +414,7 @@ int curses_ext_cmd() wmove(extwin, starty, startx + 2); waddstr(extwin, cur_choice); wmove(extwin, starty, strlen(cur_choice) + startx + 2); - wprintw(extwin, " ", cur_choice); + wprintw(extwin, " "); /* if we have an autocomplete command, AND it matches uniquely */ if (matches == 1) @@ -461,7 +467,7 @@ int curses_ext_cmd() } } - if (letter != '*' && prompt_width < BUFSZ -1) { + if (letter != '*' && prompt_width < maxlen) { cur_choice[prompt_width] = letter; cur_choice[prompt_width + 1] = '\0'; ret = -1; @@ -490,6 +496,7 @@ int curses_ext_cmd() } curses_destroy_win(extwin); + if (extwin2) curses_destroy_win(extwin2); return ret; } From 94628a4bb83ac5a22c95371cbbf51b82997ab381 Mon Sep 17 00:00:00 2001 From: Tangles Date: Sun, 30 Apr 2017 13:29:30 +1000 Subject: [PATCH 07/69] curses darkgray fixes 1. actually save the default terminal colour for darkgray so that it doesn't get restored to a random uninitialised value. 2. Actually check the use_darkgray option, and present 'blue' if it's not set - for consistency with other windowports. 3. Fix clash on >16 colour terminals where darkgray was mapping to one of the colorpair entries used by hilite-stairs, and appearing as black-on-red. Fixed by remapping black-on-default colorpair entry to darkgray-on-default if these conditions are met. --- win/curses/cursinit.c | 4 ++++ win/curses/cursmisc.c | 19 ++++++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index a10624ce..6b350a7a 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -661,7 +661,11 @@ void curses_init_nhcolors() #ifdef USE_DARKGRAY if (COLORS > 16) { + color_content(CURSES_DARK_GRAY, &orig_darkgray.r, + &orig_darkgray.g, &orig_darkgray.b); init_color(CURSES_DARK_GRAY, 300, 300, 300); + /* just override black colorpair entry here */ + init_pair(1, CURSES_DARK_GRAY, -1); } #endif } diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index 9dd7fc0d..116ee833 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -100,16 +100,21 @@ void curses_toggle_color_attr(WINDOW *win, int color, int attr, int onoff) if (color == 0) /* make black fg visible */ { #ifdef USE_DARKGRAY - if (can_change_color() && (COLORS > 16)) + if (iflags.wc2_darkgray) { - color = CURSES_DARK_GRAY - 1; - } - else /* Use bold for a bright black */ + if (can_change_color() && (COLORS > 16)) + { + /* colorpair for black is already darkgray */ + } + else /* Use bold for a bright black */ + { + wattron(win, A_BOLD); + } + else +#else { - wattron(win, A_BOLD); + color = CLR_BLUE; } -#else - color = CLR_BLUE; #endif /* USE_DARKGRAY */ } curses_color = color + 1; From 1087a2f761190f09aece76bee65852c0e50056e9 Mon Sep 17 00:00:00 2001 From: Tangles Date: Sun, 30 Apr 2017 13:42:24 +1000 Subject: [PATCH 08/69] fix use_darkgray option handling properly --- win/curses/cursmisc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index 116ee833..35a1cce1 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -110,12 +110,10 @@ void curses_toggle_color_attr(WINDOW *win, int color, int attr, int onoff) { wattron(win, A_BOLD); } - else -#else - { - color = CLR_BLUE; } + else #endif /* USE_DARKGRAY */ + color = CLR_BLUE; } curses_color = color + 1; if (COLORS < 16) From 9842329d7e48eb76266d191b616ed1560b74d6aa Mon Sep 17 00:00:00 2001 From: Tangles Date: Mon, 1 May 2017 22:50:45 +1000 Subject: [PATCH 09/69] .gitignore add dlb and nhdat --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 4f50d101..4fab1f25 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ dat/*.lev dat/data dat/dungeon dat/dungeon.pdf +dat/nhdat dat/options dat/oracles dat/quest.dat @@ -28,6 +29,7 @@ src/vis_tab.c util/dgn_comp util/dgn_lex.c util/dgn_yacc.c +util/dlb util/lev_comp util/lev_lex.c util/lev_yacc.c From 0d6ecc4592e8e785ac897ec32e3f819b76e7fb13 Mon Sep 17 00:00:00 2001 From: k21971 Date: Mon, 1 May 2017 00:56:52 -0400 Subject: [PATCH 10/69] curses - Display items in inventory list --- win/curses/cursmain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index 37c2307f..d96e2c33 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -399,7 +399,7 @@ void curses_add_menu(winid wid, int glyph, const ANY_P * identifier, { int curses_attr = curses_convert_attr(attr); - curses_add_nhmenu_item(wid, identifier, accelerator, group_accel, + curses_add_nhmenu_item(wid, glyph, identifier, accelerator, group_accel, curses_attr, str, presel); } From af37b9c6027b907216e4ffe6ab5441dd3edd1b50 Mon Sep 17 00:00:00 2001 From: Tangles Date: Mon, 1 May 2017 22:05:05 +1000 Subject: [PATCH 11/69] curses - Display items in inventory list --- include/wincurs.h | 2 +- win/curses/cursdial.c | 32 +++++++++++++++++++++++--------- win/curses/cursdial.h | 2 +- win/curses/curswins.c | 2 +- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/include/wincurs.h b/include/wincurs.h index f631517d..866540b1 100644 --- a/include/wincurs.h +++ b/include/wincurs.h @@ -243,7 +243,7 @@ extern int curses_ext_cmd(void); extern void curses_create_nhmenu(winid wid); -extern void curses_add_nhmenu_item(winid wid, const ANY_P *identifier, +extern void curses_add_nhmenu_item(winid wid, int glyph, const ANY_P *identifier, CHAR_P accelerator, CHAR_P group_accel, int attr, const char *str, BOOLEAN_P presel); diff --git a/win/curses/cursdial.c b/win/curses/cursdial.c index da811b15..53615969 100644 --- a/win/curses/cursdial.c +++ b/win/curses/cursdial.c @@ -13,6 +13,7 @@ typedef struct nhmi { winid wid; /* NetHack window id */ + int glyph; /* Menu glyphs */ anything identifier; /* Value returned if item selected */ CHAR_P accelerator; /* Character used to select item from menu */ CHAR_P group_accel; /* Group accelerator for menu item, if any */ @@ -564,7 +565,7 @@ void curses_create_nhmenu(winid wid) /* Add a menu item to the given menu window */ -void curses_add_nhmenu_item(winid wid, const ANY_P *identifier, +void curses_add_nhmenu_item(winid wid, int glyph, const ANY_P *identifier, CHAR_P accelerator, CHAR_P group_accel, int attr, const char *str, BOOLEAN_P presel) { @@ -581,6 +582,7 @@ void curses_add_nhmenu_item(winid wid, const ANY_P *identifier, curses_rtrim((char *) new_str); new_item = malloc(sizeof(nhmenu_item)); new_item->wid = wid; + new_item->glyph = glyph; new_item->identifier = *identifier; new_item->accelerator = accelerator; new_item->group_accel = group_accel; @@ -1128,6 +1130,26 @@ static void menu_display_page(nhmenu *menu, WINDOW *win, int page_num) mvwprintw(win, menu_item_ptr->line_num + 1, 3, ") "); } } + entry_cols = menu->width; + start_col = 1; + + if (menu_item_ptr->identifier.a_void != NULL) + { + entry_cols -= 4; + start_col += 4; + } + if (menu_item_ptr->glyph != NO_GLYPH) + { + /* stuff to display the glyph at line_num+1, start_col goes here */ + unsigned special; /*notused */ + mapglyph(menu_item_ptr->glyph, &curletter, &color, &special, 0, 0); + curses_toggle_color_attr(win, color, NONE, ON); + mvwaddch(win, menu_item_ptr->line_num + 1, start_col, curletter); + curses_toggle_color_attr(win, color, NONE, OFF); + mvwaddch(win, menu_item_ptr->line_num + 1, start_col + 1, ' '); + entry_cols -= 2; + start_col += 2; + } #ifdef MENU_COLOR if (iflags.use_menu_color && (menu_color = get_menu_coloring ((char *)menu_item_ptr->str, &color, &attr))) @@ -1143,14 +1165,6 @@ static void menu_display_page(nhmenu *menu, WINDOW *win, int page_num) } #endif /* MENU_COLOR */ curses_toggle_color_attr(win, NONE, menu_item_ptr->attr, ON); - entry_cols = menu->width; - start_col = 1; - - if (menu_item_ptr->identifier.a_void != NULL) - { - entry_cols -= 4; - start_col += 4; - } num_lines = curses_num_lines(menu_item_ptr->str, entry_cols); diff --git a/win/curses/cursdial.h b/win/curses/cursdial.h index dccdbe80..e2ce5244 100644 --- a/win/curses/cursdial.h +++ b/win/curses/cursdial.h @@ -18,7 +18,7 @@ int curses_ext_cmd(void); void curses_create_nhmenu(winid wid); -void curses_add_nhmenu_item(winid wid, const ANY_P *identifier, +void curses_add_nhmenu_item(winid wid, int glyph, const ANY_P *identifier, CHAR_P accelerator, CHAR_P group_accel, int attr, const char *str, BOOLEAN_P presel); diff --git a/win/curses/curswins.c b/win/curses/curswins.c index 25109a4c..75fef72d 100644 --- a/win/curses/curswins.c +++ b/win/curses/curswins.c @@ -529,7 +529,7 @@ void curses_puts(winid wid, int attr, const char *text) } identifier = malloc(sizeof(anything)); identifier->a_void = NULL; - curses_add_nhmenu_item(wid, identifier, 0, 0, attr, text, + curses_add_nhmenu_item(wid, NO_GLYPH, identifier, 0, 0, attr, text, FALSE); } else From 7e3effecaba3c4d1ee10ce588a54155ffbf4cf7a Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Sat, 6 May 2017 03:06:44 +0200 Subject: [PATCH 12/69] Simplify stat highlight timer logic --- win/curses/cursstat.c | 264 +++++++----------------------------------- 1 file changed, 45 insertions(+), 219 deletions(-) diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index f96c36bb..d6438531 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -37,6 +37,8 @@ struct color_option percentage_color_of(int value, int max, static boolean stat_colored(const char *id); #endif +static int decrement_highlight(nhstat *); + static void init_stats(void); static void set_labels(int label_width); @@ -1458,235 +1460,59 @@ void curses_update_stats(boolean redraw) wrefresh(win); } +/* Decrement a single highlight, return 1 if decremented to zero */ -/* Decrement the highlight_turns for all stats. Call curses_update_stats -if needed to unhighlight a stat */ - -void curses_decrement_highlight() +static int decrement_highlight(nhstat *stat) { - boolean unhighlight = FALSE; - - if (prevname.highlight_turns > 0) - { - prevname.highlight_turns--; - if (prevname.highlight_turns == 0) - { - unhighlight = TRUE; - } - } - if (prevdepth.highlight_turns > 0) - { - prevdepth.highlight_turns--; - if (prevdepth.highlight_turns == 0) - { - unhighlight = TRUE; - } - } - if (prevstr.highlight_turns > 0) - { - prevstr.highlight_turns--; - if (prevstr.highlight_turns == 0) - { - unhighlight = TRUE; - } - } - if (prevint.highlight_turns > 0) - { - prevint.highlight_turns--; - if (prevint.highlight_turns == 0) - { - unhighlight = TRUE; - } - } - if (prevwis.highlight_turns > 0) - { - prevwis.highlight_turns--; - if (prevwis.highlight_turns == 0) - { - unhighlight = TRUE; - } - } - if (prevdex.highlight_turns > 0) - { - prevdex.highlight_turns--; - if (prevdex.highlight_turns == 0) - { - unhighlight = TRUE; - } - } - if (prevcon.highlight_turns > 0) + if (stat->highlight_turns > 0) { - prevcon.highlight_turns--; - if (prevcon.highlight_turns == 0) + stat->highlight_turns--; + if (stat->highlight_turns == 0) { - unhighlight = TRUE; - } - } - if (prevcha.highlight_turns > 0) - { - prevcha.highlight_turns--; - if (prevcha.highlight_turns == 0) - { - unhighlight = TRUE; - } - } - if (prevalign.highlight_turns > 0) - { - prevalign.highlight_turns--; - if (prevalign.highlight_turns == 0) - { - unhighlight = TRUE; - } - } - if (prevau.highlight_turns > 0) - { - prevau.highlight_turns--; - if (prevau.highlight_turns == 0) - { - unhighlight = TRUE; - } - } - if (prevhp.highlight_turns > 0) - { - prevhp.highlight_turns--; - if (prevhp.highlight_turns == 0) - { - unhighlight = TRUE; - } - } - if (prevmhp.highlight_turns > 0) - { - prevmhp.highlight_turns--; - if (prevmhp.highlight_turns == 0) - { - unhighlight = TRUE; - } - } - if (prevlevel.highlight_turns > 0) - { - prevlevel.highlight_turns--; - if (prevlevel.highlight_turns == 0) - { - unhighlight = TRUE; - } - } - if (prevpow.highlight_turns > 0) - { - prevpow.highlight_turns--; - if (prevpow.highlight_turns == 0) - { - unhighlight = TRUE; - } - } - if (prevmpow.highlight_turns > 0) - { - prevmpow.highlight_turns--; - if (prevmpow.highlight_turns == 0) - { - unhighlight = TRUE; - } - } - if (prevac.highlight_turns > 0) - { - prevac.highlight_turns--; - if (prevac.highlight_turns == 0) - { - unhighlight = TRUE; + return 1; } } + return 0; +} + +/* Decrement the highlight_turns for all stats. Call curses_update_stats +if needed to unhighlight a stat */ + +void curses_decrement_highlight() +{ + int unhighlight = 0; + unhighlight |= decrement_highlight(&prevname); + unhighlight |= decrement_highlight(&prevdepth); + unhighlight |= decrement_highlight(&prevstr); + unhighlight |= decrement_highlight(&prevint); + unhighlight |= decrement_highlight(&prevwis); + unhighlight |= decrement_highlight(&prevdex); + unhighlight |= decrement_highlight(&prevcon); + unhighlight |= decrement_highlight(&prevcha); + unhighlight |= decrement_highlight(&prevalign); + unhighlight |= decrement_highlight(&prevau); + unhighlight |= decrement_highlight(&prevhp); + unhighlight |= decrement_highlight(&prevmhp); + unhighlight |= decrement_highlight(&prevlevel); + unhighlight |= decrement_highlight(&prevpow); + unhighlight |= decrement_highlight(&prevmpow); + unhighlight |= decrement_highlight(&prevac); #ifdef EXP_ON_BOTL - if (prevexp.highlight_turns > 0) - { - prevexp.highlight_turns--; - if (prevexp.highlight_turns == 0) - { - unhighlight = TRUE; - } - } + unhighlight |= decrement_highlight(&prevexp); #endif - if (prevtime.highlight_turns > 0) - { - prevtime.highlight_turns--; - if (prevtime.highlight_turns == 0) - { - unhighlight = TRUE; - } - } + unhighlight |= decrement_highlight(&prevtime); #ifdef SCORE_ON_BOTL - if (prevscore.highlight_turns > 0) - { - prevscore.highlight_turns--; - if (prevscore.highlight_turns == 0) - { - unhighlight = TRUE; - } - } + unhighlight |= decrement_highlight(&prevscore); #endif - if (prevhunger.highlight_turns > 0) - { - prevhunger.highlight_turns--; - if (prevhunger.highlight_turns == 0) - { - unhighlight = TRUE; - } - } - if (prevconf.highlight_turns > 0) - { - prevconf.highlight_turns--; - if (prevconf.highlight_turns == 0) - { - unhighlight = TRUE; - } - } - if (prevblind.highlight_turns > 0) - { - prevblind.highlight_turns--; - if (prevblind.highlight_turns == 0) - { - unhighlight = TRUE; - } - } - if (prevstun.highlight_turns > 0) - { - prevstun.highlight_turns--; - if (prevstun.highlight_turns == 0) - { - unhighlight = TRUE; - } - } - if (prevhallu.highlight_turns > 0) - { - prevhallu.highlight_turns--; - if (prevhallu.highlight_turns == 0) - { - unhighlight = TRUE; - } - } - if (prevsick.highlight_turns > 0) - { - prevsick.highlight_turns--; - if (prevsick.highlight_turns == 0) - { - unhighlight = TRUE; - } - } - if (prevslime.highlight_turns > 0) - { - prevslime.highlight_turns--; - if (prevslime.highlight_turns == 0) - { - unhighlight = TRUE; - } - } - if (prevencumb.highlight_turns > 0) - { - prevencumb.highlight_turns--; - if (prevencumb.highlight_turns == 0) - { - unhighlight = TRUE; - } - } - + unhighlight |= decrement_highlight(&prevhunger); + unhighlight |= decrement_highlight(&prevconf); + unhighlight |= decrement_highlight(&prevblind); + unhighlight |= decrement_highlight(&prevstun); + unhighlight |= decrement_highlight(&prevhallu); + unhighlight |= decrement_highlight(&prevsick); + unhighlight |= decrement_highlight(&prevslime); + unhighlight |= decrement_highlight(&prevencumb); + if (unhighlight) { curses_update_stats(FALSE); From a94609867b625d4cf5e35dcc1fcb256346892a78 Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Sat, 6 May 2017 04:54:46 +0200 Subject: [PATCH 13/69] Remove a lot of copy/paste from curses_update_stats Still a lot of cruft left before I can start doing some actual work here --- win/curses/cursstat.c | 1035 ++++++++--------------------------------- win/curses/cursstat.h | 8 + 2 files changed, 199 insertions(+), 844 deletions(-) diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index d6438531..505d1e54 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -37,6 +37,12 @@ struct color_option percentage_color_of(int value, int max, static boolean stat_colored(const char *id); #endif +static void handle_status_problem(nhstat *, int, const char *, int *, int *, + int, boolean); + +static void handle_stat_change(nhstat *, int, int, int *, int *, + int, boolean); + static int decrement_highlight(nhstat *); static void init_stats(void); @@ -84,6 +90,148 @@ static nhstat prevencumb; extern const char *hu_stat[]; /* from eat.c */ extern const char *enc_stat[]; /* from botl.c */ +/* Handles numerical stat changes of various kinds. + type is generally STAT_OTHER (generic "do nothing special"), + but is used if the stat needs to be handled in a special way. */ + +static void handle_stat_change(nhstat *stat, int new, int type, + int *sx, int *sy, int sx_start, + boolean horiz) +{ + char buf[BUFSZ]; + WINDOW *win = curses_get_nhwin(STATUS_WIN); + + /* Turncount isn't highlighted, or it would be highlighted constantly. + Also note that these colors can be ignored if statuscolors is enabled + in color_stat() */ + if (new != stat->value && type != STAT_TIME) + { + /* Less AC is better */ + if ((type == STAT_AC && new < stat->value) || + (type != STAT_AC && new > stat->value)) + { + if (type == STAT_GOLD) + { + stat->highlight_color = HI_GOLD; + } + else + { + stat->highlight_color = STAT_UP_COLOR; + } + } + else + { + stat->highlight_color = STAT_DOWN_COLOR; + } + stat->value = new; + + /* Strength might be displayed differently */ + if (type == STAT_STR && new > 18) + { + if (new > 118) + { + sprintf(buf, "%d", new - 100); + } + else if (new == 118) + { + sprintf(buf, "%d/**"); + } + else + { + sprintf(buf, "18/%02d", new - 18); + } + } + else + { + sprintf(buf, "%d", new); + } + + free(stat->txt); + stat->txt = curses_copy_of(buf); + stat->highlight_turns = 5; + if (type == STAT_HPEN) + { + stat->highlight_turns = 3; + } + } + + if (stat->label) + { + mvwaddstr(win, *sy, *sx, stat->label); + *sx += strlen(stat->label); + } + + color_stat(*stat, ON); + mvwaddstr(win, *sy, *sx, stat->txt); + color_stat(*stat, OFF); + + if (type == STAT_HPEN) + { + *sx += strlen(stat->txt); + } + else if (horiz) + { + *sx += strlen(stat->txt) + 1; + } + else + { + *sx = sx_start; + *sy += 1; + } +} + +static void handle_status_problem(nhstat *stat, int new, const char *str, + int *sx, int *sy, int sx_start, + boolean horiz) +{ + WINDOW *win = curses_get_nhwin(STATUS_WIN); + + if (new != stat->value) + { + stat->highlight_color = STAT_DOWN_COLOR; + if (stat->txt != NULL) + { + free(stat->txt); + } + if (new) + { + stat->txt = curses_copy_of(str); + } + else + { + stat->txt = NULL; + } + if (stat->value == 0) + { + stat->highlight_turns = 5; + } + stat->value = new; + } + + if (stat->label != NULL) + { + mvwaddstr(win, *sy, *sx, stat->label); + *sx += strlen(stat->label); + } + + if (stat->txt != NULL) + { + color_stat(*stat, ON); + mvwaddstr(win, *sy, *sx, stat->txt); + color_stat(*stat, OFF); + + if (horiz) + { + *sx += strlen(stat->txt) + 1; + } + else + { + sx = sx_start; + *sy += 1; /* ++ would increase the pointer addr */ + } + } +} + /* Update the status win - this is called when NetHack would normally write to the status window, so we know somwthing has changed. We override the write and update what needs to be updated ourselves. */ @@ -161,7 +309,12 @@ void curses_update_stats(boolean redraw) curses_clear_nhwin(STATUS_WIN); /* Line 1 */ - + + /* Improve when this code is workable, this is a bit awkward at the moment */ + +#define statchange(stat,new,type) handle_stat_change(stat, new, type, &sx, &sy, \ + sx_start, horiz) + /* Player name and title */ strcpy(buf, plname); if ('a' <= buf[0] && buf[0] <= 'z') buf[0] += 'A'-'a'; @@ -233,252 +386,12 @@ void curses_update_stats(boolean redraw) } /* Strength */ - if (ACURR(A_STR) != prevstr.value) /* Strength changed */ - { - - if (ACURR(A_STR) > prevstr.value) - { - prevstr.highlight_color = STAT_UP_COLOR; - } - else - { - prevstr.highlight_color = STAT_DOWN_COLOR; - } - prevstr.value = ACURR(A_STR); - if (ACURR(A_STR) > 118) - { - sprintf(buf, "%d", ACURR(A_STR) - 100); - } - else if (ACURR(A_STR)==118) - { - sprintf(buf, "18/**"); - } - else if(ACURR(A_STR) > 18) - { - sprintf(buf, "18/%02d", ACURR(A_STR) - 18); - } - else - { - sprintf(buf, "%d", ACURR(A_STR)); - } - free(prevstr.txt); - prevstr.txt = curses_copy_of(buf); - prevstr.highlight_turns = 5; - } - - if (prevstr.label != NULL) - { - mvwaddstr(win, sy, sx, prevstr.label); - sx += strlen(prevstr.label); - } - - color_stat(prevstr, ON); - mvwaddstr(win, sy, sx, prevstr.txt); - color_stat(prevstr, OFF); - - if (horiz) - { - sx += strlen(prevstr.txt) + 1; - } - else - { - sx = sx_start; - sy++; - } - - /* Intelligence */ - if (ACURR(A_INT) != prevint.value) /* Intelligence changed */ - { - - if (ACURR(A_INT) > prevint.value) - { - prevint.highlight_color = STAT_UP_COLOR; - } - else - { - prevint.highlight_color = STAT_DOWN_COLOR; - } - prevint.value = ACURR(A_INT); - sprintf(buf, "%d", ACURR(A_INT)); - free(prevint.txt); - prevint.txt = curses_copy_of(buf); - prevint.highlight_turns = 5; - } - - if (prevint.label != NULL) - { - mvwaddstr(win, sy, sx, prevint.label); - sx += strlen(prevint.label); - } - - color_stat(prevint, ON); - mvwaddstr(win, sy, sx, prevint.txt); - color_stat(prevint, OFF); - - if (horiz) - { - sx += strlen(prevint.txt) + 1; - } - else - { - sx = sx_start; - sy++; - } - - /* Wisdom */ - if (ACURR(A_WIS) != prevwis.value) /* Wisdom changed */ - { - - if (ACURR(A_WIS) > prevwis.value) - { - prevwis.highlight_color = STAT_UP_COLOR; - } - else - { - prevwis.highlight_color = STAT_DOWN_COLOR; - } - prevwis.value = ACURR(A_WIS); - sprintf(buf, "%d", ACURR(A_WIS)); - free(prevwis.txt); - prevwis.txt = curses_copy_of(buf); - prevwis.highlight_turns = 5; - } - - if (prevwis.label != NULL) - { - mvwaddstr(win, sy, sx, prevwis.label); - sx += strlen(prevwis.label); - } - - color_stat(prevwis, ON); - mvwaddstr(win, sy, sx, prevwis.txt); - color_stat(prevwis, OFF); - - if (horiz) - { - sx += strlen(prevwis.txt) + 1; - } - else - { - sx = sx_start; - sy++; - } - - /* Dexterity */ - if (ACURR(A_DEX) != prevdex.value) /* Dexterity changed */ - { - - if (ACURR(A_DEX) > prevdex.value) - { - prevdex.highlight_color = STAT_UP_COLOR; - } - else - { - prevdex.highlight_color = STAT_DOWN_COLOR; - } - prevdex.value = ACURR(A_DEX); - sprintf(buf, "%d", ACURR(A_DEX)); - free(prevdex.txt); - prevdex.txt = curses_copy_of(buf); - prevdex.highlight_turns = 5; - } - - if (prevdex.label != NULL) - { - mvwaddstr(win, sy, sx, prevdex.label); - sx += strlen(prevdex.label); - } - - color_stat(prevdex, ON); - mvwaddstr(win, sy, sx, prevdex.txt); - color_stat(prevdex, OFF); - - if (horiz) - { - sx += strlen(prevdex.txt) + 1; - } - else - { - sx = sx_start; - sy++; - } - - /* Constitution */ - if (ACURR(A_CON) != prevcon.value) /* Constitution changed */ - { - - if (ACURR(A_CON) > prevcon.value) - { - prevcon.highlight_color = STAT_UP_COLOR; - } - else - { - prevcon.highlight_color = STAT_DOWN_COLOR; - } - prevcon.value = ACURR(A_CON); - sprintf(buf, "%d", ACURR(A_CON)); - free(prevcon.txt); - prevcon.txt = curses_copy_of(buf); - prevcon.highlight_turns = 5; - } - - if (prevcon.label != NULL) - { - mvwaddstr(win, sy, sx, prevcon.label); - sx += strlen(prevcon.label); - } - - color_stat(prevcon, ON); - mvwaddstr(win, sy, sx, prevcon.txt); - color_stat(prevcon, OFF); - - if (horiz) - { - sx += strlen(prevcon.txt) + 1; - } - else - { - sx = sx_start; - sy++; - } - - /* Charisma */ - if (ACURR(A_CHA) != prevcha.value) /* Charisma changed */ - { - if (ACURR(A_CHA) > prevcha.value) - { - prevcha.highlight_color = STAT_UP_COLOR; - } - else - { - prevcha.highlight_color = STAT_DOWN_COLOR; - } - prevcha.value = ACURR(A_CHA); - sprintf(buf, "%d", ACURR(A_CHA)); - free(prevcha.txt); - prevcha.txt = curses_copy_of(buf); - prevcha.highlight_turns = 5; - } - - if (prevcha.label != NULL) - { - mvwaddstr(win, sy, sx, prevcha.label); - sx += strlen(prevcha.label); - } - - color_stat(prevcha, ON); - mvwaddstr(win, sy, sx, prevcha.txt); - color_stat(prevcha, OFF); - - if (horiz) - { - sx += strlen(prevcha.txt) + 1; - } - else - { - sx = sx_start; - sy ++; - } + statchange(&prevstr, ACURR(A_STR), STAT_STR); + statchange(&prevint, ACURR(A_INT), STAT_OTHER); + statchange(&prevwis, ACURR(A_WIS), STAT_OTHER); + statchange(&prevdex, ACURR(A_DEX), STAT_OTHER); + statchange(&prevcon, ACURR(A_CON), STAT_OTHER); + statchange(&prevcha, ACURR(A_CHA), STAT_OTHER); /* Alignment */ if (prevalign.alignment != u.ualign.type) /* Alignment changed */ @@ -562,252 +475,33 @@ void curses_update_stats(boolean redraw) /* Gold */ #ifndef GOLDOBJ - if (prevau.value != u.ugold) /* Gold changed */ - { - if (u.ugold > prevau.value) - { -#else - if (prevau.value != money_cnt(invent)) /* Gold changed */ - { - if (money_cnt(invent) > prevau.value) - { -#endif - prevau.highlight_color = HI_GOLD; - } - else - { - prevau.highlight_color = STAT_DOWN_COLOR; - } -#ifndef GOLDOBJ - prevau.value = u.ugold; - sprintf(buf,"%ld", u.ugold); + statchange(&prevau, u.ugold, STAT_GOLD); #else - prevau.value = money_cnt(invent); - sprintf(buf,"%ld", money_cnt(invent)); + statchange(&prevau, money_cnt(invent), STAT_GOLD); #endif - free(prevau.txt); - prevau.txt = curses_copy_of(buf); - prevau.highlight_turns = 5; - } - - if (prevau.label != NULL) - { - mvwaddstr(win, sy, sx, prevau.label); - sx += strlen(prevau.label); - } - - color_stat(prevau, ON); - mvwaddstr(win, sy, sx, prevau.txt); - color_stat(prevau, OFF); - if (horiz) + /* Hit Points */ + + if (u.mtimedone) /* Currently polymorphed - show monster HP */ { - sx += strlen(prevau.txt) + 1; + hp = u.mh; + hpmax = u.mhmax; } - else + else /* Not polymorphed */ { - sx = sx_start; - sy++; + hp = u.uhp; + hpmax = u.uhpmax; } + statchange(&prevhp, hp, STAT_HPEN); + statchange(&prevmhp, hpmax, STAT_OTHER); + statchange(&prevpow, u.uen, STAT_HPEN); + statchange(&prevmpow, u.uenmax, STAT_OTHER); + statchange(&prevac, u.uac, STAT_AC); - /* Hit Points */ - - if (u.mtimedone) /* Currently polymorphed - show monster HP */ - { - hp = u.mh; - hpmax = u.mhmax; - } - else /* Not polymorphed */ - { - hp = u.uhp; - hpmax = u.uhpmax; - } - - if (hp != prevhp.value) - { - if (hp > prevhp.value) - { - prevhp.highlight_color = STAT_UP_COLOR; - } - else - { - prevhp.highlight_color = STAT_DOWN_COLOR; - } - prevhp.value = hp; - if (prevhp.value < 0) - { - prevhp.value = 0; - } - sprintf(buf, "%ld", prevhp.value); - free(prevhp.txt); - prevhp.txt = curses_copy_of(buf); - prevhp.highlight_turns = 3; - } - - if (prevhp.label != NULL) - { - mvwaddstr(win, sy, sx, prevhp.label); - sx += strlen(prevhp.label); - } - - color_stat(prevhp, ON); - mvwaddstr(win, sy, sx, prevhp.txt); - color_stat(prevhp, OFF); - - sx += strlen(prevhp.txt); - - /* Max Hit Points */ - - if (hpmax != prevmhp.value) /* Not polymorphed */ - { - if (hpmax > prevmhp.value) - { - prevmhp.highlight_color = STAT_UP_COLOR; - } - else - { - prevmhp.highlight_color = STAT_DOWN_COLOR; - } - prevmhp.value = hpmax; - sprintf(buf, "%d", hpmax); - free(prevmhp.txt); - prevmhp.txt = curses_copy_of(buf); - prevmhp.highlight_turns = 3; - } - - if (prevmhp.label != NULL) - { - mvwaddstr(win, sy, sx, prevmhp.label); - sx += strlen(prevmhp.label); - } - - color_stat(prevmhp, ON); - mvwaddstr(win, sy, sx, prevmhp.txt); - color_stat(prevmhp, OFF); - - if (horiz) - { - color_stat(prevmhp, ON); - sx += strlen(prevmhp.txt) + 1; - color_stat(prevmhp, OFF); - } - else - { - sx = sx_start; - sy++; - } - - /* Power */ - if (u.uen != prevpow.value) - { - if (u.uen > prevpow.value) - { - prevpow.highlight_color = STAT_UP_COLOR; - } - else - { - prevpow.highlight_color = STAT_DOWN_COLOR; - } - prevpow.value = u.uen; - sprintf(buf, "%d", u.uen); - free(prevpow.txt); - prevpow.txt = curses_copy_of(buf); - prevpow.highlight_turns = 3; - } - - if (prevpow.label != NULL) - { - mvwaddstr(win, sy, sx, prevpow.label); - sx += strlen(prevpow.label); - } - - color_stat(prevpow, ON); - mvwaddstr(win, sy, sx, prevpow.txt); - color_stat(prevpow, OFF); - - sx += strlen(prevpow.txt); - - /* Max Power */ - if (u.uenmax != prevmpow.value) - { - if (u.uenmax > prevmpow.value) - { - prevmpow.highlight_color = STAT_UP_COLOR; - } - else - { - prevmpow.highlight_color = STAT_DOWN_COLOR; - } - prevmpow.value = u.uenmax; - sprintf(buf, "%d", u.uenmax); - free(prevmpow.txt); - prevmpow.txt = curses_copy_of(buf); - prevmpow.highlight_turns = 3; - } - - if (prevmpow.label != NULL) - { - mvwaddstr(win, sy, sx, prevmpow.label); - sx += strlen(prevmpow.label); - } - - color_stat(prevmpow, ON); - mvwaddstr(win, sy, sx, prevmpow.txt); - color_stat(prevmpow, OFF); - - if (horiz) - { - sx += strlen(prevmpow.txt) + 1; - } - else - { - sx = sx_start; - sy++; - } - - - /* Armor Class */ - if (u.uac != prevac.value) - { - if (u.uac > prevac.value) /* Lower is better for AC */ - { - prevac.highlight_color = STAT_DOWN_COLOR; - } - else - { - prevac.highlight_color = STAT_UP_COLOR; - } - prevac.value = u.uac; - sprintf(buf, "%d", u.uac); - free(prevac.txt); - prevac.txt = curses_copy_of(buf); - prevac.highlight_turns = 5; - } - - if (prevac.label != NULL) - { - mvwaddstr(win, sy, sx, prevac.label); - sx += strlen(prevac.label); - } - - color_stat(prevac, ON); - mvwaddstr(win, sy, sx, prevac.txt); - color_stat(prevac, OFF); - - if (horiz) - { - sx += strlen(prevac.txt) + 1; - } - else - { - sx = sx_start; - sy++; - } - - /* Experience */ -#ifdef EXP_ON_BOTL - if (prevexp.display != flags.showexp) /* Setting has changed */ + /* Experience */ +#ifdef EXP_ON_BOTL + if (prevexp.display != flags.showexp) /* Setting has changed */ { prevexp.display = flags.showexp; free(prevlevel.label); @@ -974,32 +668,7 @@ void curses_update_stats(boolean redraw) } if (prevtime.display) { - if (moves != prevtime.value) - { - sprintf(buf, "%ld", moves); - free(prevtime.txt); - prevtime.txt = curses_copy_of(buf); - } - - if (prevtime.label != NULL) - { - mvwaddstr(win, sy, sx, prevtime.label); - sx += strlen(prevtime.label); - } - - color_stat(prevtime, ON); - mvwaddstr(win, sy, sx, prevtime.txt); - color_stat(prevtime, OFF); - - if (horiz) - { - sx += strlen(prevtime.txt) + 1; - } - else - { - sx = sx_start; - sy++; - } + statchange(&prevtime, moves, STAT_TIME); } /* Score */ @@ -1010,41 +679,7 @@ void curses_update_stats(boolean redraw) } if (prevscore.display) { - if (botl_score() != prevscore.value) - { - if (botl_score() > prevscore.value) - { - prevscore.highlight_color = STAT_UP_COLOR; - } - else /* Not sure this is possible */ - { - prevscore.highlight_color = STAT_DOWN_COLOR; - } - sprintf(buf, "%ld", botl_score()); - free(prevscore.txt); - prevscore.txt = curses_copy_of(buf); - prevscore.highlight_turns = 3; - } - - if (prevscore.label != NULL) - { - mvwaddstr(win, sy, sx, prevscore.label); - sx += strlen(prevscore.label); - } - - color_stat(prevscore, ON); - mvwaddstr(win, sy, sx, prevscore.txt); - color_stat(prevscore, OFF); - - if (horiz) - { - sx += strlen(prevscore.txt) + 1; - } - else - { - sx = sx_start; - sy++; - } + statchange(&prevscore, botl_score(), STAT_OTHER); } prevscore.value = botl_score(); /* Track it even when it's not displayed */ @@ -1100,306 +735,18 @@ void curses_update_stats(boolean redraw) } } - /* Confusion */ - if (Confusion != prevconf.value) - { - prevconf.highlight_color = STAT_DOWN_COLOR; - if (prevconf.txt != NULL) - { - free(prevconf.txt); - } - if (Confusion) - { - prevconf.txt = curses_copy_of("Conf"); - } - else - { - prevconf.txt = NULL; - } - if (prevconf.value == 0) - { - prevconf.highlight_turns = 5; - } - prevconf.value = Confusion; - } - - if (prevconf.label != NULL) - { - mvwaddstr(win, sy, sx, prevconf.label); - sx += strlen(prevconf.label); - } - - if (prevconf.txt != NULL) - { - color_stat(prevconf, ON); - mvwaddstr(win, sy, sx, prevconf.txt); - color_stat(prevconf, OFF); - } +#define statusproblem(stat,new,str) handle_status_problem(stat, new, str, &sx, &sy, \ + sx_start, horiz) - if (prevconf.txt != NULL) - { - if (horiz) - { - sx += strlen(prevconf.txt) + 1; - } - else - { - sx = sx_start; - sy++; - } - } - - /* Blindness */ - if (Blind != prevblind.value) - { - prevblind.highlight_color = STAT_DOWN_COLOR; - if (prevblind.txt != NULL) - { - free(prevblind.txt); - } - if (Blind) - { - prevblind.txt = curses_copy_of("Blind"); - } - else - { - prevblind.txt = NULL; - } - if (prevblind.value == 0) - { - prevblind.highlight_turns = 5; - } - prevblind.value = Blind; - } - - if (prevblind.label != NULL) - { - mvwaddstr(win, sy, sx, prevblind.label); - sx += strlen(prevblind.label); - } - - if (prevblind.txt != NULL) - { - color_stat(prevblind, ON); - mvwaddstr(win, sy, sx, prevblind.txt); - color_stat(prevblind, OFF); - } - - if (prevblind.txt != NULL) - { - if (horiz) - { - sx += strlen(prevblind.txt) + 1; - } - else - { - sx = sx_start; - sy++; - } - } - - /* Stun */ - if (Stunned != prevstun.value) - { - prevstun.highlight_color = STAT_DOWN_COLOR; - if (prevstun.txt != NULL) - { - free(prevstun.txt); - } - if (Stunned) - { - prevstun.txt = curses_copy_of("Stun"); - } - else - { - prevstun.txt = NULL; - } - if (prevstun.value == 0) - { - prevstun.highlight_turns = 5; - } - prevstun.value = Stunned; - } - - if (prevstun.label != NULL) - { - mvwaddstr(win, sy, sx, prevstun.label); - sx += strlen(prevstun.label); - } - - if (prevstun.txt != NULL) - { - color_stat(prevstun, ON); - mvwaddstr(win, sy, sx, prevstun.txt); - color_stat(prevstun, OFF); - } - - if (prevstun.txt != NULL) - { - if (horiz) - { - sx += strlen(prevstun.txt) + 1; - } - else - { - sx = sx_start; - sy++; - } - } - - /* Hallucination */ - if (Hallucination != prevhallu.value) - { - prevhallu.highlight_color = STAT_DOWN_COLOR; - if (prevhallu.txt != NULL) - { - free(prevhallu.txt); - } - if (Hallucination) - { - prevhallu.txt = curses_copy_of("Hallu"); - } - else - { - prevhallu.txt = NULL; - } - if (prevhallu.value == 0) - { - prevhallu.highlight_turns = 5; - } - prevhallu.value = Hallucination; - } - - if (prevhallu.label != NULL) - { - mvwaddstr(win, sy, sx, prevhallu.label); - sx += strlen(prevhallu.label); - } - - if (prevhallu.txt != NULL) - { - color_stat(prevhallu, ON); - mvwaddstr(win, sy, sx, prevhallu.txt); - color_stat(prevhallu, OFF); - } - - if (prevhallu.txt != NULL) - { - if (horiz) - { - sx += strlen(prevhallu.txt) + 1; - } - else - { - sx = sx_start; - sy++; - } - } - - /* Sick */ - if (Sick != prevsick.value) - { - prevsick.highlight_color = STAT_DOWN_COLOR; - if (prevsick.txt != NULL) - { - free(prevsick.txt); - } - if (Sick) - { - if (u.usick_type & SICK_VOMITABLE) - { - prevsick.txt = curses_copy_of("FoodPois"); - } - else - { - prevsick.txt = curses_copy_of("Ill"); - } - } - else - { - prevsick.txt = NULL; - } - if (prevsick.value == 0) - { - prevsick.highlight_turns = 5; - } - prevsick.value = Sick; - } - - if (prevsick.label != NULL) - { - mvwaddstr(win, sy, sx, prevsick.label); - sx += strlen(prevsick.label); - } - - if (prevsick.txt != NULL) - { - color_stat(prevsick, ON); - mvwaddstr(win, sy, sx, prevsick.txt); - color_stat(prevsick, OFF); - } - - if (prevsick.txt != NULL) - { - if (horiz) - { - sx += strlen(prevsick.txt) + 1; - } - else - { - sx = sx_start; - sy++; - } - } - - /* Slime */ - if (Slimed != prevslime.value) - { - prevslime.highlight_color = STAT_DOWN_COLOR; - if (prevslime.txt != NULL) - { - free(prevslime.txt); - } - if (Slimed) - { - prevslime.txt = curses_copy_of("Slime"); - } - else - { - prevslime.txt = NULL; - } - if (prevslime.value == 0) - { - prevslime.highlight_turns = 5; - } - prevslime.value = Slimed; - } - - if (prevslime.label != NULL) - { - mvwaddstr(win, sy, sx, prevslime.label); - sx += strlen(prevslime.label); - } - - if (prevslime.txt != NULL) - { - color_stat(prevslime, ON); - mvwaddstr(win, sy, sx, prevslime.txt); - color_stat(prevslime, OFF); - } - - if (prevslime.txt != NULL) - { - if (horiz) - { - sx += strlen(prevslime.txt) + 1; - } - else - { - sx = sx_start; - sy++; - } - } + /* Confusion */ + statusproblem(&prevconf, Confusion, "Conf"); + statusproblem(&prevblind, Blind, "Blind"); + statusproblem(&prevstun, Stunned, "Stun"); + statusproblem(&prevhallu, Hallucination, "Hallu"); + + /* TODO: allow all 3 kinds of sickness seperately: FoodPois, Ill, Zombie */ + statusproblem(&prevsick, Sick, (u.usick_type & SICK_VOMITABLE) ? "FoodPois" : "Ill"); + statusproblem(&prevslime, Slimed, "Slime"); /* Encumberance */ enc = near_capacity(); diff --git a/win/curses/cursstat.h b/win/curses/cursstat.h index cde3624e..f8a07602 100644 --- a/win/curses/cursstat.h +++ b/win/curses/cursstat.h @@ -1,6 +1,14 @@ #ifndef CURSSTAT_H #define CURSSTAT_H +/* Used by handle_stat_change to handle some stats differently. Not an enum + because this is how NetHack code generally handles them. */ +#define STAT_OTHER 0 +#define STAT_STR 1 +#define STAT_GOLD 2 +#define STAT_HPEN 3 /* HP or Pw */ +#define STAT_AC 4 +#define STAT_TIME 5 /* Global declarations */ From e6ed6f6747625325e171297424126941c7821667 Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Sat, 6 May 2017 16:32:28 +0200 Subject: [PATCH 14/69] Change code formatting of the Curses interface Done as follows: * Run all files through `indent -bad -bap -br -ce -cbi0 -npcs -cs -bs -saf -sai -saw -di4 -nbc -psl -T nhstat -T nhmenu_item -T nhmenu -T menu_op -T nhrgb -T nhprev_mesg -T nethack_window -T nethack_wid -T nethack_char -brs -blf -i4 -lp -ip0 -ppi1 -l80 -nbbo` * Remove reundant {}s from case statements * Run "untabify" (Emacs) on all the source files (Probably some indent option I missed somewhere) * Insert an emacs/vim indent line on top of all files so that these programs obey the new formatting --- win/curses/cursdial.c | 1299 ++++++++++++++------------------ win/curses/cursdial.h | 25 +- win/curses/cursinit.c | 1241 +++++++++++++++---------------- win/curses/cursinit.h | 8 +- win/curses/cursmain.c | 324 ++++---- win/curses/cursmesg.c | 320 ++++---- win/curses/cursmesg.h | 6 +- win/curses/cursmisc.c | 916 ++++++++++------------- win/curses/cursmisc.h | 8 +- win/curses/cursstat.c | 1627 +++++++++++++++++------------------------ win/curses/cursstat.h | 18 +- win/curses/curswins.c | 667 ++++++++--------- win/curses/curswins.h | 13 +- 13 files changed, 2810 insertions(+), 3662 deletions(-) diff --git a/win/curses/cursdial.c b/win/curses/cursdial.c index 53615969..e4b18db4 100644 --- a/win/curses/cursdial.c +++ b/win/curses/cursdial.c @@ -1,3 +1,5 @@ +/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ + #include "curses.h" #include "hack.h" #include "wincurs.h" @@ -10,41 +12,38 @@ /* Private declarations */ -typedef struct nhmi -{ - winid wid; /* NetHack window id */ - int glyph; /* Menu glyphs */ - anything identifier; /* Value returned if item selected */ - CHAR_P accelerator; /* Character used to select item from menu */ - CHAR_P group_accel; /* Group accelerator for menu item, if any */ - int attr; /* Text attributes for item */ - const char *str; /* Text of menu item */ - BOOLEAN_P presel; /* Whether menu item should be preselected */ - boolean selected; /* Whether item is currently selected */ - int page_num; /* Display page number for entry */ - int line_num; /* Line number on page where entry begins */ - int num_lines; /* Number of lines entry uses on page */ - int count; /* Count for selected item */ - struct nhmi *prev_item; /* Pointer to previous entry */ - struct nhmi *next_item; /* Pointer to next entry */ +typedef struct nhmi { + winid wid; /* NetHack window id */ + int glyph; /* Menu glyphs */ + anything identifier; /* Value returned if item selected */ + CHAR_P accelerator; /* Character used to select item from menu */ + CHAR_P group_accel; /* Group accelerator for menu item, if any */ + int attr; /* Text attributes for item */ + const char *str; /* Text of menu item */ + BOOLEAN_P presel; /* Whether menu item should be preselected */ + boolean selected; /* Whether item is currently selected */ + int page_num; /* Display page number for entry */ + int line_num; /* Line number on page where entry begins */ + int num_lines; /* Number of lines entry uses on page */ + int count; /* Count for selected item */ + struct nhmi *prev_item; /* Pointer to previous entry */ + struct nhmi *next_item; /* Pointer to next entry */ } nhmenu_item; -typedef struct nhm -{ - winid wid; /* NetHack window id */ - const char *prompt; /* Menu prompt text */ - nhmenu_item *entries; /* Menu entries */ - int num_entries; /* Number of menu entries */ - int num_pages; /* Number of display pages for entry */ - int height; /* Window height of menu */ - int width; /* Window width of menu */ - boolean reuse_accels; /* Non-unique accelerators per page */ - struct nhm *prev_menu; /* Pointer to previous entry */ - struct nhm *next_menu; /* Pointer to next entry */ +typedef struct nhm { + winid wid; /* NetHack window id */ + const char *prompt; /* Menu prompt text */ + nhmenu_item *entries; /* Menu entries */ + int num_entries; /* Number of menu entries */ + int num_pages; /* Number of display pages for entry */ + int height; /* Window height of menu */ + int width; /* Window width of menu */ + boolean reuse_accels; /* Non-unique accelerators per page */ + struct nhm *prev_menu; /* Pointer to previous entry */ + struct nhm *next_menu; /* Pointer to next entry */ } nhmenu; -typedef enum menu_op_type -{ +typedef enum menu_op_type { SELECT, DESELECT, INVERT @@ -64,14 +63,15 @@ static boolean menu_is_multipage(nhmenu *menu, int width, int height); static void menu_win_size(nhmenu *menu); -static void menu_display_page(nhmenu *menu, WINDOW *win, int page_num); +static void menu_display_page(nhmenu *menu, WINDOW * win, int page_num); -static int menu_get_selections(WINDOW *win, nhmenu *menu, int how); +static int menu_get_selections(WINDOW * win, nhmenu *menu, int how); -static void menu_select_deselect(WINDOW *win, nhmenu_item *item, menu_op operation); +static void menu_select_deselect(WINDOW * win, nhmenu_item *item, + menu_op operation); -static int menu_operation(WINDOW *win, nhmenu *menu, menu_op operation, - int page_num); +static int menu_operation(WINDOW * win, nhmenu *menu, menu_op operation, + int page_num); static void menu_clear_selections(nhmenu *menu); @@ -84,7 +84,8 @@ static nhmenu *nhmenus = NULL; /* NetHack menu array */ /* Get a line of text from the player, such as asking for a character name or a wish */ -void curses_line_input_dialog(const char *prompt, char *answer, int buffer) +void +curses_line_input_dialog(const char *prompt, char *answer, int buffer) { int map_height, map_width, maxwidth, remaining_buf, winx, winy, count; WINDOW *askwin, *bwin; @@ -96,61 +97,50 @@ void curses_line_input_dialog(const char *prompt, char *answer, int buffer) maxwidth = term_cols - 2; - if (iflags.window_inited) - { + if (iflags.window_inited) { curses_get_window_size(MAP_WIN, &map_height, &map_width); if ((prompt_width + 2) > map_width) maxwidth = map_width - 2; } - - if (prompt_width > maxwidth) - { + + if (prompt_width > maxwidth) { prompt_height = curses_num_lines(prompt, maxwidth); height = prompt_height; prompt_width = maxwidth; tmpstr = curses_break_str(prompt, maxwidth, prompt_height); remaining_buf = buffer - (strlen(tmpstr) - 1); - if (remaining_buf > 0 ) - { + if (remaining_buf > 0) { height += (remaining_buf / prompt_width); - if ((remaining_buf % prompt_width) > 0) - { + if ((remaining_buf % prompt_width) > 0) { height++; } } } - - if (iflags.window_inited) - { + + if (iflags.window_inited) { bwin = curses_create_window(prompt_width, height, UP); wrefresh(bwin); getbegyx(bwin, winy, winx); askwin = newwin(height, prompt_width, winy + 1, winx + 1); - } - else - { + } else { bwin = curses_create_window(prompt_width, height, CENTER); wrefresh(bwin); getbegyx(bwin, winy, winx); askwin = newwin(height, prompt_width, winy + 1, winx + 1); } - for (count = 0; count < prompt_height; count++) - { + for (count = 0; count < prompt_height; count++) { tmpstr = curses_break_str(prompt, maxwidth, count + 1); - if (count == (prompt_height - 1)) /* Last line */ - { + if (count == (prompt_height - 1)) { /* Last line */ mvwprintw(askwin, count, 0, "%s ", tmpstr); - } - else - { + } else { mvwaddstr(askwin, count, 0, tmpstr); } free(tmpstr); } - + echo(); curs_set(1); - wgetnstr(askwin, input, buffer-1); + wgetnstr(askwin, input, buffer - 1); curs_set(0); strcpy(answer, input); werase(bwin); @@ -162,7 +152,9 @@ void curses_line_input_dialog(const char *prompt, char *answer, int buffer) /* Get a single character response from the player, such as a y/n prompt */ -int curses_character_input_dialog(const char *prompt, const char *choices, CHAR_P def) +int +curses_character_input_dialog(const char *prompt, const char *choices, + CHAR_P def) { WINDOW *askwin = NULL; int answer, count, maxwidth, map_height, map_width; @@ -174,82 +166,65 @@ int curses_character_input_dialog(const char *prompt, const char *choices, CHAR_ boolean any_choice = FALSE; boolean accept_count = FALSE; - if (invent || (moves > 1)) - { + if (invent || (moves > 1)) { curses_get_window_size(MAP_WIN, &map_height, &map_width); - } - else - { + } else { map_height = term_rows; map_width = term_cols; } - + maxwidth = map_width - 2; - - if (choices != NULL) - { - for (count = 0; choices[count] != '\0'; count++) - { - if (choices[count] == '#') /* Accept a count */ - { + + if (choices != NULL) { + for (count = 0; choices[count] != '\0'; count++) { + if (choices[count] == '#') { /* Accept a count */ accept_count = TRUE; } } choicestr[0] = ' '; choicestr[1] = '['; - for (count = 0; choices[count] != '\0'; count++) - { - if (choices[count] == DOESCAPE) /* Escape */ - { + for (count = 0; choices[count] != '\0'; count++) { + if (choices[count] == DOESCAPE) { /* Escape */ break; } choicestr[count + 2] = choices[count]; } choicestr[count + 2] = ']'; - if (((def >= 'A') && (def <= 'Z')) || ((def >= 'a') && (def <= 'z'))) - { + if (((def >= 'A') && (def <= 'Z')) || ((def >= 'a') && (def <= 'z'))) { choicestr[count + 3] = ' '; choicestr[count + 4] = '('; choicestr[count + 5] = def; choicestr[count + 6] = ')'; choicestr[count + 7] = '\0'; - } - else /* No usable default choice */ - { + } else { /* No usable default choice */ + choicestr[count + 3] = '\0'; - def = '\0'; /* Mark as no default */ + def = '\0'; /* Mark as no default */ } strcpy(askstr, prompt); strcat(askstr, choicestr); - } - else - { + } else { strcpy(askstr, prompt); any_choice = TRUE; } - + prompt_width = strlen(askstr); - - if ((prompt_width + 2) > maxwidth) - { + + if ((prompt_width + 2) > maxwidth) { prompt_height = curses_num_lines(askstr, maxwidth); prompt_width = map_width - 2; } - if (iflags.wc_popup_dialog || curses_stupid_hack) - { + if (iflags.wc_popup_dialog || curses_stupid_hack) { askwin = curses_create_window(prompt_width, prompt_height, UP); - for (count = 0; count < prompt_height; count++) - { + for (count = 0; count < prompt_height; count++) { linestr = curses_break_str(askstr, maxwidth, count + 1); mvwaddstr(askwin, count + 1, 1, linestr); free(linestr); } - + wrefresh(askwin); - } - else - { + } else { linestr = curses_copy_of(askstr); pline("%s", linestr); free(linestr); @@ -258,90 +233,69 @@ int curses_character_input_dialog(const char *prompt, const char *choices, CHAR_ curses_stupid_hack = 0; - while (1) - { + while (1) { answer = getch(); - if (answer == ERR) { - answer = def; - break; - } + if (answer == ERR) { + answer = def; + break; + } answer = curses_convert_keys(answer); - if (answer==KEY_ESC) - { - if (choices == NULL) - { + if (answer == KEY_ESC) { + if (choices == NULL) { break; } answer = def; - for (count = 0; choices[count] != '\0'; count++) - { - if (choices[count] == 'q') /* q is preferred over n */ - { + for (count = 0; choices[count] != '\0'; count++) { + if (choices[count] == 'q') { /* q is preferred over n */ answer = 'q'; - } - else if ((choices[count] == 'n') && answer != 'q') - { + } else if ((choices[count] == 'n') && answer != 'q') { answer = 'n'; } } break; - } - else if ((answer == '\n') || (answer == '\r') || - (answer == ' ')) - { - if ((choices != NULL) && (def != '\0')) - { + } else if ((answer == '\n') || (answer == '\r') || (answer == ' ')) { + if ((choices != NULL) && (def != '\0')) { answer = def; } break; } - - if (digit(answer)) - { - if (accept_count) - { - if (answer != '0') - { + + if (digit(answer)) { + if (accept_count) { + if (answer != '0') { yn_number = curses_get_count(answer - '0'); touchwin(askwin); refresh(); } - + answer = '#'; break; } } - - if (any_choice) - { + + if (any_choice) { break; } - - if (choices != NULL) - { - for (count = 0; count < strlen(choices); count++) - { - if (choices[count] == answer) - { + + if (choices != NULL) { + for (count = 0; count < strlen(choices); count++) { + if (choices[count] == answer) { break; } } - if (choices[count] == answer) - { + if (choices[count] == answer) { break; } } } - if (iflags.wc_popup_dialog) - { + if (iflags.wc_popup_dialog) { /* Kludge to make prompt visible after window is dismissed - when inputting a number */ - if (digit(answer)) - { + when inputting a number */ + if (digit(answer)) { linestr = curses_copy_of(askstr); pline("%s", linestr); free(linestr); @@ -349,9 +303,7 @@ int curses_character_input_dialog(const char *prompt, const char *choices, CHAR_ } curses_destroy_win(askwin); - } - else - { + } else { curses_clear_unhighlight_message_window(); curs_set(0); } @@ -362,7 +314,8 @@ int curses_character_input_dialog(const char *prompt, const char *choices, CHAR_ /* Return an extended command from the user */ -int curses_ext_cmd() +int +curses_ext_cmd() { int count, letter, prompt_width, startx, starty, winx, winy; int messageh, messagew, maxlen = BUFSZ - 1; @@ -371,8 +324,7 @@ int curses_ext_cmd() int matches = 0; WINDOW *extwin = NULL, *extwin2 = NULL; - if (iflags.extmenu) - { + if (iflags.extmenu) { return extcmd_via_menu(); } @@ -393,13 +345,12 @@ int curses_ext_cmd() { curses_get_window_xy(MESSAGE_WIN, &winx, &winy); curses_get_window_size(MESSAGE_WIN, &messageh, &messagew); - - if (curses_window_has_border(MESSAGE_WIN)) - { + + if (curses_window_has_border(MESSAGE_WIN)) { winx++; winy++; } - + winy += messageh - 1; extwin = newwin(1, messagew-2, winy, winx); if (messagew - 4 < maxlen) maxlen = messagew - 4; @@ -408,8 +359,7 @@ int curses_ext_cmd() cur_choice[0] = '\0'; - while (1) - { + while (1) { wmove(extwin, starty, startx); waddstr(extwin, "# "); wmove(extwin, starty, startx + 2); @@ -418,12 +368,10 @@ int curses_ext_cmd() wprintw(extwin, " "); /* if we have an autocomplete command, AND it matches uniquely */ - if (matches == 1) - { + if (matches == 1) { curses_toggle_color_attr(extwin, NONE, A_UNDERLINE, ON); wmove(extwin, starty, strlen(cur_choice) + startx + 2); - wprintw(extwin, "%s", extcmdlist[ret].ef_txt - + strlen(cur_choice)); + wprintw(extwin, "%s", extcmdlist[ret].ef_txt + strlen(cur_choice)); curses_toggle_color_attr(extwin, NONE, A_UNDERLINE, OFF); mvwprintw(extwin, starty, strlen(extcmdlist[ret].ef_txt) + 2, " "); @@ -431,61 +379,52 @@ int curses_ext_cmd() wrefresh(extwin); letter = getch(); - prompt_width = strlen(cur_choice); + prompt_width = strlen(cur_choice); matches = 0; - if (letter == DOESCAPE || letter == ERR) - { + if (letter == DOESCAPE || letter == ERR) { ret = -1; break; } - if ((letter == '\r') || (letter == '\n')) - { + if ((letter == '\r') || (letter == '\n')) { if (ret == -1) { - for (count = 0; extcmdlist[count].ef_txt; count++) { - if (!strcasecmp(cur_choice, extcmdlist[count].ef_txt)) { - ret = count; - break; - } - } + for (count = 0; extcmdlist[count].ef_txt; count++) { + if (!strcasecmp(cur_choice, extcmdlist[count].ef_txt)) { + ret = count; + break; + } + } } break; } - if ((letter == '\b') || (letter == KEY_BACKSPACE)) - { - if (prompt_width == 0) - { + if ((letter == '\b') || (letter == KEY_BACKSPACE)) { + if (prompt_width == 0) { ret = -1; break; - } - else - { + } else { cur_choice[prompt_width - 1] = '\0'; letter = '*'; prompt_width--; } } - if (letter != '*' && prompt_width < maxlen) { + + if (letter != '*' && prompt_width < BUFSZ - 1) { cur_choice[prompt_width] = letter; cur_choice[prompt_width + 1] = '\0'; ret = -1; } - for (count = 0; extcmdlist[count].ef_txt; count++) - { - if (!extcmdlist[count].autocomplete) continue; - if (strlen(extcmdlist[count].ef_txt) > prompt_width) - { + for (count = 0; extcmdlist[count].ef_txt; count++) { + if (!extcmdlist[count].autocomplete) + continue; + if (strlen(extcmdlist[count].ef_txt) > prompt_width) { if (strncasecmp(cur_choice, extcmdlist[count].ef_txt, - prompt_width) == 0) - { + prompt_width) == 0) { if ((extcmdlist[count].ef_txt[prompt_width] == - lowc(letter)) || letter == '*') - { - if (matches == 0) - { + lowc(letter)) || letter == '*') { + if (matches == 0) { ret = count; } @@ -504,39 +443,36 @@ int curses_ext_cmd() /* Initialize a menu from given NetHack winid */ -void curses_create_nhmenu(winid wid) +void +curses_create_nhmenu(winid wid) { nhmenu *new_menu = NULL; nhmenu *menuptr = nhmenus; nhmenu_item *menu_item_ptr = NULL; nhmenu_item *tmp_menu_item = NULL; - + new_menu = get_menu(wid); - - if (new_menu != NULL) - { + + if (new_menu != NULL) { /* Reuse existing menu, clearing out current entries */ menu_item_ptr = new_menu->entries; - - if (menu_item_ptr != NULL) - { - while (menu_item_ptr->next_item != NULL) - { + + if (menu_item_ptr != NULL) { + while (menu_item_ptr->next_item != NULL) { tmp_menu_item = menu_item_ptr->next_item; free(menu_item_ptr); menu_item_ptr = tmp_menu_item; } - free(menu_item_ptr); /* Last entry */ + free(menu_item_ptr); /* Last entry */ new_menu->entries = NULL; } - if (new_menu->prompt != NULL) /* Reusing existing menu */ - { - free((char *)new_menu->prompt); - } + if (new_menu->prompt != NULL) { /* Reusing existing menu */ + free((char *) new_menu->prompt); + } return; } - - new_menu = malloc(sizeof(nhmenu)); + + new_menu = malloc(sizeof (nhmenu)); new_menu->wid = wid; new_menu->prompt = NULL; new_menu->entries = NULL; @@ -545,16 +481,12 @@ void curses_create_nhmenu(winid wid) new_menu->width = 0; new_menu->reuse_accels = FALSE; new_menu->next_menu = NULL; - - if (nhmenus == NULL) /* no menus in memory yet */ - { + + if (nhmenus == NULL) { /* no menus in memory yet */ new_menu->prev_menu = NULL; nhmenus = new_menu; - } - else - { - while (menuptr->next_menu != NULL) - { + } else { + while (menuptr->next_menu != NULL) { menuptr = menuptr->next_menu; } new_menu->prev_menu = menuptr; @@ -565,22 +497,22 @@ void curses_create_nhmenu(winid wid) /* Add a menu item to the given menu window */ -void curses_add_nhmenu_item(winid wid, int glyph, const ANY_P *identifier, - CHAR_P accelerator, CHAR_P group_accel, int attr, const char *str, - BOOLEAN_P presel) +void +curses_add_nhmenu_item(winid wid, int glyph, const ANY_P * identifier, + CHAR_P accelerator, CHAR_P group_accel, int attr, + const char *str, BOOLEAN_P presel) { char *new_str; nhmenu_item *new_item, *current_items, *menu_item_ptr; nhmenu *current_menu = get_menu(wid); - - if (str == NULL) - { + + if (str == NULL) { return; } new_str = curses_copy_of(str); curses_rtrim((char *) new_str); - new_item = malloc(sizeof(nhmenu_item)); + new_item = malloc(sizeof (nhmenu_item)); new_item->wid = wid; new_item->glyph = glyph; new_item->identifier = *identifier; @@ -595,24 +527,20 @@ void curses_add_nhmenu_item(winid wid, int glyph, const ANY_P *identifier, new_item->num_lines = 0; new_item->count = -1; new_item->next_item = NULL; - - if (current_menu == NULL) - { - panic("curses_add_nhmenu_item: attempt to add item to nonexistant menu"); + + if (current_menu == NULL) { + panic + ("curses_add_nhmenu_item: attempt to add item to nonexistant menu"); } current_items = current_menu->entries; menu_item_ptr = current_items; - if (current_items == NULL) - { + if (current_items == NULL) { new_item->prev_item = NULL; current_menu->entries = new_item; - } - else - { - while (menu_item_ptr->next_item != NULL) - { + } else { + while (menu_item_ptr->next_item != NULL) { menu_item_ptr = menu_item_ptr->next_item; } new_item->prev_item = menu_item_ptr; @@ -624,19 +552,18 @@ void curses_add_nhmenu_item(winid wid, int glyph, const ANY_P *identifier, /* No more entries are to be added to menu, so details of the menu can be finalized in memory */ -void curses_finalize_nhmenu(winid wid, const char *prompt) +void +curses_finalize_nhmenu(winid wid, const char *prompt) { int count = 0; nhmenu *current_menu = get_menu(wid); nhmenu_item *menu_item_ptr = current_menu->entries; - if (current_menu == NULL) - { + if (current_menu == NULL) { panic("curses_finalize_nhmenu: attempt to finalize nonexistant menu"); } - while (menu_item_ptr != NULL) - { + while (menu_item_ptr != NULL) { menu_item_ptr = menu_item_ptr->next_item; count++; } @@ -649,7 +576,8 @@ void curses_finalize_nhmenu(winid wid, const char *prompt) /* Display a nethack menu, and return a selection, if applicable */ -int curses_display_nhmenu(winid wid, int how, MENU_ITEM_P **_selected) +int +curses_display_nhmenu(winid wid, int how, MENU_ITEM_P ** _selected) { nhmenu *current_menu = get_menu(wid); nhmenu_item *menu_item_ptr; @@ -657,116 +585,101 @@ int curses_display_nhmenu(winid wid, int how, MENU_ITEM_P **_selected) WINDOW *win; MENU_ITEM_P *selected = NULL; - *_selected = NULL; - - if (current_menu == NULL) - { + *_selected = NULL; + + if (current_menu == NULL) { panic("curses_display_nhmenu: attempt to display nonexistant menu"); } - + menu_item_ptr = current_menu->entries; - - if (menu_item_ptr == NULL) - { + + if (menu_item_ptr == NULL) { panic("curses_display_nhmenu: attempt to display empty menu"); } - + /* Reset items to unselected to clear out selections from previous - invocations of this menu, and preselect appropriate items */ - while (menu_item_ptr != NULL) - { + invocations of this menu, and preselect appropriate items */ + while (menu_item_ptr != NULL) { menu_item_ptr->selected = menu_item_ptr->presel; menu_item_ptr = menu_item_ptr->next_item; } menu_win_size(current_menu); menu_determine_pages(current_menu); - + /* Display pre and post-game menus centered */ - if (((moves <= 1) && !invent) || program_state.gameover) - { + if (((moves <= 1) && !invent) || program_state.gameover) { win = curses_create_window(current_menu->width, - current_menu->height, CENTER); - } - else /* Display during-game menus on the right out of the way */ - { + current_menu->height, CENTER); + } else { /* Display during-game menus on the right out of the way */ + win = curses_create_window(current_menu->width, - current_menu->height, RIGHT); + current_menu->height, RIGHT); } - + num_chosen = menu_get_selections(win, current_menu, how); curses_destroy_win(win); - - if (num_chosen > 0) - { - selected = (MENU_ITEM_P*) malloc(num_chosen * - sizeof(MENU_ITEM_P)); + + if (num_chosen > 0) { + selected = (MENU_ITEM_P *) malloc(num_chosen * sizeof (MENU_ITEM_P)); count = 0; - + menu_item_ptr = current_menu->entries; - while (menu_item_ptr != NULL) - { - if (menu_item_ptr->selected) - { - if (count == num_chosen) - { + while (menu_item_ptr != NULL) { + if (menu_item_ptr->selected) { + if (count == num_chosen) { panic("curses_display_nhmenu: Selected items " - "exceeds expected number"); + "exceeds expected number"); } selected[count].item = menu_item_ptr->identifier; selected[count].count = menu_item_ptr->count; - count++; + count++; } menu_item_ptr = menu_item_ptr->next_item; } - - if (count != num_chosen) - { + + if (count != num_chosen) { panic("curses_display_nhmenu: Selected items less than " - "expected number"); + "expected number"); } } *_selected = selected; - + return num_chosen; } -boolean curses_menu_exists(winid wid) +boolean +curses_menu_exists(winid wid) { - if (get_menu(wid) != NULL) - { + if (get_menu(wid) != NULL) { return TRUE; - } - else - { + } else { return FALSE; } } /* Delete the menu associated with the given NetHack winid from memory */ -void curses_del_menu(winid wid) +void +curses_del_menu(winid wid) { nhmenu_item *tmp_menu_item; nhmenu_item *menu_item_ptr; nhmenu *tmpmenu; nhmenu *current_menu = get_menu(wid); - - if (current_menu == NULL) - { - return; + + if (current_menu == NULL) { + return; } - + menu_item_ptr = current_menu->entries; - + /* First free entries associated with this menu from memory */ - if (menu_item_ptr != NULL) - { - while (menu_item_ptr->next_item != NULL) - { + if (menu_item_ptr != NULL) { + while (menu_item_ptr->next_item != NULL) { tmp_menu_item = menu_item_ptr->next_item; free(menu_item_ptr); menu_item_ptr = tmp_menu_item; @@ -774,116 +687,101 @@ void curses_del_menu(winid wid) free(menu_item_ptr); /* Last entry */ current_menu->entries = NULL; } - + /* Now unlink the menu from the list and free it as well */ - if (current_menu->prev_menu != NULL) - { + if (current_menu->prev_menu != NULL) { tmpmenu = current_menu->prev_menu; tmpmenu->next_menu = current_menu->next_menu; + } else { + nhmenus = current_menu->next_menu; /* New head mode or NULL */ } - else - { - nhmenus = current_menu->next_menu; /* New head mode or NULL */ - } - if (current_menu->next_menu != NULL) - { + if (current_menu->next_menu != NULL) { tmpmenu = current_menu->next_menu; tmpmenu->prev_menu = current_menu->prev_menu; } - + free(current_menu); - + curses_del_wid(wid); } /* return a pointer to the menu associated with the given NetHack winid */ -static nhmenu *get_menu(winid wid) +static nhmenu * +get_menu(winid wid) { nhmenu *menuptr = nhmenus; - while (menuptr != NULL) - { - if (menuptr->wid == wid) - { + while (menuptr != NULL) { + if (menuptr->wid == wid) { return menuptr; } menuptr = menuptr->next_menu; } - - return NULL; /* Not found */ + + return NULL; /* Not found */ } -static char menu_get_accel(boolean first) +static char +menu_get_accel(boolean first) { char ret; static char next_letter = 'a'; - - if (first) - { + + if (first) { next_letter = 'a'; } - + ret = next_letter; - + if (((next_letter < 'z') && (next_letter >= 'a')) || ((next_letter < 'Z') - && (next_letter >= 'A')) || ((next_letter < '9') && (next_letter >= '0'))) - { + && (next_letter >= + 'A')) || + ((next_letter < '9') && (next_letter >= '0'))) { next_letter++; - } - else if (next_letter == 'z') - { + } else if (next_letter == 'z') { next_letter = 'A'; - } - else if (next_letter == 'Z') - { + } else if (next_letter == 'Z') { next_letter = '0'; } - + return ret; } /* Determine if menu will require multiple pages to display */ -static boolean menu_is_multipage(nhmenu *menu, int width, int height) +static boolean +menu_is_multipage(nhmenu *menu, int width, int height) { int num_lines; int curline = 0; nhmenu_item *menu_item_ptr = menu->entries; - if (strlen(menu->prompt) > 0) - { + if (strlen(menu->prompt) > 0) { curline += curses_num_lines(menu->prompt, width) + 1; } - - if (menu->num_entries <= (height - curline)) - { - while (menu_item_ptr != NULL) - { + + if (menu->num_entries <= (height - curline)) { + while (menu_item_ptr != NULL) { menu_item_ptr->line_num = curline; - if (menu_item_ptr->identifier.a_void == NULL) - { + if (menu_item_ptr->identifier.a_void == NULL) { num_lines = curses_num_lines(menu_item_ptr->str, width); - } - else - { + } else { /* Add space for accelerator */ num_lines = curses_num_lines(menu_item_ptr->str, width - 4); } menu_item_ptr->num_lines = num_lines; curline += num_lines; menu_item_ptr = menu_item_ptr->next_item; - if ((curline > height) || ((curline > height -2) && - (height == menu_max_height()))) - { + if ((curline > height) || ((curline > height - 2) && + (height == menu_max_height()))) { break; } } - if (menu_item_ptr == NULL) - { + if (menu_item_ptr == NULL) { return FALSE; } } @@ -893,7 +791,8 @@ static boolean menu_is_multipage(nhmenu *menu, int width, int height) /* Determine which entries go on which page, and total number of pages */ -static void menu_determine_pages(nhmenu *menu) +static void +menu_determine_pages(nhmenu *menu) { int tmpline, num_lines; int curline = 0; @@ -902,40 +801,33 @@ static void menu_determine_pages(nhmenu *menu) int width = menu->width; int height = menu->height; int page_end = height; - - - if (strlen(menu->prompt) > 0) - { + + + if (strlen(menu->prompt) > 0) { curline += curses_num_lines(menu->prompt, width) + 1; } - + tmpline = curline; - - if (menu_is_multipage(menu, width, height)) - { - page_end -= 2; /* Room to display current page number */ + + if (menu_is_multipage(menu, width, height)) { + page_end -= 2; /* Room to display current page number */ } /* Determine what entries belong on which page */ menu_item_ptr = menu->entries; - - while (menu_item_ptr != NULL) - { + + while (menu_item_ptr != NULL) { menu_item_ptr->page_num = page_num; menu_item_ptr->line_num = curline; - if (menu_item_ptr->identifier.a_void == NULL) - { + if (menu_item_ptr->identifier.a_void == NULL) { num_lines = curses_num_lines(menu_item_ptr->str, width); - } - else - { + } else { /* Add space for accelerator */ num_lines = curses_num_lines(menu_item_ptr->str, width - 4); } menu_item_ptr->num_lines = num_lines; curline += num_lines; - if (curline > page_end) - { + if (curline > page_end) { page_num++; curline = tmpline; /* Move ptr back so entry will be reprocessed on new page */ @@ -943,91 +835,78 @@ static void menu_determine_pages(nhmenu *menu) } menu_item_ptr = menu_item_ptr->next_item; } - + menu->num_pages = page_num; } /* Determine dimensions of menu window based on term size and entries */ -static void menu_win_size(nhmenu *menu) +static void +menu_win_size(nhmenu *menu) { int width, height, maxwidth, maxheight, curentrywidth, lastline; int maxentrywidth = strlen(menu->prompt); int maxheaderwidth = 0; nhmenu_item *menu_item_ptr = menu->entries; - - maxwidth = 38; /* Reasonable minimum usable width */ - - if ((term_cols / 2) > maxwidth) - { - maxwidth = (term_cols / 2); /* Half the screen */ + + maxwidth = 38; /* Reasonable minimum usable width */ + + if ((term_cols / 2) > maxwidth) { + maxwidth = (term_cols / 2); /* Half the screen */ } - + maxheight = menu_max_height(); - + /* First, determine the width of the longest menu entry */ while (menu_item_ptr != NULL) - { - if (menu_item_ptr->identifier.a_void == NULL) - { - curentrywidth=strlen(menu_item_ptr->str); + if (menu_item_ptr->identifier.a_void == NULL) { + curentrywidth = strlen(menu_item_ptr->str); - if (curentrywidth > maxheaderwidth) - { + if (curentrywidth > maxheaderwidth) { maxheaderwidth = curentrywidth; } - } - else - { + } else { /* Add space for accelerator */ - curentrywidth=strlen(menu_item_ptr->str) + 4; + curentrywidth = strlen(menu_item_ptr->str) + 4; } - if (curentrywidth > maxentrywidth) - { - maxentrywidth = curentrywidth; + if (curentrywidth > maxentrywidth) { + maxentrywidth = curentrywidth; } menu_item_ptr = menu_item_ptr->next_item; } - + /* If the widest entry is smaller than maxwidth, reduce maxwidth accordingly */ - if (maxentrywidth < maxwidth) - { + if (maxentrywidth < maxwidth) { maxwidth = maxentrywidth; } - + /* Try not to wrap headers/normal text lines if possible. We can - go wider than half the screen for this purpose if need be */ - - if ((maxheaderwidth > maxwidth) && (maxheaderwidth < (term_cols - 2))) - { + go wider than half the screen for this purpose if need be */ + + if ((maxheaderwidth > maxwidth) && (maxheaderwidth < (term_cols - 2))) { maxwidth = maxheaderwidth; } - + width = maxwidth; - - /* Possibly reduce height if only 1 page */ - if (!menu_is_multipage(menu, maxwidth, maxheight)) - { + + /* Possibly reduce height if only 1 page */ + if (!menu_is_multipage(menu, maxwidth, maxheight)) { menu_item_ptr = menu->entries; - - while (menu_item_ptr->next_item != NULL) - { + + while (menu_item_ptr->next_item != NULL) { menu_item_ptr = menu_item_ptr->next_item; } - + lastline = (menu_item_ptr->line_num) + menu_item_ptr->num_lines; - - if (lastline < maxheight) - { + + if (lastline < maxheight) { maxheight = lastline; } - } - else /* If multipage, make sure we have enough width for page footer */ - { - if (width < 20) - { + } else { /* If multipage, make sure we have enough width for page footer */ + + if (width < 20) { width = 20; } } @@ -1040,90 +919,74 @@ static void menu_win_size(nhmenu *menu) /* Displays menu selections in the given window */ -static void menu_display_page(nhmenu *menu, WINDOW *win, int page_num) +static void +menu_display_page(nhmenu *menu, WINDOW * win, int page_num) { nhmenu_item *menu_item_ptr; int count, curletter, entry_cols, start_col, num_lines, footer_x; boolean first_accel = TRUE; + #ifdef MENU_COLOR int color = NO_COLOR; int attr = A_NORMAL; boolean menu_color = FALSE; #endif /* MENU_COLOR */ - + /* Cycle through entries until we are on the correct page */ menu_item_ptr = menu->entries; - - while (menu_item_ptr != NULL) - { - if (menu_item_ptr->page_num == page_num) - { + + while (menu_item_ptr != NULL) { + if (menu_item_ptr->page_num == page_num) { break; } menu_item_ptr = menu_item_ptr->next_item; } - - if (menu_item_ptr == NULL) /* Page not found */ - { + + if (menu_item_ptr == NULL) { /* Page not found */ panic("menu_display_page: attempt to display nonexistant page"); } werase(win); - if (strlen(menu->prompt) > 0) - { + if (strlen(menu->prompt) > 0) { num_lines = curses_num_lines(menu->prompt, menu->width); - - for (count = 0; count < num_lines; count++) - { + + for (count = 0; count < num_lines; count++) { mvwprintw(win, count + 1, 1, "%s", - curses_break_str(menu->prompt, menu->width, count + 1)); + curses_break_str(menu->prompt, menu->width, count + 1)); } } /* Display items for current page */ - - while (menu_item_ptr != NULL) - { - if (menu_item_ptr->page_num != page_num) - { + + while (menu_item_ptr != NULL) { + if (menu_item_ptr->page_num != page_num) { break; } - if (menu_item_ptr->identifier.a_void != NULL) - { - if (menu_item_ptr->accelerator != 0) - { + if (menu_item_ptr->identifier.a_void != NULL) { + if (menu_item_ptr->accelerator != 0) { curletter = menu_item_ptr->accelerator; - } - else - { - if (first_accel) - { + } else { + if (first_accel) { curletter = menu_get_accel(TRUE); first_accel = FALSE; - if (!menu->reuse_accels && (menu->num_pages > 1)) - { + if (!menu->reuse_accels && (menu->num_pages > 1)) { menu->reuse_accels = TRUE; } - } - else - { + } else { curletter = menu_get_accel(FALSE); } menu_item_ptr->accelerator = curletter; } - if (menu_item_ptr->selected) - { + if (menu_item_ptr->selected) { curses_toggle_color_attr(win, HIGHLIGHT_COLOR, A_REVERSE, ON); mvwaddch(win, menu_item_ptr->line_num + 1, 1, '<'); mvwaddch(win, menu_item_ptr->line_num + 1, 2, curletter); mvwaddch(win, menu_item_ptr->line_num + 1, 3, '>'); curses_toggle_color_attr(win, HIGHLIGHT_COLOR, A_REVERSE, OFF); - } - else - { + } else { curses_toggle_color_attr(win, HIGHLIGHT_COLOR, NONE, ON); mvwaddch(win, menu_item_ptr->line_num + 1, 2, curletter); curses_toggle_color_attr(win, HIGHLIGHT_COLOR, NONE, OFF); @@ -1133,15 +996,14 @@ static void menu_display_page(nhmenu *menu, WINDOW *win, int page_num) entry_cols = menu->width; start_col = 1; - if (menu_item_ptr->identifier.a_void != NULL) - { + if (menu_item_ptr->identifier.a_void != NULL) { entry_cols -= 4; start_col += 4; - } - if (menu_item_ptr->glyph != NO_GLYPH) - { + } + if (menu_item_ptr->glyph != NO_GLYPH) { /* stuff to display the glyph at line_num+1, start_col goes here */ - unsigned special; /*notused */ + unsigned special; /*notused */ + mapglyph(menu_item_ptr->glyph, &curletter, &color, &special, 0, 0); curses_toggle_color_attr(win, color, NONE, ON); mvwaddch(win, menu_item_ptr->line_num + 1, start_col, curletter); @@ -1151,61 +1013,53 @@ static void menu_display_page(nhmenu *menu, WINDOW *win, int page_num) start_col += 2; } #ifdef MENU_COLOR - if (iflags.use_menu_color && (menu_color = get_menu_coloring - ((char *)menu_item_ptr->str, &color, &attr))) - { - if (color != NO_COLOR) - { + if (iflags.use_menu_color && (menu_color = get_menu_coloring + ((char *) menu_item_ptr->str, &color, + &attr))) { + if (color != NO_COLOR) { curses_toggle_color_attr(win, color, NONE, ON); - } - if (attr != A_NORMAL) - { - menu_item_ptr->attr = menu_item_ptr->attr|attr; - } - } + } + if (attr != A_NORMAL) { + menu_item_ptr->attr = menu_item_ptr->attr | attr; + } + } #endif /* MENU_COLOR */ curses_toggle_color_attr(win, NONE, menu_item_ptr->attr, ON); - + num_lines = curses_num_lines(menu_item_ptr->str, entry_cols); - - for (count = 0; count < num_lines; count++) - { - if (strlen(menu_item_ptr->str) > 0) - { + + for (count = 0; count < num_lines; count++) { + if (strlen(menu_item_ptr->str) > 0) { mvwprintw(win, menu_item_ptr->line_num + count + 1, - start_col, "%s", curses_break_str(menu_item_ptr->str, - entry_cols, count + 1)); - } + start_col, "%s", curses_break_str(menu_item_ptr->str, + entry_cols, + count + 1)); + } } #ifdef MENU_COLOR - if (menu_color && (color != NO_COLOR)) - { - curses_toggle_color_attr(win, color, NONE, OFF); - } + if (menu_color && (color != NO_COLOR)) { + curses_toggle_color_attr(win, color, NONE, OFF); + } #endif /* MENU_COLOR */ curses_toggle_color_attr(win, NONE, menu_item_ptr->attr, OFF); menu_item_ptr = menu_item_ptr->next_item; } - if (menu->num_pages > 1) - { + if (menu->num_pages > 1) { footer_x = menu->width - strlen("<- (Page X of Y) ->"); - if (menu->num_pages > 9) /* Unlikely */ - { + if (menu->num_pages > 9) { /* Unlikely */ footer_x -= 2; } mvwprintw(win, menu->height, footer_x + 3, "(Page %d of %d)", - page_num, menu->num_pages); - if (page_num != 1) - { + page_num, menu->num_pages); + if (page_num != 1) { curses_toggle_color_attr(win, HIGHLIGHT_COLOR, NONE, ON); mvwaddstr(win, menu->height, footer_x, "<="); curses_toggle_color_attr(win, HIGHLIGHT_COLOR, NONE, OFF); } - if (page_num != menu->num_pages) - { + if (page_num != menu->num_pages) { curses_toggle_color_attr(win, HIGHLIGHT_COLOR, NONE, ON); - mvwaddstr(win, menu->height, menu->width - 2, "=>"); + mvwaddstr(win, menu->height, menu->width - 2, "=>"); curses_toggle_color_attr(win, HIGHLIGHT_COLOR, NONE, OFF); } } @@ -1216,7 +1070,8 @@ static void menu_display_page(nhmenu *menu, WINDOW *win, int page_num) } -static int menu_get_selections(WINDOW *win, nhmenu *menu, int how) +static int +menu_get_selections(WINDOW * win, nhmenu *menu, int how) { int curletter; int count = -1; @@ -1229,247 +1084,173 @@ static int menu_get_selections(WINDOW *win, nhmenu *menu, int how) menu_display_page(menu, win, 1); - while (!dismiss) - { + while (!dismiss) { curletter = getch(); - if (curletter == ERR) { - num_selected = -1; - dismiss = TRUE; - } - - if (curletter == DOESCAPE) - { + if (curletter == ERR) { + num_selected = -1; + dismiss = TRUE; + } + + if (curletter == DOESCAPE) { curletter = curses_convert_keys(curletter); } - - - - switch (how) - { - case PICK_NONE: - { - if (menu->num_pages == 1) - { - if (curletter == KEY_ESC) - { - num_selected = -1; - } - else - { - num_selected = 0; - - } - dismiss = TRUE; - break; + + switch (how) { + case PICK_NONE: + if (menu->num_pages == 1) { + if (curletter == KEY_ESC) { + num_selected = -1; + } else { + num_selected = 0; + } + dismiss = TRUE; break; } - case PICK_ANY: - { - switch (curletter) - { - case MENU_SELECT_PAGE: - { - (void) menu_operation(win, menu, SELECT, curpage); - break; - } - case MENU_SELECT_ALL: - { - curpage = menu_operation(win, menu, SELECT, 0); - break; - } - case MENU_UNSELECT_PAGE: - { - (void) menu_operation(win, menu, DESELECT, curpage); - break; - } - case MENU_UNSELECT_ALL: - { - curpage = menu_operation(win, menu, DESELECT, 0); - break; - } - case MENU_INVERT_PAGE: - { - (void) menu_operation(win, menu, INVERT, curpage); - break; - } - case MENU_INVERT_ALL: - { - curpage = menu_operation(win, menu, INVERT, 0); - break; - } - } + break; + case PICK_ANY: + switch (curletter) { + case MENU_SELECT_PAGE: + (void) menu_operation(win, menu, SELECT, curpage); + break; + case MENU_SELECT_ALL: + curpage = menu_operation(win, menu, SELECT, 0); + break; + case MENU_UNSELECT_PAGE: + (void) menu_operation(win, menu, DESELECT, curpage); + break; + case MENU_UNSELECT_ALL: + curpage = menu_operation(win, menu, DESELECT, 0); + break; + case MENU_INVERT_PAGE: + (void) menu_operation(win, menu, INVERT, curpage); + break; + case MENU_INVERT_ALL: + curpage = menu_operation(win, menu, INVERT, 0); + break; } - default: - { - if (isdigit(curletter)) - { - count = curses_get_count(curletter - '0'); - touchwin(win); - refresh(); - curletter = getch(); - if (count > 0) - { - count_letter = curletter; - } + default: + if (isdigit(curletter)) { + count = curses_get_count(curletter - '0'); + touchwin(win); + refresh(); + curletter = getch(); + if (count > 0) { + count_letter = curletter; } } } - - - - - switch (curletter) - { - case KEY_ESC: - { - num_selected = -1; - dismiss = TRUE; - break; - } - case '\n': - case '\r': - { + + switch (curletter) { + case KEY_ESC: + num_selected = -1; + dismiss = TRUE; + break; + case '\n': + case '\r': + dismiss = TRUE; + break; + case KEY_RIGHT: + case KEY_NPAGE: + case MENU_NEXT_PAGE: + case ' ': + if (curpage < menu->num_pages) { + curpage++; + menu_display_page(menu, win, curpage); + } else if (curletter == ' ') { dismiss = TRUE; break; } - case KEY_RIGHT: - case KEY_NPAGE: - case MENU_NEXT_PAGE: - case ' ': - { - if (curpage < menu->num_pages) - { - curpage++; - menu_display_page(menu, win, curpage); - } - else if (curletter == ' ') - { - dismiss = TRUE; - break; - } - break; + break; + case KEY_LEFT: + case KEY_PPAGE: + case MENU_PREVIOUS_PAGE: + if (curpage > 1) { + curpage--; + menu_display_page(menu, win, curpage); } - case KEY_LEFT: - case KEY_PPAGE: - case MENU_PREVIOUS_PAGE: - { - if (curpage > 1) - { - curpage--; - menu_display_page(menu, win, curpage); - } - break; + break; + case KEY_END: + case MENU_LAST_PAGE: + if (curpage != menu->num_pages) { + curpage = menu->num_pages; + menu_display_page(menu, win, curpage); } - case KEY_END: - case MENU_LAST_PAGE: - { - if (curpage != menu->num_pages) - { - curpage = menu->num_pages; - menu_display_page(menu, win, curpage); - } - break; + break; + case KEY_HOME: + case MENU_FIRST_PAGE: + if (curpage != 1) { + curpage = 1; + menu_display_page(menu, win, curpage); } - case KEY_HOME: - case MENU_FIRST_PAGE: - { - if (curpage != 1) - { - curpage = 1; - menu_display_page(menu, win, curpage); - } + break; + case MENU_SEARCH: + curses_line_input_dialog("Search for:", search_key, BUFSZ); + + refresh(); + touchwin(win); + wrefresh(win); + + if (strlen(search_key) == 0) { break; } - case MENU_SEARCH: - { - curses_line_input_dialog("Search for:", search_key, - BUFSZ); - - refresh(); - touchwin(win); - wrefresh(win); - - if (strlen(search_key) == 0) - { - break; - } - - menu_item_ptr = menu->entries; - - while (menu_item_ptr != NULL) - { - if ((menu_item_ptr->identifier.a_void != NULL) && - (strstri(menu_item_ptr->str, search_key))) - { - if (how == PICK_ONE) - { - menu_clear_selections(menu); - menu_select_deselect(win, menu_item_ptr, - SELECT); - num_selected = 1; - dismiss = TRUE; - break; - } - else - { - menu_select_deselect(win, menu_item_ptr, - INVERT); - } - } - menu_item_ptr = menu_item_ptr->next_item; + menu_item_ptr = menu->entries; + + while (menu_item_ptr != NULL) { + if ((menu_item_ptr->identifier.a_void != NULL) && + (strstri(menu_item_ptr->str, search_key))) { + if (how == PICK_ONE) { + menu_clear_selections(menu); + menu_select_deselect(win, menu_item_ptr, SELECT); + num_selected = 1; + dismiss = TRUE; + break; + } else { + menu_select_deselect(win, menu_item_ptr, INVERT); + } } - menu_item_ptr = menu->entries; - break; + menu_item_ptr = menu_item_ptr->next_item; } - default: - { - if (how==PICK_NONE) - { - num_selected = 0; - dismiss = TRUE; - break; - } + + menu_item_ptr = menu->entries; + break; + default: + if (how == PICK_NONE) { + num_selected = 0; + dismiss = TRUE; + break; } } - menu_item_ptr = menu->entries; - while (menu_item_ptr != NULL) - { - if (menu_item_ptr->identifier.a_void != NULL) - { + while (menu_item_ptr != NULL) { + if (menu_item_ptr->identifier.a_void != NULL) { if (((curletter == menu_item_ptr->accelerator) && - ((curpage == menu_item_ptr->page_num) || - (!menu->reuse_accels))) || ((menu_item_ptr->group_accel) - && (curletter == menu_item_ptr->group_accel))) - { - if (curpage != menu_item_ptr->page_num) - { + ((curpage == menu_item_ptr->page_num) || + (!menu->reuse_accels))) || ((menu_item_ptr->group_accel) + && (curletter == + menu_item_ptr-> + group_accel))) { + if (curpage != menu_item_ptr->page_num) { curpage = menu_item_ptr->page_num; menu_display_page(menu, win, curpage); } - if (how == PICK_ONE) - { + if (how == PICK_ONE) { menu_clear_selections(menu); menu_select_deselect(win, menu_item_ptr, SELECT); num_selected = 1; dismiss = TRUE; break; - } - else if ((how == PICK_ANY) && (curletter == count_letter)) - { + } else if ((how == PICK_ANY) && (curletter == count_letter)) { menu_select_deselect(win, menu_item_ptr, SELECT); menu_item_ptr->count = count; count = 0; count_letter = '\0'; - } - else - { + } else { menu_select_deselect(win, menu_item_ptr, INVERT); } } @@ -1477,47 +1258,40 @@ static int menu_get_selections(WINDOW *win, nhmenu *menu, int how) menu_item_ptr = menu_item_ptr->next_item; } } - - if ((how == PICK_ANY) && (num_selected != -1)) - { + + if ((how == PICK_ANY) && (num_selected != -1)) { num_selected = 0; menu_item_ptr = menu->entries; - - while (menu_item_ptr != NULL) - { - if (menu_item_ptr->identifier.a_void != NULL) - { - if (menu_item_ptr->selected) - { + + while (menu_item_ptr != NULL) { + if (menu_item_ptr->identifier.a_void != NULL) { + if (menu_item_ptr->selected) { num_selected++; } } menu_item_ptr = menu_item_ptr->next_item; } } - + return num_selected; } /* Select, deselect, or toggle selected for the given menu entry */ -static void menu_select_deselect(WINDOW *win, nhmenu_item *item, menu_op operation) +static void +menu_select_deselect(WINDOW * win, nhmenu_item *item, menu_op operation) { int curletter = item->accelerator; - - if ((operation == DESELECT) || (item->selected && (operation == - INVERT))) - { + + if ((operation == DESELECT) || (item->selected && (operation == INVERT))) { item->selected = FALSE; mvwaddch(win, item->line_num + 1, 1, ' '); curses_toggle_color_attr(win, HIGHLIGHT_COLOR, NONE, ON); mvwaddch(win, item->line_num + 1, 2, curletter); curses_toggle_color_attr(win, HIGHLIGHT_COLOR, NONE, OFF); mvwaddch(win, item->line_num + 1, 3, ')'); - } - else - { + } else { item->selected = TRUE; curses_toggle_color_attr(win, HIGHLIGHT_COLOR, A_REVERSE, ON); mvwaddch(win, item->line_num + 1, 1, '<'); @@ -1525,7 +1299,7 @@ static void menu_select_deselect(WINDOW *win, nhmenu_item *item, menu_op operati mvwaddch(win, item->line_num + 1, 3, '>'); curses_toggle_color_attr(win, HIGHLIGHT_COLOR, A_REVERSE, OFF); } - + wrefresh(win); } @@ -1534,79 +1308,69 @@ static void menu_select_deselect(WINDOW *win, nhmenu_item *item, menu_op operati on the given menu page. If menu_page is 0, then perform opetation on all pages in menu. Returns last page displayed. */ -static int menu_operation(WINDOW *win, nhmenu *menu, menu_op - operation, int page_num) +static int +menu_operation(WINDOW * win, nhmenu *menu, menu_op + operation, int page_num) { int first_page, last_page, current_page; - nhmenu_item *menu_item_ptr = menu->entries; - - if (page_num == 0) /* Operation to occur on all pages */ - { + nhmenu_item *menu_item_ptr = menu->entries; + + if (page_num == 0) { /* Operation to occur on all pages */ first_page = 1; last_page = menu->num_pages; - } - else - { + } else { first_page = page_num; last_page = page_num; } /* Cycle through entries until we are on the correct page */ - while (menu_item_ptr != NULL) - { - if (menu_item_ptr->page_num == first_page) - { + while (menu_item_ptr != NULL) { + if (menu_item_ptr->page_num == first_page) { break; } menu_item_ptr = menu_item_ptr->next_item; } - + current_page = first_page; - - if (page_num == 0) - { + + if (page_num == 0) { menu_display_page(menu, win, current_page); } - - if (menu_item_ptr == NULL) /* Page not found */ - { + + if (menu_item_ptr == NULL) { /* Page not found */ panic("menu_display_page: attempt to display nonexistant page"); } - - while (menu_item_ptr != NULL) - { - if (menu_item_ptr->page_num != current_page) - { - if (menu_item_ptr->page_num > last_page) - { + + while (menu_item_ptr != NULL) { + if (menu_item_ptr->page_num != current_page) { + if (menu_item_ptr->page_num > last_page) { break; } current_page = menu_item_ptr->page_num; menu_display_page(menu, win, current_page); } - - if (menu_item_ptr->identifier.a_void != NULL) - { + + if (menu_item_ptr->identifier.a_void != NULL) { menu_select_deselect(win, menu_item_ptr, operation); } - + menu_item_ptr = menu_item_ptr->next_item; } - + return current_page; } /* Set all menu items to unselected in menu */ -static void menu_clear_selections(nhmenu *menu) +static void +menu_clear_selections(nhmenu *menu) { - nhmenu_item *menu_item_ptr = menu->entries; + nhmenu_item *menu_item_ptr = menu->entries; - while (menu_item_ptr != NULL) - { + while (menu_item_ptr != NULL) { menu_item_ptr->selected = FALSE; menu_item_ptr = menu_item_ptr->next_item; } @@ -1617,25 +1381,27 @@ static void menu_clear_selections(nhmenu *menu) applied */ #ifdef MENU_COLOR -static boolean get_menu_coloring(char *str, int *color, int *attr) +static boolean +get_menu_coloring(char *str, int *color, int *attr) { struct menucoloring *tmpmc; + if (iflags.use_menu_color) - for (tmpmc = menu_colorings; tmpmc; tmpmc = tmpmc->next) + for (tmpmc = menu_colorings; tmpmc; tmpmc = tmpmc->next) # ifdef MENU_COLOR_REGEX # ifdef MENU_COLOR_REGEX_POSIX - if (regexec(&tmpmc->match, str, 0, NULL, 0) == 0) { + if (regexec(&tmpmc->match, str, 0, NULL, 0) == 0) { # else - if (re_search(&tmpmc->match, str, strlen(str), 0, 9999, 0) >= 0) { + if (re_search(&tmpmc->match, str, strlen(str), 0, 9999, 0) >= 0) { # endif # else - if (pmatch(tmpmc->match, str)) { + if (pmatch(tmpmc->match, str)) { # endif - *color = tmpmc->color; - *attr = curses_convert_attr(tmpmc->attr); - return TRUE; - } + *color = tmpmc->color; + *attr = curses_convert_attr(tmpmc->attr); + return TRUE; + } return FALSE; } #endif /* MENU_COLOR */ @@ -1643,7 +1409,8 @@ static boolean get_menu_coloring(char *str, int *color, int *attr) /* Get the maximum height for a menu */ -static int menu_max_height(void) +static int +menu_max_height(void) { return term_rows - 2; } diff --git a/win/curses/cursdial.h b/win/curses/cursdial.h index e2ce5244..0401062b 100644 --- a/win/curses/cursdial.h +++ b/win/curses/cursdial.h @@ -1,30 +1,33 @@ +/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ + #ifndef CURSDIAL_H -#define CURSDIAL_H +# define CURSDIAL_H -#ifdef MENU_COLOR -# ifdef MENU_COLOR_REGEX -# include +# ifdef MENU_COLOR +# ifdef MENU_COLOR_REGEX +# include +# endif # endif -#endif /* Global declarations */ void curses_line_input_dialog(const char *prompt, char *answer, int buffer); -int curses_character_input_dialog(const char *prompt, const char *choices, CHAR_P def); +int curses_character_input_dialog(const char *prompt, const char *choices, + CHAR_P def); int curses_ext_cmd(void); void curses_create_nhmenu(winid wid); -void curses_add_nhmenu_item(winid wid, int glyph, const ANY_P *identifier, - CHAR_P accelerator, CHAR_P group_accel, int attr, const char *str, - BOOLEAN_P presel); +void curses_add_nhmenu_item(winid wid, int glyph, const ANY_P * identifier, + CHAR_P accelerator, CHAR_P group_accel, int attr, + const char *str, BOOLEAN_P presel); void curses_finalize_nhmenu(winid wid, const char *prompt); -int curses_display_nhmenu(winid wid, int how, MENU_ITEM_P **_selected); +int curses_display_nhmenu(winid wid, int how, MENU_ITEM_P ** _selected); boolean curses_menu_exists(winid wid); @@ -32,4 +35,4 @@ void curses_del_menu(winid wid); -#endif /* CURSDIAL_H */ +#endif /* CURSDIAL_H */ diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index 6b350a7a..1c8619e3 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -1,3 +1,5 @@ +/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ + #include "curses.h" #include "hack.h" #include "wincurs.h" @@ -19,8 +21,7 @@ /* array to save initial terminal colors for later restoration */ -typedef struct nhrgb_type -{ +typedef struct nhrgb_type { short r; short g; short b; @@ -139,7 +140,8 @@ nhrgb orig_hiwhite; /* Create the "main" nonvolitile windows used by nethack */ -void curses_create_main_windows() +void +curses_create_main_windows() { int message_x = 0; int message_y = 0; @@ -160,95 +162,69 @@ void curses_create_main_windows() int hspace = term_cols - 80; boolean borders = FALSE; - switch (iflags.wc2_windowborders) - { - case 1: /* On */ - { + switch (iflags.wc2_windowborders) { + case 1: /* On */ + borders = TRUE; + break; + case 2: /* Off */ + borders = FALSE; + break; + case 3: /* Auto */ + if ((term_cols > 81) && (term_rows > 25)) { borders = TRUE; - break; - } - case 2: /* Off */ - { - borders = FALSE; - break; - } - case 3: /* Auto */ - { - if ((term_cols > 81) && (term_rows > 25)) - { - borders = TRUE; - } - break; - } - default: - { - borders = FALSE; } + break; + default: + borders = FALSE; } - - if (borders) - { + + if (borders) { border_space = 2; hspace -= border_space; } - - if ((term_cols - border_space) < COLNO) - { + + if ((term_cols - border_space) < COLNO) { min_message_height++; } - - /* Determine status window orientation */ + + /* Determine status window orientation */ if (!iflags.wc_align_status || (iflags.wc_align_status == ALIGN_TOP) - || (iflags.wc_align_status == ALIGN_BOTTOM)) - { - if (!iflags.wc_align_status) - { + || (iflags.wc_align_status == ALIGN_BOTTOM)) { + if (!iflags.wc_align_status) { iflags.wc_align_status = ALIGN_BOTTOM; } status_orientation = iflags.wc_align_status; - } - else /* left or right alignment */ - { + } else { /* left or right alignment */ + /* Max space for player name and title horizontally */ - if ((hspace >= 26) && (term_rows >= 24)) - { + if ((hspace >= 26) && (term_rows >= 24)) { status_orientation = iflags.wc_align_status; hspace -= (26 + border_space); - } - else - { + } else { status_orientation = ALIGN_BOTTOM; } } - - /* Determine message window orientation */ + + /* Determine message window orientation */ if (!iflags.wc_align_message || (iflags.wc_align_message == ALIGN_TOP) - || (iflags.wc_align_message == ALIGN_BOTTOM)) - { - if (!iflags.wc_align_message) - { + || (iflags.wc_align_message == ALIGN_BOTTOM)) { + if (!iflags.wc_align_message) { iflags.wc_align_message = ALIGN_TOP; } message_orientation = iflags.wc_align_message; - } - else /* left or right alignment */ - { - if ((hspace - border_space) >= 25) /* Arbitrary */ - { + } else { /* left or right alignment */ + + if ((hspace - border_space) >= 25) { /* Arbitrary */ message_orientation = iflags.wc_align_message; - } - else - { + } else { message_orientation = ALIGN_TOP; } } - + /* Determine window placement and size - 16 possible combos If anyone wants to try to generalize this, be my guest! */ - if ((status_orientation == ALIGN_TOP) && - (message_orientation == ALIGN_TOP)) - { + if ((status_orientation == ALIGN_TOP) && (message_orientation == ALIGN_TOP)) { status_x = 0; status_y = 0; status_width = (term_cols - border_space); @@ -256,19 +232,18 @@ void curses_create_main_windows() message_x = 0; message_y = status_y + (status_height + border_space); message_width = (term_cols - border_space); - message_height = term_rows - (status_height + ROWNO + (border_space * 3)); - if (message_height < min_message_height) - { + message_height = + term_rows - (status_height + ROWNO + (border_space * 3)); + if (message_height < min_message_height) { message_height = min_message_height; } map_x = 0; map_y = message_y + (message_height + border_space); map_width = (term_cols - border_space); - map_height = term_rows - (status_height + message_height + (border_space * 3)); - } - else if ((status_orientation == ALIGN_TOP) && - (message_orientation == ALIGN_RIGHT)) - { + map_height = + term_rows - (status_height + message_height + (border_space * 3)); + } else if ((status_orientation == ALIGN_TOP) && + (message_orientation == ALIGN_RIGHT)) { status_x = 0; status_y = 0; status_height = 2; @@ -281,10 +256,8 @@ void curses_create_main_windows() map_y = status_y + (status_height + border_space); map_width = status_width; map_height = term_rows - (status_height + (border_space * 2)); - } - else if ((status_orientation == ALIGN_TOP) && - (message_orientation == ALIGN_BOTTOM)) - { + } else if ((status_orientation == ALIGN_TOP) && + (message_orientation == ALIGN_BOTTOM)) { status_x = 0; status_y = 0; status_width = (term_cols - border_space); @@ -292,19 +265,18 @@ void curses_create_main_windows() map_x = 0; map_y = status_y + (status_height + border_space); map_width = (term_cols - border_space); - message_height = term_rows - (status_height + ROWNO + (border_space * 3)); - if (message_height < min_message_height) - { + message_height = + term_rows - (status_height + ROWNO + (border_space * 3)); + if (message_height < min_message_height) { message_height = min_message_height; } - map_height = term_rows - (status_height + message_height + (border_space * 3)); + map_height = + term_rows - (status_height + message_height + (border_space * 3)); message_x = 0; message_y = map_y + (map_height + border_space); message_width = (term_cols - border_space); - } - else if ((status_orientation == ALIGN_TOP) && - (message_orientation == ALIGN_LEFT)) - { + } else if ((status_orientation == ALIGN_TOP) && + (message_orientation == ALIGN_LEFT)) { message_x = 0; message_y = 0; message_height = (term_rows - border_space); @@ -319,8 +291,7 @@ void curses_create_main_windows() map_width = status_width; } if ((status_orientation == ALIGN_RIGHT) && - (message_orientation == ALIGN_TOP)) - { + (message_orientation == ALIGN_TOP)) { status_width = 26; status_height = (term_rows - border_space); status_x = term_cols - (status_width + border_space); @@ -329,41 +300,36 @@ void curses_create_main_windows() message_y = 0; message_width = term_cols - (status_width + (border_space * 2)); message_height = term_rows - (ROWNO + (border_space * 2)); - if (message_height < min_message_height) - { + if (message_height < min_message_height) { message_height = min_message_height; } map_x = 0; map_y = message_y + (message_height + border_space); map_width = term_cols - (status_width + (border_space * 2)); map_height = term_rows - (message_height + (border_space * 2)); - } - else if ((status_orientation == ALIGN_RIGHT) && - (message_orientation == ALIGN_RIGHT)) - { + } else if ((status_orientation == ALIGN_RIGHT) && + (message_orientation == ALIGN_RIGHT)) { map_x = 0; map_y = 0; map_height = (term_rows - border_space); status_width = 26; message_width = term_cols - (COLNO + status_width + (border_space * 3)); - map_width = term_cols - (status_width + message_width + (border_space * 3)); + map_width = + term_cols - (status_width + message_width + (border_space * 3)); message_x = map_x + (map_width + border_space); message_y = 0; message_height = (term_rows - border_space); status_x = message_x + (message_width + border_space); status_y = 0; status_height = (term_rows - border_space); - } - else if ((status_orientation == ALIGN_RIGHT) && - (message_orientation == ALIGN_BOTTOM)) - { + } else if ((status_orientation == ALIGN_RIGHT) && + (message_orientation == ALIGN_BOTTOM)) { map_x = 0; map_y = 0; status_width = 26; map_width = term_cols - (status_width + (border_space * 2)); message_height = term_rows - (ROWNO + (border_space * 2)); - if (message_height < min_message_height) - { + if (message_height < min_message_height) { message_height = min_message_height; } map_height = term_rows - (message_height + (border_space * 2)); @@ -373,10 +339,8 @@ void curses_create_main_windows() status_x = map_x + (map_width + border_space); status_y = 0; status_height = (term_rows - border_space); - } - else if ((status_orientation == ALIGN_RIGHT) && - (message_orientation == ALIGN_LEFT)) - { + } else if ((status_orientation == ALIGN_RIGHT) && + (message_orientation == ALIGN_LEFT)) { status_x = 0; status_y = 0; status_height = (term_rows - border_space); @@ -385,34 +349,33 @@ void curses_create_main_windows() map_x = status_x + (status_width + border_space); map_y = 0; map_height = (term_rows - border_space); - map_width = term_cols - (status_width + message_width + (border_space * 3)); + map_width = + term_cols - (status_width + message_width + (border_space * 3)); message_x = map_x + (map_width + border_space); message_y = 0; message_height = (term_rows - border_space); } if ((status_orientation == ALIGN_BOTTOM) && - (message_orientation == ALIGN_TOP)) - { + (message_orientation == ALIGN_TOP)) { message_x = 0; message_y = 0; message_width = (term_cols - border_space); status_height = 2; - message_height = term_rows - (status_height + ROWNO + (border_space * 3)); - if (message_height < min_message_height) - { + message_height = + term_rows - (status_height + ROWNO + (border_space * 3)); + if (message_height < min_message_height) { message_height = min_message_height; } map_x = 0; map_y = message_y + (message_height + border_space); map_width = (term_cols - border_space); - map_height = term_rows - (status_height + message_height + (border_space * 3)); + map_height = + term_rows - (status_height + message_height + (border_space * 3)); status_x = 0; status_y = map_y + (map_height + border_space); status_width = (term_cols - border_space); - } - else if ((status_orientation == ALIGN_BOTTOM) && - (message_orientation == ALIGN_RIGHT)) - { + } else if ((status_orientation == ALIGN_BOTTOM) && + (message_orientation == ALIGN_RIGHT)) { map_x = 0; map_y = 0; status_height = 2; @@ -425,30 +388,27 @@ void curses_create_main_windows() message_x = map_x + (map_width + border_space); message_y = 0; message_height = (term_rows - border_space); - } - else if ((status_orientation == ALIGN_BOTTOM) && - (message_orientation == ALIGN_BOTTOM)) - { + } else if ((status_orientation == ALIGN_BOTTOM) && + (message_orientation == ALIGN_BOTTOM)) { map_x = 0; map_y = 0; message_x = 0; status_x = 0; message_width = (term_cols - border_space); status_height = 2; - message_height = term_rows - (status_height + ROWNO + (border_space * 3)); - if (message_height < min_message_height) - { + message_height = + term_rows - (status_height + ROWNO + (border_space * 3)); + if (message_height < min_message_height) { message_height = min_message_height; } map_width = (term_cols - border_space); - map_height = term_rows - (status_height + message_height + (border_space * 3)); + map_height = + term_rows - (status_height + message_height + (border_space * 3)); message_y = map_y + (map_height + border_space); status_y = message_y + (message_height + border_space); status_width = (term_cols - border_space); - } - else if ((status_orientation == ALIGN_BOTTOM) && - (message_orientation == ALIGN_LEFT)) - { + } else if ((status_orientation == ALIGN_BOTTOM) && + (message_orientation == ALIGN_LEFT)) { message_x = 0; message_y = 0; message_height = (term_rows - border_space); @@ -463,8 +423,7 @@ void curses_create_main_windows() status_width = term_cols - (message_width + (border_space * 2)); } if ((status_orientation == ALIGN_LEFT) && - (message_orientation == ALIGN_TOP)) - { + (message_orientation == ALIGN_TOP)) { status_x = 0; status_y = 0; status_height = (term_rows - border_space); @@ -472,8 +431,7 @@ void curses_create_main_windows() message_x = status_x + (status_width + border_space); message_y = 0; message_height = term_rows - (ROWNO + (border_space * 2)); - if (message_height < min_message_height) - { + if (message_height < min_message_height) { message_height = min_message_height; } message_width = term_cols - (status_width + (border_space * 2)); @@ -481,10 +439,8 @@ void curses_create_main_windows() map_y = message_y + (message_height + border_space); map_height = term_rows - (message_height + (border_space * 2)); map_width = term_cols - (status_width + (border_space * 2)); - } - else if ((status_orientation == ALIGN_LEFT) && - (message_orientation == ALIGN_RIGHT)) - { + } else if ((status_orientation == ALIGN_LEFT) && + (message_orientation == ALIGN_RIGHT)) { message_x = 0; message_y = 0; message_height = (term_rows - border_space); @@ -493,14 +449,13 @@ void curses_create_main_windows() map_x = message_x + (message_width + border_space); map_y = 0; map_height = (term_rows - border_space); - map_width = term_cols - (status_width + message_width + (border_space * 3)); + map_width = + term_cols - (status_width + message_width + (border_space * 3)); status_x = map_x + (map_width + border_space); status_y = 0; status_height = (term_rows - border_space); - } - else if ((status_orientation == ALIGN_LEFT) && - (message_orientation == ALIGN_BOTTOM)) - { + } else if ((status_orientation == ALIGN_LEFT) && + (message_orientation == ALIGN_BOTTOM)) { status_x = 0; status_y = 0; status_height = (term_rows - border_space); @@ -508,8 +463,7 @@ void curses_create_main_windows() map_x = status_x + (status_width + border_space); map_y = 0; message_height = term_rows - (ROWNO + (border_space * 2)); - if (message_height < min_message_height) - { + if (message_height < min_message_height) { message_height = min_message_height; } map_height = term_rows - (message_height + (border_space * 2)); @@ -517,10 +471,8 @@ void curses_create_main_windows() message_x = status_x + (status_width + border_space); message_y = map_y + (map_height + border_space); message_width = map_width; - } - else if ((status_orientation == ALIGN_LEFT) && - (message_orientation == ALIGN_LEFT)) - { + } else if ((status_orientation == ALIGN_LEFT) && + (message_orientation == ALIGN_LEFT)) { status_x = 0; status_y = 0; status_height = (term_rows - border_space); @@ -532,21 +484,19 @@ void curses_create_main_windows() map_x = message_x + (message_width + border_space); map_y = 0; map_height = message_height; - map_width = term_cols - (status_width + message_width + (border_space * 3)); + map_width = + term_cols - (status_width + message_width + (border_space * 3)); } - - if (map_width > COLNO) - { + + if (map_width > COLNO) { map_width = COLNO; } - - if (map_height > ROWNO) - { + + if (map_height > ROWNO) { map_height = ROWNO; } - - if (curses_window_exists(STATUS_WIN)) - { + + if (curses_window_exists(STATUS_WIN)) { curses_del_nhwin(STATUS_WIN); curses_del_nhwin(MESSAGE_WIN); curses_del_nhwin(MAP_WIN); @@ -554,24 +504,20 @@ void curses_create_main_windows() } curses_add_nhwin(STATUS_WIN, status_height, status_width, status_y, - status_x, status_orientation, borders); + status_x, status_orientation, borders); curses_add_nhwin(MESSAGE_WIN, message_height, message_width, message_y, - message_x, message_orientation, borders); + message_x, message_orientation, borders); - curses_add_nhwin(MAP_WIN, map_height, map_width, map_y, map_x, 0, - borders); + curses_add_nhwin(MAP_WIN, map_height, map_width, map_y, map_x, 0, borders); refresh(); - + curses_refresh_nethack_windows(); - if (iflags.window_inited) - { + if (iflags.window_inited) { curses_update_stats(TRUE); - } - else - { + } else { iflags.window_inited = TRUE; } } @@ -579,11 +525,11 @@ void curses_create_main_windows() /* Initialize curses colors to colors used by NetHack */ -void curses_init_nhcolors() +void +curses_init_nhcolors() { #ifdef TEXTCOLOR - if (has_colors()) - { + if (has_colors()) { use_default_colors(); init_pair(1, COLOR_BLACK, -1); init_pair(2, COLOR_RED, -1); @@ -594,23 +540,25 @@ void curses_init_nhcolors() init_pair(7, COLOR_CYAN, -1); init_pair(8, -1, -1); - { - int i; - for (i = 0; i < 16; i++) { - int clr_remap[16] = { - COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE, - COLOR_MAGENTA, COLOR_CYAN, -1, COLOR_WHITE, - COLOR_RED+8, COLOR_GREEN+8, COLOR_YELLOW+8, COLOR_BLUE+8, - COLOR_MAGENTA+8, COLOR_CYAN+8, COLOR_WHITE+8 - }; - init_pair(17 + (i*2) + 0, clr_remap[i], COLOR_RED); - init_pair(17 + (i*2) + 1, clr_remap[i], COLOR_BLUE); - } - } - - - if (COLORS >= 16) { + int i; + + for (i = 0; i < 16; i++) { + int clr_remap[16] = { + COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, + COLOR_BLUE, + COLOR_MAGENTA, COLOR_CYAN, -1, COLOR_WHITE, + COLOR_RED + 8, COLOR_GREEN + 8, COLOR_YELLOW + 8, + COLOR_BLUE + 8, + COLOR_MAGENTA + 8, COLOR_CYAN + 8, COLOR_WHITE + 8 + }; + init_pair(17 + (i * 2) + 0, clr_remap[i], COLOR_RED); + init_pair(17 + (i * 2) + 1, clr_remap[i], COLOR_BLUE); + } + } + + + if (COLORS >= 16) { init_pair(9, COLOR_WHITE, -1); init_pair(10, COLOR_RED + 8, -1); init_pair(11, COLOR_GREEN + 8, -1); @@ -621,35 +569,33 @@ void curses_init_nhcolors() init_pair(16, COLOR_WHITE + 8, -1); } - if (can_change_color()) - { + if (can_change_color()) { /* Preserve initial terminal colors */ color_content(COLOR_YELLOW, &orig_yellow.r, &orig_yellow.g, - &orig_yellow.b); + &orig_yellow.b); color_content(COLOR_WHITE, &orig_white.r, &orig_white.g, - &orig_white.b); - + &orig_white.b); + /* Set colors to appear as NetHack expects */ init_color(COLOR_YELLOW, 500, 300, 0); init_color(COLOR_WHITE, 600, 600, 600); - if (COLORS >= 16) - { + if (COLORS >= 16) { /* Preserve initial terminal colors */ color_content(COLOR_RED + 8, &orig_hired.r, - &orig_hired.g, &orig_hired.b); + &orig_hired.g, &orig_hired.b); color_content(COLOR_GREEN + 8, &orig_higreen.r, - &orig_higreen.g, &orig_higreen.b); + &orig_higreen.g, &orig_higreen.b); color_content(COLOR_YELLOW + 8, &orig_hiyellow.r, - &orig_hiyellow.g, &orig_hiyellow.b); + &orig_hiyellow.g, &orig_hiyellow.b); color_content(COLOR_BLUE + 8, &orig_hiblue.r, - &orig_hiblue.g, &orig_hiblue.b); + &orig_hiblue.g, &orig_hiblue.b); color_content(COLOR_MAGENTA + 8, &orig_himagenta.r, - &orig_himagenta.g, &orig_himagenta.b); + &orig_himagenta.g, &orig_himagenta.b); color_content(COLOR_CYAN + 8, &orig_hicyan.r, - &orig_hicyan.g, &orig_hicyan.b); + &orig_hicyan.g, &orig_hicyan.b); color_content(COLOR_WHITE + 8, &orig_hiwhite.r, - &orig_hiwhite.g, &orig_hiwhite.b); - + &orig_hiwhite.g, &orig_hiwhite.b); + /* Set colors to appear as NetHack expects */ init_color(COLOR_RED + 8, 1000, 500, 0); init_color(COLOR_GREEN + 8, 0, 1000, 0); @@ -658,19 +604,16 @@ void curses_init_nhcolors() init_color(COLOR_MAGENTA + 8, 1000, 0, 1000); init_color(COLOR_CYAN + 8, 0, 1000, 1000); init_color(COLOR_WHITE + 8, 1000, 1000, 1000); -#ifdef USE_DARKGRAY - if (COLORS > 16) - { +# ifdef USE_DARKGRAY + if (COLORS > 16) { color_content(CURSES_DARK_GRAY, &orig_darkgray.r, - &orig_darkgray.g, &orig_darkgray.b); + &orig_darkgray.g, &orig_darkgray.b); init_color(CURSES_DARK_GRAY, 300, 300, 300); /* just override black colorpair entry here */ init_pair(1, CURSES_DARK_GRAY, -1); } -#endif - } - else - { +# endif + } else { /* Set flag to use bold for bright colors */ } } @@ -682,195 +625,199 @@ void curses_init_nhcolors() /* Allow player to pick character's role, race, gender, and alignment. Borrowed from the Gnome window port. */ -void curses_choose_character() +void +curses_choose_character() { int n, i, sel, count_off, pick4u; int count = 0; int cur_character = 0; - const char** choices; - int* pickmap; + const char **choices; + int *pickmap; char *prompt; char pbuf[QBUFSZ]; char choice[QBUFSZ]; char tmpchoice[QBUFSZ]; + #ifdef TUTORIAL_MODE - winid win; - anything any; - menu_item *selected = 0; + winid win; + anything any; + menu_item *selected = 0; #endif - prompt = build_plselection_prompt(pbuf, QBUFSZ, flags.initrole, - flags.initrace, flags.initgend, flags.initalign); + prompt = build_plselection_prompt(pbuf, QBUFSZ, flags.initrole, + flags.initrace, flags.initgend, + flags.initalign); /* This part is irritating: we have to strip the choices off of - the string and put them in a separate string in order to use - curses_character_input_dialog for this prompt. */ + the string and put them in a separate string in order to use + curses_character_input_dialog for this prompt. */ - while (cur_character != '[') - { + while (cur_character != '[') { cur_character = prompt[count]; count++; } - + count_off = count; - - while (cur_character != ']') - { + + while (cur_character != ']') { tmpchoice[count - count_off] = prompt[count]; count++; cur_character = prompt[count]; } - + tmpchoice[count - count_off] = '\0'; lcase(tmpchoice); - - while (!isspace(prompt[count_off])) - { + + while (!isspace(prompt[count_off])) { count_off--; } - + prompt[count_off] = '\0'; sprintf(choice, "%s%c", tmpchoice, '\033'); - if(strchr(tmpchoice, 't')) /* Tutorial mode */ - { + if (strchr(tmpchoice, 't')) { /* Tutorial mode */ mvaddstr(0, 1, "New? Press t to enter a tutorial."); } - + /* Add capital letters as choices that aren't displayed */ - - for (count = 0; tmpchoice[count]; count++) - { + + for (count = 0; tmpchoice[count]; count++) { tmpchoice[count] = toupper(tmpchoice[count]); } - + sprintf(choice, "%s%s", choice, tmpchoice); /* prevent an unnecessary prompt */ - rigid_role_checks(); - - if (!flags.randomall && - (flags.initrole == ROLE_NONE || flags.initrace == ROLE_NONE || - flags.initgend == ROLE_NONE || flags.initalign == ROLE_NONE)) - { - pick4u = tolower(curses_character_input_dialog(prompt, choice, - 'y')); - } - else - { + rigid_role_checks(); + + if (!flags.randomall && + (flags.initrole == ROLE_NONE || flags.initrace == ROLE_NONE || + flags.initgend == ROLE_NONE || flags.initalign == ROLE_NONE)) { + pick4u = tolower(curses_character_input_dialog(prompt, choice, 'y')); + } else { pick4u = 'y'; } - - if (pick4u == 'q') /* Quit or cancelled */ - { - clearlocks(); - curses_bail(0); + + if (pick4u == 'q') { /* Quit or cancelled */ + clearlocks(); + curses_bail(0); } - - if (pick4u == 'y') - { + + if (pick4u == 'y') { flags.randomall = TRUE; } #ifdef TUTORIAL_MODE - else if (pick4u == 't') /* Tutorial mode in UnNetHack */ - { - clear(); + else if (pick4u == 't') { /* Tutorial mode in UnNetHack */ + clear(); mvaddstr(0, 1, "Choose a character"); refresh(); - win = curses_get_wid(NHW_MENU); + win = curses_get_wid(NHW_MENU); curses_create_nhmenu(win); - any.a_int = 1; - curses_add_menu(win, NO_GLYPH, &any, 'v', 0, ATR_NONE, - "lawful female dwarf Valkyrie (uses melee and thrown weapons)", - MENU_UNSELECTED); - any.a_int = 2; - curses_add_menu(win, NO_GLYPH, &any, 'w', 0, ATR_NONE, - "chaotic male elf Wizard (relies mostly on spells)", - MENU_UNSELECTED); - any.a_int = 3; - curses_add_menu(win, NO_GLYPH, &any, 'R', 0, ATR_NONE, - "neutral female human Ranger (good with ranged combat)", - MENU_UNSELECTED); - any.a_int = 4; - curses_add_menu(win, NO_GLYPH, &any, 'q', 0, ATR_NONE, - "quit", MENU_UNSELECTED); - curses_end_menu(win, "What character do you want to try?"); - n = curses_select_menu(win, PICK_ONE, &selected); - destroy_nhwindow(win); - if (n != 1 || selected[0].item.a_int == 4) - { - clearlocks(); - curses_bail(0); - } - switch (selected[0].item.a_int) { - case 1: - flags.initrole = str2role("Valkyrie"); - flags.initrace = str2race("dwarf"); - flags.initgend = str2gend("female"); - flags.initalign = str2align("lawful"); - break; - case 2: - flags.initrole = str2role("Wizard"); - flags.initrace = str2race("elf"); - flags.initgend = str2gend("male"); - flags.initalign = str2align("chaotic"); - break; - case 3: - flags.initrole = str2role("Ranger"); - flags.initrace = str2race("human"); - flags.initgend = str2gend("female"); - flags.initalign = str2align("neutral"); - break; - default: panic("Impossible menu selection"); break; - } - free((genericptr_t) selected); - selected = 0; - flags.tutorial = 1; - } + any.a_int = 1; + curses_add_menu(win, NO_GLYPH, &any, 'v', 0, ATR_NONE, + "lawful female dwarf Valkyrie (uses melee and thrown weapons)", + MENU_UNSELECTED); + any.a_int = 2; + curses_add_menu(win, NO_GLYPH, &any, 'w', 0, ATR_NONE, + "chaotic male elf Wizard (relies mostly on spells)", + MENU_UNSELECTED); + any.a_int = 3; + curses_add_menu(win, NO_GLYPH, &any, 'R', 0, ATR_NONE, + "neutral female human Ranger (good with ranged combat)", + MENU_UNSELECTED); + any.a_int = 4; + curses_add_menu(win, NO_GLYPH, &any, 'q', 0, ATR_NONE, + "quit", MENU_UNSELECTED); + curses_end_menu(win, "What character do you want to try?"); + n = curses_select_menu(win, PICK_ONE, &selected); + destroy_nhwindow(win); + if (n != 1 || selected[0].item.a_int == 4) { + clearlocks(); + curses_bail(0); + } + switch (selected[0].item.a_int) { + case 1: + flags.initrole = str2role("Valkyrie"); + flags.initrace = str2race("dwarf"); + flags.initgend = str2gend("female"); + flags.initalign = str2align("lawful"); + break; + case 2: + flags.initrole = str2role("Wizard"); + flags.initrace = str2race("elf"); + flags.initgend = str2gend("male"); + flags.initalign = str2align("chaotic"); + break; + case 3: + flags.initrole = str2role("Ranger"); + flags.initrace = str2race("human"); + flags.initgend = str2gend("female"); + flags.initalign = str2align("neutral"); + break; + default: + panic("Impossible menu selection"); + break; + } + free((genericptr_t) selected); + selected = 0; + flags.tutorial = 1; + } #endif - + clear(); refresh(); if (!flags.randomall && flags.initrole < 0) { - /* select a role */ - for (n = 0; roles[n].name.m; n++) continue; - choices = (const char **)alloc(sizeof(char *) * (n+1)); - pickmap = (int*)alloc(sizeof(int) * (n+1)); - for (;;) { - for (n = 0, i = 0; roles[i].name.m; i++) { - if (ok_role(i, flags.initrace, - flags.initgend, flags.initalign)) { - if (flags.initgend >= 0 && flags.female && roles[i].name.f) - choices[n] = roles[i].name.f; - else - choices[n] = roles[i].name.m; - pickmap[n++] = i; - } - } - if (n > 0) break; - else if (flags.initalign >= 0) flags.initalign = -1; /* reset */ - else if (flags.initgend >= 0) flags.initgend = -1; - else if (flags.initrace >= 0) flags.initrace = -1; - else panic("no available ROLE+race+gender+alignment combinations"); - } - choices[n] = (const char *) 0; - if (n > 1) - sel = curses_character_dialog(choices, "Choose one of the following roles:"); - else sel = 0; - if (sel >= 0) sel = pickmap[sel]; - else if (sel == ROLE_NONE) { /* Quit */ - clearlocks(); - curses_bail(0); - } - free(choices); - free(pickmap); - } else if (flags.initrole < 0) sel = ROLE_RANDOM; - else sel = flags.initrole; - - if (sel == ROLE_RANDOM) { /* Random role */ - sel = pick_role(flags.initrace, flags.initgend, - flags.initalign, PICK_RANDOM); - if (sel < 0) sel = randrole(); + /* select a role */ + for (n = 0; roles[n].name.m; n++) + continue; + choices = (const char **) alloc(sizeof (char *) * (n + 1)); + pickmap = (int *) alloc(sizeof (int) * (n + 1)); + for (;;) { + for (n = 0, i = 0; roles[i].name.m; i++) { + if (ok_role(i, flags.initrace, flags.initgend, flags.initalign)) { + if (flags.initgend >= 0 && flags.female && roles[i].name.f) + choices[n] = roles[i].name.f; + else + choices[n] = roles[i].name.m; + pickmap[n++] = i; + } + } + if (n > 0) + break; + else if (flags.initalign >= 0) + flags.initalign = -1; /* reset */ + else if (flags.initgend >= 0) + flags.initgend = -1; + else if (flags.initrace >= 0) + flags.initrace = -1; + else + panic("no available ROLE+race+gender+alignment combinations"); + } + choices[n] = (const char *) 0; + if (n > 1) + sel = + curses_character_dialog(choices, + "Choose one of the following roles:"); + else + sel = 0; + if (sel >= 0) + sel = pickmap[sel]; + else if (sel == ROLE_NONE) { /* Quit */ + clearlocks(); + curses_bail(0); + } + free(choices); + free(pickmap); + } else if (flags.initrole < 0) + sel = ROLE_RANDOM; + else + sel = flags.initrole; + + if (sel == ROLE_RANDOM) { /* Random role */ + sel = pick_role(flags.initrace, flags.initgend, + flags.initalign, PICK_RANDOM); + if (sel < 0) + sel = randrole(); } flags.initrole = sel; @@ -879,165 +826,182 @@ void curses_choose_character() /* force compatibility with role, try for compatibility with * pre-selected gender/alignment */ if (flags.initrace < 0 || !validrace(flags.initrole, flags.initrace)) { - if (flags.initrace == ROLE_RANDOM || flags.randomall) { - flags.initrace = pick_race(flags.initrole, flags.initgend, - flags.initalign, PICK_RANDOM); - if (flags.initrace < 0) flags.initrace = randrace(flags.initrole); - } else { - /* Count the number of valid races */ - n = 0; /* number valid */ - for (i = 0; races[i].noun; i++) { - if (ok_race(flags.initrole, i, flags.initgend, flags.initalign)) - n++; - } - if (n == 0) { - for (i = 0; races[i].noun; i++) { - if (validrace(flags.initrole, i)) n++; - } - } - - choices = (const char **)alloc(sizeof(char *) * (n+1)); - pickmap = (int*)alloc(sizeof(int) * (n + 1)); - for (n = 0, i = 0; races[i].noun; i++) { - if (ok_race(flags.initrole, i, flags.initgend, - flags.initalign)) { - choices[n] = races[i].noun; - pickmap[n++] = i; - } - } - choices[n] = (const char *) 0; - /* Permit the user to pick, if there is more than one */ - if (n > 1) - sel = curses_character_dialog(choices, "Choose one of the following races:"); - else sel = 0; - if (sel >= 0) sel = pickmap[sel]; - else if (sel == ROLE_NONE) { /* Quit */ - clearlocks(); - curses_bail(0); - } - flags.initrace = sel; - free(choices); - free(pickmap); - } - if (flags.initrace == ROLE_RANDOM) { /* Random role */ - sel = pick_race(flags.initrole, flags.initgend, - flags.initalign, PICK_RANDOM); - if (sel < 0) sel = randrace(flags.initrole); - flags.initrace = sel; - } + if (flags.initrace == ROLE_RANDOM || flags.randomall) { + flags.initrace = pick_race(flags.initrole, flags.initgend, + flags.initalign, PICK_RANDOM); + if (flags.initrace < 0) + flags.initrace = randrace(flags.initrole); + } else { + /* Count the number of valid races */ + n = 0; /* number valid */ + for (i = 0; races[i].noun; i++) { + if (ok_race(flags.initrole, i, flags.initgend, flags.initalign)) + n++; + } + if (n == 0) { + for (i = 0; races[i].noun; i++) { + if (validrace(flags.initrole, i)) + n++; + } + } + + choices = (const char **) alloc(sizeof (char *) * (n + 1)); + pickmap = (int *) alloc(sizeof (int) * (n + 1)); + for (n = 0, i = 0; races[i].noun; i++) { + if (ok_race(flags.initrole, i, flags.initgend, flags.initalign)) { + choices[n] = races[i].noun; + pickmap[n++] = i; + } + } + choices[n] = (const char *) 0; + /* Permit the user to pick, if there is more than one */ + if (n > 1) + sel = + curses_character_dialog(choices, + "Choose one of the following races:"); + else + sel = 0; + if (sel >= 0) + sel = pickmap[sel]; + else if (sel == ROLE_NONE) { /* Quit */ + clearlocks(); + curses_bail(0); + } + flags.initrace = sel; + free(choices); + free(pickmap); + } + if (flags.initrace == ROLE_RANDOM) { /* Random role */ + sel = pick_race(flags.initrole, flags.initgend, + flags.initalign, PICK_RANDOM); + if (sel < 0) + sel = randrace(flags.initrole); + flags.initrace = sel; + } } /* Select a gender, if necessary */ /* force compatibility with role/race, try for compatibility with * pre-selected alignment */ if (flags.initgend < 0 || - !validgend(flags.initrole, flags.initrace, flags.initgend)) { - if (flags.initgend == ROLE_RANDOM || flags.randomall) { - flags.initgend = pick_gend(flags.initrole, flags.initrace, - flags.initalign, PICK_RANDOM); - if (flags.initgend < 0) - flags.initgend = randgend(flags.initrole, flags.initrace); - } else { - /* Count the number of valid genders */ - n = 0; /* number valid */ - for (i = 0; i < ROLE_GENDERS; i++) { - if (ok_gend(flags.initrole, flags.initrace, i, flags.initalign)) - n++; - } - if (n == 0) { - for (i = 0; i < ROLE_GENDERS; i++) { - if (validgend(flags.initrole, flags.initrace, i)) n++; - } - } - - choices = (const char **)alloc(sizeof(char *) * (n+1)); - pickmap = (int*)alloc(sizeof(int) * (n + 1)); - for (n = 0, i = 0; i < ROLE_GENDERS; i++) { - if (ok_gend(flags.initrole, flags.initrace, i, - flags.initalign)) { - choices[n] = genders[i].adj; - pickmap[n++] = i; - } - } - choices[n] = (const char *) 0; - /* Permit the user to pick, if there is more than one */ - if (n > 1) - sel = curses_character_dialog(choices, "Choose one of the following genders:"); - else sel = 0; - if (sel >= 0) sel = pickmap[sel]; - else if (sel == ROLE_NONE) { /* Quit */ - clearlocks(); - curses_bail(0); - } - flags.initgend = sel; - free(choices); - free(pickmap); - } - if (flags.initgend == ROLE_RANDOM) { /* Random gender */ - sel = pick_gend(flags.initrole, flags.initrace, - flags.initalign, PICK_RANDOM); - if (sel < 0) sel = randgend(flags.initrole, flags.initrace); - flags.initgend = sel; - } + !validgend(flags.initrole, flags.initrace, flags.initgend)) { + if (flags.initgend == ROLE_RANDOM || flags.randomall) { + flags.initgend = pick_gend(flags.initrole, flags.initrace, + flags.initalign, PICK_RANDOM); + if (flags.initgend < 0) + flags.initgend = randgend(flags.initrole, flags.initrace); + } else { + /* Count the number of valid genders */ + n = 0; /* number valid */ + for (i = 0; i < ROLE_GENDERS; i++) { + if (ok_gend(flags.initrole, flags.initrace, i, flags.initalign)) + n++; + } + if (n == 0) { + for (i = 0; i < ROLE_GENDERS; i++) { + if (validgend(flags.initrole, flags.initrace, i)) + n++; + } + } + + choices = (const char **) alloc(sizeof (char *) * (n + 1)); + pickmap = (int *) alloc(sizeof (int) * (n + 1)); + for (n = 0, i = 0; i < ROLE_GENDERS; i++) { + if (ok_gend(flags.initrole, flags.initrace, i, flags.initalign)) { + choices[n] = genders[i].adj; + pickmap[n++] = i; + } + } + choices[n] = (const char *) 0; + /* Permit the user to pick, if there is more than one */ + if (n > 1) + sel = + curses_character_dialog(choices, + "Choose one of the following genders:"); + else + sel = 0; + if (sel >= 0) + sel = pickmap[sel]; + else if (sel == ROLE_NONE) { /* Quit */ + clearlocks(); + curses_bail(0); + } + flags.initgend = sel; + free(choices); + free(pickmap); + } + if (flags.initgend == ROLE_RANDOM) { /* Random gender */ + sel = pick_gend(flags.initrole, flags.initrace, + flags.initalign, PICK_RANDOM); + if (sel < 0) + sel = randgend(flags.initrole, flags.initrace); + flags.initgend = sel; + } } /* Select an alignment, if necessary */ /* force compatibility with role/race/gender */ if (flags.initalign < 0 || - !validalign(flags.initrole, flags.initrace, flags.initalign)) { - if (flags.initalign == ROLE_RANDOM || flags.randomall) { - flags.initalign = pick_align(flags.initrole, flags.initrace, - flags.initgend, PICK_RANDOM); - if (flags.initalign < 0) - flags.initalign = randalign(flags.initrole, flags.initrace); - } else { - /* Count the number of valid alignments */ - n = 0; /* number valid */ - for (i = 0; i < ROLE_ALIGNS; i++) { - if (ok_align(flags.initrole, flags.initrace, flags.initgend, i)) - n++; - } - if (n == 0) { - for (i = 0; i < ROLE_ALIGNS; i++) - if (validalign(flags.initrole, flags.initrace, i)) n++; - } - - choices = (const char **)alloc(sizeof(char *) * (n+1)); - pickmap = (int*)alloc(sizeof(int) * (n + 1)); - for (n = 0, i = 0; i < ROLE_ALIGNS; i++) { - if (ok_align(flags.initrole, - flags.initrace, flags.initgend, i)) { - choices[n] = aligns[i].adj; - pickmap[n++] = i; - } - } - choices[n] = (const char *) 0; - /* Permit the user to pick, if there is more than one */ - if (n > 1) - sel = curses_character_dialog(choices, "Choose one of the following alignments:"); - else sel = 0; - if (sel >= 0) sel = pickmap[sel]; - else if (sel == ROLE_NONE) { /* Quit */ - clearlocks(); - curses_bail(0); - } - flags.initalign = sel; - free(choices); - free(pickmap); - } - if (flags.initalign == ROLE_RANDOM) { - sel = pick_align(flags.initrole, flags.initrace, - flags.initgend, PICK_RANDOM); - if (sel < 0) sel = randalign(flags.initrole, flags.initrace); - flags.initalign = sel; - } + !validalign(flags.initrole, flags.initrace, flags.initalign)) { + if (flags.initalign == ROLE_RANDOM || flags.randomall) { + flags.initalign = pick_align(flags.initrole, flags.initrace, + flags.initgend, PICK_RANDOM); + if (flags.initalign < 0) + flags.initalign = randalign(flags.initrole, flags.initrace); + } else { + /* Count the number of valid alignments */ + n = 0; /* number valid */ + for (i = 0; i < ROLE_ALIGNS; i++) { + if (ok_align(flags.initrole, flags.initrace, flags.initgend, i)) + n++; + } + if (n == 0) { + for (i = 0; i < ROLE_ALIGNS; i++) + if (validalign(flags.initrole, flags.initrace, i)) + n++; + } + + choices = (const char **) alloc(sizeof (char *) * (n + 1)); + pickmap = (int *) alloc(sizeof (int) * (n + 1)); + for (n = 0, i = 0; i < ROLE_ALIGNS; i++) { + if (ok_align(flags.initrole, flags.initrace, flags.initgend, i)) { + choices[n] = aligns[i].adj; + pickmap[n++] = i; + } + } + choices[n] = (const char *) 0; + /* Permit the user to pick, if there is more than one */ + if (n > 1) + sel = + curses_character_dialog(choices, + "Choose one of the following alignments:"); + else + sel = 0; + if (sel >= 0) + sel = pickmap[sel]; + else if (sel == ROLE_NONE) { /* Quit */ + clearlocks(); + curses_bail(0); + } + flags.initalign = sel; + free(choices); + free(pickmap); + } + if (flags.initalign == ROLE_RANDOM) { + sel = pick_align(flags.initrole, flags.initrace, + flags.initgend, PICK_RANDOM); + if (sel < 0) + sel = randalign(flags.initrole, flags.initrace); + flags.initalign = sel; + } } } /* Prompt user for character race, role, alignment, or gender */ -int curses_character_dialog(const char** choices, const char *prompt) +int +curses_character_dialog(const char **choices, const char *prompt) { int count, count2, ret, curletter; char used_letters[52]; @@ -1048,48 +1012,42 @@ int curses_character_dialog(const char** choices, const char *prompt) identifier.a_void = 0; curses_start_menu(wid); - for (count=0; choices[count]; count++) - { - curletter=tolower(choices[count][0]); - for (count2=0; count2item.a_int); - } - else /* Cancelled selection */ - { + } else { /* Cancelled selection */ + ret = ROLE_NONE; } - - if (ret > 0) - { + + if (ret > 0) { ret--; } - + free(selected); return ret; } @@ -1097,10 +1055,11 @@ int curses_character_dialog(const char** choices, const char *prompt) /* Initialize and display options appropriately */ -void curses_init_options() +void +curses_init_options() { - set_wc_option_mod_status(WC_ALIGN_MESSAGE|WC_ALIGN_STATUS|WC_COLOR| - WC_HILITE_PET|WC_POPUP_DIALOG, SET_IN_GAME); + set_wc_option_mod_status(WC_ALIGN_MESSAGE | WC_ALIGN_STATUS | WC_COLOR | + WC_HILITE_PET | WC_POPUP_DIALOG, SET_IN_GAME); set_wc2_option_mod_status(WC2_GUICOLOR, SET_IN_GAME); @@ -1110,64 +1069,51 @@ void curses_init_options() set_option_mod_status("eight_bit_tty", SET_IN_FILE); /* Make sure that DECgraphics is not set to true via the config - file, as this will cause display issues. We can't disable it in - options.c in case the game is compiled with both tty and curses.*/ - if (iflags.DECgraphics) - { + file, as this will cause display issues. We can't disable it in + options.c in case the game is compiled with both tty and curses. */ + if (iflags.DECgraphics) { switch_graphics(CURS_GRAPHICS); } - #ifdef PDCURSES /* PDCurses for SDL, win32 and OS/2 has the ability to set the - terminal size programatically. If the user does not specify a - size in the config file, we will set it to a nice big 110x32 to - take advantage of some of the nice features of this windowport. */ - if (iflags.wc2_term_cols == 0) - { + terminal size programatically. If the user does not specify a + size in the config file, we will set it to a nice big 110x32 to + take advantage of some of the nice features of this windowport. */ + if (iflags.wc2_term_cols == 0) { iflags.wc2_term_cols = 110; } - - if (iflags.wc2_term_rows == 0) - { + + if (iflags.wc2_term_rows == 0) { iflags.wc2_term_rows = 32; } - + resize_term(iflags.wc2_term_rows, iflags.wc2_term_cols); getmaxyx(base_term, term_rows, term_cols); - + /* This is needed for an odd bug with PDCurses-SDL */ switch_graphics(ASCII_GRAPHICS); - if (iflags.IBMgraphics) - { + if (iflags.IBMgraphics) { switch_graphics(IBM_GRAPHICS); - } - else if (iflags.cursesgraphics) - { + } else if (iflags.cursesgraphics) { switch_graphics(CURS_GRAPHICS); - } - else - { + } else { switch_graphics(ASCII_GRAPHICS); } -#endif /* PDCURSES */ - if (!iflags.wc2_windowborders) - { - iflags.wc2_windowborders = 3; /* Set to auto if not specified */ +#endif /* PDCURSES */ + if (!iflags.wc2_windowborders) { + iflags.wc2_windowborders = 3; /* Set to auto if not specified */ } - - if (!iflags.wc2_petattr) - { + + if (!iflags.wc2_petattr) { iflags.wc2_petattr = A_REVERSE; - } - else /* Pet attribute specified, so hilite_pet should be true */ - { + } else { /* Pet attribute specified, so hilite_pet should be true */ + iflags.hilite_pet = TRUE; } #ifdef NCURSES_MOUSE_VERSION - if (iflags.wc_mouse_support) - { - mousemask(BUTTON1_CLICKED, NULL); + if (iflags.wc_mouse_support) { + mousemask(BUTTON1_CLICKED, NULL); } #endif } @@ -1175,123 +1121,102 @@ void curses_init_options() /* Display an ASCII splash screen if the splash_screen option is set */ -void curses_display_splash_window() +void +curses_display_splash_window() { int x_start = 1; int y_start = 6; - int which_variant = NETHACK_CURSES; /* Default to NetHack */ + int which_variant = NETHACK_CURSES; /* Default to NetHack */ - if ((term_cols < 70) || (term_rows < 20)) - { - iflags.wc_splash_screen = FALSE; /* No room for s.s. */ + if ((term_cols < 70) || (term_rows < 20)) { + iflags.wc_splash_screen = FALSE; /* No room for s.s. */ } - #ifdef DEF_GAME_NAME - if (strcmp(DEF_GAME_NAME, "SlashEM") == 0) - { + if (strcmp(DEF_GAME_NAME, "SlashEM") == 0) { which_variant = SLASHEM_CURSES; } #endif #ifdef GAME_SHORT_NAME - if (strcmp(GAME_SHORT_NAME, "UNH") == 0) - { + if (strcmp(GAME_SHORT_NAME, "UNH") == 0) { which_variant = UNNETHACK_CURSES; } #endif - if (strncmp("SporkHack", COPYRIGHT_BANNER_A, 9) == 0) - { + if (strncmp("SporkHack", COPYRIGHT_BANNER_A, 9) == 0) { which_variant = SPORKHACK_CURSES; } - if (strncmp("GruntHack", COPYRIGHT_BANNER_A, 9) == 0) - { + if (strncmp("GruntHack", COPYRIGHT_BANNER_A, 9) == 0) { which_variant = GRUNTHACK_CURSES; } - if (strncmp("dNethack", COPYRIGHT_BANNER_A, 8) == 0) - { + if (strncmp("dNethack", COPYRIGHT_BANNER_A, 8) == 0) { which_variant = DNETHACK_CURSES; } curses_toggle_color_attr(stdscr, CLR_WHITE, A_NORMAL, ON); - if (iflags.wc_splash_screen) - { - switch (which_variant) - { - case NETHACK_CURSES: - { - mvaddstr(y_start, x_start, NETHACK_SPLASH_A); - mvaddstr(y_start + 1, x_start, NETHACK_SPLASH_B); - mvaddstr(y_start + 2, x_start, NETHACK_SPLASH_C); - mvaddstr(y_start + 3, x_start, NETHACK_SPLASH_D); - mvaddstr(y_start + 4, x_start, NETHACK_SPLASH_E); - mvaddstr(y_start + 5, x_start, NETHACK_SPLASH_F); - y_start += 7; - break; - } - case SLASHEM_CURSES: - { - mvaddstr(y_start, x_start, SLASHEM_SPLASH_A); - mvaddstr(y_start + 1, x_start, SLASHEM_SPLASH_B); - mvaddstr(y_start + 2, x_start, SLASHEM_SPLASH_C); - mvaddstr(y_start + 3, x_start, SLASHEM_SPLASH_D); - mvaddstr(y_start + 4, x_start, SLASHEM_SPLASH_E); - mvaddstr(y_start + 5, x_start, SLASHEM_SPLASH_F); - y_start += 7; - break; - } - case UNNETHACK_CURSES: - { - mvaddstr(y_start, x_start, UNNETHACK_SPLASH_A); - mvaddstr(y_start + 1, x_start, UNNETHACK_SPLASH_B); - mvaddstr(y_start + 2, x_start, UNNETHACK_SPLASH_C); - mvaddstr(y_start + 3, x_start, UNNETHACK_SPLASH_D); - mvaddstr(y_start + 4, x_start, UNNETHACK_SPLASH_E); - mvaddstr(y_start + 5, x_start, UNNETHACK_SPLASH_F); - y_start += 7; - break; - } - case SPORKHACK_CURSES: - mvaddstr(y_start, x_start, SPORKHACK_SPLASH_A); - mvaddstr(y_start + 1, x_start, SPORKHACK_SPLASH_B); - mvaddstr(y_start + 2, x_start, SPORKHACK_SPLASH_C); - mvaddstr(y_start + 3, x_start, SPORKHACK_SPLASH_D); - mvaddstr(y_start + 4, x_start, SPORKHACK_SPLASH_E); - mvaddstr(y_start + 5, x_start, SPORKHACK_SPLASH_F); - mvaddstr(y_start + 6, x_start, SPORKHACK_SPLASH_G); - mvaddstr(y_start + 7, x_start, SPORKHACK_SPLASH_H); - y_start += 9; - break; - case GRUNTHACK_CURSES: - { - mvaddstr(y_start, x_start, GRUNTHACK_SPLASH_A); - mvaddstr(y_start + 1, x_start, GRUNTHACK_SPLASH_B); - mvaddstr(y_start + 2, x_start, GRUNTHACK_SPLASH_C); - mvaddstr(y_start + 3, x_start, GRUNTHACK_SPLASH_D); - mvaddstr(y_start + 4, x_start, GRUNTHACK_SPLASH_E); - mvaddstr(y_start + 5, x_start, GRUNTHACK_SPLASH_F); - y_start += 7; - break; - } - case DNETHACK_CURSES: - { - mvaddstr(y_start, x_start, DNETHACK_SPLASH_A); - mvaddstr(y_start + 1, x_start, DNETHACK_SPLASH_B); - mvaddstr(y_start + 2, x_start, DNETHACK_SPLASH_C); - mvaddstr(y_start + 3, x_start, DNETHACK_SPLASH_D); - mvaddstr(y_start + 4, x_start, DNETHACK_SPLASH_E); - mvaddstr(y_start + 5, x_start, DNETHACK_SPLASH_F); - y_start += 7; - break; - } - default: - { - impossible("which_variant number %d out of range", - which_variant); - } + if (iflags.wc_splash_screen) { + switch (which_variant) { + case NETHACK_CURSES: + mvaddstr(y_start, x_start, NETHACK_SPLASH_A); + mvaddstr(y_start + 1, x_start, NETHACK_SPLASH_B); + mvaddstr(y_start + 2, x_start, NETHACK_SPLASH_C); + mvaddstr(y_start + 3, x_start, NETHACK_SPLASH_D); + mvaddstr(y_start + 4, x_start, NETHACK_SPLASH_E); + mvaddstr(y_start + 5, x_start, NETHACK_SPLASH_F); + y_start += 7; + break; + case SLASHEM_CURSES: + mvaddstr(y_start, x_start, SLASHEM_SPLASH_A); + mvaddstr(y_start + 1, x_start, SLASHEM_SPLASH_B); + mvaddstr(y_start + 2, x_start, SLASHEM_SPLASH_C); + mvaddstr(y_start + 3, x_start, SLASHEM_SPLASH_D); + mvaddstr(y_start + 4, x_start, SLASHEM_SPLASH_E); + mvaddstr(y_start + 5, x_start, SLASHEM_SPLASH_F); + y_start += 7; + break; + case UNNETHACK_CURSES: + mvaddstr(y_start, x_start, UNNETHACK_SPLASH_A); + mvaddstr(y_start + 1, x_start, UNNETHACK_SPLASH_B); + mvaddstr(y_start + 2, x_start, UNNETHACK_SPLASH_C); + mvaddstr(y_start + 3, x_start, UNNETHACK_SPLASH_D); + mvaddstr(y_start + 4, x_start, UNNETHACK_SPLASH_E); + mvaddstr(y_start + 5, x_start, UNNETHACK_SPLASH_F); + y_start += 7; + break; + case SPORKHACK_CURSES: + mvaddstr(y_start, x_start, SPORKHACK_SPLASH_A); + mvaddstr(y_start + 1, x_start, SPORKHACK_SPLASH_B); + mvaddstr(y_start + 2, x_start, SPORKHACK_SPLASH_C); + mvaddstr(y_start + 3, x_start, SPORKHACK_SPLASH_D); + mvaddstr(y_start + 4, x_start, SPORKHACK_SPLASH_E); + mvaddstr(y_start + 5, x_start, SPORKHACK_SPLASH_F); + mvaddstr(y_start + 6, x_start, SPORKHACK_SPLASH_G); + mvaddstr(y_start + 7, x_start, SPORKHACK_SPLASH_H); + y_start += 9; + break; + case GRUNTHACK_CURSES: + mvaddstr(y_start, x_start, GRUNTHACK_SPLASH_A); + mvaddstr(y_start + 1, x_start, GRUNTHACK_SPLASH_B); + mvaddstr(y_start + 2, x_start, GRUNTHACK_SPLASH_C); + mvaddstr(y_start + 3, x_start, GRUNTHACK_SPLASH_D); + mvaddstr(y_start + 4, x_start, GRUNTHACK_SPLASH_E); + mvaddstr(y_start + 5, x_start, GRUNTHACK_SPLASH_F); + y_start += 7; + break; + case DNETHACK_CURSES: + mvaddstr(y_start, x_start, DNETHACK_SPLASH_A); + mvaddstr(y_start + 1, x_start, DNETHACK_SPLASH_B); + mvaddstr(y_start + 2, x_start, DNETHACK_SPLASH_C); + mvaddstr(y_start + 3, x_start, DNETHACK_SPLASH_D); + mvaddstr(y_start + 4, x_start, DNETHACK_SPLASH_E); + mvaddstr(y_start + 5, x_start, DNETHACK_SPLASH_F); + y_start += 7; + break; + default: + impossible("which_variant number %d out of range", which_variant); } } @@ -1312,7 +1237,7 @@ void curses_display_splash_window() y_start++; #endif -#ifdef COPYRIGHT_BANNER_D /* Just in case */ +#ifdef COPYRIGHT_BANNER_D /* Just in case */ mvaddstr(y_start, x_start, COPYRIGHT_BANNER_D); y_start++; #endif @@ -1322,41 +1247,35 @@ void curses_display_splash_window() /* Resore colors and cursor state before exiting */ -void curses_cleanup() +void +curses_cleanup() { #ifdef TEXTCOLOR - if (has_colors() && can_change_color()) - { - init_color(COLOR_YELLOW, orig_yellow.r, orig_yellow.g, - orig_yellow.b); - init_color(COLOR_WHITE, orig_white.r, orig_white.g, - orig_white.b); - - if (COLORS >= 16) - { - init_color(COLOR_RED + 8, orig_hired.r, orig_hired.g, - orig_hired.b); + if (has_colors() && can_change_color()) { + init_color(COLOR_YELLOW, orig_yellow.r, orig_yellow.g, orig_yellow.b); + init_color(COLOR_WHITE, orig_white.r, orig_white.g, orig_white.b); + + if (COLORS >= 16) { + init_color(COLOR_RED + 8, orig_hired.r, orig_hired.g, orig_hired.b); init_color(COLOR_GREEN + 8, orig_higreen.r, orig_higreen.g, - orig_higreen.b); + orig_higreen.b); init_color(COLOR_YELLOW + 8, orig_hiyellow.r, - orig_hiyellow.g, orig_hiyellow.b); + orig_hiyellow.g, orig_hiyellow.b); init_color(COLOR_BLUE + 8, orig_hiblue.r, orig_hiblue.g, - orig_hiblue.b); + orig_hiblue.b); init_color(COLOR_MAGENTA + 8, orig_himagenta.r, - orig_himagenta.g, orig_himagenta.b); + orig_himagenta.g, orig_himagenta.b); init_color(COLOR_CYAN + 8, orig_hicyan.r, orig_hicyan.g, - orig_hicyan.b); + orig_hicyan.b); init_color(COLOR_WHITE + 8, orig_hiwhite.r, orig_hiwhite.g, - orig_hiwhite.b); + orig_hiwhite.b); # ifdef USE_DARKGRAY - if (COLORS > 16) - { + if (COLORS > 16) { init_color(CURSES_DARK_GRAY, orig_darkgray.r, - orig_darkgray.g, orig_darkgray.b); + orig_darkgray.g, orig_darkgray.b); } # endif } } #endif } - diff --git a/win/curses/cursinit.h b/win/curses/cursinit.h index 94459622..e330736b 100644 --- a/win/curses/cursinit.h +++ b/win/curses/cursinit.h @@ -1,5 +1,7 @@ +/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ + #ifndef CURSINIT_H -#define CURSINIT_H +# define CURSINIT_H /* Global declarations */ @@ -9,7 +11,7 @@ void curses_init_nhcolors(void); void curses_choose_character(void); -int curses_character_dialog(const char** choices, const char *prompt); +int curses_character_dialog(const char **choices, const char *prompt); void curses_init_options(void); @@ -18,4 +20,4 @@ void curses_display_splash_window(void); void curses_cleanup(void); -#endif /* CURSINIT_H */ +#endif /* CURSINIT_H */ diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index d96e2c33..0803b8cb 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -1,3 +1,5 @@ +/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ + #include "curses.h" #include "hack.h" #include "patchlevel.h" @@ -9,10 +11,10 @@ /* Interface definition, for windows.c */ struct window_procs curses_procs = { "curses", - WC_ALIGN_MESSAGE|WC_ALIGN_STATUS|WC_COLOR|WC_HILITE_PET| - WC_POPUP_DIALOG|WC_SPLASH_SCREEN, - WC2_TERM_COLS|WC2_TERM_ROWS|WC2_WINDOWBORDERS|WC2_PETATTR| - WC2_GUICOLOR, + WC_ALIGN_MESSAGE | WC_ALIGN_STATUS | WC_COLOR | WC_HILITE_PET | + WC_POPUP_DIALOG | WC_SPLASH_SCREEN, + WC2_TERM_COLS | WC2_TERM_ROWS | WC2_WINDOWBORDERS | WC2_PETATTR | + WC2_GUICOLOR, curses_init_nhwindows, curses_player_selection, curses_askname, @@ -53,7 +55,7 @@ struct window_procs curses_procs = { curses_get_ext_cmd, curses_number_pad, curses_delay_output, -#ifdef CHANGE_COLOR /* only a Mac option currently */ +#ifdef CHANGE_COLOR /* only a Mac option currently */ donull, donull, #endif @@ -77,7 +79,8 @@ init_nhwindows(int* argcp, char** argv) ** Why not have init_nhwindows() create all of the "standard" ** windows? Or at least all but WIN_INFO? -dean */ -void curses_init_nhwindows(int* argcp, char** argv) +void +curses_init_nhwindows(int *argcp, char **argv) { #ifdef PDCURSES char window_title[BUFSZ]; @@ -89,23 +92,20 @@ void curses_init_nhwindows(int* argcp, char** argv) base_term = initscr(); #endif #ifdef TEXTCOLOR - if (has_colors()) - { + if (has_colors()) { start_color(); curses_init_nhcolors(); - } - else - { + } else { iflags.use_color = FALSE; set_option_mod_status("color", SET_IN_FILE); iflags.wc2_guicolor = FALSE; - set_wc2_option_mod_status(WC2_GUICOLOR, SET_IN_FILE); + set_wc2_option_mod_status(WC2_GUICOLOR, SET_IN_FILE); } #else iflags.use_color = FALSE; - set_option_mod_status("color", SET_IN_FILE); + set_option_mod_status("color", SET_IN_FILE); iflags.wc2_guicolor = FALSE; - set_wc2_option_mod_status(WC2_GUICOLOR, SET_IN_FILE); + set_wc2_option_mod_status(WC2_GUICOLOR, SET_IN_FILE); #endif noecho(); raw(); @@ -114,36 +114,37 @@ void curses_init_nhwindows(int* argcp, char** argv) keypad(stdscr, TRUE); #ifdef NCURSES_VERSION # ifdef __APPLE__ - ESCDELAY = 25; + ESCDELAY = 25; # else set_escdelay(25); -# endif /* __APPLE__ */ -#endif /* NCURSES_VERSION */ +# endif/* __APPLE__ */ +#endif /* NCURSES_VERSION */ #ifdef PDCURSES # ifdef DEF_GAME_NAME # ifdef VERSION_STRING sprintf(window_title, "%s %s", DEF_GAME_NAME, VERSION_STRING); # else sprintf(window_title, "%s", DEF_GAME_NAME); -# endif /* VERSION_STRING */ +# endif + /* VERSION_STRING */ # else # ifdef VERSION_STRING sprintf(window_title, "%s %s", "NetHack", VERSION_STRING); # else sprintf(window_title, "%s", "NetHack"); -# endif /* VERSION_STRING */ -# endif /* DEF_GAME_NAME */ +# endif + /* VERSION_STRING */ +# endif/* DEF_GAME_NAME */ PDC_set_title(window_title); - PDC_set_blink(TRUE); /* Only if the user asks for it! */ + PDC_set_blink(TRUE); /* Only if the user asks for it! */ timeout(1); - (void)getch(); + (void) getch(); timeout(-1); -#endif /* PDCURSES */ +#endif /* PDCURSES */ getmaxyx(base_term, term_rows, term_cols); counting = FALSE; curses_init_options(); - if ((term_rows < 15) || (term_cols < 40)) - { + if ((term_rows < 15) || (term_cols < 40)) { panic("Terminal too small. Must be minumum 40 width and 15 height"); } @@ -157,14 +158,16 @@ void curses_init_nhwindows(int* argcp, char** argv) offers a Quit option, it is its responsibility to clean up and terminate the process. You need to fill in pl_character[0]. */ -void curses_player_selection() +void +curses_player_selection() { curses_choose_character(); } /* Ask the user for a player name. */ -void curses_askname() +void +curses_askname() { curses_line_input_dialog("Who are you?", plname, PL_NSIZ); } @@ -173,11 +176,11 @@ void curses_askname() /* Does window event processing (e.g. exposure events). A noop for the tty and X window-ports. */ -void curses_get_nh_event() +void +curses_get_nh_event() { #ifdef PDCURSES - if (is_termresized()) - { + if (is_termresized()) { resize_term(0, 0); getmaxyx(base_term, term_rows, term_cols); curses_create_main_windows(); @@ -185,14 +188,12 @@ void curses_get_nh_event() doredraw(); } #endif -#ifdef NCURSES_VERSION /* Is there a better way to detect ncurses? */ - if (is_term_resized(term_rows, term_cols)) - { - if (!isendwin()) - { +#ifdef NCURSES_VERSION /* Is there a better way to detect ncurses? */ + if (is_term_resized(term_rows, term_cols)) { + if (!isendwin()) { endwin(); } - + refresh(); getmaxyx(base_term, term_rows, term_cols); curses_create_main_windows(); @@ -205,27 +206,29 @@ void curses_get_nh_event() /* Exits the window system. This should dismiss all windows, except the "window" used for raw_print(). str is printed if possible. */ -void curses_exit_nhwindows(const char *str) +void +curses_exit_nhwindows(const char *str) { curses_cleanup(); curs_set(orig_cursor); endwin(); iflags.window_inited = 0; - if (str != NULL) - { + if (str != NULL) { raw_print(str); } } /* Prepare the window to be suspended. */ -void curses_suspend_nhwindows(const char *str) +void +curses_suspend_nhwindows(const char *str) { endwin(); } /* Restore the windows after being suspended. */ -void curses_resume_nhwindows() +void +curses_resume_nhwindows() { curses_refresh_nethack_windows(); } @@ -237,25 +240,25 @@ void curses_resume_nhwindows() NHW_MENU (inventory or other "corner" windows) NHW_TEXT (help/text, full screen paged window) */ -winid curses_create_nhwindow(int type) +winid +curses_create_nhwindow(int type) { winid wid = curses_get_wid(type); - if (curses_is_menu(wid) || curses_is_text(wid)) - { + if (curses_is_menu(wid) || curses_is_text(wid)) { curses_start_menu(wid); curses_add_wid(wid); } - + return wid; } /* Clear the given window, when asked to. */ -void curses_clear_nhwindow(winid wid) +void +curses_clear_nhwindow(winid wid) { - if (wid != NHW_MESSAGE) - { + if (wid != NHW_MESSAGE) { curses_clear_nhwin(wid); } } @@ -269,25 +272,24 @@ void curses_clear_nhwindow(winid wid) -- Calling display_nhwindow(WIN_MESSAGE,???) will do a --more--, if necessary, in the tty window-port. */ -void curses_display_nhwindow(winid wid, BOOLEAN_P block) +void +curses_display_nhwindow(winid wid, BOOLEAN_P block) { menu_item *selected = NULL; - if ((wid == MAP_WIN) && block) - { - (void) curses_more(); + if ((wid == MAP_WIN) && block) { + (void) curses_more(); } - if ((wid == MESSAGE_WIN) && block) - { - if (u.uhp != -1 && program_state.gameover != 1) - (void) curses_block(TRUE); - /* don't bug player with TAB prompt on "Saving..." or endgame*/ - else (void) curses_more(); + if ((wid == MESSAGE_WIN) && block) { + if (u.uhp != -1 && program_state.gameover != 1) + (void) curses_block(TRUE); + /* don't bug player with TAB prompt on "Saving..." or endgame */ + else + (void) curses_more(); } - if (curses_is_menu(wid) || curses_is_text(wid)) - { + if (curses_is_menu(wid) || curses_is_text(wid)) { curses_end_menu(wid, ""); curses_select_menu(wid, PICK_NONE, &selected); return; @@ -298,7 +300,8 @@ void curses_display_nhwindow(winid wid, BOOLEAN_P block) /* Destroy will dismiss the window if the window has not * already been dismissed. */ -void curses_destroy_nhwindow(winid wid) +void +curses_destroy_nhwindow(winid wid) { curses_del_nhwin(wid); } @@ -308,7 +311,8 @@ void curses_destroy_nhwindow(winid wid) 1 <= x < cols, 0 <= y < rows, where cols and rows are the size of window. */ -void curses_curs(winid wid, int x, int y) +void +curses_curs(winid wid, int x, int y) { curses_move_cursor(wid, x, y); } @@ -336,10 +340,11 @@ Attributes then the second. In the tty port, pline() achieves this by calling more() or displaying both on the same line. */ -void curses_putstr(winid wid, int attr, const char *text) +void +curses_putstr(winid wid, int attr, const char *text) { int curses_attr = curses_convert_attr(attr); - + /* We need to convert NetHack attributes to curses attributes */ curses_puts(wid, curses_attr, text); } @@ -347,7 +352,8 @@ void curses_putstr(winid wid, int attr, const char *text) /* Display the file named str. Complain about missing files iff complain is TRUE. */ -void curses_display_file(const char *filename,BOOLEAN_P must_exist) +void +curses_display_file(const char *filename, BOOLEAN_P must_exist) { curses_view_file(filename, must_exist); } @@ -357,7 +363,8 @@ void curses_display_file(const char *filename,BOOLEAN_P must_exist) putstr() to the window. Only windows of type NHW_MENU may be used for menus. */ -void curses_start_menu(winid wid) +void +curses_start_menu(winid wid) { curses_create_nhmenu(wid); } @@ -393,14 +400,15 @@ add_menu(winid wid, int glyph, const anything identifier, -- If you want this choice to be preselected when the menu is displayed, set preselected to TRUE. */ -void curses_add_menu(winid wid, int glyph, const ANY_P * identifier, - CHAR_P accelerator, CHAR_P group_accel, int attr, - const char *str, BOOLEAN_P presel) +void +curses_add_menu(winid wid, int glyph, const ANY_P * identifier, + CHAR_P accelerator, CHAR_P group_accel, int attr, + const char *str, BOOLEAN_P presel) { int curses_attr = curses_convert_attr(attr); curses_add_nhmenu_item(wid, glyph, identifier, accelerator, group_accel, - curses_attr, str, presel); + curses_attr, str, presel); } /* @@ -412,7 +420,8 @@ end_menu(window, prompt) ** This probably shouldn't flush the window any more (if ** it ever did). That should be select_menu's job. -dean */ -void curses_end_menu(winid wid, const char *prompt) +void +curses_end_menu(winid wid, const char *prompt) { curses_finalize_nhmenu(wid, prompt); } @@ -442,7 +451,8 @@ int select_menu(winid window, int how, menu_item **selected) select_menu() will be called for the window at create_nhwindow() time. */ -int curses_select_menu(winid wid, int how, MENU_ITEM_P **selected) +int +curses_select_menu(winid wid, int how, MENU_ITEM_P ** selected) { return curses_display_nhmenu(wid, how, selected); } @@ -450,9 +460,10 @@ int curses_select_menu(winid wid, int how, MENU_ITEM_P **selected) /* -- Indicate to the window port that the inventory has been changed. -- Merely calls display_inventory() for window-ports that leave the - window up, otherwise empty. + window up, otherwise empty. */ -void curses_update_inventory() +void +curses_update_inventory() { } @@ -461,7 +472,8 @@ mark_synch() -- Don't go beyond this point in I/O on any channel until all channels are caught up to here. Can be an empty call for the moment */ -void curses_mark_synch() +void +curses_mark_synch() { } @@ -471,7 +483,8 @@ wait_synch() -- Wait until all pending output is complete (*flush*() for -- May also deal with exposure events etc. so that the display is OK when return from wait_synch(). */ -void curses_wait_synch() +void +curses_wait_synch() { } @@ -480,13 +493,13 @@ cliparound(x, y)-- Make sure that the user is more-or-less centered on the screen if the playing area is larger than the screen. -- This function is only defined if CLIPPING is defined. */ -void curses_cliparound(int x, int y) +void +curses_cliparound(int x, int y) { int sx, sy, ex, ey; boolean redraw = curses_map_borders(&sx, &sy, &ex, &ey, x, y); - - if (redraw) - { + + if (redraw) { curses_draw_map(sx, sy, ex, ey); } } @@ -498,7 +511,8 @@ print_glyph(window, x, y, glyph) port wants (symbol, font, color, attributes, ...there's a 1-1 map between glyphs and distinct things on the map). */ -void curses_print_glyph(winid wid, XCHAR_P x, XCHAR_P y, int glyph) +void +curses_print_glyph(winid wid, XCHAR_P x, XCHAR_P y, int glyph) { glyph_t ch; int color; @@ -507,26 +521,23 @@ void curses_print_glyph(winid wid, XCHAR_P x, XCHAR_P y, int glyph) /* map glyph to character and color */ mapglyph(glyph, &ch, &color, &special, x, y); - if ((special & MG_PET) && iflags.hilite_pet) - { + if ((special & MG_PET) && iflags.hilite_pet) { attr = iflags.wc2_petattr; } - if ((special & MG_DETECT) && iflags.use_inverse) - { - attr = A_REVERSE; - } - if (iflags.cursesgraphics) - { - ch = curses_convert_glyph(ch, glyph); - } - - if (wid == NHW_MAP) { - if ((special & MG_STAIRS) && iflags.hilite_hidden_stairs) { - color = 16 + (color*2); - } else if ((special & MG_OBJPILE) && iflags.hilite_obj_piles) { - color = 16 + (color*2) + 1; - } - } + if ((special & MG_DETECT) && iflags.use_inverse) { + attr = A_REVERSE; + } + if (iflags.cursesgraphics) { + ch = curses_convert_glyph(ch, glyph); + } + + if (wid == NHW_MAP) { + if ((special & MG_STAIRS) && iflags.hilite_hidden_stairs) { + color = 16 + (color * 2); + } else if ((special & MG_OBJPILE) && iflags.hilite_obj_piles) { + color = 16 + (color * 2) + 1; + } + } curses_putch(wid, x, y, ch, color, attr); } @@ -540,7 +551,8 @@ raw_print(str) -- Print directly to a screen, or otherwise guarantee that for error messages, and maybe other "msg" uses. E.g. updating status for micros (i.e, "saving"). */ -void curses_raw_print(const char *str) +void +curses_raw_print(const char *str) { puts(str); } @@ -549,7 +561,8 @@ void curses_raw_print(const char *str) raw_print_bold(str) -- Like raw_print(), but prints in bold/standout (if possible). */ -void curses_raw_print_bold(const char *str) +void +curses_raw_print_bold(const char *str) { curses_raw_print(str); } @@ -560,14 +573,15 @@ int nhgetch() -- Returns a single character input from the user. will be the routine the OS provides to read a character. Returned character _must_ be non-zero. */ -int curses_nhgetch() -{ +int +curses_nhgetch() +{ int ch; - + curses_prehousekeeping(); ch = curses_read_char(); curses_posthousekeeping(); - + return ch; } @@ -586,14 +600,14 @@ int nh_poskey(int *x, int *y, int *mod) hardware supports. If no mouse is supported, this routine always returns a non-zero character. */ -int curses_nh_poskey(int *x, int *y, int *mod) +int +curses_nh_poskey(int *x, int *y, int *mod) { int key = curses_nhgetch(); - + #ifdef NCURSES_MOUSE_VERSION /* Mouse event if mouse_support is true */ - if (key == KEY_MOUSE) - { + if (key == KEY_MOUSE) { key = curses_get_mouse(x, y, mod); } #endif @@ -605,7 +619,8 @@ int curses_nh_poskey(int *x, int *y, int *mod) nhbell() -- Beep at user. [This will exist at least until sounds are redone, since sounds aren't attributable to windows anyway.] */ -void curses_nhbell() +void +curses_nhbell() { beep(); } @@ -615,7 +630,8 @@ doprev_message() -- Display previous messages. Used by the ^P command. -- On the tty-port this scrolls WIN_MESSAGE back one line. */ -int curses_doprev_message() +int +curses_doprev_message() { curses_prev_mesg(); return 0; @@ -640,33 +656,36 @@ char yn_function(const char *ques, const char *choices, char default) -- This uses the top line in the tty window-port, other ports might use a popup. */ -char curses_yn_function(const char *question, const char *choices, CHAR_P def) +char +curses_yn_function(const char *question, const char *choices, CHAR_P def) { - return (char)curses_character_input_dialog(question, choices, def); + return (char) curses_character_input_dialog(question, choices, def); } /* getlin(const char *ques, char *input) - -- Prints ques as a prompt and reads a single line of text, - up to a newline. The string entered is returned without the - newline. ESC is used to cancel, in which case the string - "\033\000" is returned. - -- getlin() must call flush_screen(1) before doing anything. - -- This uses the top line in the tty window-port, other - ports might use a popup. + -- Prints ques as a prompt and reads a single line of text, + up to a newline. The string entered is returned without the + newline. ESC is used to cancel, in which case the string + "\033\000" is returned. + -- getlin() must call flush_screen(1) before doing anything. + -- This uses the top line in the tty window-port, other + ports might use a popup. */ -void curses_getlin(const char *question, char *input) +void +curses_getlin(const char *question, char *input) { curses_line_input_dialog(question, input, BUFSZ); } /* int get_ext_cmd(void) - -- Get an extended command in a window-port specific way. - An index into extcmdlist[] is returned on a successful - selection, -1 otherwise. + -- Get an extended command in a window-port specific way. + An index into extcmdlist[] is returned on a successful + selection, -1 otherwise. */ -int curses_get_ext_cmd() +int +curses_get_ext_cmd() { return curses_ext_cmd(); } @@ -674,65 +693,70 @@ int curses_get_ext_cmd() /* number_pad(state) - -- Initialize the number pad to the given state. + -- Initialize the number pad to the given state. */ -void curses_number_pad(int state) +void +curses_number_pad(int state) { } /* delay_output() -- Causes a visible delay of 50ms in the output. - Conceptually, this is similar to wait_synch() followed - by a nap(50ms), but allows asynchronous operation. + Conceptually, this is similar to wait_synch() followed + by a nap(50ms), but allows asynchronous operation. */ -void curses_delay_output() +void +curses_delay_output() { napms(50); } /* start_screen() -- Only used on Unix tty ports, but must be declared for - completeness. Sets up the tty to work in full-screen - graphics mode. Look at win/tty/termcap.c for an - example. If your window-port does not need this function - just declare an empty function. + completeness. Sets up the tty to work in full-screen + graphics mode. Look at win/tty/termcap.c for an + example. If your window-port does not need this function + just declare an empty function. */ -void curses_start_screen() +void +curses_start_screen() { } /* end_screen() -- Only used on Unix tty ports, but must be declared for - completeness. The complement of start_screen(). + completeness. The complement of start_screen(). */ -void curses_end_screen() +void +curses_end_screen() { } /* outrip(winid, int) - -- The tombstone code. If you want the traditional code use - genl_outrip for the value and check the #if in rip.c. + -- The tombstone code. If you want the traditional code use + genl_outrip for the value and check the #if in rip.c. */ -void curses_outrip(winid wid, int how) +void +curses_outrip(winid wid, int how) { } /* preference_update(preference) - -- The player has just changed one of the wincap preference - settings, and the NetHack core is notifying your window - port of that change. If your window-port is capable of - dynamically adjusting to the change then it should do so. - Your window-port will only be notified of a particular - change if it indicated that it wants to be by setting the - corresponding bit in the wincap mask. + -- The player has just changed one of the wincap preference + settings, and the NetHack core is notifying your window + port of that change. If your window-port is capable of + dynamically adjusting to the change then it should do so. + Your window-port will only be notified of a particular + change if it indicated that it wants to be by setting the + corresponding bit in the wincap mask. */ -void curses_preference_update(const char *pref) +void +curses_preference_update(const char *pref) { if ((strcmp(pref, "align_status") == 0) || - (strcmp(pref, "align_message") == 0)) - { + (strcmp(pref, "align_message") == 0)) { curses_create_main_windows(); curses_last_messages(); doredraw(); diff --git a/win/curses/cursmesg.c b/win/curses/cursmesg.c index 8446ec02..491413a4 100644 --- a/win/curses/cursmesg.c +++ b/win/curses/cursmesg.c @@ -1,3 +1,5 @@ +/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ + #include "curses.h" #include "hack.h" #include "wincurs.h" @@ -7,12 +9,11 @@ /* Private declatations */ -typedef struct nhpm -{ - char *str; /* Message text */ - long turn; /* Turn number for message */ - struct nhpm *prev_mesg; /* Pointer to previous message */ - struct nhpm *next_mesg; /* Pointer to next message */ +typedef struct nhpm { + char *str; /* Message text */ + long turn; /* Turn number for message */ + struct nhpm *prev_mesg; /* Pointer to previous message */ + struct nhpm *next_mesg; /* Pointer to next message */ } nhprev_mesg; static void scroll_window(winid wid); @@ -23,7 +24,7 @@ static nhprev_mesg *get_msg_line(boolean reverse, int mindex); static int turn_lines = 1; static int mx = 0; -static int my = 0; /* message window text location */ +static int my = 0; /* message window text location */ static nhprev_mesg *first_mesg = NULL; static nhprev_mesg *last_mesg = NULL; static int max_messages; @@ -33,7 +34,8 @@ static int num_messages = 0; /* Write a string to the message window. Attributes set by calling function. */ -void curses_message_win_puts(const char *message, boolean recursed) +void +curses_message_win_puts(const char *message, boolean recursed) { int height, width, linespace; char *tmpstr; @@ -43,108 +45,84 @@ void curses_message_win_puts(const char *message, boolean recursed) int border_space = 0; static long suppress_turn = -1; - if (strncmp("Count:", message, 6) == 0) - { + if (strncmp("Count:", message, 6) == 0) { curses_count_window(message); return; } - - if (suppress_turn == moves) - { + + if (suppress_turn == moves) { return; } - + curses_get_window_size(MESSAGE_WIN, &height, &width); - if (border) - { + if (border) { border_space = 1; - if (mx < 1) - { + if (mx < 1) { mx = 1; } - if (my < 1) - { + if (my < 1) { my = 1; } } - + linespace = ((width + border_space) - 3) - mx; - - if (strcmp(message, "#") == 0) /* Extended command or Count: */ - { - if ((strcmp(toplines, "#") != 0) && (my >= (height - 1 + - border_space)) && (height != 1)) /* Bottom of message window */ - { + + if (strcmp(message, "#") == 0) { /* Extended command or Count: */ + if ((strcmp(toplines, "#") != 0) && (my >= (height - 1 + border_space)) && (height != 1)) { /* Bottom of message window */ scroll_window(MESSAGE_WIN); mx = width; my--; strcpy(toplines, message); } - + return; } - if (!recursed) - { + if (!recursed) { strcpy(toplines, message); mesg_add_line((char *) message); } - - if (linespace < message_length) - { - if (my >= (height - 1 + border_space)) /* bottom of message win */ - { - if ((turn_lines > height) || (height == 1)) - { + + if (linespace < message_length) { + if (my >= (height - 1 + border_space)) { /* bottom of message win */ + if ((turn_lines > height) || (height == 1)) { /* Pause until key is hit - Esc suppresses any further - messages that turn */ - if (curses_more() == DOESCAPE) - { + messages that turn */ + if (curses_more() == DOESCAPE) { suppress_turn = moves; return; } - } - else - { + } else { scroll_window(MESSAGE_WIN); turn_lines++; } - } - else - { - if (mx != border_space) - { + } else { + if (mx != border_space) { my++; mx = border_space; } } } - if (height > 1) - { + if (height > 1) { curses_toggle_color_attr(win, NONE, A_BOLD, ON); } - - if ((mx == border_space) && ((message_length + 2) > width)) - { + + if ((mx == border_space) && ((message_length + 2) > width)) { tmpstr = curses_break_str(message, (width - 2), 1); mvwprintw(win, my, mx, "%s", tmpstr); mx += strlen(tmpstr); - if (strlen(tmpstr) < (width - 2)) - { + if (strlen(tmpstr) < (width - 2)) { mx++; } free(tmpstr); - if (height > 1) - { + if (height > 1) { curses_toggle_color_attr(win, NONE, A_BOLD, OFF); } wrefresh(win); curses_message_win_puts(curses_str_remainder(message, (width - 2), 1), - TRUE); - } - else - { + TRUE); + } else { mvwprintw(win, my, mx, "%s", message); curses_toggle_color_attr(win, NONE, A_BOLD, OFF); mx += message_length + 1; @@ -153,38 +131,38 @@ void curses_message_win_puts(const char *message, boolean recursed) } -int curses_block(boolean require_tab) +int +curses_block(boolean require_tab) { int height, width, ret; WINDOW *win = curses_get_nhwin(MESSAGE_WIN); - + curses_get_window_size(MESSAGE_WIN, &height, &width); curses_toggle_color_attr(win, MORECOLOR, NONE, ON); mvwprintw(win, my, mx, require_tab ? "" : ">>"); curses_toggle_color_attr(win, MORECOLOR, NONE, OFF); - if (require_tab) curses_alert_main_borders(TRUE); + if (require_tab) + curses_alert_main_borders(TRUE); wrefresh(win); while ((ret = wgetch(win) != '\t') && require_tab); - if (require_tab) curses_alert_main_borders(FALSE); - if (height == 1) - { + if (require_tab) + curses_alert_main_borders(FALSE); + if (height == 1) { curses_clear_unhighlight_message_window(); - } - else - { + } else { mvwprintw(win, my, mx, " "); wrefresh(win); - if (!require_tab) - { + if (!require_tab) { scroll_window(MESSAGE_WIN); turn_lines = 1; } } - + return ret; } -int curses_more() +int +curses_more() { return curses_block(FALSE); } @@ -192,43 +170,35 @@ int curses_more() /* Clear the message window if one line; otherwise unhighlight old messages */ -void curses_clear_unhighlight_message_window() +void +curses_clear_unhighlight_message_window() { int mh, mw, count; boolean border = curses_window_has_border(MESSAGE_WIN); WINDOW *win = curses_get_nhwin(MESSAGE_WIN); turn_lines = 1; - - curses_get_window_size(MESSAGE_WIN, &mh, &mw); - + + curses_get_window_size(MESSAGE_WIN, &mh, &mw); + mx = 0; - - if (border) - { + + if (border) { mx++; } - - if (mh == 1) - { + + if (mh == 1) { curses_clear_nhwin(MESSAGE_WIN); - } - else - { - mx += mw; /* Force new line on new turn */ - - if (border) - { + } else { + mx += mw; /* Force new line on new turn */ + + if (border) { - for (count = 0; count < mh; count++) - { - mvwchgat(win, count+1, 1, mw, COLOR_PAIR(8), A_NORMAL, NULL); + for (count = 0; count < mh; count++) { + mvwchgat(win, count + 1, 1, mw, COLOR_PAIR(8), A_NORMAL, NULL); } - } - else - { - for (count = 0; count < mh; count++) - { + } else { + for (count = 0; count < mh; count++) { mvwchgat(win, count, 0, mw, COLOR_PAIR(8), A_NORMAL, NULL); } } @@ -241,38 +211,35 @@ void curses_clear_unhighlight_message_window() /* Reset message window cursor to starting position, and display most recent messages. */ -void curses_last_messages() +void +curses_last_messages() { boolean border = curses_window_has_border(MESSAGE_WIN); - if (border) - { + if (border) { mx = 1; my = 1; - } - else - { + } else { mx = 0; my = 0; } - + pline("%s", toplines); } /* Initialize list for message history */ -void curses_init_mesg_history() +void +curses_init_mesg_history() { max_messages = iflags.msg_history; - - if (max_messages < 1) - { + + if (max_messages < 1) { max_messages = 1; } - if (max_messages > MESG_HISTORY_MAX) - { + if (max_messages > MESG_HISTORY_MAX) { max_messages = MESG_HISTORY_MAX; } } @@ -280,7 +247,8 @@ void curses_init_mesg_history() /* Display previous message window messages in reverse chron order */ -void curses_prev_mesg() +void +curses_prev_mesg() { int count; winid wid; @@ -291,22 +259,20 @@ void curses_prev_mesg() wid = curses_get_wid(NHW_MENU); curses_create_nhmenu(wid); - identifier = malloc(sizeof(anything)); + identifier = malloc(sizeof (anything)); identifier->a_void = NULL; - - for (count = 0; count < num_messages; count++) - { + + for (count = 0; count < num_messages; count++) { mesg = get_msg_line(TRUE, count); - if ((turn != mesg->turn) && (count != 0)) - { + if ((turn != mesg->turn) && (count != 0)) { curses_add_menu(wid, NO_GLYPH, identifier, 0, 0, A_NORMAL, - "---", FALSE); + "---", FALSE); } curses_add_menu(wid, NO_GLYPH, identifier, 0, 0, A_NORMAL, - mesg->str, FALSE); + mesg->str, FALSE); turn = mesg->turn; } - + curses_end_menu(wid, ""); curses_select_menu(wid, PICK_NONE, &selected); } @@ -315,65 +281,59 @@ void curses_prev_mesg() /* Shows Count: in a separate window, or at the bottom of the message window, depending on the user's settings */ -void curses_count_window(const char *count_text) +void +curses_count_window(const char *count_text) { int startx, starty, winx, winy; int messageh, messagew; static WINDOW *countwin = NULL; - if ((count_text == NULL) && (countwin != NULL)) - { + if ((count_text == NULL) && (countwin != NULL)) { delwin(countwin); countwin = NULL; counting = FALSE; return; } - + counting = TRUE; - if (iflags.wc_popup_dialog) /* Display count in popup window */ - { + if (iflags.wc_popup_dialog) { /* Display count in popup window */ startx = 1; starty = 1; - - if (countwin == NULL) - { + + if (countwin == NULL) { countwin = curses_create_window(25, 1, UP); } - - } - else /* Display count at bottom of message window */ - { + + } else { /* Display count at bottom of message window */ + curses_get_window_xy(MESSAGE_WIN, &winx, &winy); curses_get_window_size(MESSAGE_WIN, &messageh, &messagew); - - if (curses_window_has_border(MESSAGE_WIN)) - { + + if (curses_window_has_border(MESSAGE_WIN)) { winx++; winy++; } - + winy += messageh - 1; - - if (countwin == NULL) - { + + if (countwin == NULL) { pline("#"); #ifndef PDCURSES countwin = newwin(1, 25, winy, winx); -#endif /* !PDCURSES */ +#endif /* !PDCURSES */ } #ifdef PDCURSES - else - { + else { curses_destroy_win(countwin); } - + countwin = newwin(1, 25, winy, winx); -#endif /* PDCURSES */ +#endif /* PDCURSES */ startx = 0; starty = 0; } - + mvwprintw(countwin, starty, startx, "%s", count_text); wrefresh(countwin); } @@ -381,25 +341,22 @@ void curses_count_window(const char *count_text) /* Scroll lines upward in given window, or clear window if only one line. */ -static void scroll_window(winid wid) +static void +scroll_window(winid wid) { int wh, ww, s_top, s_bottom; boolean border = curses_window_has_border(wid); WINDOW *win = curses_get_nhwin(wid); - + curses_get_window_size(wid, &wh, &ww); - if (wh == 1) - { + if (wh == 1) { curses_clear_nhwin(wid); return; } - if (border) - { + if (border) { s_top = 1; s_bottom = wh; - } - else - { + } else { s_top = 0; s_bottom = wh - 1; } @@ -407,15 +364,13 @@ static void scroll_window(winid wid) wsetscrreg(win, s_top, s_bottom); scroll(win); scrollok(win, FALSE); - if (wid == MESSAGE_WIN) - { + if (wid == MESSAGE_WIN) { if (border) mx = 1; else mx = 0; } - if (border) - { + if (border) { box(win, 0, 0); } wrefresh(win); @@ -424,34 +379,30 @@ static void scroll_window(winid wid) /* Add given line to message history */ -static void mesg_add_line(char *mline) +static void +mesg_add_line(char *mline) { nhprev_mesg *tmp_mesg = NULL; - nhprev_mesg *current_mesg = malloc(sizeof(nhprev_mesg)); + nhprev_mesg *current_mesg = malloc(sizeof (nhprev_mesg)); current_mesg->str = curses_copy_of(mline); current_mesg->turn = moves; current_mesg->next_mesg = NULL; - if (num_messages == 0) - { + if (num_messages == 0) { first_mesg = current_mesg; } - - if (last_mesg != NULL) - { + + if (last_mesg != NULL) { last_mesg->next_mesg = current_mesg; } current_mesg->prev_mesg = last_mesg; last_mesg = current_mesg; - if (num_messages < max_messages) - { + if (num_messages < max_messages) { num_messages++; - } - else - { + } else { tmp_mesg = first_mesg->next_mesg; free(first_mesg); first_mesg = tmp_mesg; @@ -461,31 +412,25 @@ static void mesg_add_line(char *mline) /* Returns specified line from message history, or NULL if out of bounds */ -static nhprev_mesg *get_msg_line(boolean reverse, int mindex) +static nhprev_mesg * +get_msg_line(boolean reverse, int mindex) { int count; nhprev_mesg *current_mesg; - if (reverse) - { + if (reverse) { current_mesg = last_mesg; - for (count = 0; count < mindex; count++) - { - if (current_mesg == NULL) - { + for (count = 0; count < mindex; count++) { + if (current_mesg == NULL) { return NULL; } current_mesg = current_mesg->prev_mesg; } return current_mesg; - } - else - { + } else { current_mesg = first_mesg; - for (count = 0; count < mindex; count++) - { - if (current_mesg == NULL) - { + for (count = 0; count < mindex; count++) { + if (current_mesg == NULL) { return NULL; } current_mesg = current_mesg->next_mesg; @@ -493,4 +438,3 @@ static nhprev_mesg *get_msg_line(boolean reverse, int mindex) return current_mesg; } } - diff --git a/win/curses/cursmesg.h b/win/curses/cursmesg.h index c1c173af..4bf9718c 100644 --- a/win/curses/cursmesg.h +++ b/win/curses/cursmesg.h @@ -1,5 +1,7 @@ +/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ + #ifndef CURSMESG_H -#define CURSMESG_H +# define CURSMESG_H /* Global declarations */ @@ -20,4 +22,4 @@ void curses_prev_mesg(void); void curses_count_window(const char *count_text); -#endif /* CURSMESG_H */ +#endif /* CURSMESG_H */ diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index 35a1cce1..74cee730 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -1,3 +1,5 @@ +/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ + #include "curses.h" #include "hack.h" #include "wincurs.h" @@ -20,42 +22,39 @@ static int parse_escape_sequence(void); #ifndef M # ifndef NHSTDC -# define M(c) (0x80 | (c)) +# define M(c) (0x80 | (c)) # else -# define M(c) ((c) - 128) -# endif /* NHSTDC */ +# define M(c) ((c) - 128) +# endif/* NHSTDC */ #endif #ifndef C -#define C(c) (0x1f & (c)) +# define C(c) (0x1f & (c)) #endif /* Read a character of input from the user */ -int curses_read_char() +int +curses_read_char() { int ch, tmpch; - + ch = getch(); tmpch = ch; ch = curses_convert_keys(ch); - if (ch == 0) - { - ch = DOESCAPE; /* map NUL to ESC since nethack doesn't expect NUL */ + if (ch == 0) { + ch = DOESCAPE; /* map NUL to ESC since nethack doesn't expect NUL */ } - -#if defined(ALT_0) && defined(ALT_9) /* PDCurses, maybe others */ - if ((ch >= ALT_0) && (ch <= ALT_9)) - { +#if defined(ALT_0) && defined(ALT_9) /* PDCurses, maybe others */ + if ((ch >= ALT_0) && (ch <= ALT_9)) { tmpch = (ch - ALT_0) + '0'; ch = M(tmpch); } #endif -#if defined(ALT_A) && defined(ALT_Z) /* PDCurses, maybe others */ - if ((ch >= ALT_A) && (ch <= ALT_Z)) - { +#if defined(ALT_A) && defined(ALT_Z) /* PDCurses, maybe others */ + if ((ch >= ALT_A) && (ch <= ALT_Z)) { tmpch = (ch - ALT_A) + 'a'; ch = M(tmpch); } @@ -63,14 +62,12 @@ int curses_read_char() #ifdef KEY_RESIZE /* Handle resize events via get_nh_event, not this code */ - if (ch == KEY_RESIZE) - { - ch = DOESCAPE; /* NetHack doesn't know what to do with KEY_RESIZE */ + if (ch == KEY_RESIZE) { + ch = DOESCAPE; /* NetHack doesn't know what to do with KEY_RESIZE */ } #endif - if (counting && !isdigit(ch)) /* Dismiss count window if necissary */ - { + if (counting && !isdigit(ch)) { /* Dismiss count window if necissary */ curses_count_window(NULL); curses_refresh_nethack_windows(); } @@ -80,101 +77,84 @@ int curses_read_char() /* Turn on or off the specified color and / or attribute */ -void curses_toggle_color_attr(WINDOW *win, int color, int attr, int onoff) +void +curses_toggle_color_attr(WINDOW * win, int color, int attr, int onoff) { #ifdef TEXTCOLOR int curses_color; /* Map color disabled */ - if ((!iflags.wc_color) && (win == mapwin)) - { + if ((!iflags.wc_color) && (win == mapwin)) { return; } - + /* GUI color disabled */ - if ((!iflags.wc2_guicolor) && (win != mapwin)) - { + if ((!iflags.wc2_guicolor) && (win != mapwin)) { return; } - - if (color == 0) /* make black fg visible */ - { -#ifdef USE_DARKGRAY - if (iflags.wc2_darkgray) - { - if (can_change_color() && (COLORS > 16)) - { + + if (color == 0) { /* make black fg visible */ +# ifdef USE_DARKGRAY + if (iflags.wc2_darkgray) { + if (can_change_color() && (COLORS > 16)) { /* colorpair for black is already darkgray */ - } - else /* Use bold for a bright black */ - { + } else { /* Use bold for a bright black */ + wattron(win, A_BOLD); } - } - else -#endif /* USE_DARKGRAY */ + } else +# endif/* USE_DARKGRAY */ color = CLR_BLUE; } curses_color = color + 1; - if (COLORS < 16) - { + if (COLORS < 16) { if (curses_color > 8 && curses_color < 17) curses_color -= 8; - else if (curses_color > (17+16)) + else if (curses_color > (17 + 16)) curses_color -= 16; } - if (onoff == ON) /* Turn on color/attributes */ - { - if (color != NONE) - { + if (onoff == ON) { /* Turn on color/attributes */ + if (color != NONE) { if ((((color > 7) && (color < 17)) || - (color > 17+17)) && (COLORS < 16)) - { + (color > 17 + 17)) && (COLORS < 16)) { wattron(win, A_BOLD); } wattron(win, COLOR_PAIR(curses_color)); } - - if (attr != NONE) - { + + if (attr != NONE) { wattron(win, attr); } - } - else /* Turn off color/attributes */ - { - if (color != NONE) - { - if ((color > 7) && (COLORS < 16)) - { + } else { /* Turn off color/attributes */ + + if (color != NONE) { + if ((color > 7) && (COLORS < 16)) { wattroff(win, A_BOLD); } -#ifdef USE_DARKGRAY - if ((color == 0) && (!can_change_color() || - (COLORS <= 16))) - { +# ifdef USE_DARKGRAY + if ((color == 0) && (!can_change_color() || (COLORS <= 16))) { wattroff(win, A_BOLD); } -#else - if (iflags.use_inverse) - { +# else + if (iflags.use_inverse) { wattroff(win, A_REVERSE); } -#endif /* DARKGRAY */ +# endif/* DARKGRAY */ wattroff(win, COLOR_PAIR(curses_color)); } - - if (attr != NONE) - { + + if (attr != NONE) { wattroff(win, attr); } } -#endif /* TEXTCOLOR */ +#endif /* TEXTCOLOR */ } /* clean up and quit - taken from tty port */ -void curses_bail(const char *mesg) +void +curses_bail(const char *mesg) { clearlocks(); curses_exit_nhwindows(mesg); @@ -184,65 +164,45 @@ void curses_bail(const char *mesg) /* Return a winid for a new window of the given type */ -winid curses_get_wid(int type) +winid +curses_get_wid(int type) { - winid ret; + winid ret; static winid menu_wid = 20; /* Always even */ static winid text_wid = 21; /* Always odd */ - switch (type) - { - case NHW_MESSAGE: - { - return MESSAGE_WIN; - break; - } - case NHW_MAP: - { - return MAP_WIN; - break; - } - case NHW_STATUS: - { - return STATUS_WIN; - break; - } - case NHW_MENU: - { - ret = menu_wid; - break; - } - case NHW_TEXT: - { - ret = text_wid; - break; - } - default: - { - panic("curses_get_wid: unsupported window type"); - ret = -1; /* Not reached */ - } - } - - while (curses_window_exists(ret)) - { - ret += 2; - if ((ret + 2) > 10000) /* Avoid "wid2k" problem */ - { - ret -= 9900; - } - } - - if (type == NHW_MENU) - { - menu_wid += 2; - } - else - { - text_wid += 2; - } - - return ret; + switch (type) { + case NHW_MESSAGE: + return MESSAGE_WIN; + case NHW_MAP: + return MAP_WIN; + case NHW_STATUS: + return STATUS_WIN; + case NHW_MENU: + ret = menu_wid; + break; + case NHW_TEXT: + ret = text_wid; + break; + default: + panic("curses_get_wid: unsupported window type"); + ret = -1; /* Not reached */ + } + + while (curses_window_exists(ret)) { + ret += 2; + if ((ret + 2) > 10000) { /* Avoid "wid2k" problem */ + ret -= 9900; + } + } + + if (type == NHW_MENU) { + menu_wid += 2; + } else { + text_wid += 2; + } + + return ret; } @@ -253,9 +213,11 @@ winid curses_get_wid(int type) * This is taken from copy_of() in tty/wintty.c. */ -char *curses_copy_of(const char *s) +char * +curses_copy_of(const char *s) { - if (!s) s = ""; + if (!s) + s = ""; return strcpy((char *) alloc((unsigned) (strlen(s) + 1)), s); } @@ -263,38 +225,35 @@ char *curses_copy_of(const char *s) /* Determine the number of lines needed for a string for a dialog window of the given width */ -int curses_num_lines(const char *str, int width) +int +curses_num_lines(const char *str, int width) { int last_space, count; int curline = 1; char substr[BUFSZ]; char tmpstr[BUFSZ]; - + strcpy(substr, str); - - while (strlen(substr) > width) - { + + while (strlen(substr) > width) { last_space = 0; - - for (count = 0; count <= width; count++) - { + + for (count = 0; count <= width; count++) { if (substr[count] == ' ') - last_space = count; + last_space = count; } - if (last_space == 0) /* No spaces found */ - { + if (last_space == 0) { /* No spaces found */ last_space = count - 1; } - for (count = (last_space + 1); count < strlen(substr); count++) - { + for (count = (last_space + 1); count < strlen(substr); count++) { tmpstr[count - (last_space + 1)] = substr[count]; } tmpstr[count - (last_space + 1)] = '\0'; strcpy(substr, tmpstr); curline++; } - + return curline; } @@ -302,7 +261,8 @@ int curses_num_lines(const char *str, int width) /* Break string into smaller lines to fit into a dialog window of the given width */ -char *curses_break_str(const char *str, int width, int line_num) +char * +curses_break_str(const char *str, int width, int line_num) { int last_space, count; char *retstr; @@ -311,64 +271,54 @@ char *curses_break_str(const char *str, int width, int line_num) char substr[strsize]; char curstr[strsize]; char tmpstr[strsize]; - + strcpy(substr, str); - - while (curline < line_num) - { - if (strlen(substr) == 0 ) - { + + while (curline < line_num) { + if (strlen(substr) == 0) { break; } curline++; - last_space = 0; - for (count = 0; count <= width; count++) - { - if (substr[count] == ' ') - { + last_space = 0; + for (count = 0; count <= width; count++) { + if (substr[count] == ' ') { last_space = count; - } - else if (substr[count] == '\0') - { + } else if (substr[count] == '\0') { last_space = count; break; } } - if (last_space == 0) /* No spaces found */ - { + if (last_space == 0) { /* No spaces found */ last_space = count - 1; } - for (count = 0; count < last_space; count++) - { + for (count = 0; count < last_space; count++) { curstr[count] = substr[count]; } curstr[count] = '\0'; - if (substr[count] == '\0') - { + if (substr[count] == '\0') { break; } - for (count = (last_space + 1); count < strlen(substr); count++) - { + for (count = (last_space + 1); count < strlen(substr); count++) { tmpstr[count - (last_space + 1)] = substr[count]; } tmpstr[count - (last_space + 1)] = '\0'; strcpy(substr, tmpstr); } - - if (curline < line_num) - { + + if (curline < line_num) { return NULL; } - + retstr = curses_copy_of(curstr); - + return retstr; } /* Return the remaining portion of a string after hacking-off line_num lines */ -char *curses_str_remainder(const char *str, int width, int line_num) +char * +curses_str_remainder(const char *str, int width, int line_num) { int last_space, count; char *retstr; @@ -377,71 +327,58 @@ char *curses_str_remainder(const char *str, int width, int line_num) char substr[strsize]; char curstr[strsize]; char tmpstr[strsize]; - + strcpy(substr, str); - - while (curline < line_num) - { - if (strlen(substr) == 0 ) - { + + while (curline < line_num) { + if (strlen(substr) == 0) { break; } curline++; - last_space = 0; - for (count = 0; count <= width; count++) - { - if (substr[count] == ' ') - { + last_space = 0; + for (count = 0; count <= width; count++) { + if (substr[count] == ' ') { last_space = count; - } - else if (substr[count] == '\0') - { + } else if (substr[count] == '\0') { last_space = count; break; } } - if (last_space == 0) /* No spaces found */ - { + if (last_space == 0) { /* No spaces found */ last_space = count - 1; } - for (count = 0; count < last_space; count++) - { + for (count = 0; count < last_space; count++) { curstr[count] = substr[count]; } curstr[count] = '\0'; - if (substr[count] == '\0') - { + if (substr[count] == '\0') { break; } - for (count = (last_space + 1); count < strlen(substr); count++) - { + for (count = (last_space + 1); count < strlen(substr); count++) { tmpstr[count - (last_space + 1)] = substr[count]; } tmpstr[count - (last_space + 1)] = '\0'; strcpy(substr, tmpstr); } - - if (curline < line_num) - { + + if (curline < line_num) { return NULL; } - + retstr = curses_copy_of(substr); - + return retstr; } /* Determine if the given NetHack winid is a menu window */ -boolean curses_is_menu(winid wid) +boolean +curses_is_menu(winid wid) { - if ((wid > 19) && !(wid % 2)) /* Even number */ - { + if ((wid > 19) && !(wid % 2)) { /* Even number */ return TRUE; - } - else - { + } else { return FALSE; } } @@ -449,14 +386,12 @@ boolean curses_is_menu(winid wid) /* Determine if the given NetHack winid is a text window */ -boolean curses_is_text(winid wid) +boolean +curses_is_text(winid wid) { - if ((wid > 19) && (wid % 2)) /* Odd number */ - { + if ((wid > 19) && (wid % 2)) { /* Odd number */ return TRUE; - } - else - { + } else { return FALSE; } } @@ -465,72 +400,70 @@ boolean curses_is_text(winid wid) /* Replace certain characters with portable drawing characters if cursesgraphics option is enabled */ -int curses_convert_glyph(int ch, int glyph) +int +curses_convert_glyph(int ch, int glyph) { int symbol; - + #ifdef REINCARNATION - if (Is_rogue_level(&u.uz)) - { + if (Is_rogue_level(&u.uz)) { return ch; } #endif - + /* Save some processing time by returning if the glyph represents - an object that we don't have custom characters for */ - if (!glyph_is_cmap(glyph)) - { + an object that we don't have custom characters for */ + if (!glyph_is_cmap(glyph)) { return ch; } - + symbol = glyph_to_cmap(glyph); - + /* If user selected a custom character for this object, don't - override this. */ - if (((glyph_is_cmap(glyph)) && (ch != showsyms[symbol]))) - { + override this. */ + if (((glyph_is_cmap(glyph)) && (ch != showsyms[symbol]))) { return ch; } - switch (symbol) - { - case S_vwall: - return ACS_VLINE; - case S_hwall: - return ACS_HLINE; - case S_tlcorn: - return ACS_ULCORNER; - case S_trcorn: - return ACS_URCORNER; - case S_blcorn: - return ACS_LLCORNER; - case S_brcorn: - return ACS_LRCORNER; - case S_crwall: - return ACS_PLUS; - case S_tuwall: - return ACS_BTEE; - case S_tdwall: - return ACS_TTEE; - case S_tlwall: - return ACS_RTEE; - case S_trwall: - return ACS_LTEE; - case S_tree: - return ACS_PLMINUS; - case S_corr: - return ACS_CKBOARD; - case S_litcorr: - return ACS_CKBOARD; - } - - return ch; + switch (symbol) { + case S_vwall: + return ACS_VLINE; + case S_hwall: + return ACS_HLINE; + case S_tlcorn: + return ACS_ULCORNER; + case S_trcorn: + return ACS_URCORNER; + case S_blcorn: + return ACS_LLCORNER; + case S_brcorn: + return ACS_LRCORNER; + case S_crwall: + return ACS_PLUS; + case S_tuwall: + return ACS_BTEE; + case S_tdwall: + return ACS_TTEE; + case S_tlwall: + return ACS_RTEE; + case S_trwall: + return ACS_LTEE; + case S_tree: + return ACS_PLMINUS; + case S_corr: + return ACS_CKBOARD; + case S_litcorr: + return ACS_CKBOARD; + } + + return ch; } /* Move text cursor to specified coordinates in the given NetHack window */ -void curses_move_cursor(winid wid, int x, int y) +void +curses_move_cursor(winid wid, int x, int y) { int sx, sy, ex, ey; int xadj = 0; @@ -540,29 +473,24 @@ void curses_move_cursor(winid wid, int x, int y) WINDOW *win = curses_get_nhwin(MAP_WIN); #endif - if (wid != MAP_WIN) - { + if (wid != MAP_WIN) { return; } - #ifdef PDCURSES /* PDCurses seems to not handle wmove correctly, so we use move and - physical screen coordinates instead */ + physical screen coordinates instead */ curses_get_window_xy(wid, &xadj, &yadj); -#endif +#endif curs_x = x + xadj; curs_y = y + yadj; curses_map_borders(&sx, &sy, &ex, &ey, x, y); - - if (curses_window_has_border(wid)) - { + + if (curses_window_has_border(wid)) { curs_x++; curs_y++; } - - if ((x >= sx) && (x <= ex) && - (y >= sy) && (y <= ey)) - { + + if ((x >= sx) && (x <= ex) && (y >= sy) && (y <= ey)) { curs_x -= sx; curs_y -= sy; #ifdef PDCURSES @@ -576,22 +504,22 @@ void curses_move_cursor(winid wid, int x, int y) /* Perform actions that should be done every turn before nhgetch() */ -void curses_prehousekeeping() +void +curses_prehousekeeping() { #ifndef PDCURSES WINDOW *win = curses_get_nhwin(MAP_WIN); -#endif /* PDCURSES */ +#endif /* PDCURSES */ - if ((curs_x > -1) && (curs_y > -1)) - { + if ((curs_x > -1) && (curs_y > -1)) { curs_set(1); #ifdef PDCURSES /* PDCurses seems to not handle wmove correctly, so we use move - and physical screen coordinates instead */ + and physical screen coordinates instead */ move(curs_y, curs_x); #else wmove(win, curs_y, curs_x); -#endif /* PDCURSES */ +#endif /* PDCURSES */ curses_refresh_nhwin(MAP_WIN); } } @@ -599,7 +527,8 @@ void curses_prehousekeeping() /* Perform actions that should be done every turn after nhgetch() */ -void curses_posthousekeeping() +void +curses_posthousekeeping() { curs_set(0); curses_decrement_highlight(); @@ -607,81 +536,79 @@ void curses_posthousekeeping() } -void curses_view_file(const char *filename, boolean must_exist) +void +curses_view_file(const char *filename, boolean must_exist) { winid wid; anything *identifier; char buf[BUFSZ]; menu_item *selected = NULL; dlb *fp = dlb_fopen(filename, "r"); - - if ((fp == NULL) && (must_exist)) - { + + if ((fp == NULL) && (must_exist)) { pline("Cannot open %s for reading!", filename); } - if (fp == NULL) - { + if (fp == NULL) { return; } - + wid = curses_get_wid(NHW_MENU); curses_create_nhmenu(wid); - identifier = malloc(sizeof(anything)); + identifier = malloc(sizeof (anything)); identifier->a_void = NULL; - - while (dlb_fgets(buf, BUFSZ, fp) != NULL) - { - curses_add_menu(wid, NO_GLYPH, identifier, 0, 0, A_NORMAL, buf, - FALSE); + + while (dlb_fgets(buf, BUFSZ, fp) != NULL) { + curses_add_menu(wid, NO_GLYPH, identifier, 0, 0, A_NORMAL, buf, FALSE); } - + dlb_fclose(fp); curses_end_menu(wid, ""); curses_select_menu(wid, PICK_NONE, &selected); } -void curses_rtrim(char *str) +void +curses_rtrim(char *str) { char *s; - for(s = str; *s != '\0'; ++s); - for(--s;isspace(*s) && s > str; --s); - if(s == str) *s = '\0'; - else *(++s) = '\0'; + for (s = str; *s != '\0'; ++s); + for (--s; isspace(*s) && s > str; --s); + if (s == str) + *s = '\0'; + else + *(++s) = '\0'; } /* Read numbers until non-digit is encountered, and return number in int form. */ -int curses_get_count(int first_digit) +int +curses_get_count(int first_digit) { long current_count = first_digit; int current_char; - + current_char = curses_read_char(); - - while (isdigit(current_char)) - { + + while (isdigit(current_char)) { current_count = (current_count * 10) + (current_char - '0'); - if (current_count > LARGEST_INT) - { + if (current_count > LARGEST_INT) { current_count = LARGEST_INT; } - + pline("Count: %ld", current_count); current_char = curses_read_char(); } - + ungetch(current_char); - - if (current_char == DOESCAPE) /* Cancelled with escape */ - { + + if (current_char == DOESCAPE) { /* Cancelled with escape */ current_count = -1; } - + return current_count; } @@ -689,43 +616,31 @@ int curses_get_count(int first_digit) /* Convert the given NetHack text attributes into the format curses understands, and return that format mask. */ -int curses_convert_attr(int attr) +int +curses_convert_attr(int attr) { int curses_attr; - - switch (attr) - { - case ATR_NONE: - { - curses_attr = A_NORMAL; - break; - } - case ATR_ULINE: - { - curses_attr = A_UNDERLINE; - break; - } - case ATR_BOLD: - { - curses_attr = A_BOLD; - break; - } - case ATR_BLINK: - { - curses_attr = A_BLINK; - break; - } - case ATR_INVERSE: - { - curses_attr = A_REVERSE; - break; - } - default: - { - curses_attr = A_NORMAL; - } + + switch (attr) { + case ATR_NONE: + curses_attr = A_NORMAL; + break; + case ATR_ULINE: + curses_attr = A_UNDERLINE; + break; + case ATR_BOLD: + curses_attr = A_BOLD; + break; + case ATR_BLINK: + curses_attr = A_BLINK; + break; + case ATR_INVERSE: + curses_attr = A_REVERSE; + break; + default: + curses_attr = A_NORMAL; } - + return curses_attr; } @@ -733,43 +648,36 @@ int curses_convert_attr(int attr) /* Map letter attributes from a string to bitmask. Return mask on success, or 0 if not found */ -int curses_read_attrs(char *attrs) +int +curses_read_attrs(char *attrs) { int retattr = 0; - if (strchr(attrs, 'b') || strchr(attrs, 'B')) - { - retattr = retattr|A_BOLD; + if (strchr(attrs, 'b') || strchr(attrs, 'B')) { + retattr = retattr | A_BOLD; } - if (strchr(attrs, 'i') || strchr(attrs, 'I')) - { - retattr = retattr|A_REVERSE; + if (strchr(attrs, 'i') || strchr(attrs, 'I')) { + retattr = retattr | A_REVERSE; } - if (strchr(attrs, 'u') || strchr(attrs, 'U')) - { - retattr = retattr|A_UNDERLINE; + if (strchr(attrs, 'u') || strchr(attrs, 'U')) { + retattr = retattr | A_UNDERLINE; } - if (strchr(attrs, 'k') || strchr(attrs, 'K')) - { - retattr = retattr|A_BLINK; + if (strchr(attrs, 'k') || strchr(attrs, 'K')) { + retattr = retattr | A_BLINK; } #ifdef A_ITALIC - if (strchr(attrs, 't') || strchr(attrs, 'T')) - { - retattr = retattr|A_ITALIC; + if (strchr(attrs, 't') || strchr(attrs, 'T')) { + retattr = retattr | A_ITALIC; } #endif #ifdef A_RIGHTLINE - if (strchr(attrs, 'r') || strchr(attrs, 'R')) - { - retattr = retattr|A_RIGHTLINE; + if (strchr(attrs, 'r') || strchr(attrs, 'R')) { + retattr = retattr | A_RIGHTLINE; } - #endif #ifdef A_LEFTLINE - if (strchr(attrs, 'l') || strchr(attrs, 'L')) - { - retattr = retattr|A_LEFTLINE; + if (strchr(attrs, 'l') || strchr(attrs, 'L')) { + retattr = retattr | A_LEFTLINE; } #endif @@ -780,136 +688,90 @@ int curses_read_attrs(char *attrs) /* Convert special keys into values that NetHack can understand. Currently this is limited to arrow keys, but this may be expanded. */ -int curses_convert_keys(int key) +int +curses_convert_keys(int key) { int ret = key; - - if (ret == '\033') - { + + if (ret == '\033') { ret = parse_escape_sequence(); } /* Handle arrow keys */ - switch (key) - { - case KEY_LEFT: - { - if (iflags.num_pad) - { - ret = '4'; - } - else - { - ret = 'h'; - } - break; - } - case KEY_RIGHT: - { - if (iflags.num_pad) - { - ret = '6'; - } - else - { - ret = 'l'; - } - break; - } - case KEY_UP: - { - if (iflags.num_pad) - { - ret = '8'; - } - else - { - ret = 'k'; - } - break; - } - case KEY_DOWN: - { - if (iflags.num_pad) - { - ret = '2'; - } - else - { - ret = 'j'; - } - break; - } + switch (key) { + case KEY_LEFT: + if (iflags.num_pad) { + ret = '4'; + } else { + ret = 'h'; + } + break; + case KEY_RIGHT: + if (iflags.num_pad) { + ret = '6'; + } else { + ret = 'l'; + } + break; + case KEY_UP: + if (iflags.num_pad) { + ret = '8'; + } else { + ret = 'k'; + } + break; + case KEY_DOWN: + if (iflags.num_pad) { + ret = '2'; + } else { + ret = 'j'; + } + break; #ifdef KEY_A1 - case KEY_A1: - { - if (iflags.num_pad) - { - ret = '7'; - } - else - { - ret = 'y'; - } - break; - } -#endif /* KEY_A1 */ + case KEY_A1: + if (iflags.num_pad) { + ret = '7'; + } else { + ret = 'y'; + } + break; +#endif /* KEY_A1 */ #ifdef KEY_A3 - case KEY_A3: - { - if (iflags.num_pad) - { - ret = '9'; - } - else - { - ret = 'u'; - } - break; - } -#endif /* KEY_A3 */ + case KEY_A3: + if (iflags.num_pad) { + ret = '9'; + } else { + ret = 'u'; + } + break; +#endif /* KEY_A3 */ #ifdef KEY_C1 - case KEY_C1: - { - if (iflags.num_pad) - { - ret = '1'; - } - else - { - ret = 'b'; - } - break; - } -#endif /* KEY_C1 */ + case KEY_C1: + if (iflags.num_pad) { + ret = '1'; + } else { + ret = 'b'; + } + break; +#endif /* KEY_C1 */ #ifdef KEY_C3 - case KEY_C3: - { - if (iflags.num_pad) - { - ret = '3'; - } - else - { - ret = 'n'; - } - break; - } -#endif /* KEY_C3 */ + case KEY_C3: + if (iflags.num_pad) { + ret = '3'; + } else { + ret = 'n'; + } + break; +#endif /* KEY_C3 */ #ifdef KEY_B2 - case KEY_B2: - { - if (iflags.num_pad) - { - ret = '5'; - } - else - { - ret = 'g'; - } - break; + case KEY_B2: + if (iflags.num_pad) { + ret = '5'; + } else { + ret = 'g'; } -#endif /* KEY_B2 */ + break; +#endif /* KEY_B2 */ } return ret; @@ -921,40 +783,39 @@ mouse movement events are available. Returns 0 for a mouse click event, or the first non-mouse key event in the case of mouse movement. */ -int curses_get_mouse(int *mousex, int *mousey, int *mod) +int +curses_get_mouse(int *mousex, int *mousey, int *mod) { int key = '\033'; + #ifdef NCURSES_MOUSE_VERSION - MEVENT event; + MEVENT event; - if (getmouse(&event) == OK) - { /* When the user clicks left mouse button */ - if(event.bstate & BUTTON1_CLICKED) - { + if (getmouse(&event) == OK) { /* When the user clicks left mouse button */ + if (event.bstate & BUTTON1_CLICKED) { /* See if coords are in map window & convert coords */ - if (wmouse_trafo(mapwin, &event.y, &event.x, TRUE)) - { - key = 0; /* Flag mouse click */ + if (wmouse_trafo(mapwin, &event.y, &event.x, TRUE)) { + key = 0; /* Flag mouse click */ *mousex = event.x; *mousey = event.y; - - if (curses_window_has_border(MAP_WIN)) - { + + if (curses_window_has_border(MAP_WIN)) { (*mousex)--; (*mousey)--; } - + *mod = CLICK_1; } } } -#endif /* NCURSES_MOUSE_VERSION */ +#endif /* NCURSES_MOUSE_VERSION */ return key; } -static int parse_escape_sequence(void) +static int +parse_escape_sequence(void) { #ifndef PDCURSES int ret; @@ -963,29 +824,19 @@ static int parse_escape_sequence(void) ret = getch(); - if (ret != ERR) /* Likely an escape sequence */ - { - if (((ret >= 'a') && (ret <= 'z')) || - ((ret >= '0') && (ret <= '9'))) - { - ret |= 0x80; /* Meta key support for most terminals */ - } - else if (ret == 'O') /* Numeric keypad */ - { + if (ret != ERR) { /* Likely an escape sequence */ + if (((ret >= 'a') && (ret <= 'z')) || ((ret >= '0') && (ret <= '9'))) { + ret |= 0x80; /* Meta key support for most terminals */ + } else if (ret == 'O') { /* Numeric keypad */ ret = getch(); - if ((ret != ERR) && (ret >= 112) && (ret <= 121)) - { + if ((ret != ERR) && (ret >= 112) && (ret <= 121)) { ret = ret - 112 + '0'; /* Convert to number */ - } - else - { - ret = '\033'; /* Escape */ + } else { + ret = '\033'; /* Escape */ } } - } - else - { - ret = '\033'; /* Just an escape character */ + } else { + ret = '\033'; /* Just an escape character */ } timeout(-1); @@ -993,7 +844,7 @@ static int parse_escape_sequence(void) return ret; #else return '\033'; -#endif /* !PDCURSES */ +#endif /* !PDCURSES */ } @@ -1002,8 +853,23 @@ functions, which causes a compiler error if TTY_GRAPHICS is not defined. Adding stub functions to avoid this. */ #if defined(STATUS_COLORS) && !defined(TTY_GRAPHICS) -extern void term_start_color(int color) {} -extern void term_start_attr(int attr) {} -extern void term_end_color() {} -extern void term_end_attr(int attr) {} -#endif /* STATUS_COLORS && !TTY_GRAPGICS */ +extern void +term_start_color(int color) +{ +} + +extern void +term_start_attr(int attr) +{ +} + +extern void +term_end_color() +{ +} + +extern void +term_end_attr(int attr) +{ +} +#endif /* STATUS_COLORS && !TTY_GRAPGICS */ diff --git a/win/curses/cursmisc.h b/win/curses/cursmisc.h index 0f03246a..398f5462 100644 --- a/win/curses/cursmisc.h +++ b/win/curses/cursmisc.h @@ -1,11 +1,13 @@ +/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ + #ifndef CURSMISC_H -#define CURSMISC_H +# define CURSMISC_H /* Global declarations */ int curses_read_char(void); -void curses_toggle_color_attr(WINDOW *win, int color, int attr, int onoff); +void curses_toggle_color_attr(WINDOW * win, int color, int attr, int onoff); void curses_bail(const char *mesg); @@ -45,4 +47,4 @@ int curses_convert_keys(int key); int curses_get_mouse(int *mousex, int *mousey, int *mod); -#endif /* CURSMISC_H */ +#endif /* CURSMISC_H */ diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index 505d1e54..a6b6ea52 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -1,3 +1,5 @@ +/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ + #include "curses.h" #include "hack.h" #include "wincurs.h" @@ -7,8 +9,7 @@ /* Private declarations */ -typedef struct nhs -{ +typedef struct nhs { long value; char *txt; aligntyp alignment; @@ -29,10 +30,12 @@ extern const struct percent_color_option *hp_colors; extern const struct percent_color_option *pw_colors; extern struct color_option text_color_of(const char *text, - const struct text_color_option *color_options); + const struct text_color_option + *color_options); struct color_option percentage_color_of(int value, int max, - const struct percent_color_option *color_options); + const struct percent_color_option + *color_options); static boolean stat_colored(const char *id); #endif @@ -40,8 +43,7 @@ static boolean stat_colored(const char *id); static void handle_status_problem(nhstat *, int, const char *, int *, int *, int, boolean); -static void handle_stat_change(nhstat *, int, int, int *, int *, - int, boolean); +static void handle_stat_change(nhstat *, int, int, int *, int *, int, boolean); static int decrement_highlight(nhstat *); @@ -61,7 +63,7 @@ static nhstat prevwis; static nhstat prevdex; static nhstat prevcon; static nhstat prevcha; -static nhstat prevalign; +static nhstat prevalign; static nhstat prevau; static nhstat prevhp; static nhstat prevmhp; @@ -71,6 +73,7 @@ static nhstat prevmpow; static nhstat prevac; static nhstat prevexp; static nhstat prevtime; + #ifdef SCORE_ON_BOTL static nhstat prevscore; #endif @@ -87,16 +90,16 @@ static nhstat prevencumb; #define NORMAL_LABELS 2 #define WIDE_LABELS 3 -extern const char *hu_stat[]; /* from eat.c */ -extern const char *enc_stat[]; /* from botl.c */ +extern const char *hu_stat[]; /* from eat.c */ +extern const char *enc_stat[]; /* from botl.c */ /* Handles numerical stat changes of various kinds. type is generally STAT_OTHER (generic "do nothing special"), but is used if the stat needs to be handled in a special way. */ -static void handle_stat_change(nhstat *stat, int new, int type, - int *sx, int *sy, int sx_start, - boolean horiz) +static void +handle_stat_change(nhstat *stat, int new, int type, + int *sx, int *sy, int sx_start, boolean horiz) { char buf[BUFSZ]; WINDOW *win = curses_get_nhwin(STATUS_WIN); @@ -104,59 +107,42 @@ static void handle_stat_change(nhstat *stat, int new, int type, /* Turncount isn't highlighted, or it would be highlighted constantly. Also note that these colors can be ignored if statuscolors is enabled in color_stat() */ - if (new != stat->value && type != STAT_TIME) - { + if (new != stat->value && type != STAT_TIME) { /* Less AC is better */ if ((type == STAT_AC && new < stat->value) || - (type != STAT_AC && new > stat->value)) - { - if (type == STAT_GOLD) - { + (type != STAT_AC && new > stat->value)) { + if (type == STAT_GOLD) { stat->highlight_color = HI_GOLD; - } - else - { + } else { stat->highlight_color = STAT_UP_COLOR; } - } - else - { + } else { stat->highlight_color = STAT_DOWN_COLOR; } stat->value = new; /* Strength might be displayed differently */ - if (type == STAT_STR && new > 18) - { - if (new > 118) - { + if (type == STAT_STR && new > 18) { + if (new > 118) { sprintf(buf, "%d", new - 100); - } - else if (new == 118) - { + } else if (new == 118) { sprintf(buf, "%d/**"); - } - else - { + } else { sprintf(buf, "18/%02d", new - 18); } - } - else - { + } else { sprintf(buf, "%d", new); } free(stat->txt); stat->txt = curses_copy_of(buf); stat->highlight_turns = 5; - if (type == STAT_HPEN) - { + if (type == STAT_HPEN) { stat->highlight_turns = 3; } } - if (stat->label) - { + if (stat->label) { mvwaddstr(win, *sy, *sx, stat->label); *sx += strlen(stat->label); } @@ -165,69 +151,53 @@ static void handle_stat_change(nhstat *stat, int new, int type, mvwaddstr(win, *sy, *sx, stat->txt); color_stat(*stat, OFF); - if (type == STAT_HPEN) - { + if (type == STAT_HPEN) { *sx += strlen(stat->txt); - } - else if (horiz) - { + } else if (horiz) { *sx += strlen(stat->txt) + 1; - } - else - { + } else { *sx = sx_start; *sy += 1; } } -static void handle_status_problem(nhstat *stat, int new, const char *str, - int *sx, int *sy, int sx_start, - boolean horiz) +static void +handle_status_problem(nhstat *stat, int new, const char *str, + int *sx, int *sy, int sx_start, boolean horiz) { WINDOW *win = curses_get_nhwin(STATUS_WIN); - if (new != stat->value) - { + if (new != stat->value) { stat->highlight_color = STAT_DOWN_COLOR; - if (stat->txt != NULL) - { + if (stat->txt != NULL) { free(stat->txt); } - if (new) - { + if (new) { stat->txt = curses_copy_of(str); - } - else - { + } else { stat->txt = NULL; } - if (stat->value == 0) - { + if (stat->value == 0) { stat->highlight_turns = 5; } stat->value = new; } - if (stat->label != NULL) - { + if (stat->label != NULL) { mvwaddstr(win, *sy, *sx, stat->label); *sx += strlen(stat->label); } - if (stat->txt != NULL) - { + if (stat->txt != NULL) { color_stat(*stat, ON); mvwaddstr(win, *sy, *sx, stat->txt); color_stat(*stat, OFF); - if (horiz) - { + if (horiz) { *sx += strlen(stat->txt) + 1; - } - else - { + } else { sx = sx_start; - *sy += 1; /* ++ would increase the pointer addr */ + *sy += 1; /* ++ would increase the pointer addr */ } } } @@ -236,11 +206,12 @@ static void handle_status_problem(nhstat *stat, int new, const char *str, write to the status window, so we know somwthing has changed. We override the write and update what needs to be updated ourselves. */ -void curses_update_stats(boolean redraw) +void +curses_update_stats(boolean redraw) { char buf[BUFSZ]; int count, enc, orient, sx_start, hp, hpmax, labels, swidth, - sheight, sx_end, sy_end; + sheight, sx_end, sy_end; WINDOW *win = curses_get_nhwin(STATUS_WIN); static int prev_labels = -1; static boolean first = TRUE; @@ -248,66 +219,53 @@ void curses_update_stats(boolean redraw) int sx = 0; int sy = 0; boolean border = curses_window_has_border(STATUS_WIN); - + curses_get_window_size(STATUS_WIN, &sheight, &swidth); - if (border) - { + if (border) { sx++; sy++; swidth--; sheight--; } - + sx_end = swidth - 1; - sy_end = sheight - 1; + sy_end = sheight - 1; sx_start = sx; - - if (first) - { + + if (first) { init_stats(); first = FALSE; redraw = TRUE; } - if (redraw) - { + if (redraw) { orient = curses_get_window_orientation(STATUS_WIN); - if ((orient == ALIGN_RIGHT) || (orient == ALIGN_LEFT)) - { + if ((orient == ALIGN_RIGHT) || (orient == ALIGN_LEFT)) { horiz = FALSE; - } - else - { + } else { horiz = TRUE; } } - - if (horiz) - { - if (term_cols >= 80) - { + + if (horiz) { + if (term_cols >= 80) { labels = NORMAL_LABELS; - } - else - { + } else { labels = COMPACT_LABELS; } - } - else - { + } else { labels = WIDE_LABELS; } - - if (labels != prev_labels) - { + + if (labels != prev_labels) { set_labels(labels); prev_labels = labels; } curses_clear_nhwin(STATUS_WIN); - + /* Line 1 */ /* Improve when this code is workable, this is a bit awkward at the moment */ @@ -317,16 +275,17 @@ void curses_update_stats(boolean redraw) /* Player name and title */ strcpy(buf, plname); - if ('a' <= buf[0] && buf[0] <= 'z') buf[0] += 'A'-'a'; + if ('a' <= buf[0] && buf[0] <= 'z') + buf[0] += 'A' - 'a'; strcat(buf, " the "); if (u.mtimedone) { char mname[BUFSZ]; int k = 0; + strcpy(mname, mons[u.umonnum].mname); - while(mname[k] != 0) { - if ((k == 0 || (k > 0 && mname[k-1] == ' ')) - && 'a' <= mname[k] && mname[k] <= 'z') - { + while (mname[k] != 0) { + if ((k == 0 || (k > 0 && mname[k - 1] == ' ')) + && 'a' <= mname[k] && mname[k] <= 'z') { mname[k] += 'A' - 'a'; } k++; @@ -335,51 +294,42 @@ void curses_update_stats(boolean redraw) } else { strcat(buf, rank_of(u.ulevel, pl_character[0], flags.female)); } - - if (strcmp(buf, prevname.txt) != 0) /* Title changed */ - { + + if (strcmp(buf, prevname.txt) != 0) { /* Title changed */ prevname.highlight_turns = 5; prevname.highlight_color = HIGHLIGHT_COLOR; free(prevname.txt); prevname.txt = curses_copy_of(buf); - if ((labels == COMPACT_LABELS) && (u.ulevel > 1)) - { + if ((labels == COMPACT_LABELS) && (u.ulevel > 1)) { curses_puts(MESSAGE_WIN, A_NORMAL, "You are now known as"); curses_puts(MESSAGE_WIN, A_NORMAL, prevname.txt); } } - - if (prevname.label != NULL) - { + + if (prevname.label != NULL) { mvwaddstr(win, sy, sx, prevname.label); sx += strlen(prevname.label); } - - if (labels != COMPACT_LABELS) - { + + if (labels != COMPACT_LABELS) { color_stat(prevname, ON); mvwaddstr(win, sy, sx, prevname.txt); color_stat(prevname, OFF); } - if (horiz) - { - if (labels != COMPACT_LABELS) - { + if (horiz) { + if (labels != COMPACT_LABELS) { sx += strlen(prevname.txt) + 1; } - - - } - else - { + + + } else { sx = sx_start; sy++; } - + /* Add dungeon name and level if status window is vertical */ - if (!horiz) - { + if (!horiz) { sprintf(buf, "%s", dungeons[u.uz.dnum].dname); mvwaddstr(win, sy, sx, buf); sy += 2; @@ -392,87 +342,70 @@ void curses_update_stats(boolean redraw) statchange(&prevdex, ACURR(A_DEX), STAT_OTHER); statchange(&prevcon, ACURR(A_CON), STAT_OTHER); statchange(&prevcha, ACURR(A_CHA), STAT_OTHER); - + /* Alignment */ - if (prevalign.alignment != u.ualign.type) /* Alignment changed */ - { + if (prevalign.alignment != u.ualign.type) { /* Alignment changed */ prevalign.highlight_color = HIGHLIGHT_COLOR; prevalign.highlight_turns = 10; /* This is a major change! */ prevalign.alignment = u.ualign.type; free(prevalign.txt); - switch (u.ualign.type) - { - case A_LAWFUL: - { - prevalign.txt = curses_copy_of("Lawful"); - break; - } - case A_NEUTRAL: - { - prevalign.txt = curses_copy_of("Neutral"); - break; - } - case A_CHAOTIC: - { - prevalign.txt = curses_copy_of("Chaotic"); - break; - } + switch (u.ualign.type) { + case A_LAWFUL: + prevalign.txt = curses_copy_of("Lawful"); + break; + case A_NEUTRAL: + prevalign.txt = curses_copy_of("Neutral"); + break; + case A_CHAOTIC: + prevalign.txt = curses_copy_of("Chaotic"); + break; } } - if (prevalign.label != NULL) - { + if (prevalign.label != NULL) { mvwaddstr(win, sy, sx, prevalign.label); sx += strlen(prevalign.label); } - + color_stat(prevalign, ON); mvwaddstr(win, sy, sx, prevalign.txt); color_stat(prevalign, OFF); /* Line 2 */ - + sx = sx_start; sy++; - + /* Dungeon Level */ - if (depth(&u.uz) != prevdepth.value) /* Dungeon level changed */ - { + if (depth(&u.uz) != prevdepth.value) { /* Dungeon level changed */ prevdepth.highlight_color = HIGHLIGHT_COLOR; prevdepth.highlight_turns = 5; prevdepth.value = depth(&u.uz); free(prevdepth.txt); - if (In_endgame(&u.uz)) - { - strcpy(buf, (Is_astralevel(&u.uz) ? "Astral Plane":"End Game")); - } - else - { + if (In_endgame(&u.uz)) { + strcpy(buf, (Is_astralevel(&u.uz) ? "Astral Plane" : "End Game")); + } else { sprintf(buf, "%d", depth(&u.uz)); } prevdepth.txt = curses_copy_of(buf); } - - if (prevdepth.label != NULL) - { + + if (prevdepth.label != NULL) { mvwaddstr(win, sy, sx, prevdepth.label); sx += strlen(prevdepth.label); } - + color_stat(prevdepth, ON); mvwaddstr(win, sy, sx, prevdepth.txt); color_stat(prevdepth, OFF); - - if (horiz) - { + + if (horiz) { sx += strlen(prevdepth.txt) + 1; - } - else - { + } else { sx = sx_start; sy++; } - + /* Gold */ #ifndef GOLDOBJ statchange(&prevau, u.ugold, STAT_GOLD); @@ -482,13 +415,11 @@ void curses_update_stats(boolean redraw) /* Hit Points */ - if (u.mtimedone) /* Currently polymorphed - show monster HP */ - { + if (u.mtimedone) { /* Currently polymorphed - show monster HP */ hp = u.mh; hpmax = u.mhmax; - } - else /* Not polymorphed */ - { + } else { /* Not polymorphed */ + hp = u.uhp; hpmax = u.uhpmax; } @@ -501,54 +432,38 @@ void curses_update_stats(boolean redraw) /* Experience */ #ifdef EXP_ON_BOTL - if (prevexp.display != flags.showexp) /* Setting has changed */ - { + if (prevexp.display != flags.showexp) { /* Setting has changed */ prevexp.display = flags.showexp; free(prevlevel.label); - if (prevexp.display) - { + if (prevexp.display) { prevlevel.label = curses_copy_of("/"); - } - else - { - if (horiz) - { - if (labels == COMPACT_LABELS) - { + } else { + if (horiz) { + if (labels == COMPACT_LABELS) { prevlevel.label = curses_copy_of("Lv:"); - } - else - { + } else { prevlevel.label = curses_copy_of("Lvl:"); } - } - else - { + } else { prevlevel.label = curses_copy_of("Level: "); } } } - if (prevexp.display && !u.mtimedone) - { - if (u.uexp != prevexp.value) - { - if (u.uexp > prevexp.value) - { - prevexp.highlight_color = STAT_UP_COLOR; - } - else - { + if (prevexp.display && !u.mtimedone) { + if (u.uexp != prevexp.value) { + if (u.uexp > prevexp.value) { + prevexp.highlight_color = STAT_UP_COLOR; + } else { prevexp.highlight_color = STAT_DOWN_COLOR; - } + } sprintf(buf, "%ld", u.uexp); free(prevexp.txt); prevexp.txt = curses_copy_of(buf); prevexp.highlight_turns = 3; - } + } - if (prevexp.label != NULL) - { + if (prevexp.label != NULL) { mvwaddstr(win, sy, sx, prevexp.label); sx += strlen(prevexp.label); } @@ -559,34 +474,25 @@ void curses_update_stats(boolean redraw) sx += strlen(prevexp.txt); } - - prevexp.value = u.uexp; /* Track it even when it's not displayed */ -#endif /* EXP_ON_BOTL */ + + prevexp.value = u.uexp; /* Track it even when it's not displayed */ +#endif /* EXP_ON_BOTL */ /* Level */ - if (u.mtimedone) /* Currently polymorphed - show monster HD */ - { + if (u.mtimedone) { /* Currently polymorphed - show monster HD */ if ((strncmp(prevlevel.label, "HP:", 3) != 0) || - (strncmp(prevlevel.label, "Hit Points:", 11) != 0)) - { + (strncmp(prevlevel.label, "Hit Points:", 11) != 0)) { free(prevlevel.label); - if (horiz) - { - prevlevel.label = curses_copy_of("HD:"); - } - else - { + if (horiz) { + prevlevel.label = curses_copy_of("HD:"); + } else { prevlevel.label = curses_copy_of("Hit Dice: "); } } - if (mons[u.umonnum].mlevel != prevlevel.value) - { - if (mons[u.umonnum].mlevel > prevlevel.value) - { + if (mons[u.umonnum].mlevel != prevlevel.value) { + if (mons[u.umonnum].mlevel > prevlevel.value) { prevlevel.highlight_color = STAT_UP_COLOR; - } - else - { + } else { prevlevel.highlight_color = STAT_DOWN_COLOR; } prevlevel.highlight_turns = 5; @@ -595,43 +501,29 @@ void curses_update_stats(boolean redraw) sprintf(buf, "%d", mons[u.umonnum].mlevel); free(prevlevel.txt); prevlevel.txt = curses_copy_of(buf); - } - else /* Not polymorphed */ - { + } else { /* Not polymorphed */ + if ((strncmp(prevlevel.label, "HD:", 3) != 0) || - (strncmp(prevlevel.label, "Hit Dice:", 9) != 0)) - { + (strncmp(prevlevel.label, "Hit Dice:", 9) != 0)) { free(prevlevel.label); - if (prevexp.display) - { + if (prevexp.display) { prevlevel.label = curses_copy_of("/"); - } - else - { - if (horiz) - { - if (labels == COMPACT_LABELS) - { + } else { + if (horiz) { + if (labels == COMPACT_LABELS) { prevlevel.label = curses_copy_of("Lv:"); - } - else - { + } else { prevlevel.label = curses_copy_of("Lvl:"); } - } - else - { + } else { prevlevel.label = curses_copy_of("Level: "); } } } - if (u.ulevel > prevlevel.value) - { + if (u.ulevel > prevlevel.value) { prevlevel.highlight_color = STAT_UP_COLOR; prevlevel.highlight_turns = 5; - } - else if (u.ulevel < prevlevel.value) - { + } else if (u.ulevel < prevlevel.value) { prevlevel.highlight_color = STAT_DOWN_COLOR; prevlevel.highlight_turns = 5; } @@ -641,8 +533,7 @@ void curses_update_stats(boolean redraw) prevlevel.txt = curses_copy_of(buf); } - if (prevlevel.label != NULL) - { + if (prevlevel.label != NULL) { mvwaddstr(win, sy, sx, prevlevel.label); sx += strlen(prevlevel.label); } @@ -651,56 +542,43 @@ void curses_update_stats(boolean redraw) mvwaddstr(win, sy, sx, prevlevel.txt); color_stat(prevlevel, OFF); - if (horiz) - { + if (horiz) { sx += strlen(prevlevel.txt) + 1; - } - else - { + } else { sx = sx_start; sy++; } /* Time */ - if (prevtime.display != flags.time) /* Setting has changed */ - { + if (prevtime.display != flags.time) { /* Setting has changed */ prevtime.display = flags.time; } - if (prevtime.display) - { + if (prevtime.display) { statchange(&prevtime, moves, STAT_TIME); } - + /* Score */ #ifdef SCORE_ON_BOTL - if (prevscore.display != flags.showscore) /* Setting has changed */ - { + if (prevscore.display != flags.showscore) { /* Setting has changed */ prevscore.display = flags.showscore; } - if (prevscore.display) - { + if (prevscore.display) { statchange(&prevscore, botl_score(), STAT_OTHER); } - - prevscore.value = botl_score(); /* Track it even when it's not displayed */ -#endif /* SCORE_ON_BOTL */ + + prevscore.value = botl_score(); /* Track it even when it's not displayed */ +#endif /* SCORE_ON_BOTL */ /* Hunger */ - if (u.uhs != prevhunger.value) - { - if ((u.uhs > prevhunger.value) || (u.uhs > 3)) - { - prevhunger.highlight_color = STAT_DOWN_COLOR; - } - else - { + if (u.uhs != prevhunger.value) { + if ((u.uhs > prevhunger.value) || (u.uhs > 3)) { + prevhunger.highlight_color = STAT_DOWN_COLOR; + } else { prevhunger.highlight_color = STAT_UP_COLOR; - } + } prevhunger.value = u.uhs; - for (count = 0; count < strlen(hu_stat[u.uhs]); count++) - { - if ((hu_stat[u.uhs][count]) == ' ') - { + for (count = 0; count < strlen(hu_stat[u.uhs]); count++) { + if ((hu_stat[u.uhs][count]) == ' ') { break; } buf[count] = hu_stat[u.uhs][count]; @@ -710,10 +588,9 @@ void curses_update_stats(boolean redraw) free(prevhunger.txt); prevhunger.txt = curses_copy_of(buf); prevhunger.highlight_turns = 5; - } + } - if (prevhunger.label != NULL) - { + if (prevhunger.label != NULL) { mvwaddstr(win, sy, sx, prevhunger.label); sx += strlen(prevhunger.label); } @@ -721,20 +598,15 @@ void curses_update_stats(boolean redraw) color_stat(prevhunger, ON); mvwaddstr(win, sy, sx, prevhunger.txt); color_stat(prevhunger, OFF); - - if (strlen(prevhunger.txt) > 0) - { - if (horiz) - { + + if (strlen(prevhunger.txt) > 0) { + if (horiz) { sx += strlen(prevhunger.txt) + 1; - } - else - { + } else { sx = sx_start; sy++; } } - #define statusproblem(stat,new,str) handle_status_problem(stat, new, str, &sx, &sy, \ sx_start, horiz) @@ -745,60 +617,47 @@ void curses_update_stats(boolean redraw) statusproblem(&prevhallu, Hallucination, "Hallu"); /* TODO: allow all 3 kinds of sickness seperately: FoodPois, Ill, Zombie */ - statusproblem(&prevsick, Sick, (u.usick_type & SICK_VOMITABLE) ? "FoodPois" : "Ill"); + statusproblem(&prevsick, Sick, + (u.usick_type & SICK_VOMITABLE) ? "FoodPois" : "Ill"); statusproblem(&prevslime, Slimed, "Slime"); /* Encumberance */ enc = near_capacity(); - - if (enc != prevencumb.value) - { - if (enc < prevencumb.value) - { - prevencumb.highlight_color = STAT_UP_COLOR; - } - else - { - prevencumb.highlight_color = STAT_DOWN_COLOR; - } - if (prevencumb.txt != NULL) - { + + if (enc != prevencumb.value) { + if (enc < prevencumb.value) { + prevencumb.highlight_color = STAT_UP_COLOR; + } else { + prevencumb.highlight_color = STAT_DOWN_COLOR; + } + if (prevencumb.txt != NULL) { free(prevencumb.txt); } - if (enc > UNENCUMBERED) - { + if (enc > UNENCUMBERED) { sprintf(buf, "%s", enc_stat[enc]); prevencumb.txt = curses_copy_of(buf); prevencumb.highlight_turns = 5; - } - else - { + } else { prevencumb.txt = NULL; } prevencumb.value = enc; - } + } - if (prevencumb.label != NULL) - { + if (prevencumb.label != NULL) { mvwaddstr(win, sy, sx, prevencumb.label); sx += strlen(prevencumb.label); } - if (prevencumb.txt != NULL) - { + if (prevencumb.txt != NULL) { color_stat(prevencumb, ON); mvwaddstr(win, sy, sx, prevencumb.txt); color_stat(prevencumb, OFF); } - if (prevencumb.txt != NULL) - { - if (horiz) - { + if (prevencumb.txt != NULL) { + if (horiz) { sx += strlen(prevencumb.txt) + 1; - } - else - { + } else { sx = sx_start; sy++; } @@ -809,13 +668,12 @@ void curses_update_stats(boolean redraw) /* Decrement a single highlight, return 1 if decremented to zero */ -static int decrement_highlight(nhstat *stat) +static int +decrement_highlight(nhstat *stat) { - if (stat->highlight_turns > 0) - { + if (stat->highlight_turns > 0) { stat->highlight_turns--; - if (stat->highlight_turns == 0) - { + if (stat->highlight_turns == 0) { return 1; } } @@ -825,9 +683,11 @@ static int decrement_highlight(nhstat *stat) /* Decrement the highlight_turns for all stats. Call curses_update_stats if needed to unhighlight a stat */ -void curses_decrement_highlight() +void +curses_decrement_highlight() { int unhighlight = 0; + unhighlight |= decrement_highlight(&prevname); unhighlight |= decrement_highlight(&prevdepth); unhighlight |= decrement_highlight(&prevstr); @@ -860,8 +720,7 @@ void curses_decrement_highlight() unhighlight |= decrement_highlight(&prevslime); unhighlight |= decrement_highlight(&prevencumb); - if (unhighlight) - { + if (unhighlight) { curses_update_stats(FALSE); } } @@ -869,24 +728,25 @@ void curses_decrement_highlight() /* Initialize the stats with beginning values. */ -static void init_stats() +static void +init_stats() { char buf[BUFSZ]; int count; /* Player name and title */ strcpy(buf, plname); - if ('a' <= buf[0] && buf[0] <= 'z') buf[0] += 'A'-'a'; + if ('a' <= buf[0] && buf[0] <= 'z') + buf[0] += 'A' - 'a'; strcat(buf, " the "); if (u.mtimedone) { char mname[BUFSZ]; int k = 0; strcpy(mname, mons[u.umonnum].mname); - while(mname[k] != 0) { - if ((k == 0 || (k > 0 && mname[k-1] == ' ')) - && 'a' <= mname[k] && mname[k] <= 'z') - { + while (mname[k] != 0) { + if ((k == 0 || (k > 0 && mname[k - 1] == ' ')) + && 'a' <= mname[k] && mname[k] <= 'z') { mname[k] += 'A' - 'a'; } k++; @@ -902,22 +762,15 @@ static void init_stats() prevname.label = NULL; prevname.id = "name"; set_stat_color(&prevname); - + /* Strength */ - if (ACURR(A_STR) > 118) - { + if (ACURR(A_STR) > 118) { sprintf(buf, "%d", ACURR(A_STR) - 100); - } - else if (ACURR(A_STR)==118) - { + } else if (ACURR(A_STR) == 118) { sprintf(buf, "18/**"); - } - else if(ACURR(A_STR) > 18) - { + } else if (ACURR(A_STR) > 18) { sprintf(buf, "18/%02d", ACURR(A_STR) - 18); - } - else - { + } else { sprintf(buf, "%d", ACURR(A_STR)); } @@ -980,39 +833,29 @@ static void init_stats() set_stat_color(&prevcha); /* Alignment */ - switch (u.ualign.type) - { - case A_LAWFUL: - { - prevalign.txt = curses_copy_of("Lawful"); - break; - } - case A_NEUTRAL: - { - prevalign.txt = curses_copy_of("Neutral"); - break; - } - case A_CHAOTIC: - { - prevalign.txt = curses_copy_of("Chaotic"); - break; - } + switch (u.ualign.type) { + case A_LAWFUL: + prevalign.txt = curses_copy_of("Lawful"); + break; + case A_NEUTRAL: + prevalign.txt = curses_copy_of("Neutral"); + break; + case A_CHAOTIC: + prevalign.txt = curses_copy_of("Chaotic"); + break; } - + prevalign.alignment = u.ualign.type; prevalign.display = TRUE; prevalign.highlight_turns = 0; prevalign.label = NULL; prevalign.id = "align"; set_stat_color(&prevalign); - + /* Dungeon level */ - if (In_endgame(&u.uz)) - { - strcpy(buf, (Is_astralevel(&u.uz) ? "Astral Plane":"End Game")); - } - else - { + if (In_endgame(&u.uz)) { + strcpy(buf, (Is_astralevel(&u.uz) ? "Astral Plane" : "End Game")); + } else { sprintf(buf, "%d", depth(&u.uz)); } @@ -1023,13 +866,13 @@ static void init_stats() prevdepth.label = NULL; prevdepth.id = "dlvl"; set_stat_color(&prevdepth); - + /* Gold */ #ifndef GOLDOBJ - sprintf(buf,"%ld", u.ugold); + sprintf(buf, "%ld", u.ugold); prevau.value = u.ugold; #else - sprintf(buf,"%ld", money_cnt(invent)); + sprintf(buf, "%ld", money_cnt(invent)); prevau.value = money_cnt(invent); #endif prevau.txt = curses_copy_of(buf); @@ -1040,39 +883,34 @@ static void init_stats() set_stat_color(&prevau); /* Hit Points */ - if (u.mtimedone) /* Currently polymorphed - show monster HP */ - { + if (u.mtimedone) { /* Currently polymorphed - show monster HP */ prevhp.value = u.mh; sprintf(buf, "%d", u.mh); prevhp.txt = curses_copy_of(buf); - } - else if (u.uhp != prevhp.value) /* Not polymorphed */ - { - prevhp.value = u.uhp; + } else if (u.uhp != prevhp.value) { /* Not polymorphed */ + prevhp.value = u.uhp; sprintf(buf, "%d", u.uhp); prevhp.txt = curses_copy_of(buf); - } - prevhp.display = TRUE; - prevhp.highlight_turns = 0; + } + prevhp.display = TRUE; + prevhp.highlight_turns = 0; prevhp.label = NULL; prevhp.id = "hp"; set_stat_color(&prevhp); /* Max Hit Points */ - if (u.mtimedone) /* Currently polymorphed - show monster HP */ - { + if (u.mtimedone) { /* Currently polymorphed - show monster HP */ prevmhp.value = u.mhmax; sprintf(buf, "%d", u.mhmax); prevmhp.txt = curses_copy_of(buf); - } - else /* Not polymorphed */ - { - prevmhp.value = u.uhpmax; + } else { /* Not polymorphed */ + + prevmhp.value = u.uhpmax; sprintf(buf, "%d", u.uhpmax); prevmhp.txt = curses_copy_of(buf); - } - prevmhp.display = TRUE; - prevmhp.highlight_turns = 0; + } + prevmhp.display = TRUE; + prevmhp.highlight_turns = 0; prevmhp.label = curses_copy_of("/"); prevmhp.id = "mhp"; set_stat_color(&prevmhp); @@ -1081,8 +919,8 @@ static void init_stats() prevpow.value = u.uen; sprintf(buf, "%d", u.uen); prevpow.txt = curses_copy_of(buf); - prevpow.display = TRUE; - prevpow.highlight_turns = 0; + prevpow.display = TRUE; + prevpow.highlight_turns = 0; prevpow.label = NULL; prevpow.id = "pw"; set_stat_color(&prevpow); @@ -1091,8 +929,8 @@ static void init_stats() prevmpow.value = u.uenmax; sprintf(buf, "%d", u.uenmax); prevmpow.txt = curses_copy_of(buf); - prevmpow.display = TRUE; - prevmpow.highlight_turns = 0; + prevmpow.display = TRUE; + prevmpow.highlight_turns = 0; prevmpow.label = curses_copy_of("/"); prevmpow.id = "mpw"; set_stat_color(&prevmpow); @@ -1101,8 +939,8 @@ static void init_stats() prevac.value = u.uac; sprintf(buf, "%d", u.uac); prevac.txt = curses_copy_of(buf); - prevac.display = TRUE; - prevac.highlight_turns = 0; + prevac.display = TRUE; + prevac.highlight_turns = 0; prevac.label = NULL; prevac.id = "ac"; set_stat_color(&prevac); @@ -1112,8 +950,8 @@ static void init_stats() prevexp.value = u.uexp; sprintf(buf, "%ld", u.uexp); prevexp.txt = curses_copy_of(buf); - prevexp.display = flags.showexp; - prevexp.highlight_turns = 0; + prevexp.display = flags.showexp; + prevexp.highlight_turns = 0; prevexp.label = NULL; prevexp.id = "xp"; set_stat_color(&prevexp); @@ -1121,20 +959,17 @@ static void init_stats() /* Level */ prevlevel.label = NULL; - if (u.mtimedone) /* Currently polymorphed - show monster HP */ - { + if (u.mtimedone) { /* Currently polymorphed - show monster HP */ prevlevel.value = mons[u.umonnum].mlevel; sprintf(buf, "%d", mons[u.umonnum].mlevel); prevlevel.txt = curses_copy_of(buf); - } - else if (u.ulevel != prevlevel.value) /* Not polymorphed */ - { - prevlevel.value = u.ulevel; + } else if (u.ulevel != prevlevel.value) { /* Not polymorphed */ + prevlevel.value = u.ulevel; sprintf(buf, "%d", u.ulevel); prevlevel.txt = curses_copy_of(buf); - } - prevlevel.display = TRUE; - prevlevel.highlight_turns = 0; + } + prevlevel.display = TRUE; + prevlevel.highlight_turns = 0; prevlevel.id = "lvl"; set_stat_color(&prevlevel); @@ -1142,8 +977,8 @@ static void init_stats() prevtime.value = moves; sprintf(buf, "%ld", moves); prevtime.txt = curses_copy_of(buf); - prevtime.display = flags.time; - prevtime.highlight_turns = 0; + prevtime.display = flags.time; + prevtime.highlight_turns = 0; prevtime.label = NULL; prevtime.id = "time"; set_stat_color(&prevtime); @@ -1153,8 +988,8 @@ static void init_stats() prevscore.value = botl_score(); sprintf(buf, "%ld", botl_score()); prevscore.txt = curses_copy_of(buf); - prevscore.display = flags.showscore; - prevscore.highlight_turns = 0; + prevscore.display = flags.showscore; + prevscore.highlight_turns = 0; prevscore.label = NULL; prevscore.id = "score"; set_stat_color(&prevscore); @@ -1162,10 +997,8 @@ static void init_stats() /* Hunger */ prevhunger.value = u.uhs; - for (count = 0; count < strlen(hu_stat[u.uhs]); count++) - { - if ((hu_stat[u.uhs][count]) == ' ') - { + for (count = 0; count < strlen(hu_stat[u.uhs]); count++) { + if ((hu_stat[u.uhs][count]) == ' ') { break; } buf[count] = hu_stat[u.uhs][count]; @@ -1181,12 +1014,9 @@ static void init_stats() /* Confusion */ prevconf.value = Confusion; - if (Confusion) - { + if (Confusion) { prevconf.txt = curses_copy_of("Conf"); - } - else - { + } else { prevconf.txt = NULL; } prevconf.display = TRUE; @@ -1197,12 +1027,9 @@ static void init_stats() /* Blindness */ prevblind.value = Blind; - if (Blind) - { + if (Blind) { prevblind.txt = curses_copy_of("Blind"); - } - else - { + } else { prevblind.txt = NULL; } prevblind.display = TRUE; @@ -1213,12 +1040,9 @@ static void init_stats() /* Stun */ prevstun.value = Stunned; - if (Stunned) - { + if (Stunned) { prevstun.txt = curses_copy_of("Stun"); - } - else - { + } else { prevstun.txt = NULL; } prevstun.display = TRUE; @@ -1229,12 +1053,9 @@ static void init_stats() /* Hallucination */ prevhallu.value = Hallucination; - if (Hallucination) - { + if (Hallucination) { prevhallu.txt = curses_copy_of("Hallu"); - } - else - { + } else { prevhallu.txt = NULL; } prevhallu.display = TRUE; @@ -1245,19 +1066,13 @@ static void init_stats() /* Sick */ prevsick.value = Sick; - if (Sick) - { - if (u.usick_type & SICK_VOMITABLE) - { + if (Sick) { + if (u.usick_type & SICK_VOMITABLE) { prevsick.txt = curses_copy_of("FoodPois"); - } - else - { + } else { prevsick.txt = curses_copy_of("Ill"); } - } - else - { + } else { prevsick.txt = NULL; } prevsick.display = TRUE; @@ -1268,12 +1083,9 @@ static void init_stats() /* Slimed */ prevslime.value = Slimed; - if (Slimed) - { + if (Slimed) { prevslime.txt = curses_copy_of("Slime"); - } - else - { + } else { prevslime.txt = NULL; } prevslime.display = TRUE; @@ -1284,13 +1096,10 @@ static void init_stats() /* Encumberance */ prevencumb.value = near_capacity(); - if (prevencumb.value > UNENCUMBERED) - { + if (prevencumb.value > UNENCUMBERED) { sprintf(buf, "%s", enc_stat[prevencumb.value]); prevencumb.txt = curses_copy_of(buf); - } - else - { + } else { prevencumb.txt = NULL; } prevencumb.display = TRUE; @@ -1304,419 +1113,350 @@ static void init_stats() we want to compress this info; otherwise we know we have a width of at least 26 characters. */ -static void set_labels(int label_width) +static void +set_labels(int label_width) { char buf[BUFSZ]; - switch (label_width) - { - case COMPACT_LABELS: - { - /* Strength */ - if (prevstr.label) - { - free (prevstr.label); - } - prevstr.label = curses_copy_of("S:"); - /* Intelligence */ - if (prevint.label) - { - free (prevint.label); - } - prevint.label = curses_copy_of("I:"); + switch (label_width) { + case COMPACT_LABELS: + /* Strength */ + if (prevstr.label) { + free(prevstr.label); + } + prevstr.label = curses_copy_of("S:"); + /* Intelligence */ + if (prevint.label) { + free(prevint.label); + } + prevint.label = curses_copy_of("I:"); - /* Wisdom */ - if (prevwis.label) - { - free (prevwis.label); - } - prevwis.label = curses_copy_of("W:"); - - /* Dexterity */ - if (prevdex.label) - { - free (prevdex.label); - } - prevdex.label = curses_copy_of("D:"); - - /* Constitution */ - if (prevcon.label) - { - free (prevcon.label); - } - prevcon.label = curses_copy_of("C:"); - - /* Charisma */ - if (prevcha.label) - { - free (prevcha.label); - } - prevcha.label = curses_copy_of("Ch:"); - - /* Alignment */ - if (prevalign.label) - { - free (prevalign.label); - } - prevalign.label = NULL; - - /* Dungeon level */ - if (prevdepth.label) - { - free (prevdepth.label); - } - prevdepth.label = curses_copy_of("Dl:"); - - /* Gold */ - if (prevau.label) - { - free (prevau.label); - } - sprintf(buf, "%c:", GOLD_SYM); - prevau.label = curses_copy_of(buf); - - /* Hit points */ - if (prevhp.label) - { - free (prevhp.label); - } - prevhp.label = curses_copy_of("HP:"); - - /* Power */ - if (prevpow.label) - { - free (prevpow.label); - } - prevpow.label = curses_copy_of("Pw:"); - - /* Armor Class */ - if (prevac.label) - { - free (prevac.label); - } - prevac.label = curses_copy_of("AC:"); - -#ifdef EXP_ON_BOTL - /* Experience */ - if (prevexp.label) - { - free (prevexp.label); - } - prevexp.label = curses_copy_of("XP:"); -#endif - - /* Level */ - if (prevlevel.label) - { - free (prevlevel.label); - prevlevel.label = NULL; - } - if (u.mtimedone) /* Currently polymorphed - show monster HP */ - { - prevlevel.label = curses_copy_of("HD:"); - } - else /* Not polymorphed */ - { - if (prevexp.display) - { - prevlevel.label = curses_copy_of("/"); - } - else - { - prevlevel.label = curses_copy_of("Lv:"); - } - } - - /* Time */ - if (prevtime.label) - { - free (prevtime.label); - } - prevtime.label = curses_copy_of("T:"); - -#ifdef SCORE_ON_BOTL - /* Score */ - if (prevscore.label) - { - free (prevscore.label); - } - prevscore.label = curses_copy_of("S:"); + /* Wisdom */ + if (prevwis.label) { + free(prevwis.label); + } + prevwis.label = curses_copy_of("W:"); + + /* Dexterity */ + if (prevdex.label) { + free(prevdex.label); + } + prevdex.label = curses_copy_of("D:"); + + /* Constitution */ + if (prevcon.label) { + free(prevcon.label); + } + prevcon.label = curses_copy_of("C:"); + + /* Charisma */ + if (prevcha.label) { + free(prevcha.label); + } + prevcha.label = curses_copy_of("Ch:"); + + /* Alignment */ + if (prevalign.label) { + free(prevalign.label); + } + prevalign.label = NULL; + + /* Dungeon level */ + if (prevdepth.label) { + free(prevdepth.label); + } + prevdepth.label = curses_copy_of("Dl:"); + + /* Gold */ + if (prevau.label) { + free(prevau.label); + } + sprintf(buf, "%c:", GOLD_SYM); + prevau.label = curses_copy_of(buf); + + /* Hit points */ + if (prevhp.label) { + free(prevhp.label); + } + prevhp.label = curses_copy_of("HP:"); + + /* Power */ + if (prevpow.label) { + free(prevpow.label); + } + prevpow.label = curses_copy_of("Pw:"); + + /* Armor Class */ + if (prevac.label) { + free(prevac.label); + } + prevac.label = curses_copy_of("AC:"); + +#ifdef EXP_ON_BOTL + /* Experience */ + if (prevexp.label) { + free(prevexp.label); + } + prevexp.label = curses_copy_of("XP:"); #endif - break; + + /* Level */ + if (prevlevel.label) { + free(prevlevel.label); + prevlevel.label = NULL; } - case NORMAL_LABELS: - { - /* Strength */ - if (prevstr.label) - { - free (prevstr.label); - } - prevstr.label = curses_copy_of("Str:"); - /* Intelligence */ - if (prevint.label) - { - free (prevint.label); - } - prevint.label = curses_copy_of("Int:"); + if (u.mtimedone) { /* Currently polymorphed - show monster HP */ + prevlevel.label = curses_copy_of("HD:"); + } else { /* Not polymorphed */ - /* Wisdom */ - if (prevwis.label) - { - free (prevwis.label); - } - prevwis.label = curses_copy_of("Wis:"); - - /* Dexterity */ - if (prevdex.label) - { - free (prevdex.label); - } - prevdex.label = curses_copy_of("Dex:"); - - /* Constitution */ - if (prevcon.label) - { - free (prevcon.label); - } - prevcon.label = curses_copy_of("Con:"); - - /* Charisma */ - if (prevcha.label) - { - free (prevcha.label); - } - prevcha.label = curses_copy_of("Cha:"); - - /* Alignment */ - if (prevalign.label) - { - free (prevalign.label); - } - prevalign.label = NULL; - - /* Dungeon level */ - if (prevdepth.label) - { - free (prevdepth.label); - } - prevdepth.label = curses_copy_of("Dlvl:"); - - /* Gold */ - if (prevau.label) - { - free (prevau.label); - } - sprintf(buf, "%c:", GOLD_SYM); - prevau.label = curses_copy_of(buf); - - /* Hit points */ - if (prevhp.label) - { - free (prevhp.label); - } - prevhp.label = curses_copy_of("HP:"); - - /* Power */ - if (prevpow.label) - { - free (prevpow.label); - } - prevpow.label = curses_copy_of("Pw:"); - - /* Armor Class */ - if (prevac.label) - { - free (prevac.label); - } - prevac.label = curses_copy_of("AC:"); - -#ifdef EXP_ON_BOTL - /* Experience */ - if (prevexp.label) - { - free (prevexp.label); - } - prevexp.label = curses_copy_of("XP:"); -#endif - - /* Level */ - if (prevlevel.label) - { - free (prevlevel.label); - prevlevel.label = NULL; - } - if (u.mtimedone) /* Currently polymorphed - show monster HP */ - { - prevlevel.label = curses_copy_of("HD:"); - } - else /* Not polymorphed */ - { - if (prevexp.display) - { - prevlevel.label = curses_copy_of("/"); - } - else - { - prevlevel.label = curses_copy_of("Lvl:"); - } - } - - /* Time */ - if (prevtime.label) - { - free (prevtime.label); + if (prevexp.display) { + prevlevel.label = curses_copy_of("/"); + } else { + prevlevel.label = curses_copy_of("Lv:"); } - prevtime.label = curses_copy_of("T:"); - + } + + /* Time */ + if (prevtime.label) { + free(prevtime.label); + } + prevtime.label = curses_copy_of("T:"); + #ifdef SCORE_ON_BOTL - /* Score */ - if (prevscore.label) - { - free (prevscore.label); - } - prevscore.label = curses_copy_of("S:"); + /* Score */ + if (prevscore.label) { + free(prevscore.label); + } + prevscore.label = curses_copy_of("S:"); #endif - break; + break; + + case NORMAL_LABELS: + /* Strength */ + if (prevstr.label) { + free(prevstr.label); } - case WIDE_LABELS: - { - /* Strength */ - if (prevstr.label) - { - free (prevstr.label); - } - prevstr.label = curses_copy_of("Strength: "); - - /* Intelligence */ - if (prevint.label) - { - free (prevint.label); - } - prevint.label = curses_copy_of("Intelligence: "); - - /* Wisdom */ - if (prevwis.label) - { - free (prevwis.label); - } - prevwis.label = curses_copy_of("Wisdom: "); - - /* Dexterity */ - if (prevdex.label) - { - free (prevdex.label); - } - prevdex.label = curses_copy_of("Dexterity: "); - - /* Constitution */ - if (prevcon.label) - { - free (prevcon.label); - } - prevcon.label = curses_copy_of("Constitution: "); - - /* Charisma */ - if (prevcha.label) - { - free (prevcha.label); - } - prevcha.label = curses_copy_of("Charisma: "); - - /* Alignment */ - if (prevalign.label) - { - free (prevalign.label); - } - prevalign.label = curses_copy_of("Alignment: "); - - /* Dungeon level */ - if (prevdepth.label) - { - free (prevdepth.label); - } - prevdepth.label = curses_copy_of("Dungeon Level: "); - - /* Gold */ - if (prevau.label) - { - free (prevau.label); - } - prevau.label = curses_copy_of("Gold: "); - - /* Hit points */ - if (prevhp.label) - { - free (prevhp.label); - } - prevhp.label = curses_copy_of("Hit Points: "); - - /* Power */ - if (prevpow.label) - { - free (prevpow.label); - } - prevpow.label = curses_copy_of("Magic Power: "); - - /* Armor Class */ - if (prevac.label) - { - free (prevac.label); - } - prevac.label = curses_copy_of("Armor Class: "); - -#ifdef EXP_ON_BOTL - /* Experience */ - if (prevexp.label) - { - free (prevexp.label); - } - prevexp.label = curses_copy_of("Experience: "); -#endif + prevstr.label = curses_copy_of("Str:"); + /* Intelligence */ + if (prevint.label) { + free(prevint.label); + } + prevint.label = curses_copy_of("Int:"); - /* Level */ - if (prevlevel.label) - { - free (prevlevel.label); - } - if (u.mtimedone) /* Currently polymorphed - show monster HP */ - { - prevlevel.label = curses_copy_of("Hit Dice: "); - } - else /* Not polymorphed */ - { - if (prevexp.display) - { - prevlevel.label = curses_copy_of(" / "); - } - else - { - prevlevel.label = curses_copy_of("Level: "); - } - } - - /* Time */ - if (prevtime.label) - { - free (prevtime.label); + /* Wisdom */ + if (prevwis.label) { + free(prevwis.label); + } + prevwis.label = curses_copy_of("Wis:"); + + /* Dexterity */ + if (prevdex.label) { + free(prevdex.label); + } + prevdex.label = curses_copy_of("Dex:"); + + /* Constitution */ + if (prevcon.label) { + free(prevcon.label); + } + prevcon.label = curses_copy_of("Con:"); + + /* Charisma */ + if (prevcha.label) { + free(prevcha.label); + } + prevcha.label = curses_copy_of("Cha:"); + + /* Alignment */ + if (prevalign.label) { + free(prevalign.label); + } + prevalign.label = NULL; + + /* Dungeon level */ + if (prevdepth.label) { + free(prevdepth.label); + } + prevdepth.label = curses_copy_of("Dlvl:"); + + /* Gold */ + if (prevau.label) { + free(prevau.label); + } + sprintf(buf, "%c:", GOLD_SYM); + prevau.label = curses_copy_of(buf); + + /* Hit points */ + if (prevhp.label) { + free(prevhp.label); + } + prevhp.label = curses_copy_of("HP:"); + + /* Power */ + if (prevpow.label) { + free(prevpow.label); + } + prevpow.label = curses_copy_of("Pw:"); + + /* Armor Class */ + if (prevac.label) { + free(prevac.label); + } + prevac.label = curses_copy_of("AC:"); + +#ifdef EXP_ON_BOTL + /* Experience */ + if (prevexp.label) { + free(prevexp.label); + } + prevexp.label = curses_copy_of("XP:"); +#endif + + /* Level */ + if (prevlevel.label) { + free(prevlevel.label); + prevlevel.label = NULL; + } + if (u.mtimedone) { /* Currently polymorphed - show monster HP */ + prevlevel.label = curses_copy_of("HD:"); + } else { /* Not polymorphed */ + + if (prevexp.display) { + prevlevel.label = curses_copy_of("/"); + } else { + prevlevel.label = curses_copy_of("Lvl:"); } - prevtime.label = curses_copy_of("Time: "); - + } + + /* Time */ + if (prevtime.label) { + free(prevtime.label); + } + prevtime.label = curses_copy_of("T:"); + #ifdef SCORE_ON_BOTL - /* Score */ - if (prevscore.label) - { - free (prevscore.label); - } - prevscore.label = curses_copy_of("Score: "); + /* Score */ + if (prevscore.label) { + free(prevscore.label); + } + prevscore.label = curses_copy_of("S:"); #endif - break; + break; + + case WIDE_LABELS: + /* Strength */ + if (prevstr.label) { + free(prevstr.label); } - default: - { - panic( "set_labels(): Invalid label_width %d\n", - label_width ); - break; + prevstr.label = curses_copy_of("Strength: "); + + /* Intelligence */ + if (prevint.label) { + free(prevint.label); + } + prevint.label = curses_copy_of("Intelligence: "); + + /* Wisdom */ + if (prevwis.label) { + free(prevwis.label); + } + prevwis.label = curses_copy_of("Wisdom: "); + + /* Dexterity */ + if (prevdex.label) { + free(prevdex.label); + } + prevdex.label = curses_copy_of("Dexterity: "); + + /* Constitution */ + if (prevcon.label) { + free(prevcon.label); + } + prevcon.label = curses_copy_of("Constitution: "); + + /* Charisma */ + if (prevcha.label) { + free(prevcha.label); + } + prevcha.label = curses_copy_of("Charisma: "); + + /* Alignment */ + if (prevalign.label) { + free(prevalign.label); + } + prevalign.label = curses_copy_of("Alignment: "); + + /* Dungeon level */ + if (prevdepth.label) { + free(prevdepth.label); + } + prevdepth.label = curses_copy_of("Dungeon Level: "); + + /* Gold */ + if (prevau.label) { + free(prevau.label); + } + prevau.label = curses_copy_of("Gold: "); + + /* Hit points */ + if (prevhp.label) { + free(prevhp.label); + } + prevhp.label = curses_copy_of("Hit Points: "); + + /* Power */ + if (prevpow.label) { + free(prevpow.label); + } + prevpow.label = curses_copy_of("Magic Power: "); + + /* Armor Class */ + if (prevac.label) { + free(prevac.label); + } + prevac.label = curses_copy_of("Armor Class: "); + +#ifdef EXP_ON_BOTL + /* Experience */ + if (prevexp.label) { + free(prevexp.label); + } + prevexp.label = curses_copy_of("Experience: "); +#endif + + /* Level */ + if (prevlevel.label) { + free(prevlevel.label); + } + if (u.mtimedone) { /* Currently polymorphed - show monster HP */ + prevlevel.label = curses_copy_of("Hit Dice: "); + } else { /* Not polymorphed */ + + if (prevexp.display) { + prevlevel.label = curses_copy_of(" / "); + } else { + prevlevel.label = curses_copy_of("Level: "); + } } + + /* Time */ + if (prevtime.label) { + free(prevtime.label); + } + prevtime.label = curses_copy_of("Time: "); + +#ifdef SCORE_ON_BOTL + /* Score */ + if (prevscore.label) { + free(prevscore.label); + } + prevscore.label = curses_copy_of("Score: "); +#endif + break; + + default: + panic("set_labels(): Invalid label_width %d\n", label_width); + break; } } @@ -1724,46 +1464,44 @@ static void set_labels(int label_width) /* Get the default (non-highlighted) color for a stat. For now, this is NO_COLOR unless the statuscolors patch is in use. */ -static void set_stat_color(nhstat *stat) +static void +set_stat_color(nhstat *stat) { #ifdef STATUS_COLORS struct color_option stat_color; int count; int attr = A_NORMAL; - if (iflags.use_status_colors && stat_colored(stat->id)) - { + if (iflags.use_status_colors && stat_colored(stat->id)) { stat_color = text_color_of(stat->id, text_colors); - for (count = 0; (1 << count) <= stat_color.attr_bits; ++count) - { - if (count != ATR_NONE && stat_color.attr_bits & (1 << count)) - { - attr += curses_convert_attr(count); - } + for (count = 0; (1 << count) <= stat_color.attr_bits; ++count) { + if (count != ATR_NONE && stat_color.attr_bits & (1 << count)) { + attr += curses_convert_attr(count); + } } stat->stat_color = stat_color.color; stat->stat_attr = attr; - } - else - { + } else { stat->stat_color = NO_COLOR; stat->stat_attr = A_NORMAL; } #else stat->stat_color = NO_COLOR; stat->stat_attr = A_NORMAL; -#endif /* STATUS_COLORS */ +#endif /* STATUS_COLORS */ } /* Set the color to the base color for the given stat, or highlight a changed stat. */ -static void color_stat(nhstat stat, int onoff) +static void +color_stat(nhstat stat, int onoff) { WINDOW *win = curses_get_nhwin(STATUS_WIN); + #ifdef STATUS_COLORS struct color_option stat_color; int color, attr, hp, hpmax, count; @@ -1771,25 +1509,20 @@ static void color_stat(nhstat stat, int onoff) stat_color.color = NO_COLOR; stat_color.attr_bits = ATR_NONE; - - if (strcmp(stat.id, "hp") == 0) - { - hp = Upolyd ? u.mh : u.uhp; - hpmax = Upolyd ? u.mhmax : u.uhpmax; + + if (strcmp(stat.id, "hp") == 0) { + hp = Upolyd ? u.mh : u.uhp; + hpmax = Upolyd ? u.mhmax : u.uhpmax; stat_color = percentage_color_of(hp, hpmax, hp_colors); } - - if (strcmp(stat.id, "pw") == 0) - { + + if (strcmp(stat.id, "pw") == 0) { stat_color = percentage_color_of(u.uen, u.uenmax, pw_colors); } - - if (strcmp(stat.id, "hunger") == 0) - { - for (count = 0; count < strlen(hu_stat[u.uhs]); count++) - { - if ((hu_stat[u.uhs][count]) == ' ') - { + + if (strcmp(stat.id, "hunger") == 0) { + for (count = 0; count < strlen(hu_stat[u.uhs]); count++) { + if ((hu_stat[u.uhs][count]) == ' ') { break; } buf[count] = hu_stat[u.uhs][count]; @@ -1798,103 +1531,81 @@ static void color_stat(nhstat stat, int onoff) buf[count] = '\0'; stat_color = text_color_of(buf, text_colors); } - - if (strcmp(stat.id, "encumberance") == 0) - { - stat_color = text_color_of(enc_stat[prevencumb.value], - text_colors); - } - - if (strcmp(stat.id, "sick") == 0) - { - if (u.usick_type & SICK_VOMITABLE) - { + + if (strcmp(stat.id, "encumberance") == 0) { + stat_color = text_color_of(enc_stat[prevencumb.value], text_colors); + } + + if (strcmp(stat.id, "sick") == 0) { + if (u.usick_type & SICK_VOMITABLE) { stat_color = text_color_of("foodpois", text_colors); - } - else - { + } else { stat_color = text_color_of("ill", text_colors); } } - if (strcmp(stat.id, "align") == 0) - { - switch (u.ualign.type) - { - case A_LAWFUL: - { - stat_color = text_color_of("lawful", text_colors); - break; - } - case A_NEUTRAL: - { - stat_color = text_color_of("neutral", text_colors); - break; - } - case A_CHAOTIC: - { - stat_color = text_color_of("chaotic", text_colors); - break; - } + if (strcmp(stat.id, "align") == 0) { + switch (u.ualign.type) { + case A_LAWFUL: + stat_color = text_color_of("lawful", text_colors); + break; + case A_NEUTRAL: + stat_color = text_color_of("neutral", text_colors); + break; + case A_CHAOTIC: + stat_color = text_color_of("chaotic", text_colors); + break; } } color = stat_color.color; attr = A_NORMAL; - for (count = 0; (1 << count) <= stat_color.attr_bits; ++count) - { - if (count != ATR_NONE && stat_color.attr_bits & (1 << count)) - { - attr += curses_convert_attr(count); - } + for (count = 0; (1 << count) <= stat_color.attr_bits; ++count) { + if (count != ATR_NONE && stat_color.attr_bits & (1 << count)) { + attr += curses_convert_attr(count); + } } stat.stat_color = color; stat.stat_attr = attr; -#endif /* STATUS_COLORS */ - - if ((stat.stat_color == NO_COLOR) && (stat.stat_attr == A_NORMAL)) - { - if (stat.highlight_turns > 0) - { +#endif /* STATUS_COLORS */ + + if ((stat.stat_color == NO_COLOR) && (stat.stat_attr == A_NORMAL)) { + if (stat.highlight_turns > 0) { #ifdef STATUS_COLORS if (iflags.use_status_colors) #endif - curses_toggle_color_attr(win, stat.highlight_color, - A_NORMAL, onoff); + curses_toggle_color_attr(win, stat.highlight_color, + A_NORMAL, onoff); } return; } - #ifdef STATUS_COLORS if (iflags.use_status_colors) #endif - curses_toggle_color_attr(win, stat.stat_color, stat.stat_attr, - onoff); + curses_toggle_color_attr(win, stat.stat_color, stat.stat_attr, onoff); } /* Determine if a stat is configured via statuscolors. */ #ifdef STATUS_COLORS -static boolean stat_colored(const char *id) +static boolean +stat_colored(const char *id) { - struct text_color_option *cur_option = - (struct text_color_option *)text_colors; - - while(cur_option != NULL) - { - if (strcmpi(cur_option->text, id) == 0) - { + struct text_color_option *cur_option = + (struct text_color_option *) text_colors; + + while (cur_option != NULL) { + if (strcmpi(cur_option->text, id) == 0) { return TRUE; } - - cur_option = (struct text_color_option *)cur_option->next; + + cur_option = (struct text_color_option *) cur_option->next; } - + return FALSE; } -#endif /* STATUS_COLORS */ - +#endif /* STATUS_COLORS */ diff --git a/win/curses/cursstat.h b/win/curses/cursstat.h index f8a07602..2552c76d 100644 --- a/win/curses/cursstat.h +++ b/win/curses/cursstat.h @@ -1,14 +1,16 @@ +/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ + #ifndef CURSSTAT_H -#define CURSSTAT_H +# define CURSSTAT_H /* Used by handle_stat_change to handle some stats differently. Not an enum because this is how NetHack code generally handles them. */ -#define STAT_OTHER 0 -#define STAT_STR 1 -#define STAT_GOLD 2 -#define STAT_HPEN 3 /* HP or Pw */ -#define STAT_AC 4 -#define STAT_TIME 5 +# define STAT_OTHER 0 +# define STAT_STR 1 +# define STAT_GOLD 2 +# define STAT_HPEN 3 /* HP or Pw */ +# define STAT_AC 4 +# define STAT_TIME 5 /* Global declarations */ @@ -17,4 +19,4 @@ void curses_update_stats(boolean redraw); void curses_decrement_highlight(void); -#endif /* CURSSTAT_H */ +#endif /* CURSSTAT_H */ diff --git a/win/curses/curswins.c b/win/curses/curswins.c index 75fef72d..62913bbf 100644 --- a/win/curses/curswins.c +++ b/win/curses/curswins.c @@ -1,3 +1,5 @@ +/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ + #include "curses.h" #include "hack.h" #include "wincurs.h" @@ -7,49 +9,47 @@ /* Private declarations */ -typedef struct nhw -{ - winid nhwin; /* NetHack window id */ - WINDOW *curwin; /* Curses window pointer */ - int width; /* Usable width not counting border */ - int height; /* Usable height not counting border */ - int x; /* start of window on terminal (left) */ - int y; /* start of window on termial (top) */ - int orientation; /* Placement of window relative to map */ - boolean border; /* Whether window has a visible border */ +typedef struct nhw { + winid nhwin; /* NetHack window id */ + WINDOW *curwin; /* Curses window pointer */ + int width; /* Usable width not counting border */ + int height; /* Usable height not counting border */ + int x; /* start of window on terminal (left) */ + int y; /* start of window on termial (top) */ + int orientation; /* Placement of window relative to map */ + boolean border; /* Whether window has a visible border */ } nethack_window; -typedef struct nhwd -{ - winid nhwid; /* NetHack window id */ - struct nhwd *prev_wid; /* Pointer to previous entry */ - struct nhwd *next_wid; /* Pointer to next entry */ +typedef struct nhwd { + winid nhwid; /* NetHack window id */ + struct nhwd *prev_wid; /* Pointer to previous entry */ + struct nhwd *next_wid; /* Pointer to next entry */ } nethack_wid; -typedef struct nhchar -{ - int ch; /* character */ - int color; /* color info for character */ - int attr; /* attributes of character */ +typedef struct nhchar { + int ch; /* character */ + int color; /* color info for character */ + int attr; /* attributes of character */ } nethack_char; -static boolean map_clipped; /* Map window smaller than 80x21 */ +static boolean map_clipped; /* Map window smaller than 80x21 */ -static nethack_window nhwins[NHWIN_MAX]; /* NetHack window array */ +static nethack_window nhwins[NHWIN_MAX]; /* NetHack window array */ static nethack_char map[ROWNO][COLNO]; /* Map window contents */ -static nethack_wid *nhwids = NULL; /* NetHack wid array */ +static nethack_wid *nhwids = NULL; /* NetHack wid array */ static boolean is_main_window(winid wid); -static void write_char(WINDOW *win, int x, int y, nethack_char ch); +static void write_char(WINDOW * win, int x, int y, nethack_char ch); static void clear_map(void); /* Create a window with the specified size and orientation */ -WINDOW *curses_create_window(int width, int height, orient orientation) +WINDOW * +curses_create_window(int width, int height, orient orientation) { int mapx, mapy, maph, mapw = 0; int startx = 0; @@ -57,18 +57,14 @@ WINDOW *curses_create_window(int width, int height, orient orientation) WINDOW *win; boolean map_border = FALSE; int mapb_offset = 0; - + if ((orientation == UP) || (orientation == DOWN) || - (orientation == LEFT) || (orientation == RIGHT)) - { - if (invent || (moves > 1)) - { + (orientation == LEFT) || (orientation == RIGHT)) { + if (invent || (moves > 1)) { map_border = curses_window_has_border(MAP_WIN); curses_get_window_xy(MAP_WIN, &mapx, &mapy); curses_get_window_size(MAP_WIN, &maph, &mapw); - } - else - { + } else { map_border = TRUE; mapx = 0; mapy = 0; @@ -76,92 +72,68 @@ WINDOW *curses_create_window(int width, int height, orient orientation) mapw = term_cols; } } - - if (map_border) - { + + if (map_border) { mapb_offset = 1; } - - width += 2; /* leave room for bounding box */ + + width += 2; /* leave room for bounding box */ height += 2; - + if ((width > term_cols) || (height > term_rows)) panic("curses_create_window: Terminal too small for dialog window"); - switch (orientation) - { - case CENTER: - { - startx = (term_cols / 2) - (width / 2); - starty = (term_rows / 2) - (height / 2); - break; + switch (orientation) { + case CENTER: + startx = (term_cols / 2) - (width / 2); + starty = (term_rows / 2) - (height / 2); + break; + case UP: + if (invent || (moves > 1)) { + startx = (mapw / 2) - (width / 2) + mapx + mapb_offset; + } else { + startx = 0; } - case UP: - { - if (invent || (moves > 1)) - { - startx = (mapw / 2) - (width / 2) + mapx + mapb_offset; - } - else - { - startx = 0; - } - - starty = mapy + mapb_offset; - break; - } - case DOWN: - { - if (invent || (moves > 1)) - { - startx = (mapw / 2) - (width / 2) + mapx + mapb_offset; - } - else - { - startx = 0; - } - - starty = height - mapy - 1 - mapb_offset; - break; - } - case LEFT: - { - if (map_border && (width < term_cols)) - startx = 1; - else - startx = 0; - starty = term_rows - height; - break; - } - case RIGHT: - { - if (invent || (moves > 1)) - { - startx = (mapw + mapx + (mapb_offset * 2)) - width; - } - else - { - startx = term_cols - width; - } - - starty = 0; - break; + + starty = mapy + mapb_offset; + break; + case DOWN: + if (invent || (moves > 1)) { + startx = (mapw / 2) - (width / 2) + mapx + mapb_offset; + } else { + startx = 0; } - default: - { - panic("curses_create_window: Bad orientation"); + + starty = height - mapy - 1 - mapb_offset; + break; + case LEFT: + if (map_border && (width < term_cols)) + startx = 1; + else + startx = 0; + starty = term_rows - height; + break; + case RIGHT: + if (invent || (moves > 1)) { + startx = (mapw + mapx + (mapb_offset * 2)) - width; + } else { + startx = term_cols - width; } + + starty = 0; + break; + default: + panic("curses_create_window: Bad orientation"); + break; } - - if (startx < 0) - { + + if (startx < 0) { startx = 0; } - - if (starty < 0) - { + + if (starty < 0) { starty = 0; } - + win = newwin(height, width, starty, startx); curses_toggle_color_attr(win, DIALOG_BORDER_COLOR, NONE, ON); box(win, 0, 0); @@ -172,7 +144,8 @@ WINDOW *curses_create_window(int width, int height, orient orientation) /* Erase and delete curses window, and refresh standard windows */ -void curses_destroy_win(WINDOW *win) +void +curses_destroy_win(WINDOW * win) { werase(win); wrefresh(win); @@ -183,22 +156,20 @@ void curses_destroy_win(WINDOW *win) /* Refresh nethack windows if they exist, or base window if not */ -void curses_refresh_nethack_windows() +void +curses_refresh_nethack_windows() { WINDOW *status_window, *message_window, *map_window; - + status_window = curses_get_nhwin(STATUS_WIN); message_window = curses_get_nhwin(MESSAGE_WIN); map_window = curses_get_nhwin(MAP_WIN); - - if ((moves <= 1) && !invent) - { + + if ((moves <= 1) && !invent) { /* Main windows not yet displayed; refresh base window instead */ touchwin(stdscr); refresh(); - } - else - { + } else { touchwin(status_window); wnoutrefresh(status_window); touchwin(map_window); @@ -212,31 +183,31 @@ void curses_refresh_nethack_windows() /* Return curses window pointer for given NetHack winid */ -WINDOW *curses_get_nhwin(winid wid) +WINDOW * +curses_get_nhwin(winid wid) { - if (!is_main_window(wid)) - { + if (!is_main_window(wid)) { panic("curses_get_nhwin: wid out of range. Not a main window."); } - + return nhwins[wid].curwin; } /* Add curses window pointer and window info to list for given NetHack winid */ -void curses_add_nhwin(winid wid, int height, int width, int y, int x, - orient orientation, boolean border) +void +curses_add_nhwin(winid wid, int height, int width, int y, int x, + orient orientation, boolean border) { WINDOW *win; int real_width = width; int real_height = height; - - if (!is_main_window(wid)) - { + + if (!is_main_window(wid)) { panic("curses_add_nhwin: wid out of range. Not a main window."); } - + nhwins[wid].nhwin = wid; nhwins[wid].border = border; nhwins[wid].width = width; @@ -244,74 +215,59 @@ void curses_add_nhwin(winid wid, int height, int width, int y, int x, nhwins[wid].x = x; nhwins[wid].y = y; nhwins[wid].orientation = orientation; - - if (border) - { - real_width += 2; /* leave room for bounding box */ + + if (border) { + real_width += 2; /* leave room for bounding box */ real_height += 2; } - + win = newwin(real_height, real_width, y, x); - - switch (wid) - { - case MESSAGE_WIN: - { - messagewin = win; - break; - } - case STATUS_WIN: - { - statuswin = win; - break; - } - case MAP_WIN: - { - mapwin = win; - - if ((width < COLNO) || (height < ROWNO)) - { - map_clipped = TRUE; - } - else - { - map_clipped = FALSE; - } - - break; + + switch (wid) { + case MESSAGE_WIN: + messagewin = win; + break; + case STATUS_WIN: + statuswin = win; + break; + case MAP_WIN: + mapwin = win; + + if ((width < COLNO) || (height < ROWNO)) { + map_clipped = TRUE; + } else { + map_clipped = FALSE; } + + break; } - - if (border) - { + + if (border) { box(win, 0, 0); } - + nhwins[wid].curwin = win; } /* Add wid to list of known window IDs */ -void curses_add_wid(winid wid) +void +curses_add_wid(winid wid) { nethack_wid *new_wid; nethack_wid *widptr = nhwids; - - new_wid = malloc(sizeof(nethack_wid)); + + new_wid = malloc(sizeof (nethack_wid)); new_wid->nhwid = wid; - + new_wid->next_wid = NULL; - - if (widptr == NULL) - { + + if (widptr == NULL) { new_wid->prev_wid = NULL; nhwids = new_wid; - } - else - { - while (widptr->next_wid != NULL) - { + } else { + while (widptr->next_wid != NULL) { widptr = widptr->next_wid; } new_wid->prev_wid = widptr; @@ -322,7 +278,8 @@ void curses_add_wid(winid wid) /* refresh a curses window via given nethack winid */ -void curses_refresh_nhwin(winid wid) +void +curses_refresh_nhwin(winid wid) { wrefresh(curses_get_nhwin(wid)); } @@ -330,16 +287,15 @@ void curses_refresh_nhwin(winid wid) /* Delete curses window via given NetHack winid and remove entry from list */ -void curses_del_nhwin(winid wid) +void +curses_del_nhwin(winid wid) { - if (curses_is_menu(wid) || curses_is_text(wid)) - { + if (curses_is_menu(wid) || curses_is_text(wid)) { curses_del_menu(wid); return; } - - if (!is_main_window(wid)) - { + + if (!is_main_window(wid)) { panic("curses_del_nhwin: wid out of range. Not a main window."); } @@ -349,31 +305,25 @@ void curses_del_nhwin(winid wid) /* Delete wid from list of known window IDs */ -void curses_del_wid(winid wid) +void +curses_del_wid(winid wid) { nethack_wid *tmpwid; nethack_wid *widptr = nhwids; - - if (curses_is_menu(wid) || curses_is_text(wid)) - { + + if (curses_is_menu(wid) || curses_is_text(wid)) { curses_del_menu(wid); } - - while (widptr != NULL) - { - if (widptr->nhwid == wid) - { - if (widptr->prev_wid != NULL) - { + + while (widptr != NULL) { + if (widptr->nhwid == wid) { + if (widptr->prev_wid != NULL) { tmpwid = widptr->prev_wid; tmpwid->next_wid = widptr->next_wid; + } else { + nhwids = widptr->next_wid; /* New head mode, or NULL */ } - else - { - nhwids = widptr->next_wid; /* New head mode, or NULL */ - } - if (widptr->next_wid != NULL) - { + if (widptr->next_wid != NULL) { tmpwid = widptr->next_wid; tmpwid->prev_wid = widptr->prev_wid; } @@ -387,25 +337,23 @@ void curses_del_wid(winid wid) /* Print a single character in the given window at the given coordinates */ -void curses_putch(winid wid, int x, int y, int ch, int color, int attr) +void +curses_putch(winid wid, int x, int y, int ch, int color, int attr) { int sx, sy, ex, ey; boolean border = curses_window_has_border(wid); nethack_char nch; static boolean map_initted = FALSE; - if (wid == STATUS_WIN) - { + if (wid == STATUS_WIN) { curses_update_stats(FALSE); } - if (wid != MAP_WIN) - { + if (wid != MAP_WIN) { return; } - if (!map_initted) - { + if (!map_initted) { clear_map(); map_initted = TRUE; } @@ -414,13 +362,11 @@ void curses_putch(winid wid, int x, int y, int ch, int color, int attr) map[y][x].color = color; map[y][x].attr = attr; nch = map[y][x]; - - (void)curses_map_borders(&sx, &sy, &ex, &ey, -1, -1); - - if ((x >= sx) && (x <= ex) && (y >= sy) && (y <= ey)) - { - if (border) - { + + (void) curses_map_borders(&sx, &sy, &ex, &ey, -1, -1); + + if ((x >= sx) && (x <= ex) && (y >= sy) && (y <= ey)) { + if (border) { x++; y++; } @@ -434,10 +380,10 @@ void curses_putch(winid wid, int x, int y, int ch, int color, int attr) /* Get x, y coordinates of curses window on the physical terminal window */ -void curses_get_window_xy(winid wid, int *x, int *y) +void +curses_get_window_xy(winid wid, int *x, int *y) { - if (!is_main_window(wid)) - { + if (!is_main_window(wid)) { panic("curses_get_window_xy: wid out of range. Not a main window."); } @@ -448,7 +394,8 @@ void curses_get_window_xy(winid wid, int *x, int *y) /* Get usable width and height curses window on the physical terminal window */ -void curses_get_window_size(winid wid, int *height, int *width) +void +curses_get_window_size(winid wid, int *height, int *width) { *height = nhwins[wid].height; *width = nhwins[wid].width; @@ -457,7 +404,8 @@ void curses_get_window_size(winid wid, int *height, int *width) /* Determine if given window has a visible border */ -boolean curses_window_has_border(winid wid) +boolean +curses_window_has_border(winid wid) { return nhwins[wid].border; } @@ -465,18 +413,17 @@ boolean curses_window_has_border(winid wid) /* Determine if window for given winid exists */ -boolean curses_window_exists(winid wid) +boolean +curses_window_exists(winid wid) { nethack_wid *widptr = nhwids; - - while (widptr != NULL) - { - if (widptr->nhwid == wid) - { + + while (widptr != NULL) { + if (widptr->nhwid == wid) { return TRUE; - } + } - widptr = widptr->next_wid; + widptr = widptr->next_wid; } return FALSE; @@ -485,55 +432,50 @@ boolean curses_window_exists(winid wid) /* Return the orientation of the specified window */ -int curses_get_window_orientation(winid wid) +int +curses_get_window_orientation(winid wid) { - if (!is_main_window(wid)) - { - panic("curses_get_window_orientation: wid out of range. Not a main window."); + if (!is_main_window(wid)) { + panic + ("curses_get_window_orientation: wid out of range. Not a main window."); } - return nhwins[wid].orientation; + return nhwins[wid].orientation; } /* Output a line of text to specified NetHack window with given coordinates and text attributes */ -void curses_puts(winid wid, int attr, const char *text) +void +curses_puts(winid wid, int attr, const char *text) { anything *identifier; WINDOW *win = NULL; - - if (is_main_window(wid)) - { + + if (is_main_window(wid)) { win = curses_get_nhwin(wid); } - - if (wid == MESSAGE_WIN) - { + + if (wid == MESSAGE_WIN) { curses_message_win_puts(text, FALSE); return; } - - if (wid == STATUS_WIN) - { - curses_update_stats(FALSE); /* We will do the write ourselves */ + + if (wid == STATUS_WIN) { + curses_update_stats(FALSE); /* We will do the write ourselves */ return; } - - if (curses_is_menu(wid) || curses_is_text(wid)) - { - if (!curses_menu_exists(wid)) - { - panic("curses_puts: Attempted write to nonexistant window!"); + + if (curses_is_menu(wid) || curses_is_text(wid)) { + if (!curses_menu_exists(wid)) { + panic("curses_puts: Attempted write to nonexistant window!"); } - identifier = malloc(sizeof(anything)); + identifier = malloc(sizeof (anything)); identifier->a_void = NULL; curses_add_nhmenu_item(wid, NO_GLYPH, identifier, 0, 0, attr, text, - FALSE); - } - else - { + FALSE); + } else { waddstr(win, text); wrefresh(win); } @@ -542,38 +484,43 @@ void curses_puts(winid wid, int attr, const char *text) /* Clear the contents of a window via the given NetHack winid */ -void curses_clear_nhwin(winid wid) +void +curses_clear_nhwin(winid wid) { WINDOW *win = curses_get_nhwin(wid); boolean border = curses_window_has_border(wid); - - if (wid == MAP_WIN) - { - clearok(win, TRUE); /* Redraw entire screen when refreshed */ + + if (wid == MAP_WIN) { + clearok(win, TRUE); /* Redraw entire screen when refreshed */ clear_map(); } - + werase(win); - if (border) - { + if (border) { box(win, 0, 0); } } /* Change colour of window border to alert player to something */ -void curses_alert_win_border(winid wid, boolean onoff) +void +curses_alert_win_border(winid wid, boolean onoff) { WINDOW *win = curses_get_nhwin(wid); - if (!curses_window_has_border(wid)) return; - if (onoff) curses_toggle_color_attr(win, ALERT_BORDER_COLOR, NONE, ON); + + if (!curses_window_has_border(wid)) + return; + if (onoff) + curses_toggle_color_attr(win, ALERT_BORDER_COLOR, NONE, ON); box(win, 0, 0); - if (onoff) curses_toggle_color_attr(win, ALERT_BORDER_COLOR, NONE, OFF); + if (onoff) + curses_toggle_color_attr(win, ALERT_BORDER_COLOR, NONE, OFF); wrefresh(win); } -void curses_alert_main_borders(boolean onoff) +void +curses_alert_main_borders(boolean onoff) { curses_alert_win_border(MAP_WIN, onoff); curses_alert_win_border(MESSAGE_WIN, onoff); @@ -582,15 +529,12 @@ void curses_alert_main_borders(boolean onoff) /* Return true if given wid is a main NetHack window */ -static boolean is_main_window(winid wid) +static boolean +is_main_window(winid wid) { - if ((wid == MESSAGE_WIN) || (wid == MAP_WIN) || - (wid == STATUS_WIN)) - { + if ((wid == MESSAGE_WIN) || (wid == MAP_WIN) || (wid == STATUS_WIN)) { return TRUE; - } - else - { + } else { return FALSE; } } @@ -599,7 +543,8 @@ static boolean is_main_window(winid wid) /* Unconditionally write a single character to a window at the given coordinates without a refresh. Currently only used for the map. */ -static void write_char(WINDOW *win, int x, int y, nethack_char nch) +static void +write_char(WINDOW * win, int x, int y, nethack_char nch) { curses_toggle_color_attr(win, nch.color, nch.attr, ON); #ifdef PDCURSES @@ -614,20 +559,20 @@ static void write_char(WINDOW *win, int x, int y, nethack_char nch) /* Draw the entire visible map onto the screen given the visible map boundaries */ -void curses_draw_map(int sx, int sy, int ex, int ey) +void +curses_draw_map(int sx, int sy, int ex, int ey) { int curx, cury; int bspace = 0; + #ifdef MAP_SCROLLBARS int sbsx, sbsy, sbex, sbey, count; nethack_char hsb_back, hsb_bar, vsb_back, vsb_bar; #endif - - if (curses_window_has_border(MAP_WIN)) - { + + if (curses_window_has_border(MAP_WIN)) { bspace++; } - #ifdef MAP_SCROLLBARS hsb_back.ch = '-'; hsb_back.color = SCROLLBAR_BACK_COLOR; @@ -643,62 +588,46 @@ void curses_draw_map(int sx, int sy, int ex, int ey) vsb_bar.attr = A_NORMAL; /* Horizontal scrollbar */ - if ((sx > 0) || (ex < (COLNO - 1))) - { - sbsx = (sx * ((float)(ex - sx + 1) / COLNO)); - sbex = (ex * ((float)(ex - sx + 1) / COLNO)); - - for (count = 0; count < sbsx; count++) - { - write_char(mapwin, count + bspace, - ey - sy + 1 + bspace, hsb_back); + if ((sx > 0) || (ex < (COLNO - 1))) { + sbsx = (sx * ((float) (ex - sx + 1) / COLNO)); + sbex = (ex * ((float) (ex - sx + 1) / COLNO)); + + for (count = 0; count < sbsx; count++) { + write_char(mapwin, count + bspace, ey - sy + 1 + bspace, hsb_back); } - - for (count = sbsx; count <= sbex; count++) - { - write_char(mapwin, count + bspace, - ey - sy + 1 + bspace, hsb_bar); + + for (count = sbsx; count <= sbex; count++) { + write_char(mapwin, count + bspace, ey - sy + 1 + bspace, hsb_bar); } - - for (count = sbex + 1; count <= (ex - sx); count++) - { - write_char(mapwin, count + bspace, - ey - sy + 1 + bspace, hsb_back); + + for (count = sbex + 1; count <= (ex - sx); count++) { + write_char(mapwin, count + bspace, ey - sy + 1 + bspace, hsb_back); } } - + /* Vertical scrollbar */ - if ((sy > 0) || (ey < (ROWNO - 1))) - { - sbsy = (sy * ((float)(ey - sy + 1) / ROWNO)); - sbey = (ey * ((float)(ey - sy + 1) / ROWNO)); - - for (count = 0; count < sbsy; count++) - { - write_char(mapwin, ex - sx + 1 + bspace, count + bspace, - vsb_back); + if ((sy > 0) || (ey < (ROWNO - 1))) { + sbsy = (sy * ((float) (ey - sy + 1) / ROWNO)); + sbey = (ey * ((float) (ey - sy + 1) / ROWNO)); + + for (count = 0; count < sbsy; count++) { + write_char(mapwin, ex - sx + 1 + bspace, count + bspace, vsb_back); } - - for (count = sbsy; count <= sbey; count++) - { - write_char(mapwin, ex - sx + 1 + bspace, count + bspace, - vsb_bar); + + for (count = sbsy; count <= sbey; count++) { + write_char(mapwin, ex - sx + 1 + bspace, count + bspace, vsb_bar); } - - for (count = sbey + 1; count <= (ey - sy); count++) - { - write_char(mapwin, ex - sx + 1 + bspace, count + bspace, - vsb_back); + + for (count = sbey + 1; count <= (ey - sy); count++) { + write_char(mapwin, ex - sx + 1 + bspace, count + bspace, vsb_back); } - } -#endif /* MAP_SCROLLBARS */ + } +#endif /* MAP_SCROLLBARS */ - for (curx = sx; curx <= ex; curx++) - { - for (cury = sy; cury <= ey; cury++) - { + for (curx = sx; curx <= ex; curx++) { + for (cury = sy; cury <= ey; cury++) { write_char(mapwin, curx - sx + bspace, cury - sy + bspace, - map[cury][curx]); + map[cury][curx]); } } } @@ -706,14 +635,13 @@ void curses_draw_map(int sx, int sy, int ex, int ey) /* Init map array to blanks */ -static void clear_map() +static void +clear_map() { int x, y; - - for (x = 0; x < COLNO; x++) - { - for (y = 0; y < ROWNO; y++) - { + + for (x = 0; x < COLNO; x++) { + for (y = 0; y < ROWNO; y++) { map[y][x].ch = ' '; map[y][x].color = NO_COLOR; map[y][x].attr = A_NORMAL; @@ -725,8 +653,8 @@ static void clear_map() /* Determine visible boundaries of map, and determine if it needs to be based on the location of the player. */ -boolean curses_map_borders(int *sx, int *sy, int *ex, int *ey, int ux, - int uy) +boolean +curses_map_borders(int *sx, int *sy, int *ex, int *ey, int ux, int uy) { static int width = 0; static int height = 0; @@ -736,103 +664,80 @@ boolean curses_map_borders(int *sx, int *sy, int *ex, int *ey, int ux, static int oey = 0; static int oux = -1; static int ouy = -1; - - if ((oux == -1) || (ouy == -1)) - { + + if ((oux == -1) || (ouy == -1)) { oux = u.ux; ouy = u.uy; } - - if (ux == -1) - { + + if (ux == -1) { ux = oux; - } - else - { + } else { oux = ux; } - if (uy == -1) - { + if (uy == -1) { uy = ouy; - } - else - { + } else { ouy = uy; } curses_get_window_size(MAP_WIN, &height, &width); - + #ifdef MAP_SCROLLBARS - if (width < COLNO) - { - height--; /* room for horizontal scrollbar */ + if (width < COLNO) { + height--; /* room for horizontal scrollbar */ } - if (height < ROWNO) - { - width--; /* room for vertical scrollbar */ + if (height < ROWNO) { + width--; /* room for vertical scrollbar */ - if (width == COLNO) - { + if (width == COLNO) { height--; } } -#endif /* MAP_SCROLLBARS */ +#endif /* MAP_SCROLLBARS */ - if (width >= COLNO) - { + if (width >= COLNO) { *sx = 0; *ex = COLNO - 1; - } - else - { + } else { *ex = (width / 2) + ux; *sx = *ex - (width - 1); - - if (*ex >= COLNO) - { + + if (*ex >= COLNO) { *sx = COLNO - width; *ex = COLNO - 1; - } - else if (*sx < 0) - { + } else if (*sx < 0) { *sx = 0; *ex = width - 1; } } - - if (height >= ROWNO) - { + + if (height >= ROWNO) { *sy = 0; *ey = ROWNO - 1; - } - else - { + } else { *ey = (height / 2) + uy; *sy = *ey - (height - 1); - - if (*ey >= ROWNO) - { + + if (*ey >= ROWNO) { *sy = ROWNO - height; *ey = ROWNO - 1; - } - else if (*sy < 0) - { + } else if (*sy < 0) { *sy = 0; *ey = height - 1; } } if ((*sx != osx) || (*sy != osy) || (*ex != oex) || (*ey != oey) || - map_clipped) - { + map_clipped) { osx = *sx; osy = *sy; oex = *ex; oey = *ey; return TRUE; } - + return FALSE; } diff --git a/win/curses/curswins.h b/win/curses/curswins.h index 9a8f2e63..51c5296c 100644 --- a/win/curses/curswins.h +++ b/win/curses/curswins.h @@ -1,19 +1,21 @@ +/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ + #ifndef CURSWIN_H -#define CURSWIN_H +# define CURSWIN_H /* Global declarations */ WINDOW *curses_create_window(int width, int height, orient orientation); -void curses_destroy_win(WINDOW *win); +void curses_destroy_win(WINDOW * win); void curses_refresh_nethack_windows(void); WINDOW *curses_get_nhwin(winid wid); void curses_add_nhwin(winid wid, int height, int width, int y, int x, - orient orientation, boolean border); + orient orientation, boolean border); void curses_add_wid(winid wid); @@ -43,8 +45,7 @@ void curses_alert_main_borders(boolean onoff); void curses_draw_map(int sx, int sy, int ex, int ey); -boolean curses_map_borders(int *sx, int *sy, int *ex, int *ey, int ux, - int uy); +boolean curses_map_borders(int *sx, int *sy, int *ex, int *ey, int ux, int uy); -#endif /* CURSWIN_H */ +#endif /* CURSWIN_H */ From 5ecf25e71c30c501a53f36cb55be3c5b355dd8cc Mon Sep 17 00:00:00 2001 From: Tangles Date: Sun, 7 May 2017 00:34:05 +1000 Subject: [PATCH 15/69] curses - fix text attr, and menu width --- win/curses/cursdial.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/win/curses/cursdial.c b/win/curses/cursdial.c index e4b18db4..597ae5dd 100644 --- a/win/curses/cursdial.c +++ b/win/curses/cursdial.c @@ -870,6 +870,9 @@ menu_win_size(nhmenu *menu) } else { /* Add space for accelerator */ curentrywidth = strlen(menu_item_ptr->str) + 4; + if (menu_item_ptr->glyph != NO_GLYPH + && iflags.use_menu_glyphs) + curentrywidth += 2; } if (curentrywidth > maxentrywidth) { maxentrywidth = curentrywidth; From ae561661ed311437c276425eb1fb913b60f85d81 Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Sat, 6 May 2017 16:49:20 +0200 Subject: [PATCH 16/69] Remove blank lines between function prototype declarations --- win/curses/cursdial.c | 11 ----------- win/curses/cursdial.h | 8 -------- win/curses/cursinit.h | 6 ------ win/curses/cursmesg.c | 2 -- win/curses/cursmesg.h | 7 ------- win/curses/cursmisc.h | 20 -------------------- win/curses/cursstat.c | 8 -------- win/curses/cursstat.h | 1 - win/curses/curswins.c | 5 ----- win/curses/curswins.h | 18 ------------------ 10 files changed, 86 deletions(-) diff --git a/win/curses/cursdial.c b/win/curses/cursdial.c index 597ae5dd..85e0e8e8 100644 --- a/win/curses/cursdial.c +++ b/win/curses/cursdial.c @@ -54,29 +54,18 @@ extern struct menucoloring *menu_colorings; #endif static nhmenu *get_menu(winid wid); - static char menu_get_accel(boolean first); - static void menu_determine_pages(nhmenu *menu); - static boolean menu_is_multipage(nhmenu *menu, int width, int height); - static void menu_win_size(nhmenu *menu); - static void menu_display_page(nhmenu *menu, WINDOW * win, int page_num); - static int menu_get_selections(WINDOW * win, nhmenu *menu, int how); - static void menu_select_deselect(WINDOW * win, nhmenu_item *item, menu_op operation); - static int menu_operation(WINDOW * win, nhmenu *menu, menu_op operation, int page_num); - static void menu_clear_selections(nhmenu *menu); - static boolean get_menu_coloring(char *str, int *color, int *attr); - static int menu_max_height(void); static nhmenu *nhmenus = NULL; /* NetHack menu array */ diff --git a/win/curses/cursdial.h b/win/curses/cursdial.h index 0401062b..b1379b3a 100644 --- a/win/curses/cursdial.h +++ b/win/curses/cursdial.h @@ -13,24 +13,16 @@ /* Global declarations */ void curses_line_input_dialog(const char *prompt, char *answer, int buffer); - int curses_character_input_dialog(const char *prompt, const char *choices, CHAR_P def); - int curses_ext_cmd(void); - void curses_create_nhmenu(winid wid); - void curses_add_nhmenu_item(winid wid, int glyph, const ANY_P * identifier, CHAR_P accelerator, CHAR_P group_accel, int attr, const char *str, BOOLEAN_P presel); - void curses_finalize_nhmenu(winid wid, const char *prompt); - int curses_display_nhmenu(winid wid, int how, MENU_ITEM_P ** _selected); - boolean curses_menu_exists(winid wid); - void curses_del_menu(winid wid); diff --git a/win/curses/cursinit.h b/win/curses/cursinit.h index e330736b..c7f39004 100644 --- a/win/curses/cursinit.h +++ b/win/curses/cursinit.h @@ -6,17 +6,11 @@ /* Global declarations */ void curses_create_main_windows(void); - void curses_init_nhcolors(void); - void curses_choose_character(void); - int curses_character_dialog(const char **choices, const char *prompt); - void curses_init_options(void); - void curses_display_splash_window(void); - void curses_cleanup(void); diff --git a/win/curses/cursmesg.c b/win/curses/cursmesg.c index 491413a4..fe733c97 100644 --- a/win/curses/cursmesg.c +++ b/win/curses/cursmesg.c @@ -17,9 +17,7 @@ typedef struct nhpm { } nhprev_mesg; static void scroll_window(winid wid); - static void mesg_add_line(char *mline); - static nhprev_mesg *get_msg_line(boolean reverse, int mindex); static int turn_lines = 1; diff --git a/win/curses/cursmesg.h b/win/curses/cursmesg.h index 4bf9718c..904fbf75 100644 --- a/win/curses/cursmesg.h +++ b/win/curses/cursmesg.h @@ -7,19 +7,12 @@ /* Global declarations */ void curses_message_win_puts(const char *message, boolean recursed); - int curses_block(boolean require_tab); - int curses_more(void); - void curses_clear_unhighlight_message_window(void); - void curses_last_messages(void); - void curses_init_mesg_history(void); - void curses_prev_mesg(void); - void curses_count_window(const char *count_text); #endif /* CURSMESG_H */ diff --git a/win/curses/cursmisc.h b/win/curses/cursmisc.h index 398f5462..50821c81 100644 --- a/win/curses/cursmisc.h +++ b/win/curses/cursmisc.h @@ -6,45 +6,25 @@ /* Global declarations */ int curses_read_char(void); - void curses_toggle_color_attr(WINDOW * win, int color, int attr, int onoff); - void curses_bail(const char *mesg); - winid curses_get_wid(int type); - char *curses_copy_of(const char *s); - int curses_num_lines(const char *str, int width); - char *curses_break_str(const char *str, int width, int line_num); - char *curses_str_remainder(const char *str, int width, int line_num); - boolean curses_is_menu(winid wid); - boolean curses_is_text(winid wid); - int curses_convert_glyph(int ch, int glyph); - void curses_move_cursor(winid wid, int x, int y); - void curses_prehousekeeping(void); - void curses_posthousekeeping(void); - void curses_view_file(const char *filename, boolean must_exist); - void curses_rtrim(char *str); - int curses_get_count(int first_digit); - int curses_convert_attr(int attr); - int curses_read_attrs(char *attrs); - int curses_convert_keys(int key); - int curses_get_mouse(int *mousex, int *mousey, int *mod); #endif /* CURSMISC_H */ diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index a6b6ea52..7e7c1910 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -32,27 +32,19 @@ extern const struct percent_color_option *pw_colors; extern struct color_option text_color_of(const char *text, const struct text_color_option *color_options); - struct color_option percentage_color_of(int value, int max, const struct percent_color_option *color_options); - static boolean stat_colored(const char *id); #endif static void handle_status_problem(nhstat *, int, const char *, int *, int *, int, boolean); - static void handle_stat_change(nhstat *, int, int, int *, int *, int, boolean); - static int decrement_highlight(nhstat *); - static void init_stats(void); - static void set_labels(int label_width); - static void set_stat_color(nhstat *stat); - static void color_stat(nhstat stat, int onoff); static nhstat prevname; diff --git a/win/curses/cursstat.h b/win/curses/cursstat.h index 2552c76d..f7a974b3 100644 --- a/win/curses/cursstat.h +++ b/win/curses/cursstat.h @@ -15,7 +15,6 @@ /* Global declarations */ void curses_update_stats(boolean redraw); - void curses_decrement_highlight(void); diff --git a/win/curses/curswins.c b/win/curses/curswins.c index 62913bbf..57c717dc 100644 --- a/win/curses/curswins.c +++ b/win/curses/curswins.c @@ -33,17 +33,12 @@ typedef struct nhchar { } nethack_char; static boolean map_clipped; /* Map window smaller than 80x21 */ - static nethack_window nhwins[NHWIN_MAX]; /* NetHack window array */ - static nethack_char map[ROWNO][COLNO]; /* Map window contents */ - static nethack_wid *nhwids = NULL; /* NetHack wid array */ static boolean is_main_window(winid wid); - static void write_char(WINDOW * win, int x, int y, nethack_char ch); - static void clear_map(void); /* Create a window with the specified size and orientation */ diff --git a/win/curses/curswins.h b/win/curses/curswins.h index 51c5296c..ce1935e0 100644 --- a/win/curses/curswins.h +++ b/win/curses/curswins.h @@ -9,42 +9,24 @@ WINDOW *curses_create_window(int width, int height, orient orientation); void curses_destroy_win(WINDOW * win); - void curses_refresh_nethack_windows(void); - WINDOW *curses_get_nhwin(winid wid); - void curses_add_nhwin(winid wid, int height, int width, int y, int x, orient orientation, boolean border); - void curses_add_wid(winid wid); - void curses_refresh_nhwin(winid wid); - void curses_del_nhwin(winid wid); - void curses_del_wid(winid wid); - void curses_putch(winid wid, int x, int y, int ch, int color, int attrs); - void curses_get_window_xy(winid wid, int *x, int *y); - boolean curses_window_has_border(winid wid); - boolean curses_window_exists(winid wid); - int curses_get_window_orientation(winid wid); - void curses_puts(winid wid, int attr, const char *text); - void curses_clear_nhwin(winid wid); - void curses_alert_win_border(winid wid, boolean onoff); - void curses_alert_main_borders(boolean onoff); - void curses_draw_map(int sx, int sy, int ex, int ey); - boolean curses_map_borders(int *sx, int *sy, int *ex, int *ey, int ux, int uy); From 6a3184ec1b5a433276fe34d45b1730f34a61d18e Mon Sep 17 00:00:00 2001 From: Tangles Date: Mon, 8 May 2017 15:07:09 +1000 Subject: [PATCH 17/69] curses - non-popup version of getline() Uses message window. Word wraps, scrolls, etc. --- include/wincurs.h | 2 + win/curses/cursdial.c | 2 + win/curses/cursmesg.c | 178 +++++++++++++++++++++++++++++++++++++++++- win/curses/cursmesg.h | 1 + 4 files changed, 180 insertions(+), 3 deletions(-) diff --git a/include/wincurs.h b/include/wincurs.h index 866540b1..cafba41a 100644 --- a/include/wincurs.h +++ b/include/wincurs.h @@ -290,6 +290,8 @@ extern int curses_more(void); extern void curses_clear_unhighlight_message_window(void); +extern void curses_message_win_getline(const char *prompt, char *answer, int buffer); + extern void curses_last_messages(void); extern void curses_init_mesg_history(void); diff --git a/win/curses/cursdial.c b/win/curses/cursdial.c index 85e0e8e8..398a0bbb 100644 --- a/win/curses/cursdial.c +++ b/win/curses/cursdial.c @@ -87,6 +87,8 @@ curses_line_input_dialog(const char *prompt, char *answer, int buffer) maxwidth = term_cols - 2; if (iflags.window_inited) { + if (!iflags.wc_popup_dialog) + return curses_message_win_getline(prompt, answer, buffer); curses_get_window_size(MAP_WIN, &map_height, &map_width); if ((prompt_width + 2) > map_width) maxwidth = map_width - 2; diff --git a/win/curses/cursmesg.c b/win/curses/cursmesg.c index fe733c97..c6a7afc5 100644 --- a/win/curses/cursmesg.c +++ b/win/curses/cursmesg.c @@ -4,6 +4,8 @@ #include "hack.h" #include "wincurs.h" #include "cursmesg.h" +#include + /* Message window routines for curses interface */ @@ -17,6 +19,8 @@ typedef struct nhpm { } nhprev_mesg; static void scroll_window(winid wid); +static void unscroll_window(winid wid); +static void directional_scroll(winid wid, int nlines); static void mesg_add_line(char *mline); static nhprev_mesg *get_msg_line(boolean reverse, int mindex); @@ -118,8 +122,9 @@ curses_message_win_puts(const char *message, boolean recursed) curses_toggle_color_attr(win, NONE, A_BOLD, OFF); } wrefresh(win); - curses_message_win_puts(curses_str_remainder(message, (width - 2), 1), + curses_message_win_puts(tmpstr = curses_str_remainder(message, (width - 2), 1), TRUE); + free(tmpstr); } else { mvwprintw(win, my, mx, "%s", message); curses_toggle_color_attr(win, NONE, A_BOLD, OFF); @@ -336,11 +341,178 @@ curses_count_window(const char *count_text) wrefresh(countwin); } + /* Gets a "line" (buffer) of input. */ +void +curses_message_win_getline(const char *prompt, char *answer, int buffer) +{ + int height, width; /* of window */ + char *tmpbuf, *p_answer; /* combined prompt + answer */ + int nlines, maxlines, i; /* prompt + answer */ + int promptline; + int promptx; + char **linestarts; /* pointers to start of each line */ + char *tmpstr; /* for free() */ + int maxy, maxx; /* linewrap / scroll */ + int ch; -/* Scroll lines upward in given window, or clear window if only one line. */ + WINDOW *win = curses_get_nhwin(MESSAGE_WIN); + int border_space = 0; + int len = 0; /* of answer string */ + boolean border = curses_window_has_border(MESSAGE_WIN); + int orig_cursor = curs_set(0); + + curses_get_window_size(MESSAGE_WIN, &height, &width); + if (border) { + border_space = 1; + if (mx < 1) mx = 1; + if (my < 1) my = 1; + } + maxy = height - 1 + border_space; + maxx = width - 1 + border_space; + + tmpbuf = (char *)malloc(strlen(prompt) + buffer + 2); + maxlines = buffer / width * 2; /* can still be overflowed by the sufficiently determined */ + linestarts = (char **)malloc(sizeof(char*) * maxlines); + strcpy(tmpbuf, prompt); + strcat(tmpbuf, " "); + p_answer = tmpbuf + strlen(tmpbuf); + linestarts[0] = tmpbuf; + + if (mx > border_space) { /* newline */ + if (my >= maxy) scroll_window(MESSAGE_WIN); + else my++; + mx = border_space; + } + + curses_toggle_color_attr(win, NONE, A_BOLD, ON); + + nlines = curses_num_lines(tmpbuf,width); + for (i = 0; i < nlines-1; i++) { + tmpstr = curses_break_str(linestarts[i],width-1,1); + linestarts[i+1] = linestarts[i] + strlen(tmpstr); + if (*linestarts[i+1] == ' ') linestarts[i+1]++; + mvwaddstr(win,my,mx,tmpstr); + free(tmpstr); + if (++my >= maxy) { + scroll_window(MESSAGE_WIN); + my--; + } + } + mvwaddstr(win,my,mx,linestarts[nlines-1]); + mx = promptx = strlen(linestarts[nlines-1]) + border_space; + promptline = nlines - 1; + + while(1) { + mx = strlen(linestarts[nlines - 1]) + border_space; + if (mx > maxx) { + if (nlines < maxlines) { + tmpstr = curses_break_str(linestarts[nlines - 1], width - 1, 1); + mx = strlen(tmpstr) + border_space; + mvwprintw(win, my, mx, "%*c", maxx - mx + 1, ' '); + if (++my > maxy) { + scroll_window(MESSAGE_WIN); + my--; + } + mx = border_space; + linestarts[nlines] = linestarts[nlines - 1] + strlen(tmpstr); + if (*linestarts[nlines] == ' ') linestarts[nlines]++; + mvwaddstr(win, my, mx, linestarts[nlines]); + mx = strlen(linestarts[nlines]) + border_space; + nlines++; + free(tmpstr); + } else { + p_answer[--len] = '\0'; + mvwaddch(win, my, --mx, ' '); + } + } + wmove(win, my, mx); + curs_set(1); + wrefresh(win); + ch = getch(); + curs_set(0); + switch(ch) { + case '\033': /* DOESCAPE */ + /* blank the input but don't exit */ + while(nlines - 1 > promptline) { + if (nlines-- > height) { + unscroll_window(MESSAGE_WIN); + tmpstr = curses_break_str(linestarts[nlines - height], width - 1, 1); + mvwaddstr(win, border_space, border_space, tmpstr); + free(tmpstr); + } else { + mx = border_space; + mvwprintw(win, my, mx, "%*c", maxx - mx, ' '); + my--; + } + } + mx = promptx; + mvwprintw(win, my, mx, "%*c", maxx - mx, ' '); + *p_answer = '\0'; + len = 0; + break; + case ERR: /* should not happen */ + *answer = '\0'; + free(tmpbuf); + free(linestarts); + curs_set(orig_cursor); + curses_toggle_color_attr(win, NONE, A_BOLD, OFF); + return; + case '\r': + case '\n': + free(linestarts); + strncpy(answer, p_answer, buffer); + strcpy(toplines, tmpbuf); + mesg_add_line((char *) tmpbuf); + free(tmpbuf); + curs_set(orig_cursor); + curses_toggle_color_attr(win, NONE, A_BOLD, OFF); + return; + case '\b': + case KEY_BACKSPACE: + if (len < 1) { + len = 1; + mx = promptx; + } + p_answer[--len] = '\0'; + mvwaddch(win, my, --mx, ' '); + /* try to unwrap back to the previous line if there is one */ + if (nlines > 1 && strlen(linestarts[nlines - 2]) < width) { + mvwaddstr(win, my - 1, border_space, linestarts[nlines - 2]); + if (nlines-- > height) { + unscroll_window(MESSAGE_WIN); + tmpstr = curses_break_str(linestarts[nlines - height], width - 1, 1); + mvwaddstr(win, border_space, border_space, tmpstr); + free(tmpstr); + } else { + /* clean up the leftovers on the next line, if we didn't scroll it away */ + mvwprintw(win, my--, border_space, "%*c", strlen(linestarts[nlines]), ' '); + } + } + break; + default: + p_answer[len++] = ch; + if (len >= buffer) len = buffer-1; + else mvwaddch(win, my, mx, ch); + p_answer[len] = '\0'; + } + } +} +/* Scroll lines upward in given window, or clear window if only one line. */ static void scroll_window(winid wid) +{ + directional_scroll(wid,1); +} + +static void +unscroll_window(winid wid) +{ + directional_scroll(wid,-1); +} + +static void +directional_scroll(winid wid, int nlines) { int wh, ww, s_top, s_bottom; boolean border = curses_window_has_border(wid); @@ -360,7 +532,7 @@ scroll_window(winid wid) } scrollok(win, TRUE); wsetscrreg(win, s_top, s_bottom); - scroll(win); + wscrl(win, nlines); scrollok(win, FALSE); if (wid == MESSAGE_WIN) { if (border) diff --git a/win/curses/cursmesg.h b/win/curses/cursmesg.h index 904fbf75..54af5f9b 100644 --- a/win/curses/cursmesg.h +++ b/win/curses/cursmesg.h @@ -10,6 +10,7 @@ void curses_message_win_puts(const char *message, boolean recursed); int curses_block(boolean require_tab); int curses_more(void); void curses_clear_unhighlight_message_window(void); +void curses_message_win_getline(const char *prompt, char *answer, int buffer); void curses_last_messages(void); void curses_init_mesg_history(void); void curses_prev_mesg(void); From 9810b6b6b052695b4154cbed379a540e8adcdabd Mon Sep 17 00:00:00 2001 From: Tangles Date: Mon, 8 May 2017 18:34:47 +1000 Subject: [PATCH 18/69] curses - getline sometimes alloc too few lines User couldn't completely fill the buffer if they deliberately abused the word-wrap to use up lines. --- win/curses/cursmesg.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/win/curses/cursmesg.c b/win/curses/cursmesg.c index c6a7afc5..fe1f3406 100644 --- a/win/curses/cursmesg.c +++ b/win/curses/cursmesg.c @@ -371,10 +371,12 @@ curses_message_win_getline(const char *prompt, char *answer, int buffer) maxx = width - 1 + border_space; tmpbuf = (char *)malloc(strlen(prompt) + buffer + 2); - maxlines = buffer / width * 2; /* can still be overflowed by the sufficiently determined */ - linestarts = (char **)malloc(sizeof(char*) * maxlines); + maxlines = buffer / width * 2; strcpy(tmpbuf, prompt); strcat(tmpbuf, " "); + nlines = curses_num_lines(tmpbuf,width); + maxlines += nlines * 2; + linestarts = (char **)malloc(sizeof(char*) * maxlines); p_answer = tmpbuf + strlen(tmpbuf); linestarts[0] = tmpbuf; @@ -386,7 +388,6 @@ curses_message_win_getline(const char *prompt, char *answer, int buffer) curses_toggle_color_attr(win, NONE, A_BOLD, ON); - nlines = curses_num_lines(tmpbuf,width); for (i = 0; i < nlines-1; i++) { tmpstr = curses_break_str(linestarts[i],width-1,1); linestarts[i+1] = linestarts[i] + strlen(tmpstr); From cb8b36893ab79d3c9c5a28191693ec66eba47e8c Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Tue, 9 May 2017 03:20:15 +0200 Subject: [PATCH 19/69] Rewrite statusbar handling from scratch --- include/wincurs.h | 3 +- win/curses/cursinit.c | 34 +- win/curses/cursstat.c | 2049 +++++++++++++---------------------------- win/curses/cursstat.h | 14 +- win/curses/curswins.c | 4 +- 5 files changed, 698 insertions(+), 1406 deletions(-) diff --git a/include/wincurs.h b/include/wincurs.h index cafba41a..7a7602e5 100644 --- a/include/wincurs.h +++ b/include/wincurs.h @@ -258,8 +258,7 @@ extern void curses_del_menu(winid wid); /* cursstat.c */ -extern void curses_update_stats(boolean redraw); - +extern void curses_update_stats(void); extern void curses_decrement_highlight(void); diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index 1c8619e3..d666ffbb 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -516,7 +516,7 @@ curses_create_main_windows() curses_refresh_nethack_windows(); if (iflags.window_inited) { - curses_update_stats(TRUE); + curses_update_stats(); } else { iflags.window_inited = TRUE; } @@ -543,18 +543,32 @@ curses_init_nhcolors() { int i; - for (i = 0; i < 16; i++) { - int clr_remap[16] = { - COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, - COLOR_BLUE, - COLOR_MAGENTA, COLOR_CYAN, -1, COLOR_WHITE, - COLOR_RED + 8, COLOR_GREEN + 8, COLOR_YELLOW + 8, - COLOR_BLUE + 8, - COLOR_MAGENTA + 8, COLOR_CYAN + 8, COLOR_WHITE + 8 - }; + int clr_remap[16] = { + COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, + COLOR_BLUE, + COLOR_MAGENTA, COLOR_CYAN, -1, COLOR_WHITE, + COLOR_RED + 8, COLOR_GREEN + 8, COLOR_YELLOW + 8, + COLOR_BLUE + 8, + COLOR_MAGENTA + 8, COLOR_CYAN + 8, COLOR_WHITE + 8 + }; + + for (i = 0; i < (COLORS >= 16 ? 16 : 8); i++) { init_pair(17 + (i * 2) + 0, clr_remap[i], COLOR_RED); init_pair(17 + (i * 2) + 1, clr_remap[i], COLOR_BLUE); } + + boolean hicolor = FALSE; + if (COLORS >= 16) + hicolor = TRUE; + + /* Work around the crazy definitions above for more background colors... */ + for (i = 0; i < (COLORS >= 16 ? 16 : 8); i++) { + init_pair((hicolor ? 49 : 9) + i, clr_remap[i], COLOR_GREEN); + init_pair((hicolor ? 33 : 33) + i, clr_remap[i], COLOR_YELLOW); + init_pair((hicolor ? 81 : 41) + i, clr_remap[i], COLOR_MAGENTA); + init_pair((hicolor ? 97 : 49) + i, clr_remap[i], COLOR_CYAN); + init_pair((hicolor ? 113 : 57) + i, clr_remap[i], COLOR_WHITE); + } } diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index 7e7c1910..157a96ac 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -24,28 +24,31 @@ typedef struct nhs { const char *id; } nhstat; +static attr_t get_trouble_color(const char *); +static void statusproblem(int, const char *); +static void print_statdiff(const char *append, nhstat *, int, int); +static void get_playerrank(char *); +static attr_t curses_color_attr(int nh_color, int bg_color); +static int hpen_color(boolean, int, int); +static void draw_bar(boolean, int, int, const char *); +static void draw_horizontal(void); +static void draw_vertical(void); +static int decrement_highlight(nhstat *, boolean); +static void decrement_highlights(boolean); +static void init_stats(void); + #ifdef STATUS_COLORS -extern const struct text_color_option *text_colors; -extern const struct percent_color_option *hp_colors; -extern const struct percent_color_option *pw_colors; +static attr_t hpen_color_attr(boolean, int, int); extern struct color_option text_color_of(const char *text, - const struct text_color_option - *color_options); + const struct text_color_option *color_options); struct color_option percentage_color_of(int value, int max, - const struct percent_color_option - *color_options); -static boolean stat_colored(const char *id); -#endif + const struct percent_color_option *color_options); -static void handle_status_problem(nhstat *, int, const char *, int *, int *, - int, boolean); -static void handle_stat_change(nhstat *, int, int, int *, int *, int, boolean); -static int decrement_highlight(nhstat *); -static void init_stats(void); -static void set_labels(int label_width); -static void set_stat_color(nhstat *stat); -static void color_stat(nhstat stat, int onoff); +extern const struct text_color_option *text_colors; +extern const struct percent_color_option *hp_colors; +extern const struct percent_color_option *pw_colors; +#endif static nhstat prevname; static nhstat prevdepth; @@ -85,589 +88,716 @@ static nhstat prevencumb; extern const char *hu_stat[]; /* from eat.c */ extern const char *enc_stat[]; /* from botl.c */ +/* If the statuscolors patch isn't enabled, have some default colors for status problems + anyway */ + +struct statcolor { + const char *id; /* Identifier for statuscolors */ + const char *txt; /* For status problems */ + int color; /* Default color assuming STATUS_COLORS isn't enabled */ +}; + +static const struct statcolor default_colors[] = { + {"satiated", "Satiated", CLR_YELLOW}, + {"hungry", "Hungry", CLR_YELLOW}, + {"weak", "Weak", CLR_ORANGE}, + {"fainted", "Fainted", CLR_BRIGHT_MAGENTA}, + {"fainting", "Fainting", CLR_BRIGHT_MAGENTA}, + {"burdened", "Burdened", CLR_RED}, + {"stressed", "Stressed", CLR_RED}, + {"strained", "Strained", CLR_ORANGE}, + {"overtaxed", "Overtaxed", CLR_ORANGE}, + {"overloaded", "Overloaded", CLR_BRIGHT_MAGENTA}, + {"conf", "Conf", CLR_BRIGHT_BLUE}, + {"blind", "Blind", CLR_BRIGHT_BLUE}, + {"stun", "Stun", CLR_BRIGHT_BLUE}, + {"hallu", "Hallu", CLR_BRIGHT_BLUE}, + {"ill", "Ill", CLR_BRIGHT_MAGENTA}, + {"foodpois", "FoodPois", CLR_BRIGHT_MAGENTA}, + {"slime", "Slime", CLR_BRIGHT_MAGENTA}, + {NULL, NULL, NO_COLOR}, +}; + +static attr_t +get_trouble_color(const char *stat) +{ + attr_t res = curses_color_attr(CLR_GRAY, 0); + const struct statcolor *clr; + for (clr = default_colors; clr->txt; clr++) { + if (stat && !strcmp(clr->txt, stat)) { +#ifdef STATUS_COLORS + /* Check if we have a color enabled with statuscolors */ + if (!iflags.use_status_colors) + return CLR_GRAY; /* no color configured */ + + struct text_color_option *cur_option; + for (cur_option = text_colors; cur_option; cur_option = cur_option->next) { + if (strcmpi(cur_option->text, clr->id) == 0) { + /* We found the option, now make a curses attribute out of it */ + struct color_option status_color; + status_color = text_color_of(clr->id, cur_option); + + int count; + for (count = 0; (1 << count) <= stat_color.attr_bits; count++) { + if (count != ATR_NONE && (status_color.attr_bits & (1 << count))) + attr |= curses_convert_attr(count); + } + + return attr; + } + } + + /* No color configured, use gray */ + return curses_color_attr(CLR_GRAY, 0); +#else + return curses_color_attr(clr->color, 0); +#endif + } + } + + return res; +} + +/* TODO: This is in the wrong place. */ +void +get_playerrank(char *rank) +{ + char buf[BUFSZ]; + if (Upolyd) { + int k = 0; + + Strcpy(buf, mons[u.umonnum].mname); + while(buf[k] != 0) { + if ((k == 0 || (k > 0 && buf[k-1] == ' ')) && + 'a' <= buf[k] && buf[k] <= 'z') + buf[k] += 'A' - 'a'; + k++; + } + Strcpy(rank, buf); + } else + Strcpy(rank, rank_of(u.ulevel, Role_switch, flags.female)); +} + /* Handles numerical stat changes of various kinds. type is generally STAT_OTHER (generic "do nothing special"), but is used if the stat needs to be handled in a special way. */ static void -handle_stat_change(nhstat *stat, int new, int type, - int *sx, int *sy, int sx_start, boolean horiz) +print_statdiff(const char *append, nhstat *stat, int new, int type) { char buf[BUFSZ]; WINDOW *win = curses_get_nhwin(STATUS_WIN); - /* Turncount isn't highlighted, or it would be highlighted constantly. - Also note that these colors can be ignored if statuscolors is enabled - in color_stat() */ - if (new != stat->value && type != STAT_TIME) { + int color = CLR_GRAY; + + /* Turncount isn't highlighted, or it would be highlighted constantly. */ + if (type != STAT_TIME && new != stat->value) { /* Less AC is better */ if ((type == STAT_AC && new < stat->value) || (type != STAT_AC && new > stat->value)) { - if (type == STAT_GOLD) { - stat->highlight_color = HI_GOLD; - } else { - stat->highlight_color = STAT_UP_COLOR; - } - } else { - stat->highlight_color = STAT_DOWN_COLOR; - } + color = STAT_UP_COLOR; + if (type == STAT_GOLD) + color = HI_GOLD; + } else + color = STAT_DOWN_COLOR; + stat->value = new; + stat->highlight_color = color; + stat->highlight_turns = 5; + } else if (stat->highlight_turns) + color = stat->highlight_color; + + attr_t attr = curses_color_attr(color, 0); + wattron(win, attr); + wprintw(win, "%s", append); + if (type == STAT_STR && new > 18) { + if (new > 118) + wprintw(win, "%d", new - 100); + else if (new == 118) + wprintw(win, "18/**"); + else + wprintw(win, "18/%d", new - 18); + } else + wprintw(win, "%d", new); + + wattroff(win, attr); +} - /* Strength might be displayed differently */ - if (type == STAT_STR && new > 18) { - if (new > 118) { - sprintf(buf, "%d", new - 100); - } else if (new == 118) { - sprintf(buf, "%d/**"); - } else { - sprintf(buf, "18/%02d", new - 18); - } +static void +statusproblem(int trouble, const char *str) +{ + if (!trouble) + return; + + WINDOW *win = curses_get_nhwin(STATUS_WIN); + + /* For whatever reason, hunger states have trailing spaces. Get rid of them. */ + char buf[BUFSZ]; + Strcpy(buf, str); + int i; + for (i = 0; (buf[i] != ' ' && buf[i] != '\0'); i++) ; + + buf[i] = '\0'; + attr_t attr = get_trouble_color(buf); + wattron(win, attr); + wprintw(win, "%s", buf); + wattroff(win, attr); +} + +/* Returns a ncurses attribute for foreground and background. + This should probably be in cursinit.c or something. */ +static attr_t +curses_color_attr(int nh_color, int bg_color) +{ + int color = nh_color + 1; + attr_t cattr = A_NORMAL; + + if (!nh_color) { +#ifdef USE_DARKGRAY + if (iflags.wc2_darkgray) { + if (!can_change_color() || COLORS <= 16) + cattr |= A_BOLD; + } else +#endif + color = COLOR_BLUE; + } + + if (COLORS < 16 && color > 8) { + color -= 8; + cattr = A_BOLD; + } + + /* Can we do background colors? We can if we have more than + 16*7 colors (more than 8*7 for terminals with bold) */ + if (COLOR_PAIRS > (COLORS >= 16 ? 16 : 8) * 7) { + /* NH3 has a rather overcomplicated way of defining + its colors past the first 16: + Pair Foreground Background + 17 Black Red + 18 Black Blue + 19 Red Red + 20 Red Blue + 21 Green Red + ... + (Foreground order: Black, Red, Green, Yellow, Blue, + Magenta, Cyan, Gray/White) + + To work around these oddities, we define backgrounds + by the following pairs: + + 16 COLORS + 49-64: Green + 65-80: Yellow + 81-96: Magenta + 97-112: Cyan + 113-128: Gray/White + + 8 COLORS + 9-16: Green + 33-40: Yellow + 41-48: Magenta + 49-56: Cyan + 57-64: Gray/White */ + + if (bg_color == nh_color) + color = 1; /* Make foreground black if fg==bg */ + + if (bg_color == CLR_RED || bg_color == CLR_BLUE) { + /* already defined before extension */ + color *= 2; + color += 16; + if (bg_color == CLR_RED) + color--; } else { - sprintf(buf, "%d", new); - } + boolean hicolor = FALSE; + if (COLORS >= 16) + hicolor = TRUE; - free(stat->txt); - stat->txt = curses_copy_of(buf); - stat->highlight_turns = 5; - if (type == STAT_HPEN) { - stat->highlight_turns = 3; + switch (bg_color) { + case CLR_GREEN: + color = (hicolor ? 48 : 8) + color; + break; + case CLR_BROWN: + color = (hicolor ? 64 : 32) + color; + break; + case CLR_MAGENTA: + color = (hicolor ? 80 : 40) + color; + break; + case CLR_CYAN: + color = (hicolor ? 96 : 48) + color; + break; + case CLR_GRAY: + color = (hicolor ? 112 : 56) + color; + break; + default: + break; + } } } + cattr |= COLOR_PAIR(color); - if (stat->label) { - mvwaddstr(win, *sy, *sx, stat->label); - *sx += strlen(stat->label); - } + return cattr; +} + +#ifdef STATUS_COLORS +static attr_t +hpen_color_attr(boolean is_hp, int cur, int max) +{ + if (!iflags.use_status_colors) + return curses_color_attr(CLR_GRAY); + + struct color_option status_color; + status_color = percentage_color_of(cur, max, is_hp ? hp_colors : pw_colors); - color_stat(*stat, ON); - mvwaddstr(win, *sy, *sx, stat->txt); - color_stat(*stat, OFF); - - if (type == STAT_HPEN) { - *sx += strlen(stat->txt); - } else if (horiz) { - *sx += strlen(stat->txt) + 1; - } else { - *sx = sx_start; - *sy += 1; + int count; + for (count = 0; (1 << count) <= stat_color.attr_bits; count++) { + if (count != ATR_NONE && (status_color.attr_bits & (1 << count))) + attr |= curses_convert_attr(count); } + + return attr; +} +#endif + +static int +hpen_color(boolean is_hp, int cur, int max) +{ + int color = CLR_GRAY; + if (cur == max) + color = CLR_GRAY; + else if (cur * 3 > max * 2) /* >2/3 */ + color = is_hp ? CLR_GREEN : CLR_CYAN; + else if (cur * 3 > max) /* >1/3 */ + color = is_hp ? CLR_YELLOW : CLR_BLUE; + else if (cur * 7 > max) /* >1/7 */ + color = is_hp ? CLR_RED : CLR_MAGENTA; + else + color = is_hp ? CLR_ORANGE : CLR_BRIGHT_MAGENTA; + + return color; } +/* Draws a bar + is_hp: TRUE if we're drawing HP, Pw otherwise (determines colors) + cur/max: Current/max HP/Pw + title: Not NULL if we are drawing as part of an existing title. + Otherwise, the format is as follows: [ 11 / 11 ] */ static void -handle_status_problem(nhstat *stat, int new, const char *str, - int *sx, int *sy, int sx_start, boolean horiz) +draw_bar(boolean is_hp, int cur, int max, const char *title) { WINDOW *win = curses_get_nhwin(STATUS_WIN); - if (new != stat->value) { - stat->highlight_color = STAT_DOWN_COLOR; - if (stat->txt != NULL) { - free(stat->txt); - } - if (new) { - stat->txt = curses_copy_of(str); - } else { - stat->txt = NULL; - } - if (stat->value == 0) { - stat->highlight_turns = 5; - } - stat->value = new; + char buf[BUFSZ]; + if (title) + Strcpy(buf, title); + else { + int len = 5; + sprintf(buf, "%*d / %-*d", len, cur, len, max); } - if (stat->label != NULL) { - mvwaddstr(win, *sy, *sx, stat->label); - *sx += strlen(stat->label); - } + /* Colors */ + attr_t fillattr, attr; +#ifdef STATUS_COLORS + attr = hpen_color_attr(is_hp, cur, max); + attr &= ~A_REVERSE; + fillattr = (attr | A_REVERSE); +#else + int color = hpen_color(is_hp, cur, max); + int invcolor = color & 7; - if (stat->txt != NULL) { - color_stat(*stat, ON); - mvwaddstr(win, *sy, *sx, stat->txt); - color_stat(*stat, OFF); + fillattr = curses_color_attr(color, invcolor); + attr = curses_color_attr(color, 0); +#endif - if (horiz) { - *sx += strlen(stat->txt) + 1; - } else { - sx = sx_start; - *sy += 1; /* ++ would increase the pointer addr */ - } - } + /* Figure out how much of the bar to fill */ + int fill = 0; + int len = strlen(buf); + if (cur > 0 && max > 0) + fill = len * cur / max; + if (fill > len) + fill = len; + + waddch(win, '['); + wattron(win, fillattr); + wprintw(win, "%.*s", fill, buf); + wattroff(win, fillattr); + wattron(win, attr); + wprintw(win, "%.*s", len - fill, &buf[fill]); + wattroff(win, attr); + waddch(win, ']'); } /* Update the status win - this is called when NetHack would normally write to the status window, so we know somwthing has changed. We override the write and update what needs to be updated ourselves. */ - -void -curses_update_stats(boolean redraw) +static void +draw_horizontal(void) { char buf[BUFSZ]; - int count, enc, orient, sx_start, hp, hpmax, labels, swidth, - sheight, sx_end, sy_end; + char rank[BUFSZ]; WINDOW *win = curses_get_nhwin(STATUS_WIN); - static int prev_labels = -1; - static boolean first = TRUE; - static boolean horiz; - int sx = 0; - int sy = 0; - boolean border = curses_window_has_border(STATUS_WIN); - - curses_get_window_size(STATUS_WIN, &sheight, &swidth); - - if (border) { - sx++; - sy++; - swidth--; - sheight--; - } - - sx_end = swidth - 1; - sy_end = sheight - 1; - sx_start = sx; - if (first) { - init_stats(); - first = FALSE; - redraw = TRUE; - } + /* The area we're allowed to print on. Excludes borders */ + int x, y, h, w; - if (redraw) { - orient = curses_get_window_orientation(STATUS_WIN); + /* Starting x/y */ + x = 0; + y = 0; - if ((orient == ALIGN_RIGHT) || (orient == ALIGN_LEFT)) { - horiz = FALSE; - } else { - horiz = TRUE; - } - } + /* Starting height/width */ + curses_get_window_size(STATUS_WIN, &h, &w); - if (horiz) { - if (term_cols >= 80) { - labels = NORMAL_LABELS; - } else { - labels = COMPACT_LABELS; - } - } else { - labels = WIDE_LABELS; + boolean border = FALSE; + if (curses_window_has_border(STATUS_WIN)) { + x++; + y++; + h--; + w--; + border = TRUE; } - if (labels != prev_labels) { - set_labels(labels); - prev_labels = labels; + int hp = u.uhp; + int hpmax = u.uhpmax; + if (Upolyd) { + hp = u.mh; + hpmax = u.mhmax; } - curses_clear_nhwin(STATUS_WIN); - /* Line 1 */ + wmove(win, y, x); - /* Improve when this code is workable, this is a bit awkward at the moment */ - -#define statchange(stat,new,type) handle_stat_change(stat, new, type, &sx, &sy, \ - sx_start, horiz) + get_playerrank(rank); + sprintf(buf, "%s the %s", plname, rank); - /* Player name and title */ - strcpy(buf, plname); - if ('a' <= buf[0] && buf[0] <= 'z') - buf[0] += 'A' - 'a'; - strcat(buf, " the "); - if (u.mtimedone) { - char mname[BUFSZ]; - int k = 0; - - strcpy(mname, mons[u.umonnum].mname); - while (mname[k] != 0) { - if ((k == 0 || (k > 0 && mname[k - 1] == ' ')) - && 'a' <= mname[k] && mname[k] <= 'z') { - mname[k] += 'A' - 'a'; - } - k++; - } - strcat(buf, mname); - } else { - strcat(buf, rank_of(u.ulevel, pl_character[0], flags.female)); - } - - if (strcmp(buf, prevname.txt) != 0) { /* Title changed */ - prevname.highlight_turns = 5; - prevname.highlight_color = HIGHLIGHT_COLOR; - free(prevname.txt); - prevname.txt = curses_copy_of(buf); - if ((labels == COMPACT_LABELS) && (u.ulevel > 1)) { - curses_puts(MESSAGE_WIN, A_NORMAL, "You are now known as"); - curses_puts(MESSAGE_WIN, A_NORMAL, prevname.txt); - } - } - - if (prevname.label != NULL) { - mvwaddstr(win, sy, sx, prevname.label); - sx += strlen(prevname.label); - } - - if (labels != COMPACT_LABELS) { - color_stat(prevname, ON); - mvwaddstr(win, sy, sx, prevname.txt); - color_stat(prevname, OFF); - } + /* Use the title as HP bar (similar to hitpointbar) */ + draw_bar(TRUE, hp, hpmax, buf); - if (horiz) { - if (labels != COMPACT_LABELS) { - sx += strlen(prevname.txt) + 1; - } + /* Attributes */ + print_statdiff(" St:", &prevstr, ACURR(A_STR), STAT_STR); + print_statdiff(" Dx:", &prevdex, ACURR(A_DEX), STAT_OTHER); + print_statdiff(" Co:", &prevcon, ACURR(A_CON), STAT_OTHER); + print_statdiff(" In:", &prevint, ACURR(A_INT), STAT_OTHER); + print_statdiff(" Wi:", &prevwis, ACURR(A_WIS), STAT_OTHER); + print_statdiff(" Ch:", &prevcha, ACURR(A_CHA), STAT_OTHER); + wprintw(win, (u.ualign.type == A_CHAOTIC ? " Chaotic" : + u.ualign.type == A_NEUTRAL ? " Neutral" : " Lawful")); - } else { - sx = sx_start; - sy++; - } - - /* Add dungeon name and level if status window is vertical */ - if (!horiz) { - sprintf(buf, "%s", dungeons[u.uz.dnum].dname); - mvwaddstr(win, sy, sx, buf); - sy += 2; - } - - /* Strength */ - statchange(&prevstr, ACURR(A_STR), STAT_STR); - statchange(&prevint, ACURR(A_INT), STAT_OTHER); - statchange(&prevwis, ACURR(A_WIS), STAT_OTHER); - statchange(&prevdex, ACURR(A_DEX), STAT_OTHER); - statchange(&prevcon, ACURR(A_CON), STAT_OTHER); - statchange(&prevcha, ACURR(A_CHA), STAT_OTHER); - - /* Alignment */ - if (prevalign.alignment != u.ualign.type) { /* Alignment changed */ - prevalign.highlight_color = HIGHLIGHT_COLOR; - prevalign.highlight_turns = 10; /* This is a major change! */ - prevalign.alignment = u.ualign.type; - free(prevalign.txt); - switch (u.ualign.type) { - case A_LAWFUL: - prevalign.txt = curses_copy_of("Lawful"); - break; - case A_NEUTRAL: - prevalign.txt = curses_copy_of("Neutral"); - break; - case A_CHAOTIC: - prevalign.txt = curses_copy_of("Chaotic"); - break; - } - } +#ifdef SCORE_ON_BOTL + if (flags.showscore) + print_statdiff(" S:", &prevscore, botl_score(), STAT_OTHER); +#endif /* SCORE_ON_BOTL */ - if (prevalign.label != NULL) { - mvwaddstr(win, sy, sx, prevalign.label); - sx += strlen(prevalign.label); - } + wclrtoeol(win); - color_stat(prevalign, ON); - mvwaddstr(win, sy, sx, prevalign.txt); - color_stat(prevalign, OFF); /* Line 2 */ + y++; + wmove(win, y, x); - sx = sx_start; - sy++; - - /* Dungeon Level */ - if (depth(&u.uz) != prevdepth.value) { /* Dungeon level changed */ - prevdepth.highlight_color = HIGHLIGHT_COLOR; - prevdepth.highlight_turns = 5; - prevdepth.value = depth(&u.uz); - free(prevdepth.txt); - if (In_endgame(&u.uz)) { - strcpy(buf, (Is_astralevel(&u.uz) ? "Astral Plane" : "End Game")); - } else { - sprintf(buf, "%d", depth(&u.uz)); - } - prevdepth.txt = curses_copy_of(buf); - } + describe_level(buf); - if (prevdepth.label != NULL) { - mvwaddstr(win, sy, sx, prevdepth.label); - sx += strlen(prevdepth.label); - } - - color_stat(prevdepth, ON); - mvwaddstr(win, sy, sx, prevdepth.txt); - color_stat(prevdepth, OFF); - - if (horiz) { - sx += strlen(prevdepth.txt) + 1; - } else { - sx = sx_start; - sy++; - } + wprintw(win, "%s", buf); - /* Gold */ #ifndef GOLDOBJ - statchange(&prevau, u.ugold, STAT_GOLD); + print_statdiff("$", &prevau, u.ugold, STAT_GOLD); #else - statchange(&prevau, money_cnt(invent), STAT_GOLD); + print_statdiff("$", &prevau, money_cnt(invent), STAT_GOLD); #endif - /* Hit Points */ + /* HP/Pw use special coloring rules */ + int hpcolor, pwcolor; + attr_t attr; + hpcolor = hpen_color(TRUE, hp, hpmax); + pwcolor = hpen_color(FALSE, u.uen, u.uenmax); - if (u.mtimedone) { /* Currently polymorphed - show monster HP */ - hp = u.mh; - hpmax = u.mhmax; - } else { /* Not polymorphed */ + wprintw(win, " HP:"); + attr = curses_color_attr(hpcolor, 0); + wattron(win, attr); + wprintw(win, "%d(%d)", hp, hpmax); + wattroff(win, attr); - hp = u.uhp; - hpmax = u.uhpmax; - } + wprintw(win, " Pw:"); + attr = curses_color_attr(pwcolor, 0); + wattron(win, attr); + wprintw(win, "%d(%d)", u.uen, u.uenmax); + wattroff(win, attr); - statchange(&prevhp, hp, STAT_HPEN); - statchange(&prevmhp, hpmax, STAT_OTHER); - statchange(&prevpow, u.uen, STAT_HPEN); - statchange(&prevmpow, u.uenmax, STAT_OTHER); - statchange(&prevac, u.uac, STAT_AC); + print_statdiff(" AC:", &prevac, u.uac, STAT_AC); - /* Experience */ + if (Upolyd) + print_statdiff(" HD:", &prevlevel, mons[u.umonnum].mlevel, STAT_OTHER); #ifdef EXP_ON_BOTL - if (prevexp.display != flags.showexp) { /* Setting has changed */ - prevexp.display = flags.showexp; - free(prevlevel.label); - if (prevexp.display) { - prevlevel.label = curses_copy_of("/"); - } else { - if (horiz) { - if (labels == COMPACT_LABELS) { - prevlevel.label = curses_copy_of("Lv:"); - } else { - prevlevel.label = curses_copy_of("Lvl:"); - } - } else { - prevlevel.label = curses_copy_of("Level: "); - } - } + else if (flags.showexp) { + print_statdiff(" Xp:", &prevlevel, u.ulevel, STAT_OTHER); + /* use waddch, we don't want to highlight the '/' */ + waddch(win, '/'); + print_statdiff("", &prevexp, u.uexp, STAT_OTHER); +#endif + } else + print_statdiff(" Exp:", &prevlevel, u.ulevel, STAT_OTHER); + + if (flags.time) + print_statdiff(" T:", &prevtime, moves, STAT_TIME); +#define statprob(stat, str) \ + if (stat) { \ + waddch(win, ' '); \ + statusproblem(stat, str); \ } - if (prevexp.display && !u.mtimedone) { - if (u.uexp != prevexp.value) { - if (u.uexp > prevexp.value) { - prevexp.highlight_color = STAT_UP_COLOR; - } else { - prevexp.highlight_color = STAT_DOWN_COLOR; - } - sprintf(buf, "%ld", u.uexp); - free(prevexp.txt); - prevexp.txt = curses_copy_of(buf); - prevexp.highlight_turns = 3; - } + /* Hunger */ + statprob(u.uhs != 1, hu_stat[u.uhs]); + + /* General troubles */ + statprob(Confusion, "Conf"); + statprob(Blind, "Blind"); + statprob(Stunned, "Stun"); + statprob(Hallucination, "Hallu"); + statprob((u.usick_type & SICK_VOMITABLE), "FoodPois"); + statprob((u.usick_type & (SICK_NONVOMITABLE|SICK_ZOMBIE)), "Ill"); + statprob(Slimed, "Slime"); + + /* Encumbrance */ + int enc = near_capacity(); + statprob(enc > UNENCUMBERED, enc_stat[enc]); +#undef statprob + + wclrtoeol(win); +} - if (prevexp.label != NULL) { - mvwaddstr(win, sy, sx, prevexp.label); - sx += strlen(prevexp.label); - } - color_stat(prevexp, ON); - mvwaddstr(win, sy, sx, prevexp.txt); - color_stat(prevexp, OFF); +/* Personally I never understood the point of a vertical status bar. But removing the + option would be silly, so keep the functionality. */ +static void +draw_vertical(void) +{ + char buf[BUFSZ]; + char rank[BUFSZ]; + WINDOW *win = curses_get_nhwin(STATUS_WIN); - sx += strlen(prevexp.txt); - } + /* The area we're allowed to print on. Excludes borders */ + int x, y, h, w; - prevexp.value = u.uexp; /* Track it even when it's not displayed */ -#endif /* EXP_ON_BOTL */ - - /* Level */ - if (u.mtimedone) { /* Currently polymorphed - show monster HD */ - if ((strncmp(prevlevel.label, "HP:", 3) != 0) || - (strncmp(prevlevel.label, "Hit Points:", 11) != 0)) { - free(prevlevel.label); - if (horiz) { - prevlevel.label = curses_copy_of("HD:"); - } else { - prevlevel.label = curses_copy_of("Hit Dice: "); - } - } - if (mons[u.umonnum].mlevel != prevlevel.value) { - if (mons[u.umonnum].mlevel > prevlevel.value) { - prevlevel.highlight_color = STAT_UP_COLOR; - } else { - prevlevel.highlight_color = STAT_DOWN_COLOR; - } - prevlevel.highlight_turns = 5; - } - prevlevel.value = mons[u.umonnum].mlevel; - sprintf(buf, "%d", mons[u.umonnum].mlevel); - free(prevlevel.txt); - prevlevel.txt = curses_copy_of(buf); - } else { /* Not polymorphed */ - - if ((strncmp(prevlevel.label, "HD:", 3) != 0) || - (strncmp(prevlevel.label, "Hit Dice:", 9) != 0)) { - free(prevlevel.label); - if (prevexp.display) { - prevlevel.label = curses_copy_of("/"); - } else { - if (horiz) { - if (labels == COMPACT_LABELS) { - prevlevel.label = curses_copy_of("Lv:"); - } else { - prevlevel.label = curses_copy_of("Lvl:"); - } - } else { - prevlevel.label = curses_copy_of("Level: "); - } - } - } - if (u.ulevel > prevlevel.value) { - prevlevel.highlight_color = STAT_UP_COLOR; - prevlevel.highlight_turns = 5; - } else if (u.ulevel < prevlevel.value) { - prevlevel.highlight_color = STAT_DOWN_COLOR; - prevlevel.highlight_turns = 5; - } - prevlevel.value = u.ulevel; - sprintf(buf, "%d", u.ulevel); - free(prevlevel.txt); - prevlevel.txt = curses_copy_of(buf); + /* Starting x/y */ + x = 0; + y = 0; + + /* Starting height/width */ + curses_get_window_size(STATUS_WIN, &h, &w); + + boolean border = FALSE; + if (curses_window_has_border(STATUS_WIN)) { + x++; + y++; + h--; + w--; + border = TRUE; } - if (prevlevel.label != NULL) { - mvwaddstr(win, sy, sx, prevlevel.label); - sx += strlen(prevlevel.label); + int hp = u.uhp; + int hpmax = u.uhpmax; + if (Upolyd) { + hp = u.mh; + hpmax = u.mhmax; } - color_stat(prevlevel, ON); - mvwaddstr(win, sy, sx, prevlevel.txt); - color_stat(prevlevel, OFF); + /* Clear the window */ + werase(win); + + /* Print title and dungeon branch */ + wmove(win, y++, x); + + get_playerrank(rank); + int ranklen = strlen(rank); + int namelen = strlen(plname); + if ((ranklen + namelen) > 19) { + /* The result doesn't fit. Strip name if >10 characters, then strip title */ + if (namelen > 10) { + while (namelen > 10 && (ranklen + namelen) > 19) + namelen--; + } + + while ((ranklen + namelen) > 19) + ranklen--; /* Still doesn't fit, strip rank */ + } + sprintf(buf, "%-*s the %-*s", namelen, plname, ranklen, rank); + draw_bar(TRUE, hp, hpmax, buf); + wmove(win, y++, x); + wprintw(win, "%s", dungeons[u.uz.dnum].dname); + + y++; /* Blank line inbetween */ + wmove(win, y++, x); + + /* Attributes. Old vertical order is preserved */ + print_statdiff("Strength: ", &prevstr, ACURR(A_STR), STAT_STR); + wmove(win, y++, x); + print_statdiff("Intelligence: ", &prevint, ACURR(A_INT), STAT_OTHER); + wmove(win, y++, x); + print_statdiff("Wisdom: ", &prevwis, ACURR(A_WIS), STAT_OTHER); + wmove(win, y++, x); + print_statdiff("Dexterity: ", &prevdex, ACURR(A_DEX), STAT_OTHER); + wmove(win, y++, x); + print_statdiff("Constitution: ", &prevcon, ACURR(A_CON), STAT_OTHER); + wmove(win, y++, x); + print_statdiff("Charisma: ", &prevcha, ACURR(A_CHA), STAT_OTHER); + wmove(win, y++, x); + wprintw(win, "Alignment: "); + wprintw(win, (u.ualign.type == A_CHAOTIC ? "Chaotic" : + u.ualign.type == A_NEUTRAL ? "Neutral" : "Lawful")); + wmove(win, y++, x); + wprintw(win, "Dungeon Level: "); + + /* Astral Plane doesn't fit */ + if (In_endgame(&u.uz)) + wprintw(win, "%s", Is_astralevel(&u.uz) ? "Astral" : "End Game"); + else + wprintw(win, "%d", depth(&u.uz)); + wmove(win, y++, x); - if (horiz) { - sx += strlen(prevlevel.txt) + 1; - } else { - sx = sx_start; - sy++; - } +#ifndef GOLDOBJ + print_statdiff("Gold: ", &prevau, u.ugold, STAT_GOLD); +#else + print_statdiff("Gold: ", &prevau, money_cnt(invent), STAT_GOLD); +#endif + wmove(win, y++, x); + + /* HP/Pw use special coloring rules */ + int hpcolor, pwcolor; + attr_t attr; + hpcolor = hpen_color(TRUE, hp, hpmax); + pwcolor = hpen_color(FALSE, u.uen, u.uenmax); + + wprintw(win, "Hit Points: "); + attr = curses_color_attr(hpcolor, 0); + wattron(win, attr); + wprintw(win, "%d/%d", hp, hpmax); + wattroff(win, attr); + wmove(win, y++, x); + + wprintw(win, "Magic Power: "); + attr = curses_color_attr(pwcolor, 0); + wattron(win, attr); + wprintw(win, "%d/%d", u.uen, u.uenmax); + wattroff(win, attr); + wmove(win, y++, x); + + print_statdiff("Armor Class: ", &prevac, u.uac, STAT_AC); + wmove(win, y++, x); + + if (Upolyd) + print_statdiff("Hit Dice: ", &prevlevel, mons[u.umonnum].mlevel, STAT_OTHER); +#ifdef EXP_ON_BOTL + else if (flags.showexp) { + print_statdiff("Experience: ", &prevlevel, u.ulevel, STAT_OTHER); + /* use waddch, we don't want to highlight the '/' */ + waddch(win, '/'); + print_statdiff("", &prevexp, u.uexp, STAT_OTHER); +#endif + } else + print_statdiff("Level: ", &prevlevel, u.ulevel, STAT_OTHER); + wmove(win, y++, x); - /* Time */ - if (prevtime.display != flags.time) { /* Setting has changed */ - prevtime.display = flags.time; - } - if (prevtime.display) { - statchange(&prevtime, moves, STAT_TIME); + if (flags.time) { + print_statdiff("Time: ", &prevtime, moves, STAT_TIME); + wmove(win, y++, x); } - /* Score */ #ifdef SCORE_ON_BOTL - if (prevscore.display != flags.showscore) { /* Setting has changed */ - prevscore.display = flags.showscore; + if (flags.showscore) { + print_statdiff("Score: ", &prevscore, botl_score(), STAT_OTHER); + wmove(win, y++, x); } - if (prevscore.display) { - statchange(&prevscore, botl_score(), STAT_OTHER); - } - - prevscore.value = botl_score(); /* Track it even when it's not displayed */ #endif /* SCORE_ON_BOTL */ - /* Hunger */ - if (u.uhs != prevhunger.value) { - if ((u.uhs > prevhunger.value) || (u.uhs > 3)) { - prevhunger.highlight_color = STAT_DOWN_COLOR; - } else { - prevhunger.highlight_color = STAT_UP_COLOR; - } - prevhunger.value = u.uhs; - for (count = 0; count < strlen(hu_stat[u.uhs]); count++) { - if ((hu_stat[u.uhs][count]) == ' ') { - break; - } - buf[count] = hu_stat[u.uhs][count]; - } + /* Troubles. Uses a macro to avoid major repetition */ - buf[count] = '\0'; - free(prevhunger.txt); - prevhunger.txt = curses_copy_of(buf); - prevhunger.highlight_turns = 5; +#define statprob(stat, str) \ + if (stat) { \ + statusproblem(stat, str); \ + wmove(win, y++, x); \ } - if (prevhunger.label != NULL) { - mvwaddstr(win, sy, sx, prevhunger.label); - sx += strlen(prevhunger.label); - } + /* Hunger */ + statprob(u.uhs != 1, hu_stat[u.uhs]); + + /* General troubles */ + statprob(Confusion, "Conf"); + statprob(Blind, "Blind"); + statprob(Stunned, "Stun"); + statprob(Hallucination, "Hallu"); + statprob((u.usick_type & SICK_VOMITABLE), "FoodPois"); + statprob((u.usick_type & (SICK_NONVOMITABLE|SICK_ZOMBIE)), "Ill"); + statprob(Slimed, "Slime"); + + /* Encumbrance */ + int enc = near_capacity(); + statprob(enc > UNENCUMBERED, enc_stat[enc]); +#undef statprob +} - color_stat(prevhunger, ON); - mvwaddstr(win, sy, sx, prevhunger.txt); - color_stat(prevhunger, OFF); +void +curses_update_stats(void) +{ + char buf[BUFSZ]; + int count, enc, sx_start, hp, hpmax, labels, swidth, sheight, sx_end, sy_end, + orient; + WINDOW *win = curses_get_nhwin(STATUS_WIN); + static int prev_labels = -1; + static boolean first = TRUE; + static boolean horiz; + int sx = 0; + int sy = 0; + boolean border = curses_window_has_border(STATUS_WIN); - if (strlen(prevhunger.txt) > 0) { - if (horiz) { - sx += strlen(prevhunger.txt) + 1; - } else { - sx = sx_start; - sy++; - } - } -#define statusproblem(stat,new,str) handle_status_problem(stat, new, str, &sx, &sy, \ - sx_start, horiz) - - /* Confusion */ - statusproblem(&prevconf, Confusion, "Conf"); - statusproblem(&prevblind, Blind, "Blind"); - statusproblem(&prevstun, Stunned, "Stun"); - statusproblem(&prevhallu, Hallucination, "Hallu"); - - /* TODO: allow all 3 kinds of sickness seperately: FoodPois, Ill, Zombie */ - statusproblem(&prevsick, Sick, - (u.usick_type & SICK_VOMITABLE) ? "FoodPois" : "Ill"); - statusproblem(&prevslime, Slimed, "Slime"); - - /* Encumberance */ - enc = near_capacity(); - - if (enc != prevencumb.value) { - if (enc < prevencumb.value) { - prevencumb.highlight_color = STAT_UP_COLOR; - } else { - prevencumb.highlight_color = STAT_DOWN_COLOR; - } - if (prevencumb.txt != NULL) { - free(prevencumb.txt); - } - if (enc > UNENCUMBERED) { - sprintf(buf, "%s", enc_stat[enc]); - prevencumb.txt = curses_copy_of(buf); - prevencumb.highlight_turns = 5; - } else { - prevencumb.txt = NULL; - } - prevencumb.value = enc; - } + curses_get_window_size(STATUS_WIN, &sheight, &swidth); - if (prevencumb.label != NULL) { - mvwaddstr(win, sy, sx, prevencumb.label); - sx += strlen(prevencumb.label); + if (border) { + sx++; + sy++; + swidth--; + sheight--; } - if (prevencumb.txt != NULL) { - color_stat(prevencumb, ON); - mvwaddstr(win, sy, sx, prevencumb.txt); - color_stat(prevencumb, OFF); - } + sx_end = swidth - 1; + sy_end = sheight - 1; + sx_start = sx; - if (prevencumb.txt != NULL) { - if (horiz) { - sx += strlen(prevencumb.txt) + 1; - } else { - sx = sx_start; - sy++; - } + if (first) { + init_stats(); + first = FALSE; } + orient = curses_get_window_orientation(STATUS_WIN); + + horiz = FALSE; + if ((orient != ALIGN_RIGHT) && (orient != ALIGN_LEFT)) + horiz = TRUE; + + if (orient != ALIGN_RIGHT && orient != ALIGN_LEFT) + draw_horizontal(); + else + draw_vertical(); + + if (border) + box(win, 0, 0); + wrefresh(win); } -/* Decrement a single highlight, return 1 if decremented to zero */ - +/* Decrement a single highlight, return 1 if decremented to zero. zero is TRUE if we're + zeroing the highlight. */ static int -decrement_highlight(nhstat *stat) +decrement_highlight(nhstat *stat, boolean zero) { if (stat->highlight_turns > 0) { - stat->highlight_turns--; - if (stat->highlight_turns == 0) { + if (zero) { + stat->highlight_turns = 0; return 1; } + + stat->highlight_turns--; + if (stat->highlight_turns == 0) + return 1; } return 0; } @@ -675,929 +805,78 @@ decrement_highlight(nhstat *stat) /* Decrement the highlight_turns for all stats. Call curses_update_stats if needed to unhighlight a stat */ -void -curses_decrement_highlight() +static void +decrement_highlights(boolean zero) { int unhighlight = 0; - unhighlight |= decrement_highlight(&prevname); - unhighlight |= decrement_highlight(&prevdepth); - unhighlight |= decrement_highlight(&prevstr); - unhighlight |= decrement_highlight(&prevint); - unhighlight |= decrement_highlight(&prevwis); - unhighlight |= decrement_highlight(&prevdex); - unhighlight |= decrement_highlight(&prevcon); - unhighlight |= decrement_highlight(&prevcha); - unhighlight |= decrement_highlight(&prevalign); - unhighlight |= decrement_highlight(&prevau); - unhighlight |= decrement_highlight(&prevhp); - unhighlight |= decrement_highlight(&prevmhp); - unhighlight |= decrement_highlight(&prevlevel); - unhighlight |= decrement_highlight(&prevpow); - unhighlight |= decrement_highlight(&prevmpow); - unhighlight |= decrement_highlight(&prevac); + unhighlight |= decrement_highlight(&prevdepth, zero); + unhighlight |= decrement_highlight(&prevstr, zero); + unhighlight |= decrement_highlight(&prevdex, zero); + unhighlight |= decrement_highlight(&prevcon, zero); + unhighlight |= decrement_highlight(&prevint, zero); + unhighlight |= decrement_highlight(&prevwis, zero); + unhighlight |= decrement_highlight(&prevcha, zero); + unhighlight |= decrement_highlight(&prevau, zero); + unhighlight |= decrement_highlight(&prevhp, zero); + unhighlight |= decrement_highlight(&prevmhp, zero); + unhighlight |= decrement_highlight(&prevlevel, zero); + unhighlight |= decrement_highlight(&prevpow, zero); + unhighlight |= decrement_highlight(&prevmpow, zero); + unhighlight |= decrement_highlight(&prevac, zero); #ifdef EXP_ON_BOTL - unhighlight |= decrement_highlight(&prevexp); + unhighlight |= decrement_highlight(&prevexp, zero); #endif - unhighlight |= decrement_highlight(&prevtime); + unhighlight |= decrement_highlight(&prevtime, zero); #ifdef SCORE_ON_BOTL - unhighlight |= decrement_highlight(&prevscore); + unhighlight |= decrement_highlight(&prevscore, zero); #endif - unhighlight |= decrement_highlight(&prevhunger); - unhighlight |= decrement_highlight(&prevconf); - unhighlight |= decrement_highlight(&prevblind); - unhighlight |= decrement_highlight(&prevstun); - unhighlight |= decrement_highlight(&prevhallu); - unhighlight |= decrement_highlight(&prevsick); - unhighlight |= decrement_highlight(&prevslime); - unhighlight |= decrement_highlight(&prevencumb); - - if (unhighlight) { - curses_update_stats(FALSE); - } + + if (unhighlight) + curses_update_stats(); } -/* Initialize the stats with beginning values. */ +void +curses_decrement_highlight() +{ + decrement_highlights(FALSE); +} + +/* Initializes the prev(whatever) values */ static void init_stats() { - char buf[BUFSZ]; - int count; - - /* Player name and title */ - strcpy(buf, plname); - if ('a' <= buf[0] && buf[0] <= 'z') - buf[0] += 'A' - 'a'; - strcat(buf, " the "); - if (u.mtimedone) { - char mname[BUFSZ]; - int k = 0; - - strcpy(mname, mons[u.umonnum].mname); - while (mname[k] != 0) { - if ((k == 0 || (k > 0 && mname[k - 1] == ' ')) - && 'a' <= mname[k] && mname[k] <= 'z') { - mname[k] += 'A' - 'a'; - } - k++; - } - strcat(buf, mname); - } else { - strcat(buf, rank_of(u.ulevel, pl_character[0], flags.female)); - } - - prevname.txt = curses_copy_of(buf); - prevname.display = TRUE; - prevname.highlight_turns = 0; - prevname.label = NULL; - prevname.id = "name"; - set_stat_color(&prevname); - - /* Strength */ - if (ACURR(A_STR) > 118) { - sprintf(buf, "%d", ACURR(A_STR) - 100); - } else if (ACURR(A_STR) == 118) { - sprintf(buf, "18/**"); - } else if (ACURR(A_STR) > 18) { - sprintf(buf, "18/%02d", ACURR(A_STR) - 18); - } else { - sprintf(buf, "%d", ACURR(A_STR)); - } - + prevdepth.value = depth(&u.uz); prevstr.value = ACURR(A_STR); - prevstr.txt = curses_copy_of(buf); - prevstr.display = TRUE; - prevstr.highlight_turns = 0; - prevstr.label = NULL; - prevstr.id = "str"; - set_stat_color(&prevstr); - - /* Intelligence */ - sprintf(buf, "%d", ACURR(A_INT)); - prevint.value = ACURR(A_INT); - prevint.txt = curses_copy_of(buf); - prevint.display = TRUE; - prevint.highlight_turns = 0; - prevint.label = NULL; - prevint.id = "int"; - set_stat_color(&prevint); - - /* Wisdom */ - sprintf(buf, "%d", ACURR(A_WIS)); - prevwis.value = ACURR(A_WIS); - prevwis.txt = curses_copy_of(buf); - prevwis.display = TRUE; - prevwis.highlight_turns = 0; - prevwis.label = NULL; - prevwis.id = "wis"; - set_stat_color(&prevwis); - - /* Dexterity */ - sprintf(buf, "%d", ACURR(A_DEX)); prevdex.value = ACURR(A_DEX); - prevdex.txt = curses_copy_of(buf); - prevdex.display = TRUE; - prevdex.highlight_turns = 0; - prevdex.label = NULL; - prevdex.id = "dex"; - set_stat_color(&prevdex); - - /* Constitution */ - sprintf(buf, "%d", ACURR(A_CON)); prevcon.value = ACURR(A_CON); - prevcon.txt = curses_copy_of(buf); - prevcon.display = TRUE; - prevcon.highlight_turns = 0; - prevcon.label = NULL; - prevcon.id = "con"; - set_stat_color(&prevcon); - - /* Charisma */ - sprintf(buf, "%d", ACURR(A_CHA)); + prevint.value = ACURR(A_INT); + prevwis.value = ACURR(A_WIS); prevcha.value = ACURR(A_CHA); - prevcha.txt = curses_copy_of(buf); - prevcha.display = TRUE; - prevcha.highlight_turns = 0; - prevcha.label = NULL; - prevcha.id = "cha"; - set_stat_color(&prevcha); - - /* Alignment */ - switch (u.ualign.type) { - case A_LAWFUL: - prevalign.txt = curses_copy_of("Lawful"); - break; - case A_NEUTRAL: - prevalign.txt = curses_copy_of("Neutral"); - break; - case A_CHAOTIC: - prevalign.txt = curses_copy_of("Chaotic"); - break; - } - - prevalign.alignment = u.ualign.type; - prevalign.display = TRUE; - prevalign.highlight_turns = 0; - prevalign.label = NULL; - prevalign.id = "align"; - set_stat_color(&prevalign); - - /* Dungeon level */ - if (In_endgame(&u.uz)) { - strcpy(buf, (Is_astralevel(&u.uz) ? "Astral Plane" : "End Game")); - } else { - sprintf(buf, "%d", depth(&u.uz)); - } - - prevdepth.value = depth(&u.uz); - prevdepth.txt = curses_copy_of(buf); - prevdepth.display = TRUE; - prevdepth.highlight_turns = 0; - prevdepth.label = NULL; - prevdepth.id = "dlvl"; - set_stat_color(&prevdepth); - - /* Gold */ #ifndef GOLDOBJ - sprintf(buf, "%ld", u.ugold); prevau.value = u.ugold; #else - sprintf(buf, "%ld", money_cnt(invent)); prevau.value = money_cnt(invent); #endif - prevau.txt = curses_copy_of(buf); - prevau.display = TRUE; - prevau.highlight_turns = 0; - prevau.label = NULL; - prevau.id = "gold"; - set_stat_color(&prevau); - - /* Hit Points */ - if (u.mtimedone) { /* Currently polymorphed - show monster HP */ - prevhp.value = u.mh; - sprintf(buf, "%d", u.mh); - prevhp.txt = curses_copy_of(buf); - } else if (u.uhp != prevhp.value) { /* Not polymorphed */ - prevhp.value = u.uhp; - sprintf(buf, "%d", u.uhp); - prevhp.txt = curses_copy_of(buf); - } - prevhp.display = TRUE; - prevhp.highlight_turns = 0; - prevhp.label = NULL; - prevhp.id = "hp"; - set_stat_color(&prevhp); - - /* Max Hit Points */ - if (u.mtimedone) { /* Currently polymorphed - show monster HP */ - prevmhp.value = u.mhmax; - sprintf(buf, "%d", u.mhmax); - prevmhp.txt = curses_copy_of(buf); - } else { /* Not polymorphed */ - - prevmhp.value = u.uhpmax; - sprintf(buf, "%d", u.uhpmax); - prevmhp.txt = curses_copy_of(buf); + int hp = u.uhp; + int hpmax = u.uhpmax; + if (Upolyd) { + hp = u.mh; + hpmax = u.mhmax; } - prevmhp.display = TRUE; - prevmhp.highlight_turns = 0; - prevmhp.label = curses_copy_of("/"); - prevmhp.id = "mhp"; - set_stat_color(&prevmhp); - - /* Power */ + prevhp.value = hp; + prevmhp.value = hpmax; + prevlevel.value = (Upolyd ? mons[u.umonnum].mlevel : u.ulevel); prevpow.value = u.uen; - sprintf(buf, "%d", u.uen); - prevpow.txt = curses_copy_of(buf); - prevpow.display = TRUE; - prevpow.highlight_turns = 0; - prevpow.label = NULL; - prevpow.id = "pw"; - set_stat_color(&prevpow); - - /* Max Power */ prevmpow.value = u.uenmax; - sprintf(buf, "%d", u.uenmax); - prevmpow.txt = curses_copy_of(buf); - prevmpow.display = TRUE; - prevmpow.highlight_turns = 0; - prevmpow.label = curses_copy_of("/"); - prevmpow.id = "mpw"; - set_stat_color(&prevmpow); - - /* Armor Class */ prevac.value = u.uac; - sprintf(buf, "%d", u.uac); - prevac.txt = curses_copy_of(buf); - prevac.display = TRUE; - prevac.highlight_turns = 0; - prevac.label = NULL; - prevac.id = "ac"; - set_stat_color(&prevac); - - /* Experience */ #ifdef EXP_ON_BOTL prevexp.value = u.uexp; - sprintf(buf, "%ld", u.uexp); - prevexp.txt = curses_copy_of(buf); - prevexp.display = flags.showexp; - prevexp.highlight_turns = 0; - prevexp.label = NULL; - prevexp.id = "xp"; - set_stat_color(&prevexp); #endif - - /* Level */ - prevlevel.label = NULL; - if (u.mtimedone) { /* Currently polymorphed - show monster HP */ - prevlevel.value = mons[u.umonnum].mlevel; - sprintf(buf, "%d", mons[u.umonnum].mlevel); - prevlevel.txt = curses_copy_of(buf); - } else if (u.ulevel != prevlevel.value) { /* Not polymorphed */ - prevlevel.value = u.ulevel; - sprintf(buf, "%d", u.ulevel); - prevlevel.txt = curses_copy_of(buf); - } - prevlevel.display = TRUE; - prevlevel.highlight_turns = 0; - prevlevel.id = "lvl"; - set_stat_color(&prevlevel); - - /* Time */ prevtime.value = moves; - sprintf(buf, "%ld", moves); - prevtime.txt = curses_copy_of(buf); - prevtime.display = flags.time; - prevtime.highlight_turns = 0; - prevtime.label = NULL; - prevtime.id = "time"; - set_stat_color(&prevtime); - - /* Score */ #ifdef SCORE_ON_BOTL prevscore.value = botl_score(); - sprintf(buf, "%ld", botl_score()); - prevscore.txt = curses_copy_of(buf); - prevscore.display = flags.showscore; - prevscore.highlight_turns = 0; - prevscore.label = NULL; - prevscore.id = "score"; - set_stat_color(&prevscore); #endif - - /* Hunger */ - prevhunger.value = u.uhs; - for (count = 0; count < strlen(hu_stat[u.uhs]); count++) { - if ((hu_stat[u.uhs][count]) == ' ') { - break; - } - buf[count] = hu_stat[u.uhs][count]; - } - - buf[count] = '\0'; - prevhunger.txt = curses_copy_of(buf); - prevhunger.display = TRUE; - prevhunger.highlight_turns = 0; - prevhunger.label = NULL; - prevhunger.id = "hunger"; - set_stat_color(&prevhunger); - - /* Confusion */ - prevconf.value = Confusion; - if (Confusion) { - prevconf.txt = curses_copy_of("Conf"); - } else { - prevconf.txt = NULL; - } - prevconf.display = TRUE; - prevconf.highlight_turns = 0; - prevconf.label = NULL; - prevconf.id = "conf"; - set_stat_color(&prevconf); - - /* Blindness */ - prevblind.value = Blind; - if (Blind) { - prevblind.txt = curses_copy_of("Blind"); - } else { - prevblind.txt = NULL; - } - prevblind.display = TRUE; - prevblind.highlight_turns = 0; - prevblind.label = NULL; - prevblind.id = "blind"; - set_stat_color(&prevblind); - - /* Stun */ - prevstun.value = Stunned; - if (Stunned) { - prevstun.txt = curses_copy_of("Stun"); - } else { - prevstun.txt = NULL; - } - prevstun.display = TRUE; - prevstun.highlight_turns = 0; - prevstun.label = NULL; - prevstun.id = "stun"; - set_stat_color(&prevstun); - - /* Hallucination */ - prevhallu.value = Hallucination; - if (Hallucination) { - prevhallu.txt = curses_copy_of("Hallu"); - } else { - prevhallu.txt = NULL; - } - prevhallu.display = TRUE; - prevhallu.highlight_turns = 0; - prevhallu.label = NULL; - prevhallu.id = "hallu"; - set_stat_color(&prevhallu); - - /* Sick */ - prevsick.value = Sick; - if (Sick) { - if (u.usick_type & SICK_VOMITABLE) { - prevsick.txt = curses_copy_of("FoodPois"); - } else { - prevsick.txt = curses_copy_of("Ill"); - } - } else { - prevsick.txt = NULL; - } - prevsick.display = TRUE; - prevsick.highlight_turns = 0; - prevsick.label = NULL; - prevsick.id = "sick"; - set_stat_color(&prevsick); - - /* Slimed */ - prevslime.value = Slimed; - if (Slimed) { - prevslime.txt = curses_copy_of("Slime"); - } else { - prevslime.txt = NULL; - } - prevslime.display = TRUE; - prevslime.highlight_turns = 0; - prevslime.label = NULL; - prevslime.id = "slime"; - set_stat_color(&prevslime); - - /* Encumberance */ - prevencumb.value = near_capacity(); - if (prevencumb.value > UNENCUMBERED) { - sprintf(buf, "%s", enc_stat[prevencumb.value]); - prevencumb.txt = curses_copy_of(buf); - } else { - prevencumb.txt = NULL; - } - prevencumb.display = TRUE; - prevencumb.highlight_turns = 0; - prevencumb.label = NULL; - prevencumb.id = "encumberance"; - set_stat_color(&prevencumb); -} - -/* Set labels based on orientation of status window. If horizontal, -we want to compress this info; otherwise we know we have a width of at -least 26 characters. */ - -static void -set_labels(int label_width) -{ - char buf[BUFSZ]; - - switch (label_width) { - case COMPACT_LABELS: - /* Strength */ - if (prevstr.label) { - free(prevstr.label); - } - prevstr.label = curses_copy_of("S:"); - /* Intelligence */ - if (prevint.label) { - free(prevint.label); - } - prevint.label = curses_copy_of("I:"); - - /* Wisdom */ - if (prevwis.label) { - free(prevwis.label); - } - prevwis.label = curses_copy_of("W:"); - - /* Dexterity */ - if (prevdex.label) { - free(prevdex.label); - } - prevdex.label = curses_copy_of("D:"); - - /* Constitution */ - if (prevcon.label) { - free(prevcon.label); - } - prevcon.label = curses_copy_of("C:"); - - /* Charisma */ - if (prevcha.label) { - free(prevcha.label); - } - prevcha.label = curses_copy_of("Ch:"); - - /* Alignment */ - if (prevalign.label) { - free(prevalign.label); - } - prevalign.label = NULL; - - /* Dungeon level */ - if (prevdepth.label) { - free(prevdepth.label); - } - prevdepth.label = curses_copy_of("Dl:"); - - /* Gold */ - if (prevau.label) { - free(prevau.label); - } - sprintf(buf, "%c:", GOLD_SYM); - prevau.label = curses_copy_of(buf); - - /* Hit points */ - if (prevhp.label) { - free(prevhp.label); - } - prevhp.label = curses_copy_of("HP:"); - - /* Power */ - if (prevpow.label) { - free(prevpow.label); - } - prevpow.label = curses_copy_of("Pw:"); - - /* Armor Class */ - if (prevac.label) { - free(prevac.label); - } - prevac.label = curses_copy_of("AC:"); - -#ifdef EXP_ON_BOTL - /* Experience */ - if (prevexp.label) { - free(prevexp.label); - } - prevexp.label = curses_copy_of("XP:"); -#endif - - /* Level */ - if (prevlevel.label) { - free(prevlevel.label); - prevlevel.label = NULL; - } - if (u.mtimedone) { /* Currently polymorphed - show monster HP */ - prevlevel.label = curses_copy_of("HD:"); - } else { /* Not polymorphed */ - - if (prevexp.display) { - prevlevel.label = curses_copy_of("/"); - } else { - prevlevel.label = curses_copy_of("Lv:"); - } - } - - /* Time */ - if (prevtime.label) { - free(prevtime.label); - } - prevtime.label = curses_copy_of("T:"); - -#ifdef SCORE_ON_BOTL - /* Score */ - if (prevscore.label) { - free(prevscore.label); - } - prevscore.label = curses_copy_of("S:"); -#endif - break; - - case NORMAL_LABELS: - /* Strength */ - if (prevstr.label) { - free(prevstr.label); - } - prevstr.label = curses_copy_of("Str:"); - /* Intelligence */ - if (prevint.label) { - free(prevint.label); - } - prevint.label = curses_copy_of("Int:"); - - /* Wisdom */ - if (prevwis.label) { - free(prevwis.label); - } - prevwis.label = curses_copy_of("Wis:"); - - /* Dexterity */ - if (prevdex.label) { - free(prevdex.label); - } - prevdex.label = curses_copy_of("Dex:"); - - /* Constitution */ - if (prevcon.label) { - free(prevcon.label); - } - prevcon.label = curses_copy_of("Con:"); - - /* Charisma */ - if (prevcha.label) { - free(prevcha.label); - } - prevcha.label = curses_copy_of("Cha:"); - - /* Alignment */ - if (prevalign.label) { - free(prevalign.label); - } - prevalign.label = NULL; - - /* Dungeon level */ - if (prevdepth.label) { - free(prevdepth.label); - } - prevdepth.label = curses_copy_of("Dlvl:"); - - /* Gold */ - if (prevau.label) { - free(prevau.label); - } - sprintf(buf, "%c:", GOLD_SYM); - prevau.label = curses_copy_of(buf); - - /* Hit points */ - if (prevhp.label) { - free(prevhp.label); - } - prevhp.label = curses_copy_of("HP:"); - - /* Power */ - if (prevpow.label) { - free(prevpow.label); - } - prevpow.label = curses_copy_of("Pw:"); - - /* Armor Class */ - if (prevac.label) { - free(prevac.label); - } - prevac.label = curses_copy_of("AC:"); - -#ifdef EXP_ON_BOTL - /* Experience */ - if (prevexp.label) { - free(prevexp.label); - } - prevexp.label = curses_copy_of("XP:"); -#endif - - /* Level */ - if (prevlevel.label) { - free(prevlevel.label); - prevlevel.label = NULL; - } - if (u.mtimedone) { /* Currently polymorphed - show monster HP */ - prevlevel.label = curses_copy_of("HD:"); - } else { /* Not polymorphed */ - - if (prevexp.display) { - prevlevel.label = curses_copy_of("/"); - } else { - prevlevel.label = curses_copy_of("Lvl:"); - } - } - - /* Time */ - if (prevtime.label) { - free(prevtime.label); - } - prevtime.label = curses_copy_of("T:"); - -#ifdef SCORE_ON_BOTL - /* Score */ - if (prevscore.label) { - free(prevscore.label); - } - prevscore.label = curses_copy_of("S:"); -#endif - break; - - case WIDE_LABELS: - /* Strength */ - if (prevstr.label) { - free(prevstr.label); - } - prevstr.label = curses_copy_of("Strength: "); - - /* Intelligence */ - if (prevint.label) { - free(prevint.label); - } - prevint.label = curses_copy_of("Intelligence: "); - - /* Wisdom */ - if (prevwis.label) { - free(prevwis.label); - } - prevwis.label = curses_copy_of("Wisdom: "); - - /* Dexterity */ - if (prevdex.label) { - free(prevdex.label); - } - prevdex.label = curses_copy_of("Dexterity: "); - - /* Constitution */ - if (prevcon.label) { - free(prevcon.label); - } - prevcon.label = curses_copy_of("Constitution: "); - - /* Charisma */ - if (prevcha.label) { - free(prevcha.label); - } - prevcha.label = curses_copy_of("Charisma: "); - - /* Alignment */ - if (prevalign.label) { - free(prevalign.label); - } - prevalign.label = curses_copy_of("Alignment: "); - - /* Dungeon level */ - if (prevdepth.label) { - free(prevdepth.label); - } - prevdepth.label = curses_copy_of("Dungeon Level: "); - - /* Gold */ - if (prevau.label) { - free(prevau.label); - } - prevau.label = curses_copy_of("Gold: "); - - /* Hit points */ - if (prevhp.label) { - free(prevhp.label); - } - prevhp.label = curses_copy_of("Hit Points: "); - - /* Power */ - if (prevpow.label) { - free(prevpow.label); - } - prevpow.label = curses_copy_of("Magic Power: "); - - /* Armor Class */ - if (prevac.label) { - free(prevac.label); - } - prevac.label = curses_copy_of("Armor Class: "); - -#ifdef EXP_ON_BOTL - /* Experience */ - if (prevexp.label) { - free(prevexp.label); - } - prevexp.label = curses_copy_of("Experience: "); -#endif - - /* Level */ - if (prevlevel.label) { - free(prevlevel.label); - } - if (u.mtimedone) { /* Currently polymorphed - show monster HP */ - prevlevel.label = curses_copy_of("Hit Dice: "); - } else { /* Not polymorphed */ - - if (prevexp.display) { - prevlevel.label = curses_copy_of(" / "); - } else { - prevlevel.label = curses_copy_of("Level: "); - } - } - - /* Time */ - if (prevtime.label) { - free(prevtime.label); - } - prevtime.label = curses_copy_of("Time: "); - -#ifdef SCORE_ON_BOTL - /* Score */ - if (prevscore.label) { - free(prevscore.label); - } - prevscore.label = curses_copy_of("Score: "); -#endif - break; - - default: - panic("set_labels(): Invalid label_width %d\n", label_width); - break; - } -} - - -/* Get the default (non-highlighted) color for a stat. For now, this -is NO_COLOR unless the statuscolors patch is in use. */ - -static void -set_stat_color(nhstat *stat) -{ -#ifdef STATUS_COLORS - struct color_option stat_color; - int count; - int attr = A_NORMAL; - - if (iflags.use_status_colors && stat_colored(stat->id)) { - stat_color = text_color_of(stat->id, text_colors); - - for (count = 0; (1 << count) <= stat_color.attr_bits; ++count) { - if (count != ATR_NONE && stat_color.attr_bits & (1 << count)) { - attr += curses_convert_attr(count); - } - } - - stat->stat_color = stat_color.color; - stat->stat_attr = attr; - } else { - stat->stat_color = NO_COLOR; - stat->stat_attr = A_NORMAL; - } -#else - stat->stat_color = NO_COLOR; - stat->stat_attr = A_NORMAL; -#endif /* STATUS_COLORS */ -} - - -/* Set the color to the base color for the given stat, or highlight a - changed stat. */ - -static void -color_stat(nhstat stat, int onoff) -{ - WINDOW *win = curses_get_nhwin(STATUS_WIN); - -#ifdef STATUS_COLORS - struct color_option stat_color; - int color, attr, hp, hpmax, count; - char buf[BUFSIZ]; - - stat_color.color = NO_COLOR; - stat_color.attr_bits = ATR_NONE; - - if (strcmp(stat.id, "hp") == 0) { - hp = Upolyd ? u.mh : u.uhp; - hpmax = Upolyd ? u.mhmax : u.uhpmax; - stat_color = percentage_color_of(hp, hpmax, hp_colors); - } - - if (strcmp(stat.id, "pw") == 0) { - stat_color = percentage_color_of(u.uen, u.uenmax, pw_colors); - } - - if (strcmp(stat.id, "hunger") == 0) { - for (count = 0; count < strlen(hu_stat[u.uhs]); count++) { - if ((hu_stat[u.uhs][count]) == ' ') { - break; - } - buf[count] = hu_stat[u.uhs][count]; - } - - buf[count] = '\0'; - stat_color = text_color_of(buf, text_colors); - } - - if (strcmp(stat.id, "encumberance") == 0) { - stat_color = text_color_of(enc_stat[prevencumb.value], text_colors); - } - - if (strcmp(stat.id, "sick") == 0) { - if (u.usick_type & SICK_VOMITABLE) { - stat_color = text_color_of("foodpois", text_colors); - } else { - stat_color = text_color_of("ill", text_colors); - } - } - - if (strcmp(stat.id, "align") == 0) { - switch (u.ualign.type) { - case A_LAWFUL: - stat_color = text_color_of("lawful", text_colors); - break; - case A_NEUTRAL: - stat_color = text_color_of("neutral", text_colors); - break; - case A_CHAOTIC: - stat_color = text_color_of("chaotic", text_colors); - break; - } - } - - color = stat_color.color; - attr = A_NORMAL; - - for (count = 0; (1 << count) <= stat_color.attr_bits; ++count) { - if (count != ATR_NONE && stat_color.attr_bits & (1 << count)) { - attr += curses_convert_attr(count); - } - } - - stat.stat_color = color; - stat.stat_attr = attr; -#endif /* STATUS_COLORS */ - - if ((stat.stat_color == NO_COLOR) && (stat.stat_attr == A_NORMAL)) { - if (stat.highlight_turns > 0) { -#ifdef STATUS_COLORS - if (iflags.use_status_colors) -#endif - curses_toggle_color_attr(win, stat.highlight_color, - A_NORMAL, onoff); - } - - return; - } -#ifdef STATUS_COLORS - if (iflags.use_status_colors) -#endif - curses_toggle_color_attr(win, stat.stat_color, stat.stat_attr, onoff); -} - - -/* Determine if a stat is configured via statuscolors. */ - -#ifdef STATUS_COLORS -static boolean -stat_colored(const char *id) -{ - struct text_color_option *cur_option = - (struct text_color_option *) text_colors; - - while (cur_option != NULL) { - if (strcmpi(cur_option->text, id) == 0) { - return TRUE; - } - - cur_option = (struct text_color_option *) cur_option->next; - } - - return FALSE; } -#endif /* STATUS_COLORS */ diff --git a/win/curses/cursstat.h b/win/curses/cursstat.h index f7a974b3..148cb079 100644 --- a/win/curses/cursstat.h +++ b/win/curses/cursstat.h @@ -5,16 +5,16 @@ /* Used by handle_stat_change to handle some stats differently. Not an enum because this is how NetHack code generally handles them. */ -# define STAT_OTHER 0 -# define STAT_STR 1 -# define STAT_GOLD 2 -# define STAT_HPEN 3 /* HP or Pw */ -# define STAT_AC 4 -# define STAT_TIME 5 +# define STAT_OTHER 0 +# define STAT_STR 1 +# define STAT_GOLD 2 +# define STAT_AC 4 +# define STAT_TIME 5 +# define STAT_TROUBLE 6 /* Global declarations */ -void curses_update_stats(boolean redraw); +void curses_update_stats(); void curses_decrement_highlight(void); diff --git a/win/curses/curswins.c b/win/curses/curswins.c index 57c717dc..bc4bb038 100644 --- a/win/curses/curswins.c +++ b/win/curses/curswins.c @@ -341,7 +341,7 @@ curses_putch(winid wid, int x, int y, int ch, int color, int attr) static boolean map_initted = FALSE; if (wid == STATUS_WIN) { - curses_update_stats(FALSE); + curses_update_stats(); } if (wid != MAP_WIN) { @@ -458,7 +458,7 @@ curses_puts(winid wid, int attr, const char *text) } if (wid == STATUS_WIN) { - curses_update_stats(FALSE); /* We will do the write ourselves */ + curses_update_stats(); /* We will do the write ourselves */ return; } From 0eb76f933594baf6f96ba79bbcc6a8759a85534a Mon Sep 17 00:00:00 2001 From: Tangles Date: Thu, 27 Apr 2017 22:30:09 +1000 Subject: [PATCH 20/69] Curses - handle long #extcmd entry gracefully. --- win/curses/cursdial.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/win/curses/cursdial.c b/win/curses/cursdial.c index 398a0bbb..cbe6193f 100644 --- a/win/curses/cursdial.c +++ b/win/curses/cursdial.c @@ -321,8 +321,7 @@ curses_ext_cmd() startx = 0; starty = 0; - if (iflags.wc_popup_dialog) /* Prompt in popup window */ - { + if (iflags.wc_popup_dialog) { /* Prompt in popup window */ int x0, y0, w, h; /* bounding coords of popup */ extwin2 = curses_create_window(25, 1, UP); wrefresh(extwin2); @@ -331,9 +330,7 @@ curses_ext_cmd() getmaxyx(extwin2,h,w); extwin = newwin(1, w-2, y0+1, x0+1); if (w - 4 < maxlen) maxlen = w - 4; - } - else - { + } else { curses_get_window_xy(MESSAGE_WIN, &winx, &winy); curses_get_window_size(MESSAGE_WIN, &messageh, &messagew); @@ -401,8 +398,6 @@ curses_ext_cmd() } } if (letter != '*' && prompt_width < maxlen) { - - if (letter != '*' && prompt_width < BUFSZ - 1) { cur_choice[prompt_width] = letter; cur_choice[prompt_width + 1] = '\0'; ret = -1; From 42c7c7685666519893a83dbeb185d9a80652a505 Mon Sep 17 00:00:00 2001 From: Tangles Date: Tue, 9 May 2017 18:15:01 +1000 Subject: [PATCH 21/69] curses - statuscolors fixes (not currently used) --- win/curses/cursstat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index 157a96ac..3588d493 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -138,7 +138,7 @@ get_trouble_color(const char *stat) status_color = text_color_of(clr->id, cur_option); int count; - for (count = 0; (1 << count) <= stat_color.attr_bits; count++) { + for (count = 0; (1 << count) <= status_color.attr_bits; count++) { if (count != ATR_NONE && (status_color.attr_bits & (1 << count))) attr |= curses_convert_attr(count); } @@ -350,7 +350,7 @@ hpen_color_attr(boolean is_hp, int cur, int max) status_color = percentage_color_of(cur, max, is_hp ? hp_colors : pw_colors); int count; - for (count = 0; (1 << count) <= stat_color.attr_bits; count++) { + for (count = 0; (1 << count) <= status_color.attr_bits; count++) { if (count != ATR_NONE && (status_color.attr_bits & (1 << count))) attr |= curses_convert_attr(count); } From e98aab084f5449136980f9cde452d44c4b949163 Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Tue, 9 May 2017 13:27:31 +0200 Subject: [PATCH 22/69] Fix statuscolors Cherry-picked from dNAO --- win/curses/cursstat.c | 115 +++++++++++++++++++++++++----------------- 1 file changed, 70 insertions(+), 45 deletions(-) diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index 3588d493..12515013 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -128,27 +128,26 @@ get_trouble_color(const char *stat) #ifdef STATUS_COLORS /* Check if we have a color enabled with statuscolors */ if (!iflags.use_status_colors) - return CLR_GRAY; /* no color configured */ - - struct text_color_option *cur_option; - for (cur_option = text_colors; cur_option; cur_option = cur_option->next) { - if (strcmpi(cur_option->text, clr->id) == 0) { - /* We found the option, now make a curses attribute out of it */ - struct color_option status_color; - status_color = text_color_of(clr->id, cur_option); - - int count; - for (count = 0; (1 << count) <= status_color.attr_bits; count++) { - if (count != ATR_NONE && (status_color.attr_bits & (1 << count))) - attr |= curses_convert_attr(count); - } - - return attr; - } + return curses_color_attr(CLR_GRAY, 0); /* no color configured */ + + struct color_option stat_color; + + stat_color = text_color_of(clr->id, text_colors); + if (stat_color.color == NO_COLOR && !stat_color.attr_bits) + return curses_color_attr(CLR_GRAY, 0); + + if (stat_color.color != NO_COLOR) + res = curses_color_attr(stat_color.color, 0); + + res = curses_color_attr(stat_color.color, 0); + int count; + for (count = 0; (1 << count) <= stat_color.attr_bits; count++) { + if (count != ATR_NONE && + (stat_color.attr_bits & (1 << count))) + res |= curses_convert_attr(count); } - /* No color configured, use gray */ - return curses_color_attr(CLR_GRAY, 0); + return res; #else return curses_color_attr(clr->color, 0); #endif @@ -339,19 +338,24 @@ curses_color_attr(int nh_color, int bg_color) return cattr; } +/* Returns a complete curses attribute. Used to color HP/Pw text. */ #ifdef STATUS_COLORS static attr_t hpen_color_attr(boolean is_hp, int cur, int max) { + struct color_option stat_color; + int count; + attr_t attr = 0; if (!iflags.use_status_colors) return curses_color_attr(CLR_GRAY); - struct color_option status_color; - status_color = percentage_color_of(cur, max, is_hp ? hp_colors : pw_colors); + stat_color = percentage_color_of(cur, max, is_hp ? hp_colors : pw_colors); - int count; - for (count = 0; (1 << count) <= status_color.attr_bits; count++) { - if (count != ATR_NONE && (status_color.attr_bits & (1 << count))) + if (stat_color.color != NO_COLOR) + attr |= curses_color_attr(stat_color.color, 0); + + for (count = 0; (1 << count) <= stat_color.attr_bits; count++) { + if (count != ATR_NONE && (stat_color.attr_bits & (1 << count))) attr |= curses_convert_attr(count); } @@ -359,9 +363,27 @@ hpen_color_attr(boolean is_hp, int cur, int max) } #endif +/* Return color for the HP bar. + With status colors ON, this respect its configuration (defaulting to gray), but + only obeys the color (no weird attributes for the HP bar). + With status colors OFF, this returns reasonable defaults which are also used + for the HP/Pw text itself. */ static int hpen_color(boolean is_hp, int cur, int max) { +#ifdef STATUS_COLORS + if (iflags.use_status_colors) { + struct color_option stat_color; + stat_color = percentage_color_of(cur, max, is_hp ? hp_colors : pw_colors); + + if (stat_color.color == NO_COLOR) + return CLR_GRAY; + else + return stat_color.color; + } else + return CLR_GRAY; +#endif + int color = CLR_GRAY; if (cur == max) color = CLR_GRAY; @@ -397,17 +419,11 @@ draw_bar(boolean is_hp, int cur, int max, const char *title) /* Colors */ attr_t fillattr, attr; -#ifdef STATUS_COLORS - attr = hpen_color_attr(is_hp, cur, max); - attr &= ~A_REVERSE; - fillattr = (attr | A_REVERSE); -#else int color = hpen_color(is_hp, cur, max); int invcolor = color & 7; fillattr = curses_color_attr(color, invcolor); attr = curses_color_attr(color, 0); -#endif /* Figure out how much of the bar to fill */ int fill = 0; @@ -506,22 +522,26 @@ draw_horizontal(void) #endif /* HP/Pw use special coloring rules */ + attr_t hpattr, pwattr; +#ifdef STATUS_COLORS + hpattr = hpen_color_attr(TRUE, hp, hpmax); + pwattr = hpen_color_attr(FALSE, u.uen, u.uenmax); +#else int hpcolor, pwcolor; - attr_t attr; hpcolor = hpen_color(TRUE, hp, hpmax); pwcolor = hpen_color(FALSE, u.uen, u.uenmax); - + hpattr = curses_color_attr(hpcolor, 0); + pwattr = curses_color_attr(pwcolor, 0); +#endif wprintw(win, " HP:"); - attr = curses_color_attr(hpcolor, 0); - wattron(win, attr); + wattron(win, hpattr); wprintw(win, "%d(%d)", hp, hpmax); - wattroff(win, attr); + wattroff(win, hpattr); wprintw(win, " Pw:"); - attr = curses_color_attr(pwcolor, 0); - wattron(win, attr); + wattron(win, pwattr); wprintw(win, "%d(%d)", u.uen, u.uenmax); - wattroff(win, attr); + wattroff(win, pwattr); print_statdiff(" AC:", &prevac, u.uac, STAT_AC); @@ -662,23 +682,28 @@ draw_vertical(void) wmove(win, y++, x); /* HP/Pw use special coloring rules */ + attr_t hpattr, pwattr; +#ifdef STATUS_COLORS + hpattr = hpen_color_attr(TRUE, hp, hpmax); + pwattr = hpen_color_attr(FALSE, u.uen, u.uenmax); +#else int hpcolor, pwcolor; - attr_t attr; hpcolor = hpen_color(TRUE, hp, hpmax); pwcolor = hpen_color(FALSE, u.uen, u.uenmax); + hpattr = curses_color_attr(hpcolor, 0); + pwattr = curses_color_attr(pwcolor, 0); +#endif wprintw(win, "Hit Points: "); - attr = curses_color_attr(hpcolor, 0); - wattron(win, attr); + wattron(win, hpattr); wprintw(win, "%d/%d", hp, hpmax); - wattroff(win, attr); + wattroff(win, hpattr); wmove(win, y++, x); wprintw(win, "Magic Power: "); - attr = curses_color_attr(pwcolor, 0); - wattron(win, attr); + wattron(win, pwattr); wprintw(win, "%d/%d", u.uen, u.uenmax); - wattroff(win, attr); + wattroff(win, pwattr); wmove(win, y++, x); print_statdiff("Armor Class: ", &prevac, u.uac, STAT_AC); From 4a23580dbae61c3758c5270618daa314c84c8174 Mon Sep 17 00:00:00 2001 From: Tangles Date: Thu, 11 May 2017 00:33:41 +1000 Subject: [PATCH 23/69] curses - fix issues from grunt merge. --- win/curses/cursstat.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index 12515013..5d42cb14 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -347,7 +347,7 @@ hpen_color_attr(boolean is_hp, int cur, int max) int count; attr_t attr = 0; if (!iflags.use_status_colors) - return curses_color_attr(CLR_GRAY); + return curses_color_attr(CLR_GRAY, 0); stat_color = percentage_color_of(cur, max, is_hp ? hp_colors : pw_colors); @@ -535,7 +535,7 @@ draw_horizontal(void) #endif wprintw(win, " HP:"); wattron(win, hpattr); - wprintw(win, "%d(%d)", hp, hpmax); + wprintw(win, "%d(%d)", (hp < 0) ? 0 : hp, hpmax); wattroff(win, hpattr); wprintw(win, " Pw:"); @@ -574,7 +574,7 @@ draw_horizontal(void) statprob(Stunned, "Stun"); statprob(Hallucination, "Hallu"); statprob((u.usick_type & SICK_VOMITABLE), "FoodPois"); - statprob((u.usick_type & (SICK_NONVOMITABLE|SICK_ZOMBIE)), "Ill"); + statprob((u.usick_type & SICK_NONVOMITABLE), "Ill"); statprob(Slimed, "Slime"); /* Encumbrance */ @@ -696,7 +696,7 @@ draw_vertical(void) wprintw(win, "Hit Points: "); wattron(win, hpattr); - wprintw(win, "%d/%d", hp, hpmax); + wprintw(win, "%d/%d", (hp < 0) ? 0 : hp, hpmax); wattroff(win, hpattr); wmove(win, y++, x); @@ -751,7 +751,7 @@ draw_vertical(void) statprob(Stunned, "Stun"); statprob(Hallucination, "Hallu"); statprob((u.usick_type & SICK_VOMITABLE), "FoodPois"); - statprob((u.usick_type & (SICK_NONVOMITABLE|SICK_ZOMBIE)), "Ill"); + statprob((u.usick_type & SICK_NONVOMITABLE), "Ill"); statprob(Slimed, "Slime"); /* Encumbrance */ From 508b05584e676826dd458774d794e0a065d9cf35 Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Wed, 10 May 2017 19:34:14 +0200 Subject: [PATCH 24/69] Simplify window position initialization --- win/curses/cursinit.c | 346 +++++++++--------------------------------- win/curses/cursstat.c | 10 -- 2 files changed, 69 insertions(+), 287 deletions(-) diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index d666ffbb..43749aad 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -19,6 +19,10 @@ #define GRUNTHACK_CURSES 5 #define DNETHACK_CURSES 6 +static void set_window_position(int *, int *, int *, int *, int, + int *, int *, int *, int *, int, + int, int); + /* array to save initial terminal colors for later restoration */ typedef struct nhrgb_type { @@ -138,23 +142,52 @@ nhrgb orig_hiwhite; " \\__,_||_| \\_| \\___| \\__||_| |_| \\__,_| \\___||_|\\_\\" +/* win* is size and placement of window to change, x/y/w/h is baseline which can + decrease depending on alignment of win* in orientation. */ +static void +set_window_position(int *winx, int *winy, int *winw, int *winh, int orientation, + int *x, int *y, int *w, int *h, int border_space, + int minh, int minw) +{ + *winw = *w; + *winh = *h; + + /* Set window height/width */ + if (orientation == ALIGN_TOP || orientation == ALIGN_BOTTOM) { + if (minh == -1) + *winh = (*h - ROWNO - border_space); + else + *winh = minh; + *h -= (*winh + border_space); + } else { + if (minw == -1) + *winw = (*w - COLNO - border_space); + else + *winw = minw; + *w -= (*winw + border_space); + } + + *winx = *w + border_space; + *winy = *h + border_space; + + /* Set window position */ + if (orientation != ALIGN_RIGHT) { + *winx = *x; + if (orientation == ALIGN_LEFT) + *x += *winw + border_space; + } + if (orientation != ALIGN_BOTTOM) { + *winy = *y; + if (orientation == ALIGN_TOP) + *y += *winh + border_space; + } +} + /* Create the "main" nonvolitile windows used by nethack */ void curses_create_main_windows() { - int message_x = 0; - int message_y = 0; - int status_x = 0; - int status_y = 0; - int map_x = 0; - int map_y = 0; - int message_height = 0; - int message_width = 0; - int status_height = 0; - int status_width = 0; - int map_height = 0; - int map_width = 0; int min_message_height = 1; int message_orientation = 0; int status_orientation = 0; @@ -222,271 +255,30 @@ curses_create_main_windows() } } - /* Determine window placement and size - 16 possible combos - If anyone wants to try to generalize this, be my guest! */ - if ((status_orientation == ALIGN_TOP) && (message_orientation == ALIGN_TOP)) { - status_x = 0; - status_y = 0; - status_width = (term_cols - border_space); - status_height = 2; - message_x = 0; - message_y = status_y + (status_height + border_space); - message_width = (term_cols - border_space); - message_height = - term_rows - (status_height + ROWNO + (border_space * 3)); - if (message_height < min_message_height) { - message_height = min_message_height; - } - map_x = 0; - map_y = message_y + (message_height + border_space); - map_width = (term_cols - border_space); - map_height = - term_rows - (status_height + message_height + (border_space * 3)); - } else if ((status_orientation == ALIGN_TOP) && - (message_orientation == ALIGN_RIGHT)) { - status_x = 0; - status_y = 0; - status_height = 2; - message_height = (term_rows - border_space); - message_width = term_cols - (COLNO + (border_space * 2)); - status_width = term_cols - (message_width + (border_space * 2)); - message_x = status_x + (status_width + border_space); - message_y = 0; - map_x = 0; - map_y = status_y + (status_height + border_space); - map_width = status_width; - map_height = term_rows - (status_height + (border_space * 2)); - } else if ((status_orientation == ALIGN_TOP) && - (message_orientation == ALIGN_BOTTOM)) { - status_x = 0; - status_y = 0; - status_width = (term_cols - border_space); - status_height = 2; - map_x = 0; - map_y = status_y + (status_height + border_space); - map_width = (term_cols - border_space); - message_height = - term_rows - (status_height + ROWNO + (border_space * 3)); - if (message_height < min_message_height) { - message_height = min_message_height; - } - map_height = - term_rows - (status_height + message_height + (border_space * 3)); - message_x = 0; - message_y = map_y + (map_height + border_space); - message_width = (term_cols - border_space); - } else if ((status_orientation == ALIGN_TOP) && - (message_orientation == ALIGN_LEFT)) { - message_x = 0; - message_y = 0; - message_height = (term_rows - border_space); - message_width = term_cols - (COLNO + (border_space * 2)); - status_x = message_x + (message_width + border_space); - status_y = 0; - status_height = 2; - status_width = term_cols - (message_width + (border_space * 2)); - map_x = status_x; - map_y = status_y + (status_height + border_space); - map_height = term_rows - (status_height + (border_space * 2)); - map_width = status_width; - } - if ((status_orientation == ALIGN_RIGHT) && - (message_orientation == ALIGN_TOP)) { - status_width = 26; - status_height = (term_rows - border_space); - status_x = term_cols - (status_width + border_space); - status_y = 0; - message_x = 0; - message_y = 0; - message_width = term_cols - (status_width + (border_space * 2)); - message_height = term_rows - (ROWNO + (border_space * 2)); - if (message_height < min_message_height) { - message_height = min_message_height; - } - map_x = 0; - map_y = message_y + (message_height + border_space); - map_width = term_cols - (status_width + (border_space * 2)); - map_height = term_rows - (message_height + (border_space * 2)); - } else if ((status_orientation == ALIGN_RIGHT) && - (message_orientation == ALIGN_RIGHT)) { - map_x = 0; - map_y = 0; - map_height = (term_rows - border_space); - status_width = 26; - message_width = term_cols - (COLNO + status_width + (border_space * 3)); - map_width = - term_cols - (status_width + message_width + (border_space * 3)); - message_x = map_x + (map_width + border_space); - message_y = 0; - message_height = (term_rows - border_space); - status_x = message_x + (message_width + border_space); - status_y = 0; - status_height = (term_rows - border_space); - } else if ((status_orientation == ALIGN_RIGHT) && - (message_orientation == ALIGN_BOTTOM)) { - map_x = 0; - map_y = 0; - status_width = 26; - map_width = term_cols - (status_width + (border_space * 2)); - message_height = term_rows - (ROWNO + (border_space * 2)); - if (message_height < min_message_height) { - message_height = min_message_height; - } - map_height = term_rows - (message_height + (border_space * 2)); - message_x = 0; - message_y = map_y + (map_height + border_space); - message_width = map_width; - status_x = map_x + (map_width + border_space); - status_y = 0; - status_height = (term_rows - border_space); - } else if ((status_orientation == ALIGN_RIGHT) && - (message_orientation == ALIGN_LEFT)) { - status_x = 0; - status_y = 0; - status_height = (term_rows - border_space); - status_width = 26; - message_width = term_cols - (status_width + COLNO + (border_space * 3)); - map_x = status_x + (status_width + border_space); - map_y = 0; - map_height = (term_rows - border_space); - map_width = - term_cols - (status_width + message_width + (border_space * 3)); - message_x = map_x + (map_width + border_space); - message_y = 0; - message_height = (term_rows - border_space); - } - if ((status_orientation == ALIGN_BOTTOM) && - (message_orientation == ALIGN_TOP)) { - message_x = 0; - message_y = 0; - message_width = (term_cols - border_space); - status_height = 2; - message_height = - term_rows - (status_height + ROWNO + (border_space * 3)); - if (message_height < min_message_height) { - message_height = min_message_height; - } - map_x = 0; - map_y = message_y + (message_height + border_space); - map_width = (term_cols - border_space); - map_height = - term_rows - (status_height + message_height + (border_space * 3)); - status_x = 0; - status_y = map_y + (map_height + border_space); - status_width = (term_cols - border_space); - } else if ((status_orientation == ALIGN_BOTTOM) && - (message_orientation == ALIGN_RIGHT)) { - map_x = 0; - map_y = 0; - status_height = 2; - map_height = term_rows - (status_height + (border_space * 2)); - message_width = term_cols - (COLNO + (border_space * 2)); - map_width = term_cols - (message_width + (border_space * 2)); - status_x = 0; - status_y = map_y + (map_height + border_space); - status_width = map_width; - message_x = map_x + (map_width + border_space); - message_y = 0; - message_height = (term_rows - border_space); - } else if ((status_orientation == ALIGN_BOTTOM) && - (message_orientation == ALIGN_BOTTOM)) { - map_x = 0; - map_y = 0; - message_x = 0; - status_x = 0; - message_width = (term_cols - border_space); - status_height = 2; - message_height = - term_rows - (status_height + ROWNO + (border_space * 3)); - if (message_height < min_message_height) { - message_height = min_message_height; - } - map_width = (term_cols - border_space); - map_height = - term_rows - (status_height + message_height + (border_space * 3)); - message_y = map_y + (map_height + border_space); - status_y = message_y + (message_height + border_space); - status_width = (term_cols - border_space); - } else if ((status_orientation == ALIGN_BOTTOM) && - (message_orientation == ALIGN_LEFT)) { - message_x = 0; - message_y = 0; - message_height = (term_rows - border_space); - message_width = term_cols - (COLNO + (border_space * 2)); - status_height = 2; - map_x = message_x + (message_width + border_space); - map_y = 0; - map_height = term_rows - (status_height + (border_space * 2)); - map_width = term_cols - (message_width + (border_space * 2)); - status_x = map_x; - status_y = map_y + (map_height + border_space); - status_width = term_cols - (message_width + (border_space * 2)); - } - if ((status_orientation == ALIGN_LEFT) && - (message_orientation == ALIGN_TOP)) { - status_x = 0; - status_y = 0; - status_height = (term_rows - border_space); - status_width = 26; - message_x = status_x + (status_width + border_space); - message_y = 0; - message_height = term_rows - (ROWNO + (border_space * 2)); - if (message_height < min_message_height) { - message_height = min_message_height; - } - message_width = term_cols - (status_width + (border_space * 2)); - map_x = message_x; - map_y = message_y + (message_height + border_space); - map_height = term_rows - (message_height + (border_space * 2)); - map_width = term_cols - (status_width + (border_space * 2)); - } else if ((status_orientation == ALIGN_LEFT) && - (message_orientation == ALIGN_RIGHT)) { - message_x = 0; - message_y = 0; - message_height = (term_rows - border_space); - status_width = 26; - message_width = term_cols - (status_width + COLNO + (border_space * 3)); - map_x = message_x + (message_width + border_space); - map_y = 0; - map_height = (term_rows - border_space); - map_width = - term_cols - (status_width + message_width + (border_space * 3)); - status_x = map_x + (map_width + border_space); - status_y = 0; - status_height = (term_rows - border_space); - } else if ((status_orientation == ALIGN_LEFT) && - (message_orientation == ALIGN_BOTTOM)) { - status_x = 0; - status_y = 0; - status_height = (term_rows - border_space); - status_width = 26; - map_x = status_x + (status_width + border_space); - map_y = 0; - message_height = term_rows - (ROWNO + (border_space * 2)); - if (message_height < min_message_height) { - message_height = min_message_height; - } - map_height = term_rows - (message_height + (border_space * 2)); - map_width = term_cols - (status_width + (border_space * 2)); - message_x = status_x + (status_width + border_space); - message_y = map_y + (map_height + border_space); - message_width = map_width; - } else if ((status_orientation == ALIGN_LEFT) && - (message_orientation == ALIGN_LEFT)) { - status_x = 0; - status_y = 0; - status_height = (term_rows - border_space); - status_width = 26; - message_x = status_x + (status_width + border_space); - message_y = 0; - message_height = status_height; - message_width = term_cols - (COLNO + status_width + (border_space * 3)); - map_x = message_x + (message_width + border_space); - map_y = 0; - map_height = message_height; - map_width = - term_cols - (status_width + message_width + (border_space * 3)); - } + /* Figure out window positions and placements. Status and message area can be aligned + based on configuration. The priority alignment-wise is: status > msgarea > game. + Define everything as taking as much space as possible and shrink/move based on + alignment positions. */ + int message_x = 0; + int message_y = 0; + int status_x = 0; + int status_y = 0; + int map_x = 0; + int map_y = 0; + + int message_height = 0; + int message_width = 0; + int status_height = 0; + int status_width = 0; + int map_height = (term_rows - border_space); + int map_width = (term_cols - border_space); + + set_window_position(&status_x, &status_y, &status_width, &status_height, + status_orientation, &map_x, &map_y, &map_width, &map_height, + border_space, 2, 26); + set_window_position(&message_x, &message_y, &message_width, &message_height, + message_orientation, &map_x, &map_y, &map_width, &map_height, + border_space, -1, -1); if (map_width > COLNO) { map_width = COLNO; diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index 5d42cb14..e2774a93 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -50,7 +50,6 @@ extern const struct percent_color_option *hp_colors; extern const struct percent_color_option *pw_colors; #endif -static nhstat prevname; static nhstat prevdepth; static nhstat prevstr; static nhstat prevint; @@ -58,7 +57,6 @@ static nhstat prevwis; static nhstat prevdex; static nhstat prevcon; static nhstat prevcha; -static nhstat prevalign; static nhstat prevau; static nhstat prevhp; static nhstat prevmhp; @@ -72,14 +70,6 @@ static nhstat prevtime; #ifdef SCORE_ON_BOTL static nhstat prevscore; #endif -static nhstat prevhunger; -static nhstat prevconf; -static nhstat prevblind; -static nhstat prevstun; -static nhstat prevhallu; -static nhstat prevsick; -static nhstat prevslime; -static nhstat prevencumb; #define COMPACT_LABELS 1 #define NORMAL_LABELS 2 From 4c1b23b01d2601f52eb713406fdb98dfc91e9838 Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Wed, 10 May 2017 19:55:18 +0200 Subject: [PATCH 25/69] Avoid the new set_window_position returning negative widths, give a saner minimum for messages. --- win/curses/cursinit.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index 43749aad..d1f6f159 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -143,7 +143,8 @@ nhrgb orig_hiwhite; /* win* is size and placement of window to change, x/y/w/h is baseline which can - decrease depending on alignment of win* in orientation. */ + decrease depending on alignment of win* in orientation. + Negative minh/minw: as much as possible, but at least as much as specified. */ static void set_window_position(int *winx, int *winy, int *winw, int *winh, int orientation, int *x, int *y, int *w, int *h, int border_space, @@ -154,15 +155,19 @@ set_window_position(int *winx, int *winy, int *winw, int *winh, int orientation, /* Set window height/width */ if (orientation == ALIGN_TOP || orientation == ALIGN_BOTTOM) { - if (minh == -1) + if (minh < 0) { *winh = (*h - ROWNO - border_space); - else + if (-minh > *winh) + *winh = -minh; + } else *winh = minh; *h -= (*winh + border_space); } else { - if (minw == -1) + if (minw < 0) { *winw = (*w - COLNO - border_space); - else + if (-minw > *winw) + *winw = -minw; + } else *winw = minw; *w -= (*winw + border_space); } @@ -278,7 +283,7 @@ curses_create_main_windows() border_space, 2, 26); set_window_position(&message_x, &message_y, &message_width, &message_height, message_orientation, &map_x, &map_y, &map_width, &map_height, - border_space, -1, -1); + border_space, -1, -25); if (map_width > COLNO) { map_width = COLNO; From 6d5623d3c14c3f9d46aedb870dc86ad8aaa0934d Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Wed, 10 May 2017 20:39:53 +0200 Subject: [PATCH 26/69] Fix windows not aligning properly on align_status:top align_statusbottom or left+right --- win/curses/cursinit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index d1f6f159..37a217b9 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -172,8 +172,8 @@ set_window_position(int *winx, int *winy, int *winw, int *winh, int orientation, *w -= (*winw + border_space); } - *winx = *w + border_space; - *winy = *h + border_space; + *winx = *w + border_space + *x; + *winy = *h + border_space + *y; /* Set window position */ if (orientation != ALIGN_RIGHT) { From 2e36dbdbc2520bda4bc01ea288d7607335aba29f Mon Sep 17 00:00:00 2001 From: Tangles Date: Fri, 12 May 2017 01:21:20 +1000 Subject: [PATCH 27/69] curses - respect menu_glyphs option rather than just displaying the glyphs regardless. --- win/curses/cursdial.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/win/curses/cursdial.c b/win/curses/cursdial.c index cbe6193f..c38fc928 100644 --- a/win/curses/cursdial.c +++ b/win/curses/cursdial.c @@ -989,8 +989,7 @@ menu_display_page(nhmenu *menu, WINDOW * win, int page_num) entry_cols -= 4; start_col += 4; } - if (menu_item_ptr->glyph != NO_GLYPH) { - /* stuff to display the glyph at line_num+1, start_col goes here */ + if (menu_item_ptr->glyph != NO_GLYPH && iflags.use_menu_glyphs) { unsigned special; /*notused */ mapglyph(menu_item_ptr->glyph, &curletter, &color, &special, 0, 0); From 3675129e43aa89a3e6818281abbc905d00aec5c0 Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Thu, 11 May 2017 20:10:39 +0200 Subject: [PATCH 28/69] Split out drawing of statuses so that both horizontal/vertical can use the same logic --- win/curses/cursstat.c | 86 ++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 42 deletions(-) diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index e2774a93..05207e49 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -25,7 +25,7 @@ typedef struct nhs { } nhstat; static attr_t get_trouble_color(const char *); -static void statusproblem(int, const char *); +static void draw_trouble_str(const char *); static void print_statdiff(const char *append, nhstat *, int, int); static void get_playerrank(char *); static attr_t curses_color_attr(int nh_color, int bg_color); @@ -33,6 +33,8 @@ static int hpen_color(boolean, int, int); static void draw_bar(boolean, int, int, const char *); static void draw_horizontal(void); static void draw_vertical(void); +static void curses_add_statuses(WINDOW *, boolean, int *, int *); +static void curses_add_status(WINDOW *, boolean, int *, int *, const char *, int); static int decrement_highlight(nhstat *, boolean); static void decrement_highlights(boolean); static void init_stats(void); @@ -213,11 +215,8 @@ print_statdiff(const char *append, nhstat *stat, int new, int type) } static void -statusproblem(int trouble, const char *str) +draw_trouble_str(const char *str) { - if (!trouble) - return; - WINDOW *win = curses_get_nhwin(STATUS_WIN); /* For whatever reason, hunger states have trailing spaces. Get rid of them. */ @@ -549,29 +548,8 @@ draw_horizontal(void) if (flags.time) print_statdiff(" T:", &prevtime, moves, STAT_TIME); -#define statprob(stat, str) \ - if (stat) { \ - waddch(win, ' '); \ - statusproblem(stat, str); \ - } - - /* Hunger */ - statprob(u.uhs != 1, hu_stat[u.uhs]); - - /* General troubles */ - statprob(Confusion, "Conf"); - statprob(Blind, "Blind"); - statprob(Stunned, "Stun"); - statprob(Hallucination, "Hallu"); - statprob((u.usick_type & SICK_VOMITABLE), "FoodPois"); - statprob((u.usick_type & SICK_NONVOMITABLE), "Ill"); - statprob(Slimed, "Slime"); - - /* Encumbrance */ - int enc = near_capacity(); - statprob(enc > UNENCUMBERED, enc_stat[enc]); -#undef statprob + curses_add_statuses(win, FALSE, NULL, NULL); wclrtoeol(win); } @@ -724,32 +702,56 @@ draw_vertical(void) } #endif /* SCORE_ON_BOTL */ - /* Troubles. Uses a macro to avoid major repetition */ + curses_add_statuses(win, TRUE, &x, &y); +} -#define statprob(stat, str) \ - if (stat) { \ - statusproblem(stat, str); \ - wmove(win, y++, x); \ - } +static void +curses_add_statuses(WINDOW *win, boolean vertical, int *x, int *y) +{ +#define statprob(str, trouble) \ + curses_add_status(win, vertical, x, y, str, trouble) /* Hunger */ - statprob(u.uhs != 1, hu_stat[u.uhs]); + statprob(hu_stat[u.uhs], u.uhs != 1); /* 1 is NOT_HUNGRY (not defined here) */ /* General troubles */ - statprob(Confusion, "Conf"); - statprob(Blind, "Blind"); - statprob(Stunned, "Stun"); - statprob(Hallucination, "Hallu"); - statprob((u.usick_type & SICK_VOMITABLE), "FoodPois"); - statprob((u.usick_type & SICK_NONVOMITABLE), "Ill"); - statprob(Slimed, "Slime"); + statprob("Conf", Confusion); + statprob("Blind", Blind); + statprob("Stun", Stunned); + statprob("Hallu", Hallucination); + statprob("Ill", (u.usick_type & (SICK_NONVOMITABLE|SICK_ZOMBIE))); + statprob("FoodPois", (u.usick_type & SICK_VOMITABLE)); + statprob("Slime", Slimed); /* Encumbrance */ int enc = near_capacity(); - statprob(enc > UNENCUMBERED, enc_stat[enc]); + statprob(enc_stat[enc], enc > UNENCUMBERED); #undef statprob } +static void +curses_add_status(WINDOW *win, boolean vertical, int *x, int *y, + const char *str, int trouble) +{ + /* If vertical is TRUE here with no x/y, that's an error. But handle + it gracefully since NH3 doesn't recover well in crashes. */ + if (!x || !y) + vertical = FALSE; + + if (!trouble) + return; + + if (!vertical) + waddch(win, ' '); + + draw_trouble_str(str); + + if (vertical) { + wmove(win, *y, *x); + *y += 1; /* ++ advances the pointer addr */ + } +} + void curses_update_stats(void) { From 46079f707f1de1b397e23b8102e78246ab8915d8 Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Thu, 11 May 2017 22:43:48 +0200 Subject: [PATCH 29/69] Simplify status bar initialization --- include/wincurs.h | 3 +- win/curses/cursstat.c | 87 ++++++++----------------------------------- 2 files changed, 17 insertions(+), 73 deletions(-) diff --git a/include/wincurs.h b/include/wincurs.h index 7a7602e5..3d364ef8 100644 --- a/include/wincurs.h +++ b/include/wincurs.h @@ -31,7 +31,8 @@ boolean counting; /* Count window is active */ #define MESSAGE_WIN 1 #define STATUS_WIN 2 #define MAP_WIN 3 -#define NHWIN_MAX 4 +#define INV_WIN 4 +#define NHWIN_MAX 5 #define MESG_HISTORY_MAX 200 #if !defined(__APPLE__) || !defined(NCURSES_VERSION) # define USE_DARKGRAY /* Allow "bright" black; delete if not visible */ diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index 05207e49..3785a808 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -9,19 +9,11 @@ /* Private declarations */ +/* Used to track previous value of things, to highlight changes. */ typedef struct nhs { long value; - char *txt; - aligntyp alignment; - boolean display; int highlight_turns; int highlight_color; - int stat_color; - int stat_attr; - int x; - int y; - char *label; - const char *id; } nhstat; static attr_t get_trouble_color(const char *); @@ -37,7 +29,6 @@ static void curses_add_statuses(WINDOW *, boolean, int *, int *); static void curses_add_status(WINDOW *, boolean, int *, int *, const char *, int); static int decrement_highlight(nhstat *, boolean); static void decrement_highlights(boolean); -static void init_stats(void); #ifdef STATUS_COLORS static attr_t hpen_color_attr(boolean, int, int); @@ -52,6 +43,9 @@ extern const struct percent_color_option *hp_colors; extern const struct percent_color_option *pw_colors; #endif +/* Whether or not we have printed status window content at least once. + Used to ensure that prev* doesn't end up highlighted on game start. */ +static boolean first = TRUE; static nhstat prevdepth; static nhstat prevstr; static nhstat prevint; @@ -755,35 +749,13 @@ curses_add_status(WINDOW *win, boolean vertical, int *x, int *y, void curses_update_stats(void) { - char buf[BUFSZ]; - int count, enc, sx_start, hp, hpmax, labels, swidth, sheight, sx_end, sy_end, - orient; + int orient; WINDOW *win = curses_get_nhwin(STATUS_WIN); - static int prev_labels = -1; - static boolean first = TRUE; - static boolean horiz; + boolean horiz; int sx = 0; int sy = 0; boolean border = curses_window_has_border(STATUS_WIN); - curses_get_window_size(STATUS_WIN, &sheight, &swidth); - - if (border) { - sx++; - sy++; - swidth--; - sheight--; - } - - sx_end = swidth - 1; - sy_end = sheight - 1; - sx_start = sx; - - if (first) { - init_stats(); - first = FALSE; - } - orient = curses_get_window_orientation(STATUS_WIN); horiz = FALSE; @@ -795,6 +767,15 @@ curses_update_stats(void) else draw_vertical(); + if (first) { + first = FALSE; + + /* Zero highlight timers and re-run the status update. */ + decrement_highlights(TRUE); + curses_update_stats(); + return; + } + if (border) box(win, 0, 0); @@ -859,41 +840,3 @@ curses_decrement_highlight() { decrement_highlights(FALSE); } - - -/* Initializes the prev(whatever) values */ -static void -init_stats() -{ - prevdepth.value = depth(&u.uz); - prevstr.value = ACURR(A_STR); - prevdex.value = ACURR(A_DEX); - prevcon.value = ACURR(A_CON); - prevint.value = ACURR(A_INT); - prevwis.value = ACURR(A_WIS); - prevcha.value = ACURR(A_CHA); -#ifndef GOLDOBJ - prevau.value = u.ugold; -#else - prevau.value = money_cnt(invent); -#endif - int hp = u.uhp; - int hpmax = u.uhpmax; - if (Upolyd) { - hp = u.mh; - hpmax = u.mhmax; - } - prevhp.value = hp; - prevmhp.value = hpmax; - prevlevel.value = (Upolyd ? mons[u.umonnum].mlevel : u.ulevel); - prevpow.value = u.uen; - prevmpow.value = u.uenmax; - prevac.value = u.uac; -#ifdef EXP_ON_BOTL - prevexp.value = u.uexp; -#endif - prevtime.value = moves; -#ifdef SCORE_ON_BOTL - prevscore.value = botl_score(); -#endif -} From 6f74a83c4a15e84166eb58a6fe4fac30c362816c Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Thu, 11 May 2017 22:50:00 +0200 Subject: [PATCH 30/69] Remove some unused variables --- win/curses/cursstat.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index 3785a808..815157c8 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -752,8 +752,6 @@ curses_update_stats(void) int orient; WINDOW *win = curses_get_nhwin(STATUS_WIN); boolean horiz; - int sx = 0; - int sy = 0; boolean border = curses_window_has_border(STATUS_WIN); orient = curses_get_window_orientation(STATUS_WIN); From 1ad69930a6766712a45ed934bde36f9bc4a9dc59 Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Thu, 11 May 2017 23:02:07 +0200 Subject: [PATCH 31/69] Remove some code duplication --- win/curses/cursstat.c | 143 +++++++++++++++++------------------------- 1 file changed, 58 insertions(+), 85 deletions(-) diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index 815157c8..0b02299d 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -23,8 +23,8 @@ static void get_playerrank(char *); static attr_t curses_color_attr(int nh_color, int bg_color); static int hpen_color(boolean, int, int); static void draw_bar(boolean, int, int, const char *); -static void draw_horizontal(void); -static void draw_vertical(void); +static void draw_horizontal(int, int, int, int); +static void draw_vertical(int, int, int, int); static void curses_add_statuses(WINDOW *, boolean, int *, int *); static void curses_add_status(WINDOW *, boolean, int *, int *, const char *, int); static int decrement_highlight(nhstat *, boolean); @@ -427,34 +427,28 @@ draw_bar(boolean is_hp, int cur, int max, const char *title) } /* Update the status win - this is called when NetHack would normally -write to the status window, so we know somwthing has changed. We -override the write and update what needs to be updated ourselves. */ -static void -draw_horizontal(void) + write to the status window, so we know somwthing has changed. We + override the write and update what needs to be updated ourselves. */ +void +curses_update_stats(void) { - char buf[BUFSZ]; - char rank[BUFSZ]; + int orient; WINDOW *win = curses_get_nhwin(STATUS_WIN); + boolean horiz; + boolean border = curses_window_has_border(STATUS_WIN); - /* The area we're allowed to print on. Excludes borders */ - int x, y, h, w; - - /* Starting x/y */ - x = 0; - y = 0; - - /* Starting height/width */ - curses_get_window_size(STATUS_WIN, &h, &w); + /* Starting x/y. Passed to draw_horizontal/draw_vertical to keep track of + window positioning. */ + int x = 0; + int y = 0; - boolean border = FALSE; + /* Don't start at border position if applicable */ if (curses_window_has_border(STATUS_WIN)) { x++; y++; - h--; - w--; - border = TRUE; } + /* Get HP values. */ int hp = u.uhp; int hpmax = u.uhpmax; if (Upolyd) { @@ -462,6 +456,39 @@ draw_horizontal(void) hpmax = u.mhmax; } + orient = curses_get_window_orientation(STATUS_WIN); + + horiz = FALSE; + if ((orient != ALIGN_RIGHT) && (orient != ALIGN_LEFT)) + horiz = TRUE; + + if (orient != ALIGN_RIGHT && orient != ALIGN_LEFT) + draw_horizontal(x, y, hp, hpmax); + else + draw_vertical(x, y, hp, hpmax); + + if (first) { + first = FALSE; + + /* Zero highlight timers and re-run the status update. */ + decrement_highlights(TRUE); + curses_update_stats(); + return; + } + + if (border) + box(win, 0, 0); + + wrefresh(win); +} + +static void +draw_horizontal(int x, int y, int hp, int hpmax) +{ + char buf[BUFSZ]; + char rank[BUFSZ]; + WINDOW *win = curses_get_nhwin(STATUS_WIN); + /* Line 1 */ wmove(win, y, x); @@ -551,38 +578,12 @@ draw_horizontal(void) /* Personally I never understood the point of a vertical status bar. But removing the option would be silly, so keep the functionality. */ static void -draw_vertical(void) +draw_vertical(int x, int y, int hp, int hpmax) { char buf[BUFSZ]; char rank[BUFSZ]; WINDOW *win = curses_get_nhwin(STATUS_WIN); - /* The area we're allowed to print on. Excludes borders */ - int x, y, h, w; - - /* Starting x/y */ - x = 0; - y = 0; - - /* Starting height/width */ - curses_get_window_size(STATUS_WIN, &h, &w); - - boolean border = FALSE; - if (curses_window_has_border(STATUS_WIN)) { - x++; - y++; - h--; - w--; - border = TRUE; - } - - int hp = u.uhp; - int hpmax = u.uhpmax; - if (Upolyd) { - hp = u.mh; - hpmax = u.mhmax; - } - /* Clear the window */ werase(win); @@ -592,14 +593,20 @@ draw_vertical(void) get_playerrank(rank); int ranklen = strlen(rank); int namelen = strlen(plname); - if ((ranklen + namelen) > 19) { + int maxlen = 19; +#ifdef STATUS_COLORS + if (!iflags.hitpointbar) + maxlen += 2; /* With no hitpointbar, we can fit more since there's no "[]" */ +#endif + + if ((ranklen + namelen) > maxlen) { /* The result doesn't fit. Strip name if >10 characters, then strip title */ if (namelen > 10) { - while (namelen > 10 && (ranklen + namelen) > 19) + while (namelen > 10 && (ranklen + namelen) > maxlen) namelen--; } - while ((ranklen + namelen) > 19) + while ((ranklen + namelen) > maxlen) ranklen--; /* Still doesn't fit, strip rank */ } sprintf(buf, "%-*s the %-*s", namelen, plname, ranklen, rank); @@ -746,40 +753,6 @@ curses_add_status(WINDOW *win, boolean vertical, int *x, int *y, } } -void -curses_update_stats(void) -{ - int orient; - WINDOW *win = curses_get_nhwin(STATUS_WIN); - boolean horiz; - boolean border = curses_window_has_border(STATUS_WIN); - - orient = curses_get_window_orientation(STATUS_WIN); - - horiz = FALSE; - if ((orient != ALIGN_RIGHT) && (orient != ALIGN_LEFT)) - horiz = TRUE; - - if (orient != ALIGN_RIGHT && orient != ALIGN_LEFT) - draw_horizontal(); - else - draw_vertical(); - - if (first) { - first = FALSE; - - /* Zero highlight timers and re-run the status update. */ - decrement_highlights(TRUE); - curses_update_stats(); - return; - } - - if (border) - box(win, 0, 0); - - wrefresh(win); -} - /* Decrement a single highlight, return 1 if decremented to zero. zero is TRUE if we're zeroing the highlight. */ static int From be14b5e6205d2a9ca151e06625e4aff01f97747f Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Thu, 11 May 2017 23:06:50 +0200 Subject: [PATCH 32/69] Remove some more cruft leftover from old cursstat code --- win/curses/cursstat.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index 0b02299d..46700345 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -32,7 +32,6 @@ static void decrement_highlights(boolean); #ifdef STATUS_COLORS static attr_t hpen_color_attr(boolean, int, int); - extern struct color_option text_color_of(const char *text, const struct text_color_option *color_options); struct color_option percentage_color_of(int value, int max, @@ -67,10 +66,6 @@ static nhstat prevtime; static nhstat prevscore; #endif -#define COMPACT_LABELS 1 -#define NORMAL_LABELS 2 -#define WIDE_LABELS 3 - extern const char *hu_stat[]; /* from eat.c */ extern const char *enc_stat[]; /* from botl.c */ @@ -166,7 +161,6 @@ get_playerrank(char *rank) /* Handles numerical stat changes of various kinds. type is generally STAT_OTHER (generic "do nothing special"), but is used if the stat needs to be handled in a special way. */ - static void print_statdiff(const char *append, nhstat *stat, int new, int type) { @@ -321,7 +315,7 @@ curses_color_attr(int nh_color, int bg_color) return cattr; } -/* Returns a complete curses attribute. Used to color HP/Pw text. */ +/* Returns a complete curses attribute. Used to possibly bold/underline/etc HP/Pw. */ #ifdef STATUS_COLORS static attr_t hpen_color_attr(boolean is_hp, int cur, int max) From 8838d1c6a90224ef8ed8ef5b01b8a655f1198ca2 Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Thu, 11 May 2017 23:09:23 +0200 Subject: [PATCH 33/69] Remove the feature that allowed a label and statuscolor config to not match This was a feature I added in the rewrite of the stat handling. However, I decided to remove it since TTY doesn't have it, and actually making use of the feature would just confuse people. --- win/curses/cursstat.c | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index 46700345..7170bae8 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -73,29 +73,28 @@ extern const char *enc_stat[]; /* from botl.c */ anyway */ struct statcolor { - const char *id; /* Identifier for statuscolors */ const char *txt; /* For status problems */ int color; /* Default color assuming STATUS_COLORS isn't enabled */ }; static const struct statcolor default_colors[] = { - {"satiated", "Satiated", CLR_YELLOW}, - {"hungry", "Hungry", CLR_YELLOW}, - {"weak", "Weak", CLR_ORANGE}, - {"fainted", "Fainted", CLR_BRIGHT_MAGENTA}, - {"fainting", "Fainting", CLR_BRIGHT_MAGENTA}, - {"burdened", "Burdened", CLR_RED}, - {"stressed", "Stressed", CLR_RED}, - {"strained", "Strained", CLR_ORANGE}, - {"overtaxed", "Overtaxed", CLR_ORANGE}, - {"overloaded", "Overloaded", CLR_BRIGHT_MAGENTA}, - {"conf", "Conf", CLR_BRIGHT_BLUE}, - {"blind", "Blind", CLR_BRIGHT_BLUE}, - {"stun", "Stun", CLR_BRIGHT_BLUE}, - {"hallu", "Hallu", CLR_BRIGHT_BLUE}, - {"ill", "Ill", CLR_BRIGHT_MAGENTA}, - {"foodpois", "FoodPois", CLR_BRIGHT_MAGENTA}, - {"slime", "Slime", CLR_BRIGHT_MAGENTA}, + {"Satiated", CLR_YELLOW}, + {"Hungry", CLR_YELLOW}, + {"Weak", CLR_ORANGE}, + {"Fainted", CLR_BRIGHT_MAGENTA}, + {"Fainting", CLR_BRIGHT_MAGENTA}, + {"Burdened", CLR_RED}, + {"Stressed", CLR_RED}, + {"Strained", CLR_ORANGE}, + {"Overtaxed", CLR_ORANGE}, + {"Overloaded", CLR_BRIGHT_MAGENTA}, + {"Conf", CLR_BRIGHT_BLUE}, + {"Blind", CLR_BRIGHT_BLUE}, + {"Stun", CLR_BRIGHT_BLUE}, + {"Hallu", CLR_BRIGHT_BLUE}, + {"Ill", CLR_BRIGHT_MAGENTA}, + {"FoodPois", CLR_BRIGHT_MAGENTA}, + {"Slime", CLR_BRIGHT_MAGENTA}, {NULL, NULL, NO_COLOR}, }; @@ -113,7 +112,7 @@ get_trouble_color(const char *stat) struct color_option stat_color; - stat_color = text_color_of(clr->id, text_colors); + stat_color = text_color_of(clr->txt, text_colors); if (stat_color.color == NO_COLOR && !stat_color.attr_bits) return curses_color_attr(CLR_GRAY, 0); From c13e48526aa8af1c7630f515f7ad8e2fa624b25e Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Thu, 11 May 2017 23:17:29 +0200 Subject: [PATCH 34/69] Prev(hp|mhp|pow|mhp) is no longer used --- win/curses/cursstat.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index 7170bae8..6b0a0947 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -53,11 +53,7 @@ static nhstat prevdex; static nhstat prevcon; static nhstat prevcha; static nhstat prevau; -static nhstat prevhp; -static nhstat prevmhp; static nhstat prevlevel; -static nhstat prevpow; -static nhstat prevmpow; static nhstat prevac; static nhstat prevexp; static nhstat prevtime; @@ -780,11 +776,7 @@ decrement_highlights(boolean zero) unhighlight |= decrement_highlight(&prevwis, zero); unhighlight |= decrement_highlight(&prevcha, zero); unhighlight |= decrement_highlight(&prevau, zero); - unhighlight |= decrement_highlight(&prevhp, zero); - unhighlight |= decrement_highlight(&prevmhp, zero); unhighlight |= decrement_highlight(&prevlevel, zero); - unhighlight |= decrement_highlight(&prevpow, zero); - unhighlight |= decrement_highlight(&prevmpow, zero); unhighlight |= decrement_highlight(&prevac, zero); #ifdef EXP_ON_BOTL unhighlight |= decrement_highlight(&prevexp, zero); From 90e88c661631027b1ee6759f05d9e4ed3d4bc938 Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Thu, 11 May 2017 23:22:49 +0200 Subject: [PATCH 35/69] Remove a redundant curses_update_status --- win/curses/cursstat.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index 6b0a0947..dd9a413c 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -456,19 +456,17 @@ curses_update_stats(void) else draw_vertical(x, y, hp, hpmax); + if (border) + box(win, 0, 0); + + wrefresh(win); + if (first) { first = FALSE; - /* Zero highlight timers and re-run the status update. */ + /* Zero highlight timers. This will call curses_update_status again if needed */ decrement_highlights(TRUE); - curses_update_stats(); - return; } - - if (border) - box(win, 0, 0); - - wrefresh(win); } static void From 8d158b8645f60d23b7a05e13502d8f5392b11bae Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Thu, 11 May 2017 23:27:02 +0200 Subject: [PATCH 36/69] Remove a redundant function --- win/curses/cursmisc.c | 2 +- win/curses/cursstat.c | 17 ++++------------- win/curses/cursstat.h | 2 +- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index 74cee730..8715d5e6 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -531,7 +531,7 @@ void curses_posthousekeeping() { curs_set(0); - curses_decrement_highlight(); + curses_decrement_highlights(FALSE); curses_clear_unhighlight_message_window(); } diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index dd9a413c..2f229296 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -28,7 +28,6 @@ static void draw_vertical(int, int, int, int); static void curses_add_statuses(WINDOW *, boolean, int *, int *); static void curses_add_status(WINDOW *, boolean, int *, int *, const char *, int); static int decrement_highlight(nhstat *, boolean); -static void decrement_highlights(boolean); #ifdef STATUS_COLORS static attr_t hpen_color_attr(boolean, int, int); @@ -465,7 +464,7 @@ curses_update_stats(void) first = FALSE; /* Zero highlight timers. This will call curses_update_status again if needed */ - decrement_highlights(TRUE); + curses_decrement_highlights(TRUE); } } @@ -759,10 +758,9 @@ decrement_highlight(nhstat *stat, boolean zero) } /* Decrement the highlight_turns for all stats. Call curses_update_stats -if needed to unhighlight a stat */ - -static void -decrement_highlights(boolean zero) + if needed to unhighlight a stat */ +void +curses_decrement_highlights(boolean zero) { int unhighlight = 0; @@ -787,10 +785,3 @@ decrement_highlights(boolean zero) if (unhighlight) curses_update_stats(); } - - -void -curses_decrement_highlight() -{ - decrement_highlights(FALSE); -} diff --git a/win/curses/cursstat.h b/win/curses/cursstat.h index 148cb079..317fd3d6 100644 --- a/win/curses/cursstat.h +++ b/win/curses/cursstat.h @@ -15,7 +15,7 @@ /* Global declarations */ void curses_update_stats(); -void curses_decrement_highlight(void); +void curses_decrement_highlights(boolean); #endif /* CURSSTAT_H */ From e65c7bae91b743f882d7afddb59f7b77020986aa Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Fri, 12 May 2017 15:21:52 +0200 Subject: [PATCH 37/69] Add inventory sidebar if perm_invent is enabled --- include/wincurs.h | 10 ++++- sys/unix/Makefile.src | 7 +++- win/curses/cursdial.c | 3 +- win/curses/cursdial.h | 3 ++ win/curses/cursinit.c | 65 ++++++++++++++++++++++++----- win/curses/cursinvt.c | 95 +++++++++++++++++++++++++++++++++++++++++++ win/curses/cursinvt.h | 11 +++++ win/curses/cursmain.c | 39 ++++++++++++++---- win/curses/cursstat.c | 5 +-- win/curses/cursstat.h | 2 +- win/curses/curswins.c | 5 ++- 11 files changed, 218 insertions(+), 27 deletions(-) create mode 100644 win/curses/cursinvt.c create mode 100644 win/curses/cursinvt.h diff --git a/include/wincurs.h b/include/wincurs.h index 3d364ef8..120c14b5 100644 --- a/include/wincurs.h +++ b/include/wincurs.h @@ -243,7 +243,9 @@ extern int curses_character_input_dialog(const char *prompt, const char *choices extern int curses_ext_cmd(void); extern void curses_create_nhmenu(winid wid); - +#ifdef MENU_COLOR +extern boolean get_menu_coloring(char *, int *, int *); +#endif extern void curses_add_nhmenu_item(winid wid, int glyph, const ANY_P *identifier, CHAR_P accelerator, CHAR_P group_accel, int attr, const char *str, BOOLEAN_P presel); @@ -259,9 +261,15 @@ extern void curses_del_menu(winid wid); /* cursstat.c */ +extern attr_t curses_color_attr(int nh_color, int bg_color); extern void curses_update_stats(void); extern void curses_decrement_highlight(void); +/* cursinvt.c */ + +extern void curses_update_inv(void); +extern void curses_add_inv(int, int, CHAR_P, attr_t, const char *, + const ANY_P *); /* cursinit.c */ diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index 49fb111c..fc5028a6 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -177,9 +177,9 @@ WINTTYOBJ = getline.o termcap.o topl.o wintty.o tile.o WINCURSESSRC = ../win/curses/cursmain.c ../win/curses/curswins.c \ ../win/curses/cursmisc.c ../win/curses/cursdial.c \ ../win/curses/cursstat.c ../win/curses/cursinit.c \ - ../win/curses/cursmesg.c + ../win/curses/cursmesg.c ../win/curses/cursinvt.c WINCURSESOBJ = cursmain.o curswins.o cursmisc.o cursdial.o cursstat.o \ - cursinit.o cursmesg.o + cursinit.o cursmesg.o cursinvt.o # # # files for an X11 port @@ -635,6 +635,9 @@ cursinit.o: ../win/curses/cursinit.c $(HACK_H) ../include/wincurs.h \ cursmesg.o: ../win/curses/cursmesg.c $(HACK_H) ../include/wincurs.h \ ../win/curses/cursmesg.h $(CC) $(CFLAGS) -c ../win/curses/cursmesg.c +cursinvt.o: ../win/curses/cursinvt.c $(HACK_H) ../include/wincurs.h \ + ../win/curses/cursinvt.h + $(CC) $(CFLAGS) -c ../win/curses/cursinvt.c Window.o: ../win/X11/Window.c ../include/xwindowp.h ../include/xwindow.h \ $(CONFIG_H) $(CC) $(CFLAGS) -c ../win/X11/Window.c diff --git a/win/curses/cursdial.c b/win/curses/cursdial.c index c38fc928..1bd0af38 100644 --- a/win/curses/cursdial.c +++ b/win/curses/cursdial.c @@ -65,7 +65,6 @@ static void menu_select_deselect(WINDOW * win, nhmenu_item *item, static int menu_operation(WINDOW * win, nhmenu *menu, menu_op operation, int page_num); static void menu_clear_selections(nhmenu *menu); -static boolean get_menu_coloring(char *str, int *color, int *attr); static int menu_max_height(void); static nhmenu *nhmenus = NULL; /* NetHack menu array */ @@ -1369,7 +1368,7 @@ menu_clear_selections(nhmenu *menu) applied */ #ifdef MENU_COLOR -static boolean +boolean get_menu_coloring(char *str, int *color, int *attr) { struct menucoloring *tmpmc; diff --git a/win/curses/cursdial.h b/win/curses/cursdial.h index b1379b3a..8a7dcdb2 100644 --- a/win/curses/cursdial.h +++ b/win/curses/cursdial.h @@ -20,6 +20,9 @@ void curses_create_nhmenu(winid wid); void curses_add_nhmenu_item(winid wid, int glyph, const ANY_P * identifier, CHAR_P accelerator, CHAR_P group_accel, int attr, const char *str, BOOLEAN_P presel); +# ifdef MENU_COLOR +boolean get_menu_coloring(char *, int *, int *); +# endif void curses_finalize_nhmenu(winid wid, const char *prompt); int curses_display_nhmenu(winid wid, int how, MENU_ITEM_P ** _selected); boolean curses_menu_exists(winid wid); diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index 37a217b9..b6ee1389 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -268,6 +268,8 @@ curses_create_main_windows() int message_y = 0; int status_x = 0; int status_y = 0; + int inv_x = 0; + int inv_y = 0; int map_x = 0; int map_y = 0; @@ -275,28 +277,67 @@ curses_create_main_windows() int message_width = 0; int status_height = 0; int status_width = 0; + int inv_height = 0; + int inv_width = 0; int map_height = (term_rows - border_space); int map_width = (term_cols - border_space); - set_window_position(&status_x, &status_y, &status_width, &status_height, - status_orientation, &map_x, &map_y, &map_width, &map_height, - border_space, 2, 26); - set_window_position(&message_x, &message_y, &message_width, &message_height, - message_orientation, &map_x, &map_y, &map_width, &map_height, - border_space, -1, -25); + boolean status_vertical = FALSE; + boolean msg_vertical = FALSE; + if (status_orientation == ALIGN_LEFT || + status_orientation == ALIGN_RIGHT) + status_vertical = TRUE; + if (message_orientation == ALIGN_LEFT || + message_orientation == ALIGN_RIGHT) + msg_vertical = TRUE; + + /* Vertical windows have priority. Otherwise, priotity is: + status > inv > msg */ + if (status_vertical) + set_window_position(&status_x, &status_y, &status_width, &status_height, + status_orientation, &map_x, &map_y, &map_width, &map_height, + border_space, 2, 26); + + if (flags.perm_invent) { + /* Take up all width unless msgbar is also vertical. */ + int width = -25; + if (msg_vertical) + width = 25; + + set_window_position(&inv_x, &inv_y, &inv_width, &inv_height, + ALIGN_RIGHT, &map_x, &map_y, &map_width, &map_height, + border_space, -1, width); + } + + if (msg_vertical) + set_window_position(&message_x, &message_y, &message_width, &message_height, + message_orientation, &map_x, &map_y, &map_width, &map_height, + border_space, -1, -25); + + /* Now draw horizontal windows */ + if (!status_vertical) + set_window_position(&status_x, &status_y, &status_width, &status_height, + status_orientation, &map_x, &map_y, &map_width, &map_height, + border_space, 2, 26); + + if (!msg_vertical) + set_window_position(&message_x, &message_y, &message_width, &message_height, + message_orientation, &map_x, &map_y, &map_width, &map_height, + border_space, -1, -25); - if (map_width > COLNO) { + if (map_width > COLNO) map_width = COLNO; - } - if (map_height > ROWNO) { + if (map_height > ROWNO) map_height = ROWNO; - } if (curses_window_exists(STATUS_WIN)) { curses_del_nhwin(STATUS_WIN); curses_del_nhwin(MESSAGE_WIN); curses_del_nhwin(MAP_WIN); + if (flags.perm_invent) + curses_del_nhwin(INV_WIN); + clear(); } @@ -306,6 +347,9 @@ curses_create_main_windows() curses_add_nhwin(MESSAGE_WIN, message_height, message_width, message_y, message_x, message_orientation, borders); + curses_add_nhwin(INV_WIN, inv_height, inv_width, inv_y, inv_x, + ALIGN_RIGHT, borders); + curses_add_nhwin(MAP_WIN, map_height, map_width, map_y, map_x, 0, borders); refresh(); @@ -314,6 +358,7 @@ curses_create_main_windows() if (iflags.window_inited) { curses_update_stats(); + curses_update_inventory(); } else { iflags.window_inited = TRUE; } diff --git a/win/curses/cursinvt.c b/win/curses/cursinvt.c new file mode 100644 index 00000000..7a6714d9 --- /dev/null +++ b/win/curses/cursinvt.c @@ -0,0 +1,95 @@ +/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ + +#include "curses.h" +#include "hack.h" +#include "wincurs.h" +#include "cursinvt.h" + +/* Permanent inventory for curses interface */ + +/* Runs when the game indicates that the inventory has been updated */ +void +curses_update_inv(void) +{ + WINDOW *win = curses_get_nhwin(INV_WIN); + + /* Check if the inventory window is enabled in first place */ + if (!win) + return; + + boolean border = curses_window_has_border(INV_WIN); + + /* Figure out drawing area */ + int x = 0; + int y = 0; + if (border) { + x++; + y++; + } + + /* Clear the window as it is at the moment. */ + werase(win); + + display_inventory(NULL, FALSE); + + if (border) + box(win, 0, 0); + + wrefresh(win); +} + +/* Adds an inventory item. */ +void +curses_add_inv(int y, int glyph, CHAR_P accelerator, attr_t attr, + const char *str, const ANY_P *identifier) +{ + WINDOW *win = curses_get_nhwin(INV_WIN); + + /* Figure out where to draw the line */ + int x = 0; + y--; + if (curses_window_has_border(INV_WIN)) { + x++; + y++; + } + + wmove(win, y, x); + if (accelerator) { + attr_t bold = A_BOLD; + wattron(win, bold); + waddch(win, accelerator); + wattroff(win, bold); + wprintw(win, ") "); + } + + if (accelerator && glyph != NO_GLYPH && iflags.use_menu_glyphs) { + unsigned dummy = 0; /* Not used */ + int color = 0; + int curletter = 0; + mapglyph_obj(glyph, &curletter, &color, &dummy, + u.ux, u.uy, identifier->a_obj); + attr = curses_color_attr(color, 0); + wattron(win, attr); + wprintw(win, "%c ", curletter); + wattroff(win, attr); + } + +#ifdef MENU_COLOR + if (accelerator && /* Don't colorize categories */ + iflags.use_menu_color) { + int color = NO_COLOR; + boolean menu_color = FALSE; + char str_mutable[BUFSZ]; + Strcpy(str_mutable, str); + attr = 0; + get_menu_coloring(str_mutable, &color, &attr); + if (color != NO_COLOR) + attr |= curses_color_attr(color, 0); + } +#endif + + wattron(win, attr); + wprintw(win, "%s", str); + wattroff(win, attr); + wclrtoeol(win); +} diff --git a/win/curses/cursinvt.h b/win/curses/cursinvt.h new file mode 100644 index 00000000..99c90d27 --- /dev/null +++ b/win/curses/cursinvt.h @@ -0,0 +1,11 @@ +/* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ + +#ifndef CURSINVT_H +# define CURSINVT_H + + +/* Global declarations */ + +void curses_update_inv(void); + +#endif /* CURSINVT_H */ diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index 0803b8cb..3d8cf1df 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -65,6 +65,11 @@ struct window_procs curses_procs = { curses_preference_update, }; +/* Track if we're performing an update to the permanent window. + Needed since we aren't using the normal menu functions to handle + the inventory window. */ +static int inv_update = 0; + /* init_nhwindows(int* argcp, char** argv) -- Initialize the windows used by NetHack. This can also @@ -153,7 +158,6 @@ curses_init_nhwindows(int *argcp, char **argv) curses_display_splash_window(); } - /* Do a window-port specific player type selection. If player_selection() offers a Quit option, it is its responsibility to clean up and terminate the process. You need to fill in pl_character[0]. @@ -366,6 +370,9 @@ curses_display_file(const char *filename, BOOLEAN_P must_exist) void curses_start_menu(winid wid) { + if (inv_update) + return; + curses_create_nhmenu(wid); } @@ -407,6 +414,13 @@ curses_add_menu(winid wid, int glyph, const ANY_P * identifier, { int curses_attr = curses_convert_attr(attr); + if (inv_update) { + curses_add_inv(inv_update, glyph, accelerator, curses_attr, + str, identifier); + inv_update++; + return; + } + curses_add_nhmenu_item(wid, glyph, identifier, accelerator, group_accel, curses_attr, str, presel); } @@ -423,6 +437,9 @@ end_menu(window, prompt) void curses_end_menu(winid wid, const char *prompt) { + if (inv_update) + return; + curses_finalize_nhmenu(wid, prompt); } @@ -454,17 +471,25 @@ int select_menu(winid window, int how, menu_item **selected) int curses_select_menu(winid wid, int how, MENU_ITEM_P ** selected) { + if (inv_update) + return 0; + return curses_display_nhmenu(wid, how, selected); } -/* - -- Indicate to the window port that the inventory has been changed. - -- Merely calls display_inventory() for window-ports that leave the - window up, otherwise empty. -*/ void -curses_update_inventory() +curses_update_inventory(void) { + if (!flags.perm_invent) + return; + + /* Update inventory sidebar. NetHack uses normal menu functions + when drawing the inventory, and we don't want to change the + underlying code. So instead, track if an inventory update is + being performed with a static variable. */ + inv_update = 1; + curses_update_inv(); + inv_update = 0; } /* diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index 2f229296..9643f979 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -20,7 +20,6 @@ static attr_t get_trouble_color(const char *); static void draw_trouble_str(const char *); static void print_statdiff(const char *append, nhstat *, int, int); static void get_playerrank(char *); -static attr_t curses_color_attr(int nh_color, int bg_color); static int hpen_color(boolean, int, int); static void draw_bar(boolean, int, int, const char *); static void draw_horizontal(int, int, int, int); @@ -216,7 +215,7 @@ draw_trouble_str(const char *str) /* Returns a ncurses attribute for foreground and background. This should probably be in cursinit.c or something. */ -static attr_t +attr_t curses_color_attr(int nh_color, int bg_color) { int color = nh_color + 1; @@ -431,7 +430,7 @@ curses_update_stats(void) int y = 0; /* Don't start at border position if applicable */ - if (curses_window_has_border(STATUS_WIN)) { + if (border) { x++; y++; } diff --git a/win/curses/cursstat.h b/win/curses/cursstat.h index 317fd3d6..7773d422 100644 --- a/win/curses/cursstat.h +++ b/win/curses/cursstat.h @@ -16,6 +16,6 @@ void curses_update_stats(); void curses_decrement_highlights(boolean); - +attr_t curses_color_attr(int nh_color, int bg_color); #endif /* CURSSTAT_H */ diff --git a/win/curses/curswins.c b/win/curses/curswins.c index bc4bb038..f6c573b2 100644 --- a/win/curses/curswins.c +++ b/win/curses/curswins.c @@ -459,6 +459,9 @@ curses_puts(winid wid, int attr, const char *text) if (wid == STATUS_WIN) { curses_update_stats(); /* We will do the write ourselves */ + /* Inventory updating isn't performed on redraws, so + also update inventory here... */ + curses_update_inventory(); return; } @@ -527,7 +530,7 @@ curses_alert_main_borders(boolean onoff) static boolean is_main_window(winid wid) { - if ((wid == MESSAGE_WIN) || (wid == MAP_WIN) || (wid == STATUS_WIN)) { + if ((wid == MESSAGE_WIN) || (wid == MAP_WIN) || (wid == STATUS_WIN) || wid == INV_WIN) { return TRUE; } else { return FALSE; From 3d410780998eb835db08bc62fbb3a8f1c498dc1e Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Fri, 12 May 2017 15:30:53 +0200 Subject: [PATCH 38/69] Add "Inventory:" title to inventory sidebar and "Not carrying anything" if applicable --- win/curses/cursinvt.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/win/curses/cursinvt.c b/win/curses/cursinvt.c index 7a6714d9..b947e4be 100644 --- a/win/curses/cursinvt.c +++ b/win/curses/cursinvt.c @@ -30,6 +30,16 @@ curses_update_inv(void) /* Clear the window as it is at the moment. */ werase(win); + wmove(win, y, x); + attr_t attr = A_UNDERLINE; + wattron(win, attr); + wprintw(win, "Inventory:"); + wattroff(win, attr); + + /* The actual inventory will override this if we do carry stuff */ + wmove(win, y + 1, x); + wprintw(win, "Not carrying anything"); + display_inventory(NULL, FALSE); if (border) @@ -47,7 +57,6 @@ curses_add_inv(int y, int glyph, CHAR_P accelerator, attr_t attr, /* Figure out where to draw the line */ int x = 0; - y--; if (curses_window_has_border(INV_WIN)) { x++; y++; From 1cf44904dcc8cfbbfb055bd065edafaf1e003ab2 Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Fri, 12 May 2017 16:34:20 +0200 Subject: [PATCH 39/69] If the perm_invent option changes between the save and the file, handle that properly --- win/curses/cursinvt.c | 7 ++++++- win/curses/cursmain.c | 8 +++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/win/curses/cursinvt.c b/win/curses/cursinvt.c index b947e4be..cd216dfd 100644 --- a/win/curses/cursinvt.c +++ b/win/curses/cursinvt.c @@ -14,8 +14,13 @@ curses_update_inv(void) WINDOW *win = curses_get_nhwin(INV_WIN); /* Check if the inventory window is enabled in first place */ - if (!win) + if (!win) { + /* It's not. Re-initialize the main windows if the + option was enabled. */ + if (flags.perm_invent) + curses_create_main_windows(); return; + } boolean border = curses_window_has_border(INV_WIN); diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index 3d8cf1df..9e129aae 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -480,8 +480,14 @@ curses_select_menu(winid wid, int how, MENU_ITEM_P ** selected) void curses_update_inventory(void) { - if (!flags.perm_invent) + /* Don't do anything if perm_invent is off unless we + changed the option. */ + if (!flags.perm_invent) { + WINDOW *win = curses_get_nhwin(INV_WIN); + if (win) + curses_create_main_windows(); return; + } /* Update inventory sidebar. NetHack uses normal menu functions when drawing the inventory, and we don't want to change the From 62d522ff9c12f934f3e09ae3fa30b6f4dd7309f9 Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Fri, 12 May 2017 16:43:53 +0200 Subject: [PATCH 40/69] perm_invent is implemented, remove from TODO From d3b0252c2a62c077e9811296e1be9507315a846a Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Fri, 12 May 2017 23:10:55 +0200 Subject: [PATCH 41/69] Make the msgbuffer redraw the entire message history if redrawn, instead of just a single message --- win/curses/cursmesg.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/win/curses/cursmesg.c b/win/curses/cursmesg.c index fe1f3406..574bbcc1 100644 --- a/win/curses/cursmesg.c +++ b/win/curses/cursmesg.c @@ -227,7 +227,14 @@ curses_last_messages() my = 0; } - pline("%s", toplines); + nhprev_mesg *mesg; + int i; + for (i = (num_messages - 1); i > 0; i--) { + mesg = get_msg_line(TRUE, i); + if (mesg && mesg->str && strcmp(mesg->str, "")) + curses_message_win_puts(mesg->str, TRUE); + } + curses_message_win_puts(toplines, TRUE); } From 9a46f15ffca5d35f8d67ea7f288d7a6cea289397 Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Fri, 12 May 2017 23:11:22 +0200 Subject: [PATCH 42/69] Fix various perm_invent bugs, including a crash bug --- win/curses/cursinit.c | 14 +++++++------- win/curses/cursinvt.c | 5 ++++- win/curses/cursmain.c | 6 ++++-- win/curses/curswins.c | 1 + 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index b6ee1389..545ef5fe 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -331,12 +331,11 @@ curses_create_main_windows() if (map_height > ROWNO) map_height = ROWNO; - if (curses_window_exists(STATUS_WIN)) { + if (curses_get_nhwin(STATUS_WIN)) { curses_del_nhwin(STATUS_WIN); curses_del_nhwin(MESSAGE_WIN); curses_del_nhwin(MAP_WIN); - if (flags.perm_invent) - curses_del_nhwin(INV_WIN); + curses_del_nhwin(INV_WIN); clear(); } @@ -347,8 +346,9 @@ curses_create_main_windows() curses_add_nhwin(MESSAGE_WIN, message_height, message_width, message_y, message_x, message_orientation, borders); - curses_add_nhwin(INV_WIN, inv_height, inv_width, inv_y, inv_x, - ALIGN_RIGHT, borders); + if (flags.perm_invent) + curses_add_nhwin(INV_WIN, inv_height, inv_width, inv_y, inv_x, + ALIGN_RIGHT, borders); curses_add_nhwin(MAP_WIN, map_height, map_width, map_y, map_x, 0, borders); @@ -358,7 +358,8 @@ curses_create_main_windows() if (iflags.window_inited) { curses_update_stats(); - curses_update_inventory(); + if (flags.perm_invent) + curses_update_inventory(); } else { iflags.window_inited = TRUE; } @@ -921,7 +922,6 @@ curses_init_options() /* Remove a few options that are irrelevant to this windowport */ set_option_mod_status("DECgraphics", SET_IN_FILE); - set_option_mod_status("perm_invent", SET_IN_FILE); set_option_mod_status("eight_bit_tty", SET_IN_FILE); /* Make sure that DECgraphics is not set to true via the config diff --git a/win/curses/cursinvt.c b/win/curses/cursinvt.c index cd216dfd..10c9c721 100644 --- a/win/curses/cursinvt.c +++ b/win/curses/cursinvt.c @@ -17,8 +17,11 @@ curses_update_inv(void) if (!win) { /* It's not. Re-initialize the main windows if the option was enabled. */ - if (flags.perm_invent) + if (flags.perm_invent) { curses_create_main_windows(); + curses_last_messages(); + doredraw(); + } return; } diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index 9e129aae..28fdd2de 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -483,9 +483,11 @@ curses_update_inventory(void) /* Don't do anything if perm_invent is off unless we changed the option. */ if (!flags.perm_invent) { - WINDOW *win = curses_get_nhwin(INV_WIN); - if (win) + if (curses_get_nhwin(INV_WIN)) { curses_create_main_windows(); + curses_last_messages(); + doredraw(); + } return; } diff --git a/win/curses/curswins.c b/win/curses/curswins.c index f6c573b2..7e591841 100644 --- a/win/curses/curswins.c +++ b/win/curses/curswins.c @@ -294,6 +294,7 @@ curses_del_nhwin(winid wid) panic("curses_del_nhwin: wid out of range. Not a main window."); } + nhwins[wid].curwin = NULL; nhwins[wid].nhwin = -1; } From c8a5a78126449b0a4318a605570235dbbf057348 Mon Sep 17 00:00:00 2001 From: Tangles Date: Sat, 13 May 2017 15:38:59 +1000 Subject: [PATCH 43/69] curses - remove grunt-specifics frm recent merge. --- include/wincurs.h | 3 +-- win/curses/cursinvt.c | 10 +++++----- win/curses/cursmain.c | 3 +-- win/curses/cursstat.c | 2 +- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/include/wincurs.h b/include/wincurs.h index 120c14b5..edf44536 100644 --- a/include/wincurs.h +++ b/include/wincurs.h @@ -268,8 +268,7 @@ extern void curses_decrement_highlight(void); /* cursinvt.c */ extern void curses_update_inv(void); -extern void curses_add_inv(int, int, CHAR_P, attr_t, const char *, - const ANY_P *); +extern void curses_add_inv(int, int, CHAR_P, attr_t, const char *); /* cursinit.c */ diff --git a/win/curses/cursinvt.c b/win/curses/cursinvt.c index 10c9c721..20aefee2 100644 --- a/win/curses/cursinvt.c +++ b/win/curses/cursinvt.c @@ -59,7 +59,7 @@ curses_update_inv(void) /* Adds an inventory item. */ void curses_add_inv(int y, int glyph, CHAR_P accelerator, attr_t attr, - const char *str, const ANY_P *identifier) + const char *str) { WINDOW *win = curses_get_nhwin(INV_WIN); @@ -82,12 +82,12 @@ curses_add_inv(int y, int glyph, CHAR_P accelerator, attr_t attr, if (accelerator && glyph != NO_GLYPH && iflags.use_menu_glyphs) { unsigned dummy = 0; /* Not used */ int color = 0; - int curletter = 0; - mapglyph_obj(glyph, &curletter, &color, &dummy, - u.ux, u.uy, identifier->a_obj); + int symbol = 0; + mapglyph(glyph, &symbol, &color, &dummy, + u.ux, u.uy); attr = curses_color_attr(color, 0); wattron(win, attr); - wprintw(win, "%c ", curletter); + wprintw(win, "%c ", symbol); wattroff(win, attr); } diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index 28fdd2de..5b859851 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -415,8 +415,7 @@ curses_add_menu(winid wid, int glyph, const ANY_P * identifier, int curses_attr = curses_convert_attr(attr); if (inv_update) { - curses_add_inv(inv_update, glyph, accelerator, curses_attr, - str, identifier); + curses_add_inv(inv_update, glyph, accelerator, curses_attr, str); inv_update++; return; } diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index 9643f979..ae5f6627 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -705,7 +705,7 @@ curses_add_statuses(WINDOW *win, boolean vertical, int *x, int *y) statprob("Blind", Blind); statprob("Stun", Stunned); statprob("Hallu", Hallucination); - statprob("Ill", (u.usick_type & (SICK_NONVOMITABLE|SICK_ZOMBIE))); + statprob("Ill", (u.usick_type & SICK_NONVOMITABLE)); statprob("FoodPois", (u.usick_type & SICK_VOMITABLE)); statprob("Slime", Slimed); From 991c47f4099cb4e9f1452f2fd934ab9c49b90c85 Mon Sep 17 00:00:00 2001 From: Tangles Date: Sat, 13 May 2017 16:15:34 +1000 Subject: [PATCH 44/69] curses - Add some missing hpbar logic from grunt. --- win/curses/cursstat.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index ae5f6627..d8deeb63 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -379,6 +379,13 @@ draw_bar(boolean is_hp, int cur, int max, const char *title) { WINDOW *win = curses_get_nhwin(STATUS_WIN); +#ifdef STATUS_COLORS + if (!iflags.hitpointbar) { + wprintw(win, "%s", !title ? "---" : title); + return; + } +#endif + char buf[BUFSZ]; if (title) Strcpy(buf, title); From 28619d3e4231148bb41cf737a7a17513ff63d458 Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Sat, 13 May 2017 20:17:05 +0200 Subject: [PATCH 45/69] Fix Strength not showing correctly above 18 --- win/curses/cursstat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index d8deeb63..e5e96916 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -188,7 +188,7 @@ print_statdiff(const char *append, nhstat *stat, int new, int type) else if (new == 118) wprintw(win, "18/**"); else - wprintw(win, "18/%d", new - 18); + wprintw(win, "18/%02d", new - 18); } else wprintw(win, "%d", new); From 4df2527a6b4c301d8dda3ccdb1a15f6b40ef7add Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Sun, 14 May 2017 18:47:49 +0200 Subject: [PATCH 46/69] Add classic_status, defaults to TRUE. If set to false, it will draw a NH4-style status bar --- include/extern.h | 1 + include/flag.h | 3 +- src/exper.c | 3 +- src/options.c | 3 + win/curses/cursinit.c | 11 +- win/curses/cursstat.c | 233 +++++++++++++++++++++++++++++++++++++----- 6 files changed, 221 insertions(+), 33 deletions(-) diff --git a/include/extern.h b/include/extern.h index e3c66040..6e0eeaac 100644 --- a/include/extern.h +++ b/include/extern.h @@ -616,6 +616,7 @@ E void FDECL(make_grave, (int,int,const char *)); /* ### exper.c ### */ +E long FDECL(newuexp, (int)); E int FDECL(experience, (struct monst *,int)); E void FDECL(more_experienced, (int,int)); E void FDECL(losexp, (const char *)); diff --git a/include/flag.h b/include/flag.h index 3819c84a..ee651939 100644 --- a/include/flag.h +++ b/include/flag.h @@ -157,7 +157,8 @@ struct flag { struct instance_flags { boolean cbreak; /* in cbreak mode, rogue format */ #ifdef CURSES_GRAPHICS - boolean cursesgraphics; /* Use portable curses extended characters */ + boolean classic_status; /* What kind of horizontal statusbar to use */ + boolean cursesgraphics; /* Use portable curses extended characters */ #endif boolean DECgraphics; /* use DEC VT-xxx extended character set */ boolean echo; /* 1 to echo characters */ diff --git a/src/exper.c b/src/exper.c index 649f1c68..d3b95a63 100644 --- a/src/exper.c +++ b/src/exper.c @@ -4,10 +4,9 @@ #include "hack.h" -STATIC_DCL long FDECL(newuexp, (int)); STATIC_DCL int FDECL(enermod, (int)); -STATIC_OVL long +long newuexp(lev) int lev; { diff --git a/src/options.c b/src/options.c index 57b81653..44867814 100644 --- a/src/options.c +++ b/src/options.c @@ -79,6 +79,9 @@ static struct Bool_Opt {"checkspace", &iflags.checkspace, TRUE, SET_IN_GAME}, #else {"checkspace", (boolean *)0, FALSE, SET_IN_FILE}, +#endif +#ifdef CURSES_GRAPHICS + {"classic_status", &iflags.classic_status, TRUE, SET_IN_FILE}, #endif {"cmdassist", &iflags.cmdassist, TRUE, SET_IN_GAME}, # if defined(MICRO) || defined(WIN32) || defined(CURSES_GRAPHICS) diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index 545ef5fe..2b4d74f9 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -291,12 +291,16 @@ curses_create_main_windows() message_orientation == ALIGN_RIGHT) msg_vertical = TRUE; + int statusheight = 3; + if (iflags.classic_status) + statusheight = 2; + /* Vertical windows have priority. Otherwise, priotity is: status > inv > msg */ if (status_vertical) set_window_position(&status_x, &status_y, &status_width, &status_height, status_orientation, &map_x, &map_y, &map_width, &map_height, - border_space, 2, 26); + border_space, statusheight, 26); if (flags.perm_invent) { /* Take up all width unless msgbar is also vertical. */ @@ -318,7 +322,7 @@ curses_create_main_windows() if (!status_vertical) set_window_position(&status_x, &status_y, &status_width, &status_height, status_orientation, &map_x, &map_y, &map_width, &map_height, - border_space, 2, 26); + border_space, statusheight, 26); if (!msg_vertical) set_window_position(&message_x, &message_y, &message_width, &message_height, @@ -924,6 +928,9 @@ curses_init_options() set_option_mod_status("DECgraphics", SET_IN_FILE); set_option_mod_status("eight_bit_tty", SET_IN_FILE); + /* Add those that are */ + set_option_mod_status("classic_status", SET_IN_GAME); + /* Make sure that DECgraphics is not set to true via the config file, as this will cause display issues. We can't disable it in options.c in case the game is compiled with both tty and curses. */ diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index e5e96916..b3fa5432 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -23,9 +23,11 @@ static void get_playerrank(char *); static int hpen_color(boolean, int, int); static void draw_bar(boolean, int, int, const char *); static void draw_horizontal(int, int, int, int); +static void draw_horizontal_new(int, int, int, int); static void draw_vertical(int, int, int, int); -static void curses_add_statuses(WINDOW *, boolean, int *, int *); -static void curses_add_status(WINDOW *, boolean, int *, int *, const char *, int); +static void curses_add_statuses(WINDOW *, boolean, boolean, int *, int *); +static void curses_add_status(WINDOW *, boolean, boolean, int *, int *, + const char *, int); static int decrement_highlight(nhstat *, boolean); #ifdef STATUS_COLORS @@ -200,16 +202,9 @@ draw_trouble_str(const char *str) { WINDOW *win = curses_get_nhwin(STATUS_WIN); - /* For whatever reason, hunger states have trailing spaces. Get rid of them. */ - char buf[BUFSZ]; - Strcpy(buf, str); - int i; - for (i = 0; (buf[i] != ' ' && buf[i] != '\0'); i++) ; - - buf[i] = '\0'; - attr_t attr = get_trouble_color(buf); + attr_t attr = get_trouble_color(str); wattron(win, attr); - wprintw(win, "%s", buf); + wprintw(win, "%s", str); wattroff(win, attr); } @@ -426,11 +421,41 @@ draw_bar(boolean is_hp, int cur, int max, const char *title) void curses_update_stats(void) { - int orient; WINDOW *win = curses_get_nhwin(STATUS_WIN); - boolean horiz; + int orient = curses_get_window_orientation(STATUS_WIN); + + boolean horiz = FALSE; + if ((orient != ALIGN_RIGHT) && (orient != ALIGN_LEFT)) + horiz = TRUE; + boolean border = curses_window_has_border(STATUS_WIN); + /* Figure out if we have proper window dimensions for horizontal statusbar. */ + if (horiz) { + /* correct y */ + int cy = 3; + if (iflags.classic_status) + cy = 2; + + /* actual y (and x) */ + int ax = 0; + int ay = 0; + getmaxyx(win, ay, ax); + if (border) + ay -= 2; + + if (cy != ay) { + curses_create_main_windows(); + curses_last_messages(); + doredraw(); + + /* Reset XP highlight (since classic_status and new show different numbers) */ + prevexp.highlight_turns = 0; + curses_update_stats(); + return; + } + } + /* Starting x/y. Passed to draw_horizontal/draw_vertical to keep track of window positioning. */ int x = 0; @@ -450,12 +475,6 @@ curses_update_stats(void) hpmax = u.mhmax; } - orient = curses_get_window_orientation(STATUS_WIN); - - horiz = FALSE; - if ((orient != ALIGN_RIGHT) && (orient != ALIGN_LEFT)) - horiz = TRUE; - if (orient != ALIGN_RIGHT && orient != ALIGN_LEFT) draw_horizontal(x, y, hp, hpmax); else @@ -477,6 +496,11 @@ curses_update_stats(void) static void draw_horizontal(int x, int y, int hp, int hpmax) { + if (!iflags.classic_status) { + /* Draw new-style statusbar */ + draw_horizontal_new(x, y, hp, hpmax); + return; + } char buf[BUFSZ]; char rank[BUFSZ]; WINDOW *win = curses_get_nhwin(STATUS_WIN); @@ -562,10 +586,137 @@ draw_horizontal(int x, int y, int hp, int hpmax) if (flags.time) print_statdiff(" T:", &prevtime, moves, STAT_TIME); - curses_add_statuses(win, FALSE, NULL, NULL); - wclrtoeol(win); + curses_add_statuses(win, FALSE, FALSE, NULL, NULL); } +static void +draw_horizontal_new(int x, int y, int hp, int hpmax) +{ + char buf[BUFSZ]; + char rank[BUFSZ]; + WINDOW *win = curses_get_nhwin(STATUS_WIN); + + /* Line 1 */ + wmove(win, y, x); + + get_playerrank(rank); + char race[BUFSZ]; + Strcpy(race, urace.adj); + race[0] = highc(race[0]); + wprintw(win, "%s the %s %s%s%s", plname, + (u.ualign.type == A_CHAOTIC ? "Chaotic" : + u.ualign.type == A_NEUTRAL ? "Neutral" : "Lawful"), + Upolyd ? "" : race, Upolyd ? "" : " ", + rank); + + wclrtoeol(win); + + /* Line 2 */ + y++; + wmove(win, y, x); + wprintw(win, "HP:"); + draw_bar(TRUE, hp, hpmax, NULL); + print_statdiff(" AC:", &prevac, u.uac, STAT_AC); + if (Upolyd) + print_statdiff(" HD:", &prevlevel, mons[u.umonnum].mlevel, STAT_OTHER); +#ifdef EXP_ON_BOTL + else if (flags.showexp) { + /* Ensure that Xp have proper highlight on level change. */ + int levelchange = 0; + if (prevlevel.value != u.ulevel) { + if (prevlevel.value < u.ulevel) + levelchange = 1; + else + levelchange = 2; + } + print_statdiff(" Xp:", &prevlevel, u.ulevel, STAT_OTHER); + /* use waddch, we don't want to highlight the '/' */ + waddch(win, '('); + + /* Figure out amount of Xp needed to next level */ + int xp_left = 0; + if (u.ulevel < 29) + xp_left = (newuexp(u.ulevel) - u.uexp); + + if (levelchange) { + prevexp.value = (xp_left + 1); + if (levelchange == 2) + prevexp.value = (xp_left - 1); + } + print_statdiff("", &prevexp, xp_left, STAT_AC); + waddch(win, ')'); +#endif + } else + print_statdiff(" Exp:", &prevlevel, u.ulevel, STAT_OTHER); + + waddch(win, ' '); + describe_level(buf); + + wprintw(win, "%s", buf); + wclrtoeol(win); + + + /* Line 3 */ + y++; + wmove(win, y, x); + wprintw(win, "Pw:"); + draw_bar(FALSE, u.uen, u.uenmax, NULL); + +#ifndef GOLDOBJ + print_statdiff(" $", &prevau, u.ugold, STAT_GOLD); +#else + print_statdiff(" $", &prevau, money_cnt(invent), STAT_GOLD); +#endif + +#ifdef SCORE_ON_BOTL + if (flags.showscore) + print_statdiff(" S:", &prevscore, botl_score(), STAT_OTHER); +#endif /* SCORE_ON_BOTL */ + + if (flags.time) + print_statdiff(" T:", &prevtime, moves, STAT_TIME); + + wclrtoeol(win); + curses_add_statuses(win, TRUE, FALSE, &x, &y); + + /* Right-aligned attributes */ + int stat_length = 6; /* " Dx:xx" */ + int str_length = 6; + if (ACURR(A_STR) > 18 && ACURR(A_STR) < 119) + str_length = 9; + + getmaxyx(win, y, x); + + /* We want to deal with top line of y. getmaxx would do what we want, but it only + exist for compatibility reasons and might not exist at all in some versions. */ + y = 0; + if (curses_window_has_border(STATUS_WIN)) { + x--; + y++; + } + + x -= stat_length; + int orig_x = x; + wmove(win, y, x); + print_statdiff(" Co:", &prevcon, ACURR(A_CON), STAT_OTHER); + x -= stat_length; + wmove(win, y, x); + print_statdiff(" Dx:", &prevdex, ACURR(A_DEX), STAT_OTHER); + x -= str_length; + wmove(win, y, x); + print_statdiff(" St:", &prevstr, ACURR(A_STR), STAT_STR); + + x = orig_x; + y++; + wmove(win, y, x); + print_statdiff(" Ch:", &prevcha, ACURR(A_CHA), STAT_OTHER); + x -= stat_length; + wmove(win, y, x); + print_statdiff(" Wi:", &prevwis, ACURR(A_WIS), STAT_OTHER); + x -= str_length; + wmove(win, y, x); + print_statdiff(" In:", &prevint, ACURR(A_INT), STAT_OTHER); +} /* Personally I never understood the point of a vertical status bar. But removing the option would be silly, so keep the functionality. */ @@ -695,14 +846,28 @@ draw_vertical(int x, int y, int hp, int hpmax) } #endif /* SCORE_ON_BOTL */ - curses_add_statuses(win, TRUE, &x, &y); + curses_add_statuses(win, FALSE, TRUE, &x, &y); } static void -curses_add_statuses(WINDOW *win, boolean vertical, int *x, int *y) +curses_add_statuses(WINDOW *win, boolean align_right, + boolean vertical, int *x, int *y) { + if (align_right) { + /* Right-aligned statuses. Since add_status decrease one x more + (to separate them with spaces), add 1 to x unless we have borders + (which would offset what add_status does) */ + int mx = *x; + int my = *y; + getmaxyx(win, my, mx); + if (!curses_window_has_border(STATUS_WIN)) + mx++; + + *x = mx; + } + #define statprob(str, trouble) \ - curses_add_status(win, vertical, x, y, str, trouble) + curses_add_status(win, align_right, vertical, x, y, str, trouble) /* Hunger */ statprob(hu_stat[u.uhs], u.uhs != 1); /* 1 is NOT_HUNGRY (not defined here) */ @@ -723,8 +888,8 @@ curses_add_statuses(WINDOW *win, boolean vertical, int *x, int *y) } static void -curses_add_status(WINDOW *win, boolean vertical, int *x, int *y, - const char *str, int trouble) +curses_add_status(WINDOW *win, boolean align_right, boolean vertical, + int *x, int *y, const char *str, int trouble) { /* If vertical is TRUE here with no x/y, that's an error. But handle it gracefully since NH3 doesn't recover well in crashes. */ @@ -734,10 +899,22 @@ curses_add_status(WINDOW *win, boolean vertical, int *x, int *y, if (!trouble) return; - if (!vertical) + if (!vertical && !align_right) waddch(win, ' '); - draw_trouble_str(str); + /* For whatever reason, hunger states have trailing spaces. Get rid of them. */ + char buf[BUFSZ]; + Strcpy(buf, str); + int i; + for (i = 0; (buf[i] != ' ' && buf[i] != '\0'); i++) ; + + buf[i] = '\0'; + if (align_right) { + *x -= (strlen(buf) + 1); /* add spacing */ + wmove(win, *y, *x); + } + + draw_trouble_str(buf); if (vertical) { wmove(win, *y, *x); From feed1f732b2454cc3f9dc5deb9f6af968c1a5805 Mon Sep 17 00:00:00 2001 From: Tangles Date: Mon, 15 May 2017 19:21:07 +1000 Subject: [PATCH 47/69] Fix Buffer overflow in curses_num_lines() --- win/curses/cursmisc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index 8715d5e6..fb11c579 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -233,7 +233,7 @@ curses_num_lines(const char *str, int width) char substr[BUFSZ]; char tmpstr[BUFSZ]; - strcpy(substr, str); + strncpy(substr, str, BUFSZ-1); while (strlen(substr) > width) { last_space = 0; From ae74866b2f4922ea9c92e1441a57ba9babb962cd Mon Sep 17 00:00:00 2001 From: Tangles Date: Mon, 15 May 2017 21:30:16 +1000 Subject: [PATCH 48/69] fixup: ACTUALLY fix buffer overflow in curses_num_lines --- win/curses/cursmisc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index fb11c579..9040fa7a 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -234,6 +234,7 @@ curses_num_lines(const char *str, int width) char tmpstr[BUFSZ]; strncpy(substr, str, BUFSZ-1); + substr[BUFSZ-1] = '\0'; while (strlen(substr) > width) { last_space = 0; From 2eab2ed00f8fa0089376ed93e573555c227b2f23 Mon Sep 17 00:00:00 2001 From: Tangles Date: Tue, 16 May 2017 00:34:27 +1000 Subject: [PATCH 49/69] display splash in map area If popup_dialog is disabled, the "Shall I pick for you?" question uses pline() which draws the message window, probably over the splash screen. By using the coordinates of the map window we can mostly avoid this. --- win/curses/cursinit.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index 2b4d74f9..a749577b 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -987,9 +987,10 @@ curses_init_options() void curses_display_splash_window() { - int x_start = 1; - int y_start = 6; + int x_start; + int y_start; int which_variant = NETHACK_CURSES; /* Default to NetHack */ + curses_get_window_xy(MAP_WIN, &x_start, &y_start); if ((term_cols < 70) || (term_rows < 20)) { iflags.wc_splash_screen = FALSE; /* No room for s.s. */ From 551bda955088b16aee204e43676679417237df4a Mon Sep 17 00:00:00 2001 From: Tangles Date: Tue, 16 May 2017 11:39:17 +1000 Subject: [PATCH 50/69] Better handling of failure to open dump file. On an early panic, dump_format would be called before meaningful values existed for %n, etc. This could result in chmod() being called on a parent directory such as userdata, resulting in a complete denial of service. Also, dump file write was being attempted even if file failed to open. --- src/end.c | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/end.c b/src/end.c index 80e0005c..bd49e00f 100644 --- a/src/end.c +++ b/src/end.c @@ -169,14 +169,15 @@ dump_init () char new_dump_fn[512]; Sprintf(new_dump_fn, "%s", dump_format_str(dump_fn)); - dump_fp = fopen(new_dump_fn, "w"); -#ifdef UNIX - chmod(new_dump_fn, dumpmode); -#endif + dump_fp = fopen (new_dump_fn, "w"); if (!dump_fp) { pline("Can't open %s for output.", new_dump_fn); pline("Dump file not created."); + return; } +#if defined(UNIX) && defined(DGAMELAUNCH) + chmod(new_dump_fn, dumpmode); +#endif } } @@ -861,19 +862,21 @@ int how; program_state.something_worth_saving = 0; #ifdef DUMP_LOG /* D: Grab screen dump right here */ - if (dump_fn[0]) { - dump_init(); - Sprintf(pbuf, "%s, %s %s %s %s", plname, - aligns[1 - u.ualign.type].adj, - genders[flags.female].adj, - urace.adj, - (flags.female && urole.name.f)? - urole.name.f : urole.name.m); - dump("", pbuf); - /* D: Add a line for clearance from the screen dump */ - dump("", ""); - dump_screen(0); - } + if (dump_fn[0]) { + dump_init(); + if (dump_fp) { + Sprintf(pbuf, "%s, %s %s %s %s", plname, + aligns[1 - u.ualign.type].adj, + genders[flags.female].adj, + urace.adj, + (flags.female && urole.name.f)? + urole.name.f : urole.name.m); + dump("", pbuf); + /* D: Add a line for clearance from the screen dump */ + dump("", ""); + dump_screen(); + } + } #endif /* DUMP_LOG */ #ifdef WHEREIS_FILE From 4773290448b55a6234d04b8353d18ed9ca40e557 Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Tue, 16 May 2017 19:29:24 +0200 Subject: [PATCH 51/69] Fix a minor XP display bug in NH4status --- win/curses/cursstat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index b3fa5432..7b600379 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -635,7 +635,7 @@ draw_horizontal_new(int x, int y, int hp, int hpmax) /* Figure out amount of Xp needed to next level */ int xp_left = 0; - if (u.ulevel < 29) + if (u.ulevel < 30) xp_left = (newuexp(u.ulevel) - u.uexp); if (levelchange) { From f1a7b048bf7ea1e5c1929415e7995e6a15bdb6c1 Mon Sep 17 00:00:00 2001 From: Tangles Date: Wed, 17 May 2017 09:09:39 +1000 Subject: [PATCH 52/69] Fix number of args to dump_screen() dump fix --- src/end.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/end.c b/src/end.c index bd49e00f..51d09416 100644 --- a/src/end.c +++ b/src/end.c @@ -874,7 +874,7 @@ int how; dump("", pbuf); /* D: Add a line for clearance from the screen dump */ dump("", ""); - dump_screen(); + dump_screen(0); } } #endif /* DUMP_LOG */ From 29d0efa40ea95f41708ac8067622f5132e4fc778 Mon Sep 17 00:00:00 2001 From: Tangles Date: Wed, 17 May 2017 20:52:34 +1000 Subject: [PATCH 53/69] fix #ifdef on chmod() in dump_init() --- src/end.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/end.c b/src/end.c index 51d09416..2e51eaa5 100644 --- a/src/end.c +++ b/src/end.c @@ -175,7 +175,7 @@ dump_init () pline("Dump file not created."); return; } -#if defined(UNIX) && defined(DGAMELAUNCH) +#if defined(UNIX) chmod(new_dump_fn, dumpmode); #endif } From 129da493fbf85492e31529888b09c0c4a60a76b1 Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Wed, 17 May 2017 14:36:16 +0200 Subject: [PATCH 54/69] Replace wclrtoeols with a single werase at the start of statusbar updating Should get rid of any residual redrawing bugs --- win/curses/cursstat.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index 7b600379..511e8b2d 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -422,6 +422,10 @@ void curses_update_stats(void) { WINDOW *win = curses_get_nhwin(STATUS_WIN); + + /* Clear the window */ + werase(win); + int orient = curses_get_window_orientation(STATUS_WIN); boolean horiz = FALSE; @@ -530,8 +534,6 @@ draw_horizontal(int x, int y, int hp, int hpmax) print_statdiff(" S:", &prevscore, botl_score(), STAT_OTHER); #endif /* SCORE_ON_BOTL */ - wclrtoeol(win); - /* Line 2 */ y++; @@ -609,8 +611,6 @@ draw_horizontal_new(int x, int y, int hp, int hpmax) Upolyd ? "" : race, Upolyd ? "" : " ", rank); - wclrtoeol(win); - /* Line 2 */ y++; wmove(win, y, x); @@ -653,8 +653,6 @@ draw_horizontal_new(int x, int y, int hp, int hpmax) describe_level(buf); wprintw(win, "%s", buf); - wclrtoeol(win); - /* Line 3 */ y++; @@ -676,7 +674,6 @@ draw_horizontal_new(int x, int y, int hp, int hpmax) if (flags.time) print_statdiff(" T:", &prevtime, moves, STAT_TIME); - wclrtoeol(win); curses_add_statuses(win, TRUE, FALSE, &x, &y); /* Right-aligned attributes */ @@ -727,9 +724,6 @@ draw_vertical(int x, int y, int hp, int hpmax) char rank[BUFSZ]; WINDOW *win = curses_get_nhwin(STATUS_WIN); - /* Clear the window */ - werase(win); - /* Print title and dungeon branch */ wmove(win, y++, x); From cf185c6f467e6a43ffd519f509ea3b9eb712fde6 Mon Sep 17 00:00:00 2001 From: Tangles Date: Fri, 19 May 2017 23:01:24 +1000 Subject: [PATCH 55/69] curses - fix typo in colour initialisation --- win/curses/cursinit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index a749577b..4a64731e 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -411,7 +411,7 @@ curses_init_nhcolors() /* Work around the crazy definitions above for more background colors... */ for (i = 0; i < (COLORS >= 16 ? 16 : 8); i++) { init_pair((hicolor ? 49 : 9) + i, clr_remap[i], COLOR_GREEN); - init_pair((hicolor ? 33 : 33) + i, clr_remap[i], COLOR_YELLOW); + init_pair((hicolor ? 65 : 33) + i, clr_remap[i], COLOR_YELLOW); init_pair((hicolor ? 81 : 41) + i, clr_remap[i], COLOR_MAGENTA); init_pair((hicolor ? 97 : 49) + i, clr_remap[i], COLOR_CYAN); init_pair((hicolor ? 113 : 57) + i, clr_remap[i], COLOR_WHITE); From 006f9a10052297f657d0a913619815df6202404e Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Sun, 11 Jun 2017 22:43:17 +0200 Subject: [PATCH 56/69] Fix a bug where menuglyphs would screw up sidebar colors if menucolors was disabled --- win/curses/cursinvt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/win/curses/cursinvt.c b/win/curses/cursinvt.c index 20aefee2..7393a3e0 100644 --- a/win/curses/cursinvt.c +++ b/win/curses/cursinvt.c @@ -85,10 +85,10 @@ curses_add_inv(int y, int glyph, CHAR_P accelerator, attr_t attr, int symbol = 0; mapglyph(glyph, &symbol, &color, &dummy, u.ux, u.uy); - attr = curses_color_attr(color, 0); - wattron(win, attr); + attr_t glyphclr = curses_color_attr(color, 0); + wattron(win, glyphclr); wprintw(win, "%c ", symbol); - wattroff(win, attr); + wattroff(win, glyphclr); } #ifdef MENU_COLOR From c5c9e65d52804cce0905c1a463d0be473fae9205 Mon Sep 17 00:00:00 2001 From: Fredrik Ljungdahl Date: Mon, 12 Jun 2017 05:36:16 +0200 Subject: [PATCH 57/69] Fix a mistake in last commit From 77358345b0be9bd746619fa4266a120a2bac7d01 Mon Sep 17 00:00:00 2001 From: Tangles Date: Sat, 8 Jul 2017 11:55:43 +1000 Subject: [PATCH 58/69] curses - fix EXP_ON_BOTL code block --- win/curses/cursstat.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index 511e8b2d..b884ea36 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -581,8 +581,9 @@ draw_horizontal(int x, int y, int hp, int hpmax) /* use waddch, we don't want to highlight the '/' */ waddch(win, '/'); print_statdiff("", &prevexp, u.uexp, STAT_OTHER); + } #endif - } else + else print_statdiff(" Exp:", &prevlevel, u.ulevel, STAT_OTHER); if (flags.time) @@ -645,8 +646,9 @@ draw_horizontal_new(int x, int y, int hp, int hpmax) } print_statdiff("", &prevexp, xp_left, STAT_AC); waddch(win, ')'); + } #endif - } else + else print_statdiff(" Exp:", &prevlevel, u.ulevel, STAT_OTHER); waddch(win, ' '); @@ -823,8 +825,9 @@ draw_vertical(int x, int y, int hp, int hpmax) /* use waddch, we don't want to highlight the '/' */ waddch(win, '/'); print_statdiff("", &prevexp, u.uexp, STAT_OTHER); + } #endif - } else + else print_statdiff("Level: ", &prevlevel, u.ulevel, STAT_OTHER); wmove(win, y++, x); From 457b9919f80dc88024388215ad5a1f936fb064ef Mon Sep 17 00:00:00 2001 From: Tangles Date: Sun, 9 Jul 2017 23:09:22 +1000 Subject: [PATCH 59/69] curses - attempt to fix lag. Remove wrefresh() from putch, and make sure it only gets called when it needs to. --- src/display.c | 1 + win/curses/cursmain.c | 16 ++++++++++------ win/curses/curswins.c | 5 +++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/display.c b/src/display.c index f2bf94f8..66d17bde 100644 --- a/src/display.c +++ b/src/display.c @@ -1324,6 +1324,7 @@ row_refresh(start,stop,y) for (x = start; x <= stop; x++) if (gbuf[y][x].glyph != cmap_to_glyph(S_stone)) print_glyph(WIN_MAP,x,y,gbuf[y][x].glyph); + display_nhwindow(WIN_MAP,FALSE); } void diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index 5b859851..644f4655 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -280,7 +280,14 @@ void curses_display_nhwindow(winid wid, BOOLEAN_P block) { menu_item *selected = NULL; + if (curses_is_menu(wid) || curses_is_text(wid)) { + curses_end_menu(wid, ""); + curses_select_menu(wid, PICK_NONE, &selected); + return; + } + /* actually display the window */ + wrefresh(curses_get_nhwin(wid)); if ((wid == MAP_WIN) && block) { (void) curses_more(); } @@ -292,12 +299,6 @@ curses_display_nhwindow(winid wid, BOOLEAN_P block) else (void) curses_more(); } - - if (curses_is_menu(wid) || curses_is_text(wid)) { - curses_end_menu(wid, ""); - curses_select_menu(wid, PICK_NONE, &selected); - return; - } } @@ -740,6 +741,9 @@ delay_output() -- Causes a visible delay of 50ms in the output. void curses_delay_output() { + /* refreshing the whole display is a waste of time, + * but that's why we're here */ + refresh(); napms(50); } diff --git a/win/curses/curswins.c b/win/curses/curswins.c index 7e591841..e918fc9e 100644 --- a/win/curses/curswins.c +++ b/win/curses/curswins.c @@ -369,8 +369,9 @@ curses_putch(winid wid, int x, int y, int ch, int color, int attr) write_char(mapwin, x - sx, y - sy, nch); } - - wrefresh(mapwin); + /* refresh after every character? + * Fair go, mate! Some of us are playing from Australia! */ + /* wrefresh(mapwin); */ } From 08c65c6e70348fd17d031b25d73f7776b65c52c2 Mon Sep 17 00:00:00 2001 From: Tangles Date: Mon, 10 Jul 2017 18:51:45 +1000 Subject: [PATCH 60/69] curses - remove some more lag --- win/curses/cursinvt.c | 2 +- win/curses/cursmesg.c | 6 +++--- win/curses/cursstat.c | 2 +- win/curses/curswins.c | 10 ++++++---- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/win/curses/cursinvt.c b/win/curses/cursinvt.c index 7393a3e0..f1a022b2 100644 --- a/win/curses/cursinvt.c +++ b/win/curses/cursinvt.c @@ -53,7 +53,7 @@ curses_update_inv(void) if (border) box(win, 0, 0); - wrefresh(win); + wnoutrefresh(win); } /* Adds an inventory item. */ diff --git a/win/curses/cursmesg.c b/win/curses/cursmesg.c index 574bbcc1..a84b9808 100644 --- a/win/curses/cursmesg.c +++ b/win/curses/cursmesg.c @@ -121,7 +121,7 @@ curses_message_win_puts(const char *message, boolean recursed) if (height > 1) { curses_toggle_color_attr(win, NONE, A_BOLD, OFF); } - wrefresh(win); + //wrefresh(win); curses_message_win_puts(tmpstr = curses_str_remainder(message, (width - 2), 1), TRUE); free(tmpstr); @@ -154,7 +154,7 @@ curses_block(boolean require_tab) curses_clear_unhighlight_message_window(); } else { mvwprintw(win, my, mx, " "); - wrefresh(win); + //wrefresh(win); if (!require_tab) { scroll_window(MESSAGE_WIN); turn_lines = 1; @@ -206,7 +206,7 @@ curses_clear_unhighlight_message_window() } } - wrefresh(win); + wnoutrefresh(win); } } diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index b884ea36..36127d74 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -487,7 +487,7 @@ curses_update_stats(void) if (border) box(win, 0, 0); - wrefresh(win); + wnoutrefresh(win); if (first) { first = FALSE; diff --git a/win/curses/curswins.c b/win/curses/curswins.c index e918fc9e..c76b10ab 100644 --- a/win/curses/curswins.c +++ b/win/curses/curswins.c @@ -276,7 +276,8 @@ curses_add_wid(winid wid) void curses_refresh_nhwin(winid wid) { - wrefresh(curses_get_nhwin(wid)); + wnoutrefresh(curses_get_nhwin(wid)); + doupdate(); } @@ -477,7 +478,7 @@ curses_puts(winid wid, int attr, const char *text) FALSE); } else { waddstr(win, text); - wrefresh(win); + wnoutrefresh(win); } } @@ -508,14 +509,14 @@ curses_alert_win_border(winid wid, boolean onoff) { WINDOW *win = curses_get_nhwin(wid); - if (!curses_window_has_border(wid)) + if (!win || !curses_window_has_border(wid)) return; if (onoff) curses_toggle_color_attr(win, ALERT_BORDER_COLOR, NONE, ON); box(win, 0, 0); if (onoff) curses_toggle_color_attr(win, ALERT_BORDER_COLOR, NONE, OFF); - wrefresh(win); + wnoutrefresh(win); } @@ -525,6 +526,7 @@ curses_alert_main_borders(boolean onoff) curses_alert_win_border(MAP_WIN, onoff); curses_alert_win_border(MESSAGE_WIN, onoff); curses_alert_win_border(STATUS_WIN, onoff); + curses_alert_win_border(INV_WIN, onoff); } /* Return true if given wid is a main NetHack window */ From e39828e8f608ba20bd4edae7fa559314a13eea10 Mon Sep 17 00:00:00 2001 From: Tangles Date: Tue, 11 Jul 2017 01:21:52 +1000 Subject: [PATCH 61/69] curses - more wrefresh() tweakage --- win/curses/cursmain.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index 644f4655..efcb585b 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -287,7 +287,9 @@ curses_display_nhwindow(winid wid, BOOLEAN_P block) } /* actually display the window */ - wrefresh(curses_get_nhwin(wid)); + wnoutrefresh(curses_get_nhwin(wid)); + /* flush pending writes from other windows too */ + doupdate(); if ((wid == MAP_WIN) && block) { (void) curses_more(); } From 812dd5ae69831892cbfa6631c26eed8fe1080dc0 Mon Sep 17 00:00:00 2001 From: Tangles Date: Tue, 11 Jul 2017 01:22:52 +1000 Subject: [PATCH 62/69] curses - add inventory window to "all main windows" operations. --- win/curses/curswins.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/win/curses/curswins.c b/win/curses/curswins.c index c76b10ab..f7f03953 100644 --- a/win/curses/curswins.c +++ b/win/curses/curswins.c @@ -154,11 +154,12 @@ curses_destroy_win(WINDOW * win) void curses_refresh_nethack_windows() { - WINDOW *status_window, *message_window, *map_window; + WINDOW *status_window, *message_window, *map_window, *inv_window; status_window = curses_get_nhwin(STATUS_WIN); message_window = curses_get_nhwin(MESSAGE_WIN); map_window = curses_get_nhwin(MAP_WIN); + inv_window = curses_get_nhwin(INV_WIN); if ((moves <= 1) && !invent) { /* Main windows not yet displayed; refresh base window instead */ @@ -171,6 +172,10 @@ curses_refresh_nethack_windows() wnoutrefresh(map_window); touchwin(message_window); wnoutrefresh(message_window); + if (inv_window) { + touchwin(inv_window); + wnoutrefresh(inv_window); + } doupdate(); } } From 6ce781ccdd097de67c988b0ba1e59c72f799857f Mon Sep 17 00:00:00 2001 From: Tangles Date: Tue, 11 Jul 2017 01:28:55 +1000 Subject: [PATCH 63/69] curses - remove code commented out in earlier commits. --- win/curses/cursmesg.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/win/curses/cursmesg.c b/win/curses/cursmesg.c index a84b9808..990c565e 100644 --- a/win/curses/cursmesg.c +++ b/win/curses/cursmesg.c @@ -121,7 +121,6 @@ curses_message_win_puts(const char *message, boolean recursed) if (height > 1) { curses_toggle_color_attr(win, NONE, A_BOLD, OFF); } - //wrefresh(win); curses_message_win_puts(tmpstr = curses_str_remainder(message, (width - 2), 1), TRUE); free(tmpstr); @@ -154,7 +153,6 @@ curses_block(boolean require_tab) curses_clear_unhighlight_message_window(); } else { mvwprintw(win, my, mx, " "); - //wrefresh(win); if (!require_tab) { scroll_window(MESSAGE_WIN); turn_lines = 1; From 9853fe89d7a23bd6e79b263e103053e82364e654 Mon Sep 17 00:00:00 2001 From: Tangles Date: Fri, 14 Sep 2018 01:28:07 +1000 Subject: [PATCH 64/69] Fix crash bug in tty menus This would occur when an item's description was just less than the terminal width, but the description + accelerator + glyph + padding was just more than the terminal width. I believe this fix captures what was originally intended. --- win/tty/wintty.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/win/tty/wintty.c b/win/tty/wintty.c index 71b3d4ec..58bfc798 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -2308,7 +2308,8 @@ tty_end_menu(window, prompt) } if (len > (int)ttyDisplay->cols) { - curr->str[ttyDisplay->cols-2] = 0; + /* reduce the string by the amount len exceeds cols */ + curr->str[strlen(curr->str) - (len - ttyDisplay->cols)] = 0; len = ttyDisplay->cols; } if (len > cw->cols) cw->cols = len; From f59d9b76abfacff12d6d0aadb84745ae94266972 Mon Sep 17 00:00:00 2001 From: Tangles Date: Sat, 12 May 2018 16:52:16 +1000 Subject: [PATCH 65/69] msgtype=stop/alert improvememnts. - New msgtype 'alert', designed to fully grab player's attention for particular messages - curses - implement msgtype=alert to colour window borders orange and prompt for (this is the old msgtype=stop behaviour) - change msgtype=stop to behave the same as "-more-" (the '>>' prompt) - change behaviour of '>>' prompt (msgtype=stop, or msg window full), to only accept space or enter, instead of just any key, to prevent unintentional eating of keystrokes that were intended for something else. Also allow ESC here to dismiss all messages to end of turn. - tty - implement msgtype=alert to prompt for (and display prompt in orange) (this is the same bahaviour as curses, minus the window border effects) --- include/decl.h | 1 + include/flag.h | 3 +++ src/files.c | 2 ++ src/options.c | 1 + src/pline.c | 10 +++++++++- win/curses/cursmesg.c | 21 ++++++++++++++------- win/tty/topl.c | 16 +++++++++++----- 7 files changed, 41 insertions(+), 13 deletions(-) diff --git a/include/decl.h b/include/decl.h index 2cc539b5..c1286cdf 100644 --- a/include/decl.h +++ b/include/decl.h @@ -479,6 +479,7 @@ E struct _plinemsg *pline_msg; #define MSGTYP_NOREP 1 #define MSGTYP_NOSHOW 2 #define MSGTYP_STOP 3 +#define MSGTYP_ALERT 4 /* FIXME: These should be integrated into objclass and permonst structs, diff --git a/include/flag.h b/include/flag.h index ee651939..efb09173 100644 --- a/include/flag.h +++ b/include/flag.h @@ -343,6 +343,9 @@ struct instance_flags { #ifdef REALTIME_ON_BOTL boolean showrealtime; /* show actual elapsed time */ #endif + boolean msg_is_alert; /* suggest windowport should grab player's attention + * and request acknowlegement */ + }; /* diff --git a/src/files.c b/src/files.c index d0e356ec..8fed4eec 100644 --- a/src/files.c +++ b/src/files.c @@ -1998,6 +1998,8 @@ char *tmp_levels; else if (!strcasecmp("noshow", msgtype)) typ = MSGTYP_NOSHOW; else if (!strcasecmp("more", msgtype)) typ = MSGTYP_STOP; else if (!strcasecmp("stop", msgtype)) typ = MSGTYP_STOP; + /* 'alert' will fallback to 'stop' behaviour if windowport does not support it */ + else if (!strcasecmp("alert", msgtype)) typ = MSGTYP_ALERT; if ((typ != MSGTYP_NORMAL) || !strcasecmp("show", msgtype)) { msgpline_add(typ, pattern); } diff --git a/src/options.c b/src/options.c index 44867814..99c42a50 100644 --- a/src/options.c +++ b/src/options.c @@ -640,6 +640,7 @@ initoptions() #ifdef SORTLOOT iflags.sortloot = 'n'; #endif + iflags.msg_is_alert = FALSE; /* assert( sizeof flags.inv_order == sizeof def_inv_order ); */ (void)memcpy((genericptr_t)flags.inv_order, diff --git a/src/pline.c b/src/pline.c index a7b15645..283c4fe0 100644 --- a/src/pline.c +++ b/src/pline.c @@ -218,7 +218,15 @@ pline VA_DECL(const char *, line) putstr(WIN_MESSAGE, 0, line); strncpy(prevmsg, line, BUFSZ); - if (typ == MSGTYP_STOP) display_nhwindow(WIN_MESSAGE, TRUE); /* --more-- */ + switch (typ) { + case MSGTYP_ALERT: + iflags.msg_is_alert = TRUE; /* */ + /* FT */ + case MSGTYP_STOP: + display_nhwindow(WIN_MESSAGE, TRUE); /* --more-- */ + break; + } + iflags.msg_is_alert = FALSE; } /*VARARGS1*/ diff --git a/win/curses/cursmesg.c b/win/curses/cursmesg.c index 990c565e..03343dcc 100644 --- a/win/curses/cursmesg.c +++ b/win/curses/cursmesg.c @@ -134,26 +134,33 @@ curses_message_win_puts(const char *message, boolean recursed) int -curses_block(boolean require_tab) +curses_block(boolean noscroll) +/* noscroll - blocking because of msgtype = stop/alert */ +/* else blocking because window is full, so need to scroll after */ { - int height, width, ret; + int height, width, ret = 0; WINDOW *win = curses_get_nhwin(MESSAGE_WIN); + char *resp = " \n\033"; /* space, enter, esc */ curses_get_window_size(MESSAGE_WIN, &height, &width); curses_toggle_color_attr(win, MORECOLOR, NONE, ON); - mvwprintw(win, my, mx, require_tab ? "" : ">>"); + mvwprintw(win, my, mx, iflags.msg_is_alert ? "" : ">>"); curses_toggle_color_attr(win, MORECOLOR, NONE, OFF); - if (require_tab) + if (iflags.msg_is_alert) curses_alert_main_borders(TRUE); wrefresh(win); - while ((ret = wgetch(win) != '\t') && require_tab); - if (require_tab) + while (iflags.msg_is_alert && (ret = wgetch(win) != '\t')); + /* msgtype=stop should require space/enter rather than + * just any key, as we want to prevent YASD from + * riding direction keys. */ + while (!iflags.msg_is_alert && (ret = wgetch(win)) && !index(resp,(char)ret)); + if (iflags.msg_is_alert) curses_alert_main_borders(FALSE); if (height == 1) { curses_clear_unhighlight_message_window(); } else { mvwprintw(win, my, mx, " "); - if (!require_tab) { + if (noscroll) { scroll_window(MESSAGE_WIN); turn_lines = 1; } diff --git a/win/tty/topl.c b/win/tty/topl.c index 46b05189..632660a8 100644 --- a/win/tty/topl.c +++ b/win/tty/topl.c @@ -188,11 +188,17 @@ more() if(flags.standout) standoutbeg(); - putsyms(defmorestr); - if(flags.standout) - standoutend(); - - xwaitforspace("\033 "); + if (iflags.msg_is_alert) { + term_start_color(CLR_ORANGE); + putsyms(""); + term_end_color(); + xwaitforspace("\t"); + } else { + putsyms(defmorestr); + xwaitforspace("\033 "); + } + if (flags.standout) + standoutend(); if(morc == '\033') cw->flags |= WIN_STOP; From bd50d24fa3e8679d88197f9c732cf9ef018b10c8 Mon Sep 17 00:00:00 2001 From: Tangles Date: Wed, 25 Jul 2018 22:06:33 +1000 Subject: [PATCH 66/69] curses - change some panics to impossibles. --- win/curses/cursdial.c | 33 ++++++++++++++++++++------------- win/curses/cursmisc.c | 4 ++-- win/curses/curswins.c | 35 +++++++++++++++++++++++------------ 3 files changed, 45 insertions(+), 27 deletions(-) diff --git a/win/curses/cursdial.c b/win/curses/cursdial.c index 1bd0af38..4976623d 100644 --- a/win/curses/cursdial.c +++ b/win/curses/cursdial.c @@ -491,6 +491,12 @@ curses_add_nhmenu_item(winid wid, int glyph, const ANY_P * identifier, nhmenu_item *new_item, *current_items, *menu_item_ptr; nhmenu *current_menu = get_menu(wid); + if (current_menu == NULL) { + impossible + ("curses_add_nhmenu_item: attempt to add item to nonexistent menu"); + return; + } + if (str == NULL) { return; } @@ -513,11 +519,6 @@ curses_add_nhmenu_item(winid wid, int glyph, const ANY_P * identifier, new_item->count = -1; new_item->next_item = NULL; - if (current_menu == NULL) { - panic - ("curses_add_nhmenu_item: attempt to add item to nonexistant menu"); - } - current_items = current_menu->entries; menu_item_ptr = current_items; @@ -542,12 +543,13 @@ curses_finalize_nhmenu(winid wid, const char *prompt) { int count = 0; nhmenu *current_menu = get_menu(wid); - nhmenu_item *menu_item_ptr = current_menu->entries; if (current_menu == NULL) { - panic("curses_finalize_nhmenu: attempt to finalize nonexistant menu"); + impossible("curses_finalize_nhmenu: attempt to finalize nonexistent menu"); + return; } + nhmenu_item *menu_item_ptr = current_menu->entries; while (menu_item_ptr != NULL) { menu_item_ptr = menu_item_ptr->next_item; count++; @@ -573,13 +575,15 @@ curses_display_nhmenu(winid wid, int how, MENU_ITEM_P ** _selected) *_selected = NULL; if (current_menu == NULL) { - panic("curses_display_nhmenu: attempt to display nonexistant menu"); + impossible("curses_display_nhmenu: attempt to display nonexistent menu"); + return; } menu_item_ptr = current_menu->entries; if (menu_item_ptr == NULL) { - panic("curses_display_nhmenu: attempt to display empty menu"); + impossible("curses_display_nhmenu: attempt to display empty menu"); + return; } /* Reset items to unselected to clear out selections from previous @@ -614,8 +618,9 @@ curses_display_nhmenu(winid wid, int how, MENU_ITEM_P ** _selected) while (menu_item_ptr != NULL) { if (menu_item_ptr->selected) { if (count == num_chosen) { - panic("curses_display_nhmenu: Selected items " + impossible("curses_display_nhmenu: Selected items " "exceeds expected number"); + break; } selected[count].item = menu_item_ptr->identifier; selected[count].count = menu_item_ptr->count; @@ -625,7 +630,7 @@ curses_display_nhmenu(winid wid, int how, MENU_ITEM_P ** _selected) } if (count != num_chosen) { - panic("curses_display_nhmenu: Selected items less than " + impossible("curses_display_nhmenu: Selected items less than " "expected number"); } } @@ -932,7 +937,8 @@ menu_display_page(nhmenu *menu, WINDOW * win, int page_num) } if (menu_item_ptr == NULL) { /* Page not found */ - panic("menu_display_page: attempt to display nonexistant page"); + impossible("menu_display_page: attempt to display nonexistent page"); + return; } werase(win); @@ -1326,7 +1332,8 @@ menu_operation(WINDOW * win, nhmenu *menu, menu_op } if (menu_item_ptr == NULL) { /* Page not found */ - panic("menu_display_page: attempt to display nonexistant page"); + impossible("menu_display_page: attempt to display nonexistent page"); + return 0; } while (menu_item_ptr != NULL) { diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index 9040fa7a..374d75b7 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -185,8 +185,8 @@ curses_get_wid(int type) ret = text_wid; break; default: - panic("curses_get_wid: unsupported window type"); - ret = -1; /* Not reached */ + impossible("curses_get_wid: unsupported window type"); + ret = -1; } while (curses_window_exists(ret)) { diff --git a/win/curses/curswins.c b/win/curses/curswins.c index f7f03953..961a99cd 100644 --- a/win/curses/curswins.c +++ b/win/curses/curswins.c @@ -75,9 +75,15 @@ curses_create_window(int width, int height, orient orientation) width += 2; /* leave room for bounding box */ height += 2; - if ((width > term_cols) || (height > term_rows)) - panic("curses_create_window: Terminal too small for dialog window"); + if ((width > term_cols) || (height > term_rows)) { + impossible("curses_create_window: Terminal too small for dialog window"); + width = term_cols; + height = term_rows; + } switch (orientation) { + default: + impossible("curses_create_window: Bad orientation"); + /* fall through to centre */ case CENTER: startx = (term_cols / 2) - (width / 2); starty = (term_rows / 2) - (height / 2); @@ -116,9 +122,6 @@ curses_create_window(int width, int height, orient orientation) starty = 0; break; - default: - panic("curses_create_window: Bad orientation"); - break; } if (startx < 0) { @@ -187,7 +190,8 @@ WINDOW * curses_get_nhwin(winid wid) { if (!is_main_window(wid)) { - panic("curses_get_nhwin: wid out of range. Not a main window."); + impossible("curses_get_nhwin: wid %d out of range. Not a main window.", wid); + return NULL; } return nhwins[wid].curwin; @@ -205,7 +209,8 @@ curses_add_nhwin(winid wid, int height, int width, int y, int x, int real_height = height; if (!is_main_window(wid)) { - panic("curses_add_nhwin: wid out of range. Not a main window."); + impossible("curses_add_nhwin: wid %d out of range. Not a main window.", wid); + return; } nhwins[wid].nhwin = wid; @@ -297,7 +302,8 @@ curses_del_nhwin(winid wid) } if (!is_main_window(wid)) { - panic("curses_del_nhwin: wid out of range. Not a main window."); + impossible("curses_del_nhwin: wid %d out of range. Not a main window.", wid); + return; } nhwins[wid].curwin = NULL; @@ -387,7 +393,10 @@ void curses_get_window_xy(winid wid, int *x, int *y) { if (!is_main_window(wid)) { - panic("curses_get_window_xy: wid out of range. Not a main window."); + impossible("curses_get_window_xy: wid %d out of range. Not a main window.", wid); + *x = 0; + *y = 0; + return; } *x = nhwins[wid].x; @@ -439,8 +448,9 @@ int curses_get_window_orientation(winid wid) { if (!is_main_window(wid)) { - panic - ("curses_get_window_orientation: wid out of range. Not a main window."); + impossible + ("curses_get_window_orientation: wid %d out of range. Not a main window.", wid); + return CENTER; } return nhwins[wid].orientation; @@ -475,7 +485,8 @@ curses_puts(winid wid, int attr, const char *text) if (curses_is_menu(wid) || curses_is_text(wid)) { if (!curses_menu_exists(wid)) { - panic("curses_puts: Attempted write to nonexistant window!"); + impossible("curses_puts: Attempted write to nonexistant window %d!", wid); + return; } identifier = malloc(sizeof (anything)); identifier->a_void = NULL; From 0fd8610260f702c49e2f755fd966074d6075da5c Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 2 Dec 2018 18:47:23 -0500 Subject: [PATCH 67/69] 'curses_display_nhmenu' should return a value Caught by automated build test ../win/curses/cursdial.c:598:9: error: non-void function 'curses_display_nhmenu' should return a value [-Wreturn-type] return; ^ ../win/curses/cursdial.c:605:9: error: non-void function 'curses_display_nhmenu' should return a value [-Wreturn-type] return; --- win/curses/cursdial.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/win/curses/cursdial.c b/win/curses/cursdial.c index 4976623d..329b122d 100644 --- a/win/curses/cursdial.c +++ b/win/curses/cursdial.c @@ -576,14 +576,14 @@ curses_display_nhmenu(winid wid, int how, MENU_ITEM_P ** _selected) if (current_menu == NULL) { impossible("curses_display_nhmenu: attempt to display nonexistent menu"); - return; + return '\033'; } menu_item_ptr = current_menu->entries; if (menu_item_ptr == NULL) { impossible("curses_display_nhmenu: attempt to display empty menu"); - return; + return '\033'; } /* Reset items to unselected to clear out selections from previous From a5ed71feecd0d03e3dadbd6ddf9d2cc7058f3e72 Mon Sep 17 00:00:00 2001 From: Tangles Date: Wed, 12 Jun 2019 00:04:09 +1000 Subject: [PATCH 68/69] curses - fix logic reversal that was preventing msgwin scrolling --- win/curses/cursmesg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/curses/cursmesg.c b/win/curses/cursmesg.c index 03343dcc..c51e4496 100644 --- a/win/curses/cursmesg.c +++ b/win/curses/cursmesg.c @@ -160,7 +160,7 @@ curses_block(boolean noscroll) curses_clear_unhighlight_message_window(); } else { mvwprintw(win, my, mx, " "); - if (noscroll) { + if (!noscroll) { scroll_window(MESSAGE_WIN); turn_lines = 1; } From a3f20b2c8867936facdd8e83d5b51a315914a6fa Mon Sep 17 00:00:00 2001 From: k21971 Date: Fri, 24 May 2019 12:51:40 -0400 Subject: [PATCH 69/69] Fix: bounds checking on thrown object Authored by Tangles - remove 'else' that meant thrown objects would not be checked for walls/doors/sinks/iron bars/edge of map when missing hero or monster. This issue has caused a number of known segfaults with thrown boulders on plane of fire and in valkyrie quest. --- src/mthrowu.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/mthrowu.c b/src/mthrowu.c index 953e01d4..8582e9a2 100644 --- a/src/mthrowu.c +++ b/src/mthrowu.c @@ -421,21 +421,22 @@ m_throw(mon, x, y, dx, dy, range, obj) (void) drop_throw(singleobj, hitu, u.ux, u.uy); break; } - } else if (!range /* reached end of path */ - /* missile hits edge of screen */ - || !isok(bhitpos.x+dx,bhitpos.y+dy) - /* missile hits the wall */ - || IS_ROCK(levl[bhitpos.x+dx][bhitpos.y+dy].typ) - /* missile hit closed door */ - || closed_door(bhitpos.x+dx, bhitpos.y+dy) - /* missile might hit iron bars */ - || (levl[bhitpos.x+dx][bhitpos.y+dy].typ == IRONBARS && - hits_bars(&singleobj, bhitpos.x, bhitpos.y, !rn2(5), 0)) + } + if (!range /* reached end of path */ + /* missile hits edge of screen */ + || !isok(bhitpos.x+dx,bhitpos.y+dy) + /* missile hits the wall */ + || IS_ROCK(levl[bhitpos.x+dx][bhitpos.y+dy].typ) + /* missile hit closed door */ + || closed_door(bhitpos.x+dx, bhitpos.y+dy) + /* missile might hit iron bars */ + || (levl[bhitpos.x+dx][bhitpos.y+dy].typ == IRONBARS && + hits_bars(&singleobj, bhitpos.x, bhitpos.y, !rn2(5), 0)) #ifdef SINKS - /* Thrown objects "sink" */ - || IS_SINK(levl[bhitpos.x][bhitpos.y].typ) + /* Thrown objects "sink" */ + || IS_SINK(levl[bhitpos.x][bhitpos.y].typ) #endif - ) { + ) { if (singleobj) /* hits_bars might have destroyed it */ (void) drop_throw(singleobj, 0, bhitpos.x, bhitpos.y); break;