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