io.c 4.7 KB

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