Mercurial > hg > early-roguelike
comparison rogue5/io.c @ 33:f502bf60e6e4
Import Rogue 5.4 from the Roguelike Restoration Project (r1490)
| author | elwin |
|---|---|
| date | Mon, 24 May 2010 20:10:59 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 32:2dcd75e6a736 | 33:f502bf60e6e4 |
|---|---|
| 1 /* | |
| 2 * Various input/output functions | |
| 3 * | |
| 4 * @(#)io.c 4.32 (Berkeley) 02/05/99 | |
| 5 */ | |
| 6 | |
| 7 #include <stdarg.h> | |
| 8 #include <curses.h> | |
| 9 #include <ctype.h> | |
| 10 #include <string.h> | |
| 11 #include "rogue.h" | |
| 12 | |
| 13 /* | |
| 14 * msg: | |
| 15 * Display a message at the top of the screen. | |
| 16 */ | |
| 17 #define MAXMSG (NUMCOLS - sizeof "--More--") | |
| 18 | |
| 19 static char msgbuf[2*MAXMSG+1]; | |
| 20 static int newpos = 0; | |
| 21 | |
| 22 /* VARARGS1 */ | |
| 23 int | |
| 24 msg(const char *fmt, ...) | |
| 25 { | |
| 26 va_list args; | |
| 27 | |
| 28 /* | |
| 29 * if the string is "", just clear the line | |
| 30 */ | |
| 31 if (*fmt == '\0') | |
| 32 { | |
| 33 move(0, 0); | |
| 34 clrtoeol(); | |
| 35 mpos = 0; | |
| 36 return ~ESCAPE; | |
| 37 } | |
| 38 /* | |
| 39 * otherwise add to the message and flush it out | |
| 40 */ | |
| 41 va_start(args, fmt); | |
| 42 doadd(fmt, args); | |
| 43 va_end(args); | |
| 44 return endmsg(); | |
| 45 } | |
| 46 | |
| 47 /* | |
| 48 * addmsg: | |
| 49 * Add things to the current message | |
| 50 */ | |
| 51 /* VARARGS1 */ | |
| 52 void | |
| 53 addmsg(const char *fmt, ...) | |
| 54 { | |
| 55 va_list args; | |
| 56 | |
| 57 va_start(args, fmt); | |
| 58 doadd(fmt, args); | |
| 59 va_end(args); | |
| 60 } | |
| 61 | |
| 62 /* | |
| 63 * endmsg: | |
| 64 * Display a new msg (giving him a chance to see the previous one | |
| 65 * if it is up there with the --More--) | |
| 66 */ | |
| 67 int | |
| 68 endmsg(void) | |
| 69 { | |
| 70 int ch; | |
| 71 | |
| 72 if (save_msg) | |
| 73 strcpy(huh, msgbuf); | |
| 74 if (mpos) | |
| 75 { | |
| 76 look(FALSE); | |
| 77 mvaddstr(0, mpos, "--More--"); | |
| 78 refresh(); | |
| 79 if (!msg_esc) | |
| 80 wait_for(stdscr, ' '); | |
| 81 else | |
| 82 { | |
| 83 while ((ch = readchar()) != ' ') | |
| 84 if (ch == ESCAPE) | |
| 85 { | |
| 86 msgbuf[0] = '\0'; | |
| 87 mpos = 0; | |
| 88 newpos = 0; | |
| 89 msgbuf[0] = '\0'; | |
| 90 return ESCAPE; | |
| 91 } | |
| 92 } | |
| 93 } | |
| 94 /* | |
| 95 * All messages should start with uppercase, except ones that | |
| 96 * start with a pack addressing character | |
| 97 */ | |
| 98 if (islower((int)msgbuf[0]) && !lower_msg && msgbuf[1] != ')') | |
| 99 msgbuf[0] = (char) toupper(msgbuf[0]); | |
| 100 mvaddstr(0, 0, msgbuf); | |
| 101 clrtoeol(); | |
| 102 mpos = newpos; | |
| 103 newpos = 0; | |
| 104 msgbuf[0] = '\0'; | |
| 105 refresh(); | |
| 106 return ~ESCAPE; | |
| 107 } | |
| 108 | |
| 109 /* | |
| 110 * doadd: | |
| 111 * Perform an add onto the message buffer | |
| 112 */ | |
| 113 void | |
| 114 doadd(const char *fmt, va_list args) | |
| 115 { | |
| 116 static char buf[MAXSTR]; | |
| 117 | |
| 118 /* | |
| 119 * Do the printf into buf | |
| 120 */ | |
| 121 vsprintf(buf, fmt, args); | |
| 122 if (strlen(buf) + newpos >= MAXMSG) | |
| 123 endmsg(); | |
| 124 strcat(msgbuf, buf); | |
| 125 newpos = (int) strlen(msgbuf); | |
| 126 } | |
| 127 | |
| 128 /* | |
| 129 * step_ok: | |
| 130 * Returns true if it is ok to step on ch | |
| 131 */ | |
| 132 int | |
| 133 step_ok(int ch) | |
| 134 { | |
| 135 switch (ch) | |
| 136 { | |
| 137 case ' ': | |
| 138 case '|': | |
| 139 case '-': | |
| 140 return FALSE; | |
| 141 default: | |
| 142 return (!isalpha(ch)); | |
| 143 } | |
| 144 } | |
| 145 | |
| 146 /* | |
| 147 * readchar: | |
| 148 * Reads and returns a character, checking for gross input errors | |
| 149 */ | |
| 150 | |
| 151 int | |
| 152 readchar(void) | |
| 153 { | |
| 154 int ch; | |
| 155 | |
| 156 ch = md_readchar(stdscr); | |
| 157 | |
| 158 if (ch == 3) | |
| 159 { | |
| 160 quit(0); | |
| 161 return(27); | |
| 162 } | |
| 163 | |
| 164 return(ch); | |
| 165 } | |
| 166 | |
| 167 int | |
| 168 wreadchar(WINDOW *win) | |
| 169 { | |
| 170 int ch; | |
| 171 | |
| 172 ch = md_readchar(win); | |
| 173 | |
| 174 if (ch == 3) | |
| 175 { | |
| 176 quit(0); | |
| 177 return(27); | |
| 178 } | |
| 179 | |
| 180 return(ch); | |
| 181 } | |
| 182 | |
| 183 | |
| 184 /* | |
| 185 * status: | |
| 186 * Display the important stats line. Keep the cursor where it was. | |
| 187 */ | |
| 188 void | |
| 189 status(void) | |
| 190 { | |
| 191 int oy, ox, temp; | |
| 192 static int hpwidth = 0; | |
| 193 static int s_hungry = 0; | |
| 194 static int s_lvl = 0; | |
| 195 static int s_pur = -1; | |
| 196 static int s_hp = 0; | |
| 197 static int s_arm = 0; | |
| 198 static int s_str = 0; | |
| 199 static int s_exp = 0; | |
| 200 static char *state_name[] = | |
| 201 { | |
| 202 "", "Hungry", "Weak", "Faint" | |
| 203 }; | |
| 204 | |
| 205 /* | |
| 206 * If nothing has changed since the last status, don't | |
| 207 * bother. | |
| 208 */ | |
| 209 temp = (cur_armor != NULL ? cur_armor->o_arm : pstats.s_arm); | |
| 210 if (s_hp == pstats.s_hpt && s_exp == pstats.s_exp && s_pur == purse | |
| 211 && s_arm == temp && s_str == pstats.s_str && s_lvl == level | |
| 212 && s_hungry == hungry_state | |
| 213 && !stat_msg | |
| 214 ) | |
| 215 return; | |
| 216 | |
| 217 s_arm = temp; | |
| 218 | |
| 219 getyx(stdscr, oy, ox); | |
| 220 if (s_hp != max_hp) | |
| 221 { | |
| 222 temp = max_hp; | |
| 223 s_hp = max_hp; | |
| 224 for (hpwidth = 0; temp; hpwidth++) | |
| 225 temp /= 10; | |
| 226 } | |
| 227 | |
| 228 /* | |
| 229 * Save current status | |
| 230 */ | |
| 231 s_lvl = level; | |
| 232 s_pur = purse; | |
| 233 s_hp = pstats.s_hpt; | |
| 234 s_str = pstats.s_str; | |
| 235 s_exp = pstats.s_exp; | |
| 236 s_hungry = hungry_state; | |
| 237 | |
| 238 if (stat_msg) | |
| 239 { | |
| 240 move(0, 0); | |
| 241 msg("Level: %d Gold: %-5d Hp: %*d(%*d) Str: %2d(%d) Arm: %-2d Exp: %d/%d %s", | |
| 242 level, purse, hpwidth, pstats.s_hpt, hpwidth, max_hp, pstats.s_str, | |
| 243 max_stats.s_str, 10 - s_arm, pstats.s_lvl, pstats.s_exp, | |
| 244 state_name[hungry_state]); | |
| 245 } | |
| 246 else | |
| 247 { | |
| 248 move(STATLINE, 0); | |
| 249 | |
| 250 printw("Level: %d Gold: %-5d Hp: %*d(%*d) Str: %2d(%d) Arm: %-2d Exp: %d/%d %s", | |
| 251 level, purse, hpwidth, pstats.s_hpt, hpwidth, max_hp, pstats.s_str, | |
| 252 max_stats.s_str, 10 - s_arm, pstats.s_lvl, pstats.s_exp, | |
| 253 state_name[hungry_state]); | |
| 254 } | |
| 255 | |
| 256 clrtoeol(); | |
| 257 move(oy, ox); | |
| 258 } | |
| 259 | |
| 260 /* | |
| 261 * wait_for | |
| 262 * Sit around until the guy types the right key | |
| 263 */ | |
| 264 void | |
| 265 wait_for(WINDOW *win, int ch) | |
| 266 { | |
| 267 int c; | |
| 268 | |
| 269 if (ch == '\n') | |
| 270 while ((c = wreadchar(win)) != '\n' && c != '\r') | |
| 271 continue; | |
| 272 else | |
| 273 while (wreadchar(win) != ch) | |
| 274 continue; | |
| 275 } | |
| 276 | |
| 277 /* | |
| 278 * show_win: | |
| 279 * Function used to display a window and wait before returning | |
| 280 */ | |
| 281 void | |
| 282 show_win(const char *message) | |
| 283 { | |
| 284 WINDOW *win; | |
| 285 | |
| 286 win = hw; | |
| 287 wmove(win, 0, 0); | |
| 288 waddstr(win, message); | |
| 289 touchwin(win); | |
| 290 wrefresh(win); | |
| 291 wait_for(win, ' '); | |
| 292 clearok(curscr, TRUE); | |
| 293 touchwin(stdscr); | |
| 294 } |
