From bcced3608bdd120315d4ed1d9b9478f7caa4a2f1 Mon Sep 17 00:00:00 2001 From: jtc Date: Fri, 21 Oct 1994 21:19:39 +0000 Subject: phantasia(6), from 44lite --- phantasia/io.c | 436 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 436 insertions(+) create mode 100644 phantasia/io.c (limited to 'phantasia/io.c') diff --git a/phantasia/io.c b/phantasia/io.c new file mode 100644 index 00000000..addf1c9b --- /dev/null +++ b/phantasia/io.c @@ -0,0 +1,436 @@ +/* + * io.c - input/output routines for Phantasia + */ + +#include "include.h" + +/************************************************************************ +/ +/ FUNCTION NAME: getstring() +/ +/ FUNCTION: read a string from operator +/ +/ AUTHOR: E. A. Estes, 12/4/85 +/ +/ ARGUMENTS: +/ char *cp - pointer to buffer area to fill +/ int mx - maximum number of characters to put in buffer +/ +/ RETURN VALUE: none +/ +/ MODULES CALLED: wmove(), _filbuf(), clearok(), waddstr(), wrefresh(), +/ wclrtoeol() +/ +/ GLOBAL INPUTS: Echo, _iob[], Wizard, *stdscr +/ +/ GLOBAL OUTPUTS: _iob[] +/ +/ DESCRIPTION: +/ Read a string from the keyboard. +/ This routine is specially designed to: +/ +/ - strip non-printing characters (unless Wizard) +/ - echo, if desired +/ - redraw the screen if CH_REDRAW is entered +/ - read in only 'mx - 1' characters or less characters +/ - nul-terminate string, and throw away newline +/ +/ 'mx' is assumed to be at least 2. +/ +/************************************************************************/ + +getstring(cp, mx) +register char *cp; +register int mx; +{ +register char *inptr; /* pointer into string for next string */ +int x, y; /* original x, y coordinates on screen */ +int ch; /* input */ + + getyx(stdscr, y, x); /* get coordinates on screen */ + inptr = cp; + *inptr = '\0'; /* clear string to start */ + --mx; /* reserve room in string for nul terminator */ + + do + /* get characters and process */ + { + if (Echo) + mvaddstr(y, x, cp); /* print string on screen */ + clrtoeol(); /* clear any data after string */ + refresh(); /* update screen */ + + ch = getchar(); /* get character */ + + switch (ch) + { + case CH_ERASE: /* back up one character */ + if (inptr > cp) + --inptr; + break; + + case CH_KILL: /* back up to original location */ + inptr = cp; + break; + + case CH_NEWLINE: /* terminate string */ + break; + + case CH_REDRAW: /* redraw screen */ + clearok(stdscr, TRUE); + continue; + + default: /* put data in string */ + if (ch >= ' ' || Wizard) + /* printing char; put in string */ + *inptr++ = ch; + } + + *inptr = '\0'; /* terminate string */ + } + while (ch != CH_NEWLINE && inptr < cp + mx); +} +/* */ +/************************************************************************ +/ +/ FUNCTION NAME: more() +/ +/ FUNCTION: pause and prompt player +/ +/ AUTHOR: E. A. Estes, 12/4/85 +/ +/ ARGUMENTS: +/ int where - line on screen on which to pause +/ +/ RETURN VALUE: none +/ +/ MODULES CALLED: wmove(), waddstr(), getanswer() +/ +/ GLOBAL INPUTS: *stdscr +/ +/ GLOBAL OUTPUTS: none +/ +/ DESCRIPTION: +/ Print a message, and wait for a space character. +/ +/************************************************************************/ + +more(where) +int where; +{ + mvaddstr(where, 0, "-- more --"); + getanswer(" ", FALSE); +} +/* */ +/************************************************************************ +/ +/ FUNCTION NAME: infloat() +/ +/ FUNCTION: input a floating point number from operator +/ +/ AUTHOR: E. A. Estes, 12/4/85 +/ +/ ARGUMENTS: none +/ +/ RETURN VALUE: floating point number from operator +/ +/ MODULES CALLED: sscanf(), getstring() +/ +/ GLOBAL INPUTS: Databuf[] +/ +/ GLOBAL OUTPUTS: none +/ +/ DESCRIPTION: +/ Read a string from player, and scan for a floating point +/ number. +/ If no valid number is found, return 0.0. +/ +/************************************************************************/ + +double +infloat() +{ +double result; /* return value */ + + getstring(Databuf, SZ_DATABUF); + if (sscanf(Databuf, "%lf", &result) < 1) + /* no valid number entered */ + result = 0.0; + + return(result); +} +/* */ +/************************************************************************ +/ +/ FUNCTION NAME: inputoption() +/ +/ FUNCTION: input an option value from player +/ +/ AUTHOR: E. A. Estes, 12/4/85 +/ +/ ARGUMENTS: none +/ +/ RETURN VALUE: none +/ +/ MODULES CALLED: floor(), drandom(), getanswer() +/ +/ GLOBAL INPUTS: Player +/ +/ GLOBAL OUTPUTS: Player +/ +/ DESCRIPTION: +/ Age increases with every move. +/ Refresh screen, and get a single character option from player. +/ Return a random value if player's ring has gone bad. +/ +/************************************************************************/ + +inputoption() +{ + ++Player.p_age; /* increase age */ + + if (Player.p_ring.ring_type != R_SPOILED) + /* ring ok */ + return(getanswer("T ", TRUE)); + else + /* bad ring */ + { + getanswer(" ", TRUE); + return((int) ROLL(0.0, 5.0) + '0'); + } +} +/* */ +/************************************************************************ +/ +/ FUNCTION NAME: interrupt() +/ +/ FUNCTION: handle interrupt from operator +/ +/ AUTHOR: E. A. Estes, 12/4/85 +/ +/ ARGUMENTS: none +/ +/ RETURN VALUE: none +/ +/ MODULES CALLED: fork(), exit(), wait(), death(), alarm(), execl(), wmove(), +/ getgid(), signal(), getenv(), wclear(), setuid(), getuid(), setgid(), +/ crmode(), clearok(), waddstr(), cleanup(), wrefresh(), leavegame(), +/ getanswer() +/ +/ GLOBAL INPUTS: Player, *stdscr +/ +/ GLOBAL OUTPUTS: none +/ +/ DESCRIPTION: +/ Allow player to quit upon hitting the interrupt key. +/ If the player wants to quit while in battle, he/she automatically +/ dies. +/ +/************************************************************************/ + +interrupt() +{ +char line[81]; /* a place to store data already on screen */ +register int loop; /* counter */ +int x, y; /* coordinates on screen */ +int ch; /* input */ +unsigned savealarm; /* to save alarm value */ + +#ifdef SYS3 + signal(SIGINT, SIG_IGN); +#endif +#ifdef SYS5 + signal(SIGINT, SIG_IGN); +#endif + + savealarm = alarm(0); /* turn off any alarms */ + + getyx(stdscr, y, x); /* save cursor location */ + + for (loop = 0; loop < 80; ++loop) /* save line on screen */ + { + move(4, loop); + line[loop] = inch(); + } + line[80] = '\0'; /* nul terminate */ + + if (Player.p_status == S_INBATTLE || Player.p_status == S_MONSTER) + /* in midst of fighting */ + { + mvaddstr(4, 0, "Quitting now will automatically kill your character. Still want to ? "); + ch = getanswer("NY", FALSE); + if (ch == 'Y') + death("Bailing out"); + /*NOTREACHED*/ + } + else + { + mvaddstr(4, 0, "Do you really want to quit ? "); + ch = getanswer("NY", FALSE); + if (ch == 'Y') + leavegame(); + /*NOTREACHED*/ + } + + mvaddstr(4, 0, line); /* restore data on screen */ + move(y, x); /* restore cursor */ + refresh(); + +#ifdef SYS3 + signal(SIGINT, interrupt); +#endif +#ifdef SYS5 + signal(SIGINT, interrupt); +#endif + + alarm(savealarm); /* restore alarm */ +} +/* */ +/************************************************************************ +/ +/ FUNCTION NAME: getanswer() +/ +/ FUNCTION: get an answer from operator +/ +/ AUTHOR: E. A. Estes, 12/4/85 +/ +/ ARGUMENTS: +/ char *choices - string of (upper case) valid choices +/ bool def - set if default answer +/ +/ RETURN VALUE: none +/ +/ MODULES CALLED: alarm(), wmove(), waddch(), signal(), setjmp(), strchr(), +/ _filbuf(), clearok(), toupper(), wrefresh(), mvprintw(), wclrtoeol() +/ +/ GLOBAL INPUTS: catchalarm(), Echo, _iob[], _ctype[], *stdscr, Timeout, +/ Timeoenv[] +/ +/ GLOBAL OUTPUTS: _iob[] +/ +/ DESCRIPTION: +/ Get a single character answer from operator. +/ Timeout waiting for response. If we timeout, or the +/ answer in not in the list of valid choices, print choices, +/ and wait again, otherwise return the first character in ths +/ list of choices. +/ Give up after 3 tries. +/ +/************************************************************************/ + +getanswer(choices, def) +char *choices; +bool def; +{ +int ch; /* input */ +int loop; /* counter */ +int oldx, oldy; /* original coordinates on screen */ + + getyx(stdscr, oldy, oldx); + alarm(0); /* make sure alarm is off */ + + for (loop = 3; loop; --loop) + /* try for 3 times */ + { + if (setjmp(Timeoenv) != 0) + /* timed out waiting for response */ + { + if (def || loop <= 1) + /* return default answer */ + break; + else + /* prompt, and try again */ + goto YELL; + } + else + /* wait for response */ + { + clrtoeol(); + refresh(); +#ifdef BSD41 + sigset(SIGALRM, catchalarm); +#else + signal(SIGALRM, catchalarm); +#endif + /* set timeout */ + if (Timeout) + alarm(7); /* short */ + else + alarm(600); /* long */ + + ch = getchar(); + + alarm(0); /* turn off timeout */ + + if (ch < 0) + /* caught some signal */ + { + ++loop; + continue; + } + else if (ch == CH_REDRAW) + /* redraw screen */ + { + clearok(stdscr, TRUE); /* force clear screen */ + ++loop; /* don't count this input */ + continue; + } + else if (Echo) + { + addch(ch); /* echo character */ + refresh(); + } + + if (islower(ch)) + /* convert to upper case */ + ch = toupper(ch); + + if (def || strchr(choices, ch) != NULL) + /* valid choice */ + return(ch); + else if (!def && loop > 1) + /* bad choice; prompt, and try again */ + { +YELL: mvprintw(oldy + 1, 0, "Please choose one of : [%s]\n", choices); + move(oldy, oldx); + clrtoeol(); + continue; + } + else + /* return default answer */ + break; + } + } + + return(*choices); +} +/* */ +/************************************************************************ +/ +/ FUNCTION NAME: catchalarm() +/ +/ FUNCTION: catch timer when waiting for input +/ +/ AUTHOR: E. A. Estes, 12/4/85 +/ +/ ARGUMENTS: none +/ +/ RETURN VALUE: none +/ +/ MODULES CALLED: longjmp() +/ +/ GLOBAL INPUTS: Timeoenv[] +/ +/ GLOBAL OUTPUTS: none +/ +/ DESCRIPTION: +/ Come here when the alarm expires while waiting for input. +/ Simply longjmp() into getanswer(). +/ +/************************************************************************/ + +void +catchalarm() +{ + longjmp(Timeoenv, 1); +} -- cgit v1.2.3-56-ge451