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