Neale Pickett
·
2017-04-21
control.c
1/*
2 * Various input/output functions
3 *
4 * @(#)control.c 4.32 (Berkeley) 02/05/99
5 */
6
7#include <curses.h>
8#include <ctype.h>
9#include <string.h>
10#include "netprot.h"
11
12/*
13 * msg:
14 * Display a message at the top of the screen.
15 */
16#define MAXMSG (NUMCOLS - sizeof "--More--")
17
18static char Msgbuf[MAXMSG+1];
19static int Newpos = 0;
20
21/* VARARGS1 */
22int
23msg(char *fmt, ...)
24{
25 va_list args;
26
27 /*
28 * if the string is "", just clear the line
29 */
30 if (*fmt == '\0')
31 {
32 move(0, 0);
33 clrtoeol();
34 Mpos = 0;
35 return ~ESCAPE;
36 }
37 /*
38 * otherwise add to the message and flush it out
39 */
40 va_start(args, fmt);
41 doadd(fmt, args);
42 va_end(args);
43 return endmsg();
44}
45
46/*
47 * addmsg:
48 * Add things to the current message
49 */
50/* VARARGS1 */
51void
52addmsg(char *fmt, ...)
53{
54 va_list args;
55
56 va_start(args, fmt);
57 doadd(fmt, args);
58 va_end(args);
59}
60
61/*
62 * endmsg:
63 * Display a new msg (giving him a chance to see the previous one
64 * if it is up there with the --More--)
65 */
66int
67endmsg(void)
68{
69 char ch;
70
71 if (Save_msg)
72 strcpy(Huh, Msgbuf);
73 if (Mpos)
74 {
75 look(FALSE);
76 mvaddstr(0, Mpos, "--More--");
77 refresh();
78 if (!Msg_esc)
79 wait_for(' ');
80 else
81 {
82 while ((ch = readchar()) != ' ')
83 if (ch == ESCAPE)
84 {
85 Msgbuf[0] = '\0';
86 Mpos = 0;
87 Newpos = 0;
88 Msgbuf[0] = '\0';
89 return ESCAPE;
90 }
91 }
92 }
93 /*
94 * All messages should start with uppercase, except ones that
95 * start with a pack addressing character
96 */
97 if (islower(Msgbuf[0]) && !Lower_msg && Msgbuf[1] != ')')
98 Msgbuf[0] = toupper(Msgbuf[0]);
99 mvaddstr(0, 0, Msgbuf);
100 clrtoeol();
101 Mpos = Newpos;
102 Newpos = 0;
103 Msgbuf[0] = '\0';
104 refresh();
105 return ~ESCAPE;
106}
107
108/*
109 * doadd:
110 * Perform an add onto the message buffer
111 */
112void
113doadd(char *fmt, va_list args)
114{
115 static char buf[MAXSTR];
116
117 /*
118 * Do the printf into buf
119 */
120 vsprintf(buf, fmt, args);
121 if (strlen(buf) + Newpos >= MAXMSG)
122 endmsg();
123 strcat(Msgbuf, buf);
124 Newpos = strlen(Msgbuf);
125}
126
127/*
128 * step_ok:
129 * Returns true if it is ok to step on ch
130 */
131bool
132step_ok(char ch)
133{
134 switch (ch)
135 {
136 case ' ':
137 case '|':
138 case '-':
139 return FALSE;
140 default:
141 return (!isalpha(ch));
142 }
143}
144
145/*
146 * readchar:
147 * Reads and returns a character, checking for gross input errors
148 */
149int
150readchar(void)
151{
152 int cnt;
153 static char c;
154
155 cnt = 0;
156 while (read(0, &c, 1) <= 0)
157 if (cnt++ > 100) /* if we are getting infinite EOFs */
158 auto_save(0); /* save the game */
159 return c;
160}
161
162/*
163 * status:
164 * Display the important stats line. Keep the cursor where it was.
165 */
166void
167status(void)
168{
169 int (*print_func)(char *fmt, ...);
170# define PRINT_FUNC (*print_func)
171 int oy, ox, temp;
172 static int hpwidth = 0;
173 static int s_hungry;
174 static int s_lvl;
175 static int s_pur = -1;
176 static int s_hp;
177 static int s_arm;
178 static str_t s_str;
179 static long s_exp = 0;
180 static char *state_name[] =
181 {
182 "", "Hungry", "Weak", "Faint"
183 };
184
185 /*
186 * If nothing has changed since the last status, don't
187 * bother.
188 */
189 temp = (Cur_armor != NULL ? Cur_armor->o_arm : Pstats.s_arm);
190 if (s_hp == Pstats.s_hpt && s_exp == Pstats.s_exp && s_pur == Purse
191 && s_arm == temp && s_str == Pstats.s_str && s_lvl == Level
192 && s_hungry == Hungry_state
193 && !Stat_msg
194 )
195 return;
196
197 s_arm = temp;
198
199 getyx(stdscr, oy, ox);
200 if (s_hp != Max_hp)
201 {
202 temp = Max_hp;
203 s_hp = Max_hp;
204 for (hpwidth = 0; temp; hpwidth++)
205 temp /= 10;
206 }
207
208 /*
209 * Save current status
210 */
211 s_lvl = Level;
212 s_pur = Purse;
213 s_hp = Pstats.s_hpt;
214 s_str = Pstats.s_str;
215 s_exp = Pstats.s_exp;
216 s_hungry = Hungry_state;
217
218 if (Stat_msg)
219 {
220 print_func = msg;
221 move(0, 0);
222 }
223 else
224 {
225 move(STATLINE, 0);
226 print_func = printw;
227 }
228 PRINT_FUNC("Level: %d Gold: %-5d Hp: %*d(%*d) Str: %2d(%d) Arm: %-2d Exp: %d/%ld %s",
229 Level, Purse, hpwidth, Pstats.s_hpt, hpwidth, Max_hp, Pstats.s_str,
230 Max_stats.s_str, 10 - s_arm, Pstats.s_lvl, Pstats.s_exp,
231 state_name[Hungry_state]);
232
233 clrtoeol();
234 move(oy, ox);
235}
236
237/*
238 * wait_for
239 * Sit around until the guy types the right key
240 */
241void
242wait_for(char ch)
243{
244 char c;
245
246 if (ch == '\n')
247 while ((c = readchar()) != '\n' && c != '\r')
248 continue;
249 else
250 while (readchar() != ch)
251 continue;
252}
253
254/*
255 * show_win:
256 * Function used to display a window and wait before returning
257 */
258void
259show_win(char *message)
260{
261 WINDOW *win;
262
263 win = Hw;
264 wmove(win, 0, 0);
265 waddstr(win, message);
266 touchwin(win);
267 wmove(win, Hero.y, Hero.x);
268 wrefresh(win);
269 wait_for(' ');
270 clearok(curscr, TRUE);
271#ifdef attron
272 touchwin(stdscr);
273#endif /* attron */
274}