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