|
|
1.1 ! root 1: /* ! 2: * io.c - input/output routines for Phantasia ! 3: */ ! 4: ! 5: #include "include.h" ! 6: ! 7: /************************************************************************ ! 8: / ! 9: / FUNCTION NAME: getstring() ! 10: / ! 11: / FUNCTION: read a string from operator ! 12: / ! 13: / AUTHOR: E. A. Estes, 12/4/85 ! 14: / ! 15: / ARGUMENTS: ! 16: / char *cp - pointer to buffer area to fill ! 17: / int mx - maximum number of characters to put in buffer ! 18: / ! 19: / RETURN VALUE: none ! 20: / ! 21: / MODULES CALLED: wmove(), _filbuf(), clearok(), waddstr(), wrefresh(), ! 22: / wclrtoeol() ! 23: / ! 24: / GLOBAL INPUTS: Echo, _iob[], Wizard, *stdscr ! 25: / ! 26: / GLOBAL OUTPUTS: _iob[] ! 27: / ! 28: / DESCRIPTION: ! 29: / Read a string from the keyboard. ! 30: / This routine is specially designed to: ! 31: / ! 32: / - strip non-printing characters (unless Wizard) ! 33: / - echo, if desired ! 34: / - redraw the screen if CH_REDRAW is entered ! 35: / - read in only 'mx - 1' characters or less characters ! 36: / - nul-terminate string, and throw away newline ! 37: / ! 38: / 'mx' is assumed to be at least 2. ! 39: / ! 40: /************************************************************************/ ! 41: ! 42: getstring(cp, mx) ! 43: register char *cp; ! 44: register int mx; ! 45: { ! 46: register char *inptr; /* pointer into string for next string */ ! 47: int x, y; /* original x, y coordinates on screen */ ! 48: int ch; /* input */ ! 49: ! 50: getyx(stdscr, y, x); /* get coordinates on screen */ ! 51: inptr = cp; ! 52: *inptr = '\0'; /* clear string to start */ ! 53: --mx; /* reserve room in string for nul terminator */ ! 54: ! 55: do ! 56: /* get characters and process */ ! 57: { ! 58: if (Echo) ! 59: mvaddstr(y, x, cp); /* print string on screen */ ! 60: clrtoeol(); /* clear any data after string */ ! 61: refresh(); /* update screen */ ! 62: ! 63: ch = getchar(); /* get character */ ! 64: ! 65: switch (ch) ! 66: { ! 67: case CH_ERASE: /* back up one character */ ! 68: if (inptr > cp) ! 69: --inptr; ! 70: break; ! 71: ! 72: case CH_KILL: /* back up to original location */ ! 73: inptr = cp; ! 74: break; ! 75: ! 76: case CH_NEWLINE: /* terminate string */ ! 77: break; ! 78: ! 79: case CH_REDRAW: /* redraw screen */ ! 80: clearok(stdscr, TRUE); ! 81: continue; ! 82: ! 83: default: /* put data in string */ ! 84: if (ch >= ' ' || Wizard) ! 85: /* printing char; put in string */ ! 86: *inptr++ = ch; ! 87: } ! 88: ! 89: *inptr = '\0'; /* terminate string */ ! 90: } ! 91: while (ch != CH_NEWLINE && inptr < cp + mx); ! 92: } ! 93: /**/ ! 94: /************************************************************************ ! 95: / ! 96: / FUNCTION NAME: more() ! 97: / ! 98: / FUNCTION: pause and prompt player ! 99: / ! 100: / AUTHOR: E. A. Estes, 12/4/85 ! 101: / ! 102: / ARGUMENTS: ! 103: / int where - line on screen on which to pause ! 104: / ! 105: / RETURN VALUE: none ! 106: / ! 107: / MODULES CALLED: wmove(), waddstr(), getanswer() ! 108: / ! 109: / GLOBAL INPUTS: *stdscr ! 110: / ! 111: / GLOBAL OUTPUTS: none ! 112: / ! 113: / DESCRIPTION: ! 114: / Print a message, and wait for a space character. ! 115: / ! 116: /************************************************************************/ ! 117: ! 118: more(where) ! 119: int where; ! 120: { ! 121: mvaddstr(where, 0, "-- more --"); ! 122: getanswer(" ", FALSE); ! 123: } ! 124: /**/ ! 125: /************************************************************************ ! 126: / ! 127: / FUNCTION NAME: infloat() ! 128: / ! 129: / FUNCTION: input a floating point number from operator ! 130: / ! 131: / AUTHOR: E. A. Estes, 12/4/85 ! 132: / ! 133: / ARGUMENTS: none ! 134: / ! 135: / RETURN VALUE: floating point number from operator ! 136: / ! 137: / MODULES CALLED: sscanf(), getstring() ! 138: / ! 139: / GLOBAL INPUTS: Databuf[] ! 140: / ! 141: / GLOBAL OUTPUTS: none ! 142: / ! 143: / DESCRIPTION: ! 144: / Read a string from player, and scan for a floating point ! 145: / number. ! 146: / If no valid number is found, return 0.0. ! 147: / ! 148: /************************************************************************/ ! 149: ! 150: double ! 151: infloat() ! 152: { ! 153: double result; /* return value */ ! 154: ! 155: getstring(Databuf, SZ_DATABUF); ! 156: if (sscanf(Databuf, "%lf", &result) < 1) ! 157: /* no valid number entered */ ! 158: result = 0.0; ! 159: ! 160: return(result); ! 161: } ! 162: /**/ ! 163: /************************************************************************ ! 164: / ! 165: / FUNCTION NAME: inputoption() ! 166: / ! 167: / FUNCTION: input an option value from player ! 168: / ! 169: / AUTHOR: E. A. Estes, 12/4/85 ! 170: / ! 171: / ARGUMENTS: none ! 172: / ! 173: / RETURN VALUE: none ! 174: / ! 175: / MODULES CALLED: floor(), drandom(), getanswer() ! 176: / ! 177: / GLOBAL INPUTS: Player ! 178: / ! 179: / GLOBAL OUTPUTS: Player ! 180: / ! 181: / DESCRIPTION: ! 182: / Age increases with every move. ! 183: / Refresh screen, and get a single character option from player. ! 184: / Return a random value if player's ring has gone bad. ! 185: / ! 186: /************************************************************************/ ! 187: ! 188: inputoption() ! 189: { ! 190: ++Player.p_age; /* increase age */ ! 191: ! 192: if (Player.p_ring.ring_type != R_SPOILED) ! 193: /* ring ok */ ! 194: return(getanswer("T ", TRUE)); ! 195: else ! 196: /* bad ring */ ! 197: { ! 198: getanswer(" ", TRUE); ! 199: return((int) ROLL(0.0, 5.0) + '0'); ! 200: } ! 201: } ! 202: /**/ ! 203: /************************************************************************ ! 204: / ! 205: / FUNCTION NAME: interrupt() ! 206: / ! 207: / FUNCTION: handle interrupt from operator ! 208: / ! 209: / AUTHOR: E. A. Estes, 12/4/85 ! 210: / ! 211: / ARGUMENTS: none ! 212: / ! 213: / RETURN VALUE: none ! 214: / ! 215: / MODULES CALLED: fork(), exit(), wait(), death(), alarm(), execl(), wmove(), ! 216: / getgid(), signal(), getenv(), wclear(), setuid(), getuid(), setgid(), ! 217: / crmode(), clearok(), waddstr(), cleanup(), wrefresh(), leavegame(), ! 218: / getanswer() ! 219: / ! 220: / GLOBAL INPUTS: Player, *stdscr ! 221: / ! 222: / GLOBAL OUTPUTS: none ! 223: / ! 224: / DESCRIPTION: ! 225: / Allow player to quit upon hitting the interrupt key. ! 226: / If the player wants to quit while in battle, he/she automatically ! 227: / dies. ! 228: / ! 229: /************************************************************************/ ! 230: ! 231: interrupt() ! 232: { ! 233: char line[81]; /* a place to store data already on screen */ ! 234: register int loop; /* counter */ ! 235: int x, y; /* coordinates on screen */ ! 236: int ch; /* input */ ! 237: unsigned savealarm; /* to save alarm value */ ! 238: ! 239: #ifdef SYS3 ! 240: signal(SIGINT, SIG_IGN); ! 241: #endif ! 242: #ifdef SYS5 ! 243: signal(SIGINT, SIG_IGN); ! 244: #endif ! 245: ! 246: savealarm = alarm(0); /* turn off any alarms */ ! 247: ! 248: getyx(stdscr, y, x); /* save cursor location */ ! 249: ! 250: for (loop = 0; loop < 80; ++loop) /* save line on screen */ ! 251: { ! 252: move(4, loop); ! 253: line[loop] = inch(); ! 254: } ! 255: line[80] = '\0'; /* nul terminate */ ! 256: ! 257: if (Player.p_status == S_INBATTLE || Player.p_status == S_MONSTER) ! 258: /* in midst of fighting */ ! 259: { ! 260: mvaddstr(4, 0, "Quitting now will automatically kill your character. Still want to ? "); ! 261: ch = getanswer("NY", FALSE); ! 262: if (ch == 'Y') ! 263: death("Bailing out"); ! 264: /*NOTREACHED*/ ! 265: } ! 266: else ! 267: { ! 268: mvaddstr(4, 0, "Do you really want to quit ? "); ! 269: ch = getanswer("NY", FALSE); ! 270: if (ch == 'Y') ! 271: leavegame(); ! 272: /*NOTREACHED*/ ! 273: } ! 274: ! 275: mvaddstr(4, 0, line); /* restore data on screen */ ! 276: move(y, x); /* restore cursor */ ! 277: refresh(); ! 278: ! 279: #ifdef SYS3 ! 280: signal(SIGINT, interrupt); ! 281: #endif ! 282: #ifdef SYS5 ! 283: signal(SIGINT, interrupt); ! 284: #endif ! 285: ! 286: alarm(savealarm); /* restore alarm */ ! 287: } ! 288: /**/ ! 289: /************************************************************************ ! 290: / ! 291: / FUNCTION NAME: getanswer() ! 292: / ! 293: / FUNCTION: get an answer from operator ! 294: / ! 295: / AUTHOR: E. A. Estes, 12/4/85 ! 296: / ! 297: / ARGUMENTS: ! 298: / char *choices - string of (upper case) valid choices ! 299: / bool def - set if default answer ! 300: / ! 301: / RETURN VALUE: none ! 302: / ! 303: / MODULES CALLED: alarm(), wmove(), waddch(), signal(), setjmp(), strchr(), ! 304: / _filbuf(), clearok(), toupper(), wrefresh(), mvprintw(), wclrtoeol() ! 305: / ! 306: / GLOBAL INPUTS: catchalarm(), Echo, _iob[], _ctype[], *stdscr, Timeout, ! 307: / Timeoenv[] ! 308: / ! 309: / GLOBAL OUTPUTS: _iob[] ! 310: / ! 311: / DESCRIPTION: ! 312: / Get a single character answer from operator. ! 313: / Timeout waiting for response. If we timeout, or the ! 314: / answer in not in the list of valid choices, print choices, ! 315: / and wait again, otherwise return the first character in ths ! 316: / list of choices. ! 317: / Give up after 3 tries. ! 318: / ! 319: /************************************************************************/ ! 320: ! 321: getanswer(choices, def) ! 322: char *choices; ! 323: bool def; ! 324: { ! 325: int ch; /* input */ ! 326: int loop; /* counter */ ! 327: int oldx, oldy; /* original coordinates on screen */ ! 328: ! 329: getyx(stdscr, oldy, oldx); ! 330: alarm(0); /* make sure alarm is off */ ! 331: ! 332: for (loop = 3; loop; --loop) ! 333: /* try for 3 times */ ! 334: { ! 335: if (setjmp(Timeoenv) != 0) ! 336: /* timed out waiting for response */ ! 337: { ! 338: if (def || loop <= 1) ! 339: /* return default answer */ ! 340: break; ! 341: else ! 342: /* prompt, and try again */ ! 343: goto YELL; ! 344: } ! 345: else ! 346: /* wait for response */ ! 347: { ! 348: clrtoeol(); ! 349: refresh(); ! 350: #ifdef BSD41 ! 351: sigset(SIGALRM, catchalarm); ! 352: #else ! 353: signal(SIGALRM, catchalarm); ! 354: #endif ! 355: /* set timeout */ ! 356: if (Timeout) ! 357: alarm(7); /* short */ ! 358: else ! 359: alarm(600); /* long */ ! 360: ! 361: ch = getchar(); ! 362: ! 363: alarm(0); /* turn off timeout */ ! 364: ! 365: if (ch < 0) ! 366: /* caught some signal */ ! 367: { ! 368: ++loop; ! 369: continue; ! 370: } ! 371: else if (ch == CH_REDRAW) ! 372: /* redraw screen */ ! 373: { ! 374: clearok(stdscr, TRUE); /* force clear screen */ ! 375: ++loop; /* don't count this input */ ! 376: continue; ! 377: } ! 378: else if (Echo) ! 379: { ! 380: addch(ch); /* echo character */ ! 381: refresh(); ! 382: } ! 383: ! 384: if (islower(ch)) ! 385: /* convert to upper case */ ! 386: ch = toupper(ch); ! 387: ! 388: if (def || strchr(choices, ch) != NULL) ! 389: /* valid choice */ ! 390: return(ch); ! 391: else if (!def && loop > 1) ! 392: /* bad choice; prompt, and try again */ ! 393: { ! 394: YELL: mvprintw(oldy + 1, 0, "Please choose one of : [%s]\n", choices); ! 395: move(oldy, oldx); ! 396: clrtoeol(); ! 397: continue; ! 398: } ! 399: else ! 400: /* return default answer */ ! 401: break; ! 402: } ! 403: } ! 404: ! 405: return(*choices); ! 406: } ! 407: /**/ ! 408: /************************************************************************ ! 409: / ! 410: / FUNCTION NAME: catchalarm() ! 411: / ! 412: / FUNCTION: catch timer when waiting for input ! 413: / ! 414: / AUTHOR: E. A. Estes, 12/4/85 ! 415: / ! 416: / ARGUMENTS: none ! 417: / ! 418: / RETURN VALUE: none ! 419: / ! 420: / MODULES CALLED: longjmp() ! 421: / ! 422: / GLOBAL INPUTS: Timeoenv[] ! 423: / ! 424: / GLOBAL OUTPUTS: none ! 425: / ! 426: / DESCRIPTION: ! 427: / Come here when the alarm expires while waiting for input. ! 428: / Simply longjmp() into getanswer(). ! 429: / ! 430: /************************************************************************/ ! 431: ! 432: catchalarm() ! 433: { ! 434: longjmp(Timeoenv, 1); ! 435: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.