1 /*- 2 * Copyright (c) 1988, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Timothy C. Stoehr. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * @(#)message.c 8.1 (Berkeley) 5/31/93 33 * $FreeBSD: src/games/rogue/message.c,v 1.7.2.1 2000/07/20 10:35:07 kris Exp $ 34 */ 35 36 /* 37 * message.c 38 * 39 * This source herein may be modified and/or distributed by anybody who 40 * so desires, with the following restrictions: 41 * 1.) No portion of this notice shall be removed. 42 * 2.) Credit shall not be taken for the creation of this source. 43 * 3.) This code is not to be traded, sold, or used for personal 44 * gain or profit. 45 * 46 */ 47 48 #include <stdio.h> 49 #include "rogue.h" 50 #include "pathnames.h" 51 52 static char msgs[NMESSAGES][DCOLS] = {"", "", "", "", ""}; 53 static short msg_col = 0, imsg = -1; 54 static boolean rmsg = 0; 55 56 boolean msg_cleared = 1; 57 char hunger_str[HUNGER_STR_LEN] = ""; 58 const char *more = "-more-"; 59 60 static void pad(const char *, short); 61 static void save_screen(void); 62 63 void 64 message(const char *msg, boolean intrpt) 65 { 66 cant_int = 1; 67 68 if (!save_is_interactive) { 69 return; 70 } 71 if (intrpt) { 72 interrupted = 1; 73 if (flush) 74 md_slurp(); 75 } 76 77 if (!msg_cleared) { 78 mvaddstr(MIN_ROW-1, msg_col, more); 79 refresh(); 80 wait_for_ack(); 81 check_message(); 82 } 83 if (!rmsg) { 84 imsg = (imsg + 1) % NMESSAGES; 85 strcpy(msgs[imsg], msg); 86 } 87 mvaddstr(MIN_ROW-1, 0, msg); 88 addch(' '); 89 refresh(); 90 msg_cleared = 0; 91 msg_col = strlen(msg); 92 93 cant_int = 0; 94 95 if (did_int) { 96 did_int = 0; 97 onintr(0); 98 } 99 } 100 101 void 102 remessage(short c) 103 { 104 if (imsg != -1) { 105 check_message(); 106 rmsg = 1; 107 while (c > imsg) { 108 c -= NMESSAGES; 109 } 110 message(msgs[((imsg - c) % NMESSAGES)], 0); 111 rmsg = 0; 112 move(rogue.row, rogue.col); 113 refresh(); 114 } 115 } 116 117 void 118 check_message(void) 119 { 120 if (msg_cleared) { 121 return; 122 } 123 move(MIN_ROW-1, 0); 124 clrtoeol(); 125 refresh(); 126 msg_cleared = 1; 127 } 128 129 short 130 get_input_line(const char *prompt, const char *insert, char *buf, 131 const char *if_cancelled, boolean add_blank, boolean do_echo) 132 { 133 short ch; 134 short i = 0, n; 135 136 message(prompt, 0); 137 n = strlen(prompt); 138 139 if (insert[0]) { 140 mvaddstr(0, n + 1, insert); 141 strcpy(buf, insert); 142 i = strlen(insert); 143 move(0, (n + i + 1)); 144 refresh(); 145 } 146 147 while (((ch = rgetchar()) != '\r') && (ch != '\n') && (ch != CANCEL)) { 148 if ((ch >= ' ') && (ch <= '~') && (i < MAX_TITLE_LENGTH-2)) { 149 if ((ch != ' ') || (i > 0)) { 150 buf[i++] = ch; 151 if (do_echo) { 152 addch(ch); 153 } 154 } 155 } 156 if ((ch == '\b') && (i > 0)) { 157 if (do_echo) { 158 mvaddch(0, i + n, ' '); 159 move(MIN_ROW-1, i+n); 160 } 161 i--; 162 } 163 refresh(); 164 } 165 check_message(); 166 if (add_blank) { 167 buf[i++] = ' '; 168 } else { 169 while ((i > 0) && (buf[i-1] == ' ')) { 170 i--; 171 } 172 } 173 174 buf[i] = 0; 175 176 if ((ch == CANCEL) || (i == 0) || ((i == 1) && add_blank)) { 177 if (if_cancelled) { 178 message(if_cancelled, 0); 179 } 180 return(0); 181 } 182 return(i); 183 } 184 185 int 186 rgetchar(void) 187 { 188 int ch; 189 190 for(;;) { 191 ch = getchar(); 192 193 switch(ch) { 194 case '\022': 195 wrefresh(curscr); 196 break; 197 #ifdef UNIX_BSD4_2 198 case '\032': 199 printf("%s", CL); 200 fflush(stdout); 201 tstp(); 202 break; 203 #endif 204 case '&': 205 save_screen(); 206 break; 207 default: 208 return(ch); 209 } 210 } 211 } 212 213 /* 214 Level: 99 Gold: 999999 Hp: 999(999) Str: 99(99) Arm: 99 Exp: 21/10000000 Hungry 215 0 5 1 5 2 5 3 5 4 5 5 5 6 5 7 5 216 */ 217 218 void 219 print_stats(int stat_mask) 220 { 221 char buf[16]; 222 boolean label; 223 int row = DROWS - 1; 224 225 label = (stat_mask & STAT_LABEL) ? 1 : 0; 226 227 if (stat_mask & STAT_LEVEL) { 228 if (label) { 229 mvaddstr(row, 0, "Level: "); 230 } 231 /* max level taken care of in make_level() */ 232 sprintf(buf, "%d", cur_level); 233 mvaddstr(row, 7, buf); 234 pad(buf, 2); 235 } 236 if (stat_mask & STAT_GOLD) { 237 if (label) { 238 mvaddstr(row, 10, "Gold: "); 239 } 240 if (rogue.gold > MAX_GOLD) { 241 rogue.gold = MAX_GOLD; 242 } 243 sprintf(buf, "%ld", rogue.gold); 244 mvaddstr(row, 16, buf); 245 pad(buf, 6); 246 } 247 if (stat_mask & STAT_HP) { 248 if (label) { 249 mvaddstr(row, 23, "Hp: "); 250 } 251 if (rogue.hp_max > MAX_HP) { 252 rogue.hp_current -= (rogue.hp_max - MAX_HP); 253 rogue.hp_max = MAX_HP; 254 } 255 sprintf(buf, "%d(%d)", rogue.hp_current, rogue.hp_max); 256 mvaddstr(row, 27, buf); 257 pad(buf, 8); 258 } 259 if (stat_mask & STAT_STRENGTH) { 260 if (label) { 261 mvaddstr(row, 36, "Str: "); 262 } 263 if (rogue.str_max > MAX_STRENGTH) { 264 rogue.str_current -= (rogue.str_max - MAX_STRENGTH); 265 rogue.str_max = MAX_STRENGTH; 266 } 267 sprintf(buf, "%d(%d)", (rogue.str_current + add_strength), 268 rogue.str_max); 269 mvaddstr(row, 41, buf); 270 pad(buf, 6); 271 } 272 if (stat_mask & STAT_ARMOR) { 273 if (label) { 274 mvaddstr(row, 48, "Arm: "); 275 } 276 if (rogue.armor && (rogue.armor->d_enchant > MAX_ARMOR)) { 277 rogue.armor->d_enchant = MAX_ARMOR; 278 } 279 sprintf(buf, "%d", get_armor_class(rogue.armor)); 280 mvaddstr(row, 53, buf); 281 pad(buf, 2); 282 } 283 if (stat_mask & STAT_EXP) { 284 if (label) { 285 mvaddstr(row, 56, "Exp: "); 286 } 287 if (rogue.exp_points > MAX_EXP) { 288 rogue.exp_points = MAX_EXP; 289 } 290 if (rogue.exp > MAX_EXP_LEVEL) { 291 rogue.exp = MAX_EXP_LEVEL; 292 } 293 sprintf(buf, "%d/%ld", rogue.exp, rogue.exp_points); 294 mvaddstr(row, 61, buf); 295 pad(buf, 11); 296 } 297 if (stat_mask & STAT_HUNGER) { 298 mvaddstr(row, 73, hunger_str); 299 clrtoeol(); 300 } 301 refresh(); 302 } 303 304 static void 305 pad(const char *s, short n) 306 { 307 short i; 308 309 for (i = strlen(s); i < n; i++) { 310 addch(' '); 311 } 312 } 313 314 static void 315 save_screen(void) 316 { 317 FILE *fp; 318 short i, j; 319 char buf[DCOLS+2]; 320 boolean found_non_blank; 321 322 if ((fp = fopen(_PATH_SCREENDUMP, "w")) != NULL) { 323 for (i = 0; i < DROWS; i++) { 324 found_non_blank = 0; 325 for (j = (DCOLS - 1); j >= 0; j--) { 326 buf[j] = mvinch(i, j); 327 if (!found_non_blank) { 328 if ((buf[j] != ' ') || (j == 0)) { 329 buf[j + ((j == 0) ? 0 : 1)] = 0; 330 found_non_blank = 1; 331 } 332 } 333 } 334 fputs(buf, fp); 335 putc('\n', fp); 336 } 337 fclose(fp); 338 } else { 339 sound_bell(); 340 } 341 } 342 343 void 344 sound_bell(void) 345 { 346 putchar(7); 347 fflush(stdout); 348 } 349 350 boolean 351 is_digit(short ch) 352 { 353 return((ch >= '0') && (ch <= '9')); 354 } 355 356 int 357 r_index(const char *str, int ch, boolean last) 358 { 359 int i = 0; 360 361 if (last) { 362 for (i = strlen(str) - 1; i >= 0; i--) { 363 if (str[i] == ch) { 364 return(i); 365 } 366 } 367 } else { 368 for (i = 0; str[i]; i++) { 369 if (str[i] == ch) { 370 return(i); 371 } 372 } 373 } 374 return(-1); 375 } 376