rogue

Ken Arnold's Rogue
git clone https://git.woozle.org/neale/rogue.git

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}