Home | History | Annotate | Line # | Download | only in phantasia
io.c revision 1.7
      1 /*	$NetBSD: io.c,v 1.7 2004/04/07 17:46:47 ross Exp $	*/
      2 
      3 /*
      4  * io.c - input/output routines for Phantasia
      5  */
      6 
      7 #include "include.h"
      8 #include <curses.h>
      9 
     10 void
     11 getstring(cp, mx)
     12 	char   *cp;
     13 	int     mx;
     14 {
     15 	char   *inptr;		/* pointer into string for next string */
     16 	int     x, y;		/* original x, y coordinates on screen */
     17 	int     ch;		/* input */
     18 
     19 	getyx(stdscr, y, x);	/* get coordinates on screen */
     20 	inptr = cp;
     21 	*inptr = '\0';		/* clear string to start */
     22 	--mx;			/* reserve room in string for nul terminator */
     23 
     24 	do
     25 		/* get characters and process */
     26 	{
     27 		if (Echo)
     28 			mvaddstr(y, x, cp);	/* print string on screen */
     29 		clrtoeol();	/* clear any data after string */
     30 		refresh();	/* update screen */
     31 
     32 		ch = getchar();	/* get character */
     33 
     34 		switch (ch) {
     35 		case CH_ERASE:	/* back up one character */
     36 			if (inptr > cp)
     37 				--inptr;
     38 			break;
     39 
     40 		case CH_KILL:	/* back up to original location */
     41 			inptr = cp;
     42 			break;
     43 
     44 		case CH_NEWLINE:	/* terminate string */
     45 			break;
     46 
     47 		case CH_REDRAW:/* redraw screen */
     48 			clearok(stdscr, TRUE);
     49 			continue;
     50 
     51 		default:	/* put data in string */
     52 			if (ch >= ' ' || Wizard)
     53 				/* printing char; put in string */
     54 				*inptr++ = ch;
     55 		}
     56 
     57 		*inptr = '\0';	/* terminate string */
     58 	}
     59 	while (ch != CH_NEWLINE && inptr < cp + mx);
     60 }
     61 
     62 void
     63 more(where)
     64 	int     where;
     65 {
     66 	mvaddstr(where, 0, "-- more --");
     67 	getanswer(" ", FALSE);
     68 }
     69 
     70 double
     71 infloat()
     72 {
     73 	double  result;		/* return value */
     74 
     75 	getstring(Databuf, SZ_DATABUF);
     76 	if (sscanf(Databuf, "%lf", &result) < 1)
     77 		/* no valid number entered */
     78 		result = 0.0;
     79 
     80 	return (result);
     81 }
     82 
     83 int
     84 inputoption()
     85 {
     86 	++Player.p_age;		/* increase age */
     87 
     88 	if (Player.p_ring.ring_type != R_SPOILED)
     89 		/* ring ok */
     90 		return (getanswer("T ", TRUE));
     91 	else
     92 		/* bad ring */
     93 	{
     94 		getanswer(" ", TRUE);
     95 		return ((int) ROLL(0.0, 5.0) + '0');
     96 	}
     97 }
     98 
     99 void
    100 interrupt()
    101 {
    102 	char    line[81];	/* a place to store data already on screen */
    103 	int     loop;		/* counter */
    104 	int     x, y;		/* coordinates on screen */
    105 	int     ch;		/* input */
    106 	unsigned savealarm;	/* to save alarm value */
    107 
    108 #ifdef SYS3
    109 	signal(SIGINT, SIG_IGN);
    110 #endif
    111 #ifdef SYS5
    112 	signal(SIGINT, SIG_IGN);
    113 #endif
    114 
    115 	savealarm = alarm(0);	/* turn off any alarms */
    116 
    117 	getyx(stdscr, y, x);	/* save cursor location */
    118 
    119 	for (loop = 0; loop < 80; ++loop) {	/* save line on screen */
    120 		move(4, loop);
    121 		line[loop] = inch();
    122 	}
    123 	line[80] = '\0';	/* nul terminate */
    124 
    125 	if (Player.p_status == S_INBATTLE || Player.p_status == S_MONSTER)
    126 		/* in midst of fighting */
    127 	{
    128 		mvaddstr(4, 0, "Quitting now will automatically kill your character.  Still want to ? ");
    129 		ch = getanswer("NY", FALSE);
    130 		if (ch == 'Y')
    131 			death("Bailing out");
    132 		/* NOTREACHED */
    133 	} else {
    134 		mvaddstr(4, 0, "Do you really want to quit ? ");
    135 		ch = getanswer("NY", FALSE);
    136 		if (ch == 'Y')
    137 			leavegame();
    138 		/* NOTREACHED */
    139 	}
    140 
    141 	mvaddstr(4, 0, line);	/* restore data on screen */
    142 	move(y, x);		/* restore cursor */
    143 	refresh();
    144 
    145 #ifdef SYS3
    146 	signal(SIGINT, interrupt);
    147 #endif
    148 #ifdef SYS5
    149 	signal(SIGINT, interrupt);
    150 #endif
    151 
    152 	alarm(savealarm);	/* restore alarm */
    153 }
    154 
    155 int
    156 getanswer(choices, def)
    157 	const char   *choices;
    158 	bool    def;
    159 {
    160 	int     ch;		/* input */
    161 	volatile int	loop;	/* counter */
    162 	volatile int	oldx, oldy;	/* original coordinates on screen */
    163 
    164 	getyx(stdscr, oldy, oldx);
    165 	alarm(0);		/* make sure alarm is off */
    166 
    167 	for (loop = 3; loop; --loop)
    168 		/* try for 3 times */
    169 	{
    170 		if (setjmp(Timeoenv) != 0)
    171 			/* timed out waiting for response */
    172 		{
    173 			if (def || loop <= 1)
    174 				/* return default answer */
    175 				break;
    176 			else
    177 				/* prompt, and try again */
    178 				goto YELL;
    179 		} else
    180 			/* wait for response */
    181 		{
    182 			clrtoeol();
    183 			refresh();
    184 #ifdef BSD41
    185 			sigset(SIGALRM, catchalarm);
    186 #else
    187 			signal(SIGALRM, catchalarm);
    188 #endif
    189 			/* set timeout */
    190 			if (Timeout)
    191 				alarm(7);	/* short */
    192 			else
    193 				alarm(600);	/* long */
    194 
    195 			ch = getchar();
    196 
    197 			alarm(0);	/* turn off timeout */
    198 
    199 			if (ch < 0)
    200 				/* caught some signal */
    201 			{
    202 				++loop;
    203 				continue;
    204 			} else
    205 				if (ch == CH_REDRAW)
    206 					/* redraw screen */
    207 				{
    208 					clearok(stdscr, TRUE);	/* force clear screen */
    209 					++loop;	/* don't count this input */
    210 					continue;
    211 				} else
    212 					if (Echo) {
    213 						addch(ch);	/* echo character */
    214 						refresh();
    215 					}
    216 			if (islower(ch))
    217 				/* convert to upper case */
    218 				ch = toupper(ch);
    219 
    220 			if (def || strchr(choices, ch) != NULL)
    221 				/* valid choice */
    222 				return (ch);
    223 			else
    224 				if (!def && loop > 1)
    225 					/* bad choice; prompt, and try again */
    226 				{
    227 			YELL:		mvprintw(oldy + 1, 0, "Please choose one of : [%s]\n", choices);
    228 					move(oldy, oldx);
    229 					clrtoeol();
    230 					continue;
    231 				} else
    232 					/* return default answer */
    233 					break;
    234 		}
    235 	}
    236 
    237 	return (*choices);
    238 }
    239 
    240 void
    241 catchalarm(dummy)
    242 	int dummy __attribute__((__unused__));
    243 {
    244 	longjmp(Timeoenv, 1);
    245 }
    246