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