1 /* $NetBSD: io.c,v 1.5 1999/09/08 21:45:29 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 int loop; /* counter */ 161 int oldx, oldy; /* original coordinates on screen */ 162 163 getyx(stdscr, oldy, oldx); 164 alarm(0); /* make sure alarm is off */ 165 166 #if __GNUC__ 167 (void)&loop; /* XXX quiet gcc */ 168 #endif 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 __attribute__((__unused__)); 245 { 246 longjmp(Timeoenv, 1); 247 } 248