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