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