comparison arogue5/io.c @ 63:0ed67132cf10

Import Advanced Rogue 5.8 from the Roguelike Restoration Project (r1490)
author elwin
date Thu, 09 Aug 2012 22:58:48 +0000
parents
children c49f7927b0fa
comparison
equal deleted inserted replaced
62:0ef99244acb8 63:0ed67132cf10
1 /*
2 * Various input/output functions
3 *
4 * Advanced Rogue
5 * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
6 * All rights reserved.
7 *
8 * Based on "Rogue: Exploring the Dungeons of Doom"
9 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
10 * All rights reserved.
11 *
12 * See the file LICENSE.TXT for full copyright and licensing information.
13 */
14
15 #include "curses.h"
16 #include <ctype.h>
17 #include <stdarg.h>
18 #include "rogue.h"
19
20 /*
21 * msg:
22 * Display a message at the top of the screen.
23 */
24
25 static char msgbuf[BUFSIZ];
26 static int newpos = 0;
27
28 /*VARARGS1*/
29 msg(char *fmt, ...)
30 {
31 va_list ap;
32 /*
33 * if the string is "", just clear the line
34 */
35 if (*fmt == '\0')
36 {
37 overwrite(cw,msgw);
38 wmove(msgw, 0, 0);
39 clearok(msgw, FALSE);
40 draw(msgw);
41 mpos = 0;
42 return;
43 }
44 /*
45 * otherwise add to the message and flush it out
46 */
47 va_start(ap,fmt);
48 doadd(fmt, ap);
49 va_end(ap);
50 endmsg();
51 }
52
53 /*
54 * add things to the current message
55 */
56 addmsg(char *fmt, ...)
57 {
58 va_list ap;
59 va_start(ap,fmt);
60 doadd(fmt, ap);
61 va_end(ap);
62 }
63
64 /*
65 * Display a new msg (giving him a chance to see the previous one if it
66 * is up there with the --More--)
67 */
68 endmsg()
69 {
70 strncpy(huh, msgbuf, sizeof(huh));
71
72 huh[ sizeof(huh) - 1 ] = 0;
73
74 if (mpos)
75 {
76 wmove(msgw, 0, mpos);
77 waddstr(msgw, morestr);
78 draw(cw);
79 draw(msgw);
80 wait_for(msgw,' ');
81 overwrite(cw,msgw);
82 wmove(msgw,0,0);
83 touchwin(cw);
84 }
85 else {
86 overwrite(cw,msgw);
87 wmove(msgw,0,0);
88 }
89 waddstr(msgw, msgbuf);
90 mpos = newpos;
91 newpos = 0;
92 msgbuf[0] = '\0';
93 draw(cw);
94 clearok(msgw, FALSE);
95 draw(msgw);
96 }
97
98 doadd(char *fmt, va_list ap)
99 {
100 /*
101 * Do the sprintf into newmsg and append to msgbuf
102 */
103
104 vsnprintf(&msgbuf[newpos], sizeof(msgbuf)-newpos-1, fmt, ap);
105
106 newpos = strlen(msgbuf);
107 }
108
109 /*
110 * step_ok:
111 * returns true if it is ok for type to step on ch
112 * flgptr will be NULL if we don't know what the monster is yet!
113 */
114
115 step_ok(y, x, can_on_monst, flgptr)
116 register int y, x, can_on_monst;
117 register struct thing *flgptr;
118 {
119 /* can_on_monst = MONSTOK if all we care about are physical obstacles */
120 register struct linked_list *item;
121 char ch;
122
123 /* What is here? Don't check monster window if MONSTOK is set */
124 if (can_on_monst == MONSTOK) ch = CCHAR( mvinch(y, x) );
125 else ch = CCHAR( winat(y, x) );
126
127 switch (ch)
128 {
129 case ' ':
130 case '|':
131 case '-':
132 case SECRETDOOR:
133 if (flgptr && on(*flgptr, CANINWALL)) return(TRUE);
134 return FALSE;
135 when SCROLL:
136 if (can_on_monst == MONSTOK) return(TRUE); /* Not a real obstacle */
137 /*
138 * If it is a scroll, it might be a scare monster scroll
139 * so we need to look it up to see what type it is.
140 */
141 if (flgptr && flgptr->t_ctype == C_MONSTER) {
142 item = find_obj(y, x);
143 if (item != NULL &&
144 (OBJPTR(item))->o_which==S_SCARE &&
145 (flgptr == NULL || flgptr->t_stats.s_intel < 16))
146 return(FALSE); /* All but smart ones are scared */
147 }
148 return(TRUE);
149 otherwise:
150 return (!isalpha(ch));
151 }
152 }
153 /*
154 * shoot_ok:
155 * returns true if it is ok for type to shoot over ch
156 */
157
158 shoot_ok(ch)
159 {
160 switch (ch)
161 {
162 case ' ':
163 case '|':
164 case '-':
165 case SECRETDOOR:
166 case FOREST:
167 return FALSE;
168 default:
169 return (!isalpha(ch));
170 }
171 }
172
173 /*
174 * readchar:
175 * flushes stdout so that screen is up to date and then returns
176 * getchar.
177 */
178
179 readchar()
180 {
181 int ch;
182
183 ch = md_readchar(cw);
184
185 if ((ch == 3) || (ch == 0))
186 {
187 quit(0);
188 return(27);
189 }
190
191 return(ch);
192 }
193
194 /*
195 * status:
196 * Display the important stats line. Keep the cursor where it was.
197 */
198
199 status(display)
200 bool display; /* is TRUE, display unconditionally */
201 {
202 register struct stats *stat_ptr, *max_ptr;
203 register int oy = 0, ox = 0, temp;
204 register char *pb;
205 static char buf[LINELEN];
206 static int hpwidth = 0, s_hungry = -1;
207 static int s_lvl = -1, s_pur, s_hp = -1, s_str, maxs_str,
208 s_ac = 0;
209 static short s_intel, s_dext, s_wisdom, s_const, s_charisma;
210 static short maxs_intel, maxs_dext, maxs_wisdom, maxs_const, maxs_charisma;
211 static unsigned long s_exp = 0;
212 static int s_carry, s_pack;
213 bool first_line=FALSE;
214
215 /* Use a mini status version if we have a small window */
216 if (COLS < 80) {
217 ministat();
218 return;
219 }
220
221 stat_ptr = &pstats;
222 max_ptr = &max_stats;
223
224 /*
225 * If nothing has changed in the first line, then skip it
226 */
227 if (!display &&
228 s_lvl == level &&
229 s_intel == stat_ptr->s_intel &&
230 s_wisdom == stat_ptr->s_wisdom &&
231 s_dext == dex_compute() &&
232 s_const == stat_ptr->s_const &&
233 s_charisma == stat_ptr->s_charisma &&
234 s_str == str_compute() &&
235 s_pack == stat_ptr->s_pack &&
236 s_carry == stat_ptr->s_carry &&
237 maxs_intel == max_ptr->s_intel &&
238 maxs_wisdom == max_ptr->s_wisdom &&
239 maxs_dext == max_ptr->s_dext &&
240 maxs_const == max_ptr->s_const &&
241 maxs_charisma == max_ptr->s_charisma &&
242 maxs_str == max_ptr->s_str ) goto line_two;
243
244 /* Display the first line */
245 first_line = TRUE;
246 getyx(cw, oy, ox);
247 sprintf(buf, "Int:%d(%d) Str:%d", stat_ptr->s_intel,
248 max_ptr->s_intel, str_compute());
249
250 /* Maximum strength */
251 pb = &buf[strlen(buf)];
252 sprintf(pb, "(%d)", max_ptr->s_str);
253
254 pb = &buf[strlen(buf)];
255 sprintf(pb, " Wis:%d(%d) Dxt:%d(%d) Const:%d(%d) Carry:%d(%d)",
256 stat_ptr->s_wisdom,max_ptr->s_wisdom,dex_compute(),max_ptr->s_dext,
257 stat_ptr->s_const,max_ptr->s_const,stat_ptr->s_pack/10,
258 stat_ptr->s_carry/10);
259
260 /* Update first line status */
261 s_intel = stat_ptr->s_intel;
262 s_wisdom = stat_ptr->s_wisdom;
263 s_dext = dex_compute();
264 s_const = stat_ptr->s_const;
265 s_charisma = stat_ptr->s_charisma;
266 s_str = str_compute();
267 s_pack = stat_ptr->s_pack;
268 s_carry = stat_ptr->s_carry;
269 maxs_intel = max_ptr->s_intel;
270 maxs_wisdom = max_ptr->s_wisdom;
271 maxs_dext = max_ptr->s_dext;
272 maxs_const = max_ptr->s_const;
273 maxs_charisma = max_ptr->s_charisma;
274 maxs_str = max_ptr->s_str;
275
276 /* Print the line */
277 mvwaddstr(cw, LINES - 2, 0, buf);
278 wclrtoeol(cw);
279
280 /*
281 * If nothing has changed since the last status, don't
282 * bother.
283 */
284 line_two:
285 if (!display &&
286 s_hp == stat_ptr->s_hpt &&
287 s_exp == stat_ptr->s_exp &&
288 s_pur == purse &&
289 s_ac == ac_compute() - dext_prot(s_dext) &&
290 s_lvl == level &&
291 s_hungry == hungry_state ) return;
292
293 if (!first_line) getyx(cw, oy, ox);
294 if (s_hp != max_ptr->s_hpt)
295 {
296 temp = s_hp = max_ptr->s_hpt;
297 for (hpwidth = 0; temp; hpwidth++)
298 temp /= 10;
299 }
300 sprintf(buf, "Lvl:%d Au:%d Hp:%*d(%*d) Ac:%d Exp:%d/%lu %s",
301 level, purse, hpwidth, stat_ptr->s_hpt, hpwidth, max_ptr->s_hpt,
302 ac_compute() - dext_prot(s_dext),stat_ptr->s_lvl, stat_ptr->s_exp,
303 cnames[player.t_ctype][min(stat_ptr->s_lvl-1, 10)]);
304
305 /*
306 * Save old status
307 */
308 s_lvl = level;
309 s_pur = purse;
310 s_hp = stat_ptr->s_hpt;
311 s_exp = stat_ptr->s_exp;
312 s_ac = ac_compute() - dext_prot(s_dext);
313 mvwaddstr(cw, LINES - 1, 0, buf);
314 switch (hungry_state)
315 {
316 case F_OKAY: ;
317 when F_HUNGRY:
318 waddstr(cw, " Hungry");
319 when F_WEAK:
320 waddstr(cw, " Weak");
321 when F_FAINT:
322 waddstr(cw, " Fainting");
323 }
324 wclrtoeol(cw);
325 s_hungry = hungry_state;
326 wmove(cw, oy, ox);
327 }
328
329 ministat()
330 {
331 register int oy, ox, temp;
332 static char buf[LINELEN];
333 static int hpwidth = 0;
334 static int s_lvl = -1, s_pur, s_hp = -1;
335
336 /*
337 * If nothing has changed since the last status, don't
338 * bother.
339 */
340 if (s_hp == pstats.s_hpt && s_pur == purse && s_lvl == level)
341 return;
342
343 getyx(cw, oy, ox);
344 if (s_hp != max_stats.s_hpt)
345 {
346 temp = s_hp = max_stats.s_hpt;
347 for (hpwidth = 0; temp; hpwidth++)
348 temp /= 10;
349 }
350 sprintf(buf, "Lv: %d Au: %-5d Hp: %*d(%*d)",
351 level, purse, hpwidth, pstats.s_hpt, hpwidth, max_stats.s_hpt);
352
353 /*
354 * Save old status
355 */
356 s_lvl = level;
357 s_pur = purse;
358 s_hp = pstats.s_hpt;
359 mvwaddstr(cw, LINES - 1, 0, buf);
360 wclrtoeol(cw);
361 wmove(cw, oy, ox);
362 }
363
364 /*
365 * wait_for
366 * Sit around until the guy types the right key
367 */
368
369 wait_for(win,ch)
370 WINDOW *win;
371 register char ch;
372 {
373 register char c;
374
375 if (ch == '\n')
376 while ((c = wgetch(win)) != '\n' && c != '\r')
377 continue;
378 else
379 while (wgetch(win) != ch)
380 continue;
381 }
382
383 /*
384 * show_win:
385 * function used to display a window and wait before returning
386 */
387
388 show_win(scr, message)
389 register WINDOW *scr;
390 char *message;
391 {
392 mvwaddstr(scr, 0, 0, message);
393 touchwin(scr);
394 wmove(scr, hero.y, hero.x);
395 draw(scr);
396 wait_for(scr,' ');
397 clearok(cw, TRUE);
398 touchwin(cw);
399 }
400
401 /*
402 * dbotline:
403 * Displays message on bottom line and waits for a space to return
404 */
405 dbotline(scr,message)
406 WINDOW *scr;
407 char *message;
408 {
409 mvwaddstr(scr,LINES-1,0,message);
410 draw(scr);
411 wait_for(scr,' ');
412 }
413
414
415 /*
416 * restscr:
417 * Restores the screen to the terminal
418 */
419 restscr(scr)
420 WINDOW *scr;
421 {
422 clearok(scr,TRUE);
423 touchwin(scr);
424 }
425
426 /*
427 * netread:
428 * Read a byte, short, or long machine independently
429 * Always returns the value as an unsigned long.
430 */
431
432 unsigned long
433 netread(error, size, stream)
434 int *error;
435 int size;
436 FILE *stream;
437 {
438 unsigned long result = 0L, /* What we read in */
439 partial; /* Partial value */
440 int nextc, /* The next byte */
441 i; /* To index through the result a byte at a time */
442
443 /* Be sure we have a right sized chunk */
444 if (size < 1 || size > 4) {
445 *error = 1;
446 return(0L);
447 }
448
449 for (i=0; i<size; i++) {
450 nextc = getc(stream);
451 if (nextc == EOF) {
452 *error = 1;
453 return(0L);
454 }
455 else {
456 partial = (unsigned long) (nextc & 0xff);
457 partial <<= 8*i;
458 result |= partial;
459 }
460 }
461
462 *error = 0;
463 return(result);
464 }
465
466
467
468 /*
469 * netwrite:
470 * Write out a byte, short, or long machine independently.
471 */
472
473 netwrite(value, size, stream)
474 unsigned long value; /* What to write */
475 int size; /* How much to write out */
476 FILE *stream; /* Where to write it */
477 {
478 int i; /* Goes through value one byte at a time */
479 char outc; /* The next character to be written */
480
481 /* Be sure we have a right sized chunk */
482 if (size < 1 || size > 4) return(0);
483
484 for (i=0; i<size; i++) {
485 outc = (char) ((value >> (8 * i)) & 0xff);
486 putc(outc, stream);
487 }
488 return(size);
489 }