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 char msgs[NMESSAGES][DCOLS] = {"", "", "", "", ""}; 53 short msg_col = 0, imsg = -1; 54 boolean msg_cleared = 1, rmsg = 0; 55 char hunger_str[HUNGER_STR_LEN] = ""; 56 const char *more = "-more-"; 57 58 extern boolean cant_int, did_int, interrupted, save_is_interactive, flush; 59 extern short add_strength; 60 extern short cur_level; 61 62 static void pad(const char *, short); 63 static void save_screen(void); 64 65 void 66 message(const char *msg, boolean intrpt) 67 { 68 cant_int = 1; 69 70 if (!save_is_interactive) { 71 return; 72 } 73 if (intrpt) { 74 interrupted = 1; 75 if (flush) 76 md_slurp(); 77 } 78 79 if (!msg_cleared) { 80 mvaddstr(MIN_ROW-1, msg_col, more); 81 refresh(); 82 wait_for_ack(); 83 check_message(); 84 } 85 if (!rmsg) { 86 imsg = (imsg + 1) % NMESSAGES; 87 strcpy(msgs[imsg], msg); 88 } 89 mvaddstr(MIN_ROW-1, 0, msg); 90 addch(' '); 91 refresh(); 92 msg_cleared = 0; 93 msg_col = strlen(msg); 94 95 cant_int = 0; 96 97 if (did_int) { 98 did_int = 0; 99 onintr(0); 100 } 101 } 102 103 void 104 remessage(short c) 105 { 106 if (imsg != -1) { 107 check_message(); 108 rmsg = 1; 109 while (c > imsg) { 110 c -= NMESSAGES; 111 } 112 message(msgs[((imsg - c) % NMESSAGES)], 0); 113 rmsg = 0; 114 move(rogue.row, rogue.col); 115 refresh(); 116 } 117 } 118 119 void 120 check_message(void) 121 { 122 if (msg_cleared) { 123 return; 124 } 125 move(MIN_ROW-1, 0); 126 clrtoeol(); 127 refresh(); 128 msg_cleared = 1; 129 } 130 131 short 132 get_input_line(const char *prompt, const char *insert, char *buf, 133 const char *if_cancelled, boolean add_blank, boolean do_echo) 134 { 135 short ch; 136 short i = 0, n; 137 138 message(prompt, 0); 139 n = strlen(prompt); 140 141 if (insert[0]) { 142 mvaddstr(0, n + 1, insert); 143 strcpy(buf, insert); 144 i = strlen(insert); 145 move(0, (n + i + 1)); 146 refresh(); 147 } 148 149 while (((ch = rgetchar()) != '\r') && (ch != '\n') && (ch != CANCEL)) { 150 if ((ch >= ' ') && (ch <= '~') && (i < MAX_TITLE_LENGTH-2)) { 151 if ((ch != ' ') || (i > 0)) { 152 buf[i++] = ch; 153 if (do_echo) { 154 addch(ch); 155 } 156 } 157 } 158 if ((ch == '\b') && (i > 0)) { 159 if (do_echo) { 160 mvaddch(0, i + n, ' '); 161 move(MIN_ROW-1, i+n); 162 } 163 i--; 164 } 165 refresh(); 166 } 167 check_message(); 168 if (add_blank) { 169 buf[i++] = ' '; 170 } else { 171 while ((i > 0) && (buf[i-1] == ' ')) { 172 i--; 173 } 174 } 175 176 buf[i] = 0; 177 178 if ((ch == CANCEL) || (i == 0) || ((i == 1) && add_blank)) { 179 if (if_cancelled) { 180 message(if_cancelled, 0); 181 } 182 return(0); 183 } 184 return(i); 185 } 186 187 int 188 rgetchar(void) 189 { 190 int ch; 191 192 for(;;) { 193 ch = getchar(); 194 195 switch(ch) { 196 case '\022': 197 wrefresh(curscr); 198 break; 199 #ifdef UNIX_BSD4_2 200 case '\032': 201 printf("%s", CL); 202 fflush(stdout); 203 tstp(); 204 break; 205 #endif 206 case '&': 207 save_screen(); 208 break; 209 default: 210 return(ch); 211 } 212 } 213 } 214 215 /* 216 Level: 99 Gold: 999999 Hp: 999(999) Str: 99(99) Arm: 99 Exp: 21/10000000 Hungry 217 0 5 1 5 2 5 3 5 4 5 5 5 6 5 7 5 218 */ 219 220 void 221 print_stats(int stat_mask) 222 { 223 char buf[16]; 224 boolean label; 225 int row = DROWS - 1; 226 227 label = (stat_mask & STAT_LABEL) ? 1 : 0; 228 229 if (stat_mask & STAT_LEVEL) { 230 if (label) { 231 mvaddstr(row, 0, "Level: "); 232 } 233 /* max level taken care of in make_level() */ 234 sprintf(buf, "%d", cur_level); 235 mvaddstr(row, 7, buf); 236 pad(buf, 2); 237 } 238 if (stat_mask & STAT_GOLD) { 239 if (label) { 240 mvaddstr(row, 10, "Gold: "); 241 } 242 if (rogue.gold > MAX_GOLD) { 243 rogue.gold = MAX_GOLD; 244 } 245 sprintf(buf, "%ld", rogue.gold); 246 mvaddstr(row, 16, buf); 247 pad(buf, 6); 248 } 249 if (stat_mask & STAT_HP) { 250 if (label) { 251 mvaddstr(row, 23, "Hp: "); 252 } 253 if (rogue.hp_max > MAX_HP) { 254 rogue.hp_current -= (rogue.hp_max - MAX_HP); 255 rogue.hp_max = MAX_HP; 256 } 257 sprintf(buf, "%d(%d)", rogue.hp_current, rogue.hp_max); 258 mvaddstr(row, 27, buf); 259 pad(buf, 8); 260 } 261 if (stat_mask & STAT_STRENGTH) { 262 if (label) { 263 mvaddstr(row, 36, "Str: "); 264 } 265 if (rogue.str_max > MAX_STRENGTH) { 266 rogue.str_current -= (rogue.str_max - MAX_STRENGTH); 267 rogue.str_max = MAX_STRENGTH; 268 } 269 sprintf(buf, "%d(%d)", (rogue.str_current + add_strength), 270 rogue.str_max); 271 mvaddstr(row, 41, buf); 272 pad(buf, 6); 273 } 274 if (stat_mask & STAT_ARMOR) { 275 if (label) { 276 mvaddstr(row, 48, "Arm: "); 277 } 278 if (rogue.armor && (rogue.armor->d_enchant > MAX_ARMOR)) { 279 rogue.armor->d_enchant = MAX_ARMOR; 280 } 281 sprintf(buf, "%d", get_armor_class(rogue.armor)); 282 mvaddstr(row, 53, buf); 283 pad(buf, 2); 284 } 285 if (stat_mask & STAT_EXP) { 286 if (label) { 287 mvaddstr(row, 56, "Exp: "); 288 } 289 if (rogue.exp_points > MAX_EXP) { 290 rogue.exp_points = MAX_EXP; 291 } 292 if (rogue.exp > MAX_EXP_LEVEL) { 293 rogue.exp = MAX_EXP_LEVEL; 294 } 295 sprintf(buf, "%d/%ld", rogue.exp, rogue.exp_points); 296 mvaddstr(row, 61, buf); 297 pad(buf, 11); 298 } 299 if (stat_mask & STAT_HUNGER) { 300 mvaddstr(row, 73, hunger_str); 301 clrtoeol(); 302 } 303 refresh(); 304 } 305 306 static void 307 pad(const char *s, short n) 308 { 309 short i; 310 311 for (i = strlen(s); i < n; i++) { 312 addch(' '); 313 } 314 } 315 316 static void 317 save_screen(void) 318 { 319 FILE *fp; 320 short i, j; 321 char buf[DCOLS+2]; 322 boolean found_non_blank; 323 324 if ((fp = fopen(_PATH_SCREENDUMP, "w")) != NULL) { 325 for (i = 0; i < DROWS; i++) { 326 found_non_blank = 0; 327 for (j = (DCOLS - 1); j >= 0; j--) { 328 buf[j] = mvinch(i, j); 329 if (!found_non_blank) { 330 if ((buf[j] != ' ') || (j == 0)) { 331 buf[j + ((j == 0) ? 0 : 1)] = 0; 332 found_non_blank = 1; 333 } 334 } 335 } 336 fputs(buf, fp); 337 putc('\n', fp); 338 } 339 fclose(fp); 340 } else { 341 sound_bell(); 342 } 343 } 344 345 void 346 sound_bell(void) 347 { 348 putchar(7); 349 fflush(stdout); 350 } 351 352 boolean 353 is_digit(short ch) 354 { 355 return((ch >= '0') && (ch <= '9')); 356 } 357 358 int 359 r_index(const char *str, int ch, boolean last) 360 { 361 int i = 0; 362 363 if (last) { 364 for (i = strlen(str) - 1; i >= 0; i--) { 365 if (str[i] == ch) { 366 return(i); 367 } 368 } 369 } else { 370 for (i = 0; str[i]; i++) { 371 if (str[i] == ch) { 372 return(i); 373 } 374 } 375 } 376 return(-1); 377 } 378