home *** CD-ROM | disk | FTP | other *** search
/ Hall of Fame / HallofFameCDROM.cdr / proglc / mor4873s.lzh / IO.C < prev    next >
C/C++ Source or Header  |  1988-12-14  |  13KB  |  633 lines

  1. #include <curses.h>
  2. #if defined(MSDOS) && defined(ANSI)
  3. #include "ms_ansi.h"
  4. #else
  5. #include <sys/types.h>
  6. #include <sys/ioctl.h>
  7. #include <sys/file.h>
  8. #endif
  9.  
  10. #include "constant.h"
  11. #include "config.h"
  12. #include "types.h"
  13. #include "externs.h"
  14.  
  15. #ifdef USG
  16. #include <string.h>
  17. #else
  18. #include <strings.h>
  19. #include <sgtty.h>
  20. #include <sys/wait.h>
  21. #endif
  22.  
  23. #ifdef sun   /* correct SUN stupidity in the stdio.h file */
  24. char *sprintf();
  25. #endif
  26.  
  27. vtype pad_output;   /* static output string for the pad function */
  28.  
  29. char *getenv();
  30.  
  31. vtype old_msg[SAVED_MSGS];      /* Last messages      */
  32. int last_message = 0;           /* Number of last msg generated in old_msg */
  33. int last_displayed_msg = 0;     /* Number of last msg printed (^M) */
  34. int repeating_old_msg = 0;      /* flag which lets repeat_msg call msg_print */
  35.  
  36. /* value of msg flag at start of turn */
  37. extern int save_msg_flag;
  38.  
  39. #ifdef USG
  40. void exit();
  41. unsigned sleep();
  42. #endif
  43. #ifdef ultrix
  44. void exit();
  45. void sleep();
  46. #endif
  47.  
  48. #ifdef USG
  49. /* no local special characters */
  50. #else
  51. struct ltchars save_special_chars;
  52. #endif
  53.  
  54. /* initializes curses routines */
  55. init_curses()
  56. {
  57. #ifdef USG
  58.   /* no local special characters */
  59. #else
  60.   struct ltchars buf;
  61. #endif
  62.  
  63. #if defined(USG) && !defined(PC_CURSES)    /* PC curses returns ERR */
  64.   if (initscr() == NULL)
  65. #else
  66.   if (initscr() == ERR)
  67. #endif
  68.     {
  69.       (void) printf("error allocating screen in curses package\n");
  70.       exit(0); /* exit_game(); */
  71.     }
  72.   clear();
  73. #ifdef USG
  74.   saveterm();
  75. #endif
  76. #if defined(ultrix)
  77.   crmode();
  78. #else
  79.   cbreak();
  80. #endif
  81.   noecho();
  82. #ifndef BUGGY_CURSES
  83.   nonl();
  84. #endif
  85. #ifdef MSDOS
  86.   msdos_raw();
  87. #endif
  88.   /* save old settings of the local special characters */
  89. #ifdef USG
  90.   /* no local special characters */
  91. #else
  92.   (void) ioctl(0, TIOCGLTC, (char *)&save_special_chars);
  93.   /* disable all of the local special characters except the suspend char */
  94.   /* have to disable ^Y for tunneling */
  95.   buf.t_suspc = (char)26;  /* control-Z */
  96.   buf.t_dsuspc = (char)-1;
  97.   buf.t_rprntc = (char)-1;
  98.   buf.t_flushc = (char)-1;
  99.   buf.t_werasc = (char)-1;
  100.   buf.t_lnextc = (char)-1;
  101.   (void) ioctl(0, TIOCSLTC, (char *)&buf);
  102. #endif
  103. }
  104.  
  105.  
  106. /* Dump IO to buffer                    -RAK-    */
  107. put_buffer(out_str, row, col)
  108. char *out_str;
  109. int row, col;
  110. {
  111.   vtype tmp_str;
  112.  
  113.   if (mvaddstr(row, col, out_str) == ERR)
  114.     {
  115.       (void) sprintf(tmp_str, "error row = %d col = %d\n", row, col);
  116.       prt(tmp_str, 0, 0);
  117.       /* wait so user can see error */
  118.       (void) sleep(2);
  119.     }
  120. }
  121.  
  122.  
  123. /* Dump the IO buffer to terminal            -RAK-    */
  124. put_qio()
  125. {
  126.   refresh();
  127. }
  128.  
  129.  
  130. shell_out()
  131. {
  132. #ifdef MSDOS
  133. #include <process.h>
  134.   char    *comspec, key;
  135. #else
  136.   int val;
  137.   char *str;
  138. #endif
  139. #ifdef USG
  140.   /* no local special characters */
  141. #else
  142.   struct ltchars buf;
  143. #endif
  144.  
  145.   /* clear screen and print 'exit' message */
  146.   clear_screen(0, 0);
  147.   prt("[Entering shell, type 'exit' to resume your game]\n",0,0);
  148.   put_qio();
  149.  
  150. #ifndef BUGGY_CURSES
  151.   nl();
  152. #endif
  153. #if defined(ultrix)
  154.   nocrmode();
  155. #else
  156.   nocbreak();
  157. #endif
  158. #ifdef MSDOS
  159.   msdos_noraw();
  160. #endif
  161.   echo();
  162.   ignore_signals();
  163. #ifdef MSDOS        /*{*/
  164.   if ((comspec = getenv("COMSPEC")) == NULL
  165.   ||  spawnl(P_WAIT, comspec, comspec, (char *) NULL) < 0) {
  166.       clear_screen(0, 0);    /* BOSS key if shell failed */
  167.       prt("M:\\> ", 0, 0);
  168.       do {
  169.           inkey(&key);
  170.       } while (key != '!');
  171.   }
  172.  
  173. #else        /* MSDOS }{*/
  174.   val = fork();
  175.   if (val == 0)
  176.     {
  177.       default_signals();
  178. #ifdef USG
  179.       /* no local special characters */
  180.       resetterm();
  181. #else
  182.       (void) ioctl(0, TIOCSLTC, (char *)&save_special_chars);
  183. #endif
  184.       /* close scoreboard descriptor */
  185.       (void) close(highscore_fd);
  186.       if (str = getenv("SHELL"))
  187.     (void) execl(str, str, (char *) 0);
  188.       else
  189.     (void) execl("/bin/sh", "sh", (char *) 0);
  190.       msg_print("Cannot execute shell");
  191.       exit(1);
  192.     }
  193.   if (val == -1)
  194.     {
  195.       msg_print("Fork failed. Try again.");
  196.       return;
  197.     }
  198. #ifdef USG
  199.   (void) wait((int *) 0);
  200. #else
  201.   (void) wait((union wait *) 0);
  202. #endif
  203. #endif         /* MSDOS }*/
  204.   restore_signals();
  205.   /* restore the cave to the screen */
  206.   really_clear_screen();
  207.   draw_cave();
  208. #if defined(ultrix)
  209.   crmode();
  210. #else
  211.   cbreak();
  212. #endif
  213.   noecho();
  214. #ifndef BUGGY_CURSES
  215.   nonl();
  216. #endif
  217. #ifdef MSDOS
  218.   msdos_raw();
  219. #endif
  220.   /* disable all of the local special characters except the suspend char */
  221.   /* have to disable ^Y for tunneling */
  222. #ifdef USG
  223.   /* no local special characters */
  224. #else
  225.   buf.t_suspc = (char)26;  /* control-Z */
  226.   buf.t_dsuspc = (char)-1;
  227.   buf.t_rprntc = (char)-1;
  228.   buf.t_flushc = (char)-1;
  229.   buf.t_werasc = (char)-1;
  230.   buf.t_lnextc = (char)-1;
  231.   (void) ioctl(0, TIOCSLTC, (char *)&buf);
  232. #endif
  233. }
  234.  
  235. exit_game()
  236. {
  237.   /* restore the saved values of the local special chars */
  238.   put_qio();    /* Dump any remaining buffer    */
  239. #ifdef MSDOS
  240.   sleep(2);    /* And let it be read */
  241. #endif
  242.   endwin();     /* exit curses */
  243.   echo();
  244. #ifndef BUGGY_CURSES
  245.   nl();
  246. #endif
  247. #if defined(ultrix)
  248.   nocrmode();
  249. #else
  250.   nocbreak();
  251. #endif
  252. #ifdef MSDOS
  253.   msdos_noraw();
  254.   clear();
  255. #endif
  256. #ifdef USG
  257.   /* no local special characters */
  258.   resetterm();
  259. #else
  260.   (void) ioctl(0, TIOCSLTC, (char *)&save_special_chars);
  261. #endif
  262.   exit(0);    /* exit from game        */
  263. }
  264.  
  265.  
  266. /* Gets single character from keyboard and returns        */
  267. inkey(ch)
  268. char *ch;
  269. {
  270.   put_qio();            /* Dump IO buffer        */
  271. #ifdef MSDOS
  272.   *ch = msdos_getch();
  273. #else
  274.   *ch = getch();
  275. #endif
  276.   msg_flag = FALSE;
  277. }
  278.  
  279.  
  280. /* Flush the buffer                    -RAK-    */
  281. flush()
  282. {
  283. #ifdef MSDOS
  284.   while (kbhit())
  285.     (void) getch();
  286. #else
  287. #ifdef USG
  288.   (void) ioctl(0, TCFLSH, 0);  /* flush the input queue */
  289. #else
  290.   int arg;
  291.  
  292.   arg = FREAD;
  293.   (void) ioctl(0, TIOCFLUSH, (char *)&arg);   /* flush all input */
  294. #endif
  295. #endif
  296. }
  297.  
  298.  
  299. #if 0
  300. /* this is no longer used anywhere */
  301. /* Flush buffer before input                -RAK-    */
  302. inkey_flush(x)
  303. char *x;
  304. {
  305.   if (!wizard1)  flush();
  306.   inkey(x);
  307. }
  308. #endif
  309.  
  310. /* Clears given line of text                -RAK-    */
  311. erase_line(row, col)
  312. int row;
  313. int col;
  314. {
  315.   move(row, col);
  316.   clrtoeol();
  317.   if (row == MSG_LINE)
  318.     msg_flag = FALSE;
  319. }
  320.  
  321.  
  322. /* Clears screen at given row, column                */
  323. clear_screen(row, col)
  324. int row, col;
  325. {
  326.   register int i;
  327.  
  328.   for (i = row; i < 23; i++)
  329.     used_line[i] = FALSE;
  330.   move(row, col);
  331.   clrtobot();
  332.   msg_flag = FALSE;
  333. }
  334.  
  335.  
  336. /* Clears entire screen, even if there are characters that curses
  337.    does not know about */
  338. really_clear_screen()
  339. {
  340.   register int i;
  341.  
  342.   for (i = 1; i < 23; i++)
  343.     used_line[i] = FALSE;
  344.   clear();
  345. #if defined(MSDOS) && defined(PC_CURSES)
  346.   bios_clear();            /* PC_curses bug */
  347. #endif
  348.   msg_flag = FALSE;
  349. }
  350.  
  351.  
  352. /* Outputs a line to a given interpolated y, x position    -RAK-    */
  353. print(str_buff, row, col)
  354. char *str_buff;
  355. int row;
  356. int col;
  357. {
  358.   row -= panel_row_prt;/* Real co-ords convert to screen positions */
  359.   col -= panel_col_prt;
  360.   used_line[row] = TRUE;
  361.   put_buffer(str_buff, row, col);
  362. }
  363.  
  364.  
  365. /* Outputs a line to a given y, x position        -RAK-    */
  366. prt(str_buff, row, col)
  367. char *str_buff;
  368. int row;
  369. int col;
  370. {
  371.   move(row, col);
  372.   clrtoeol();
  373.   put_buffer(str_buff, row, col);
  374. }
  375.  
  376.  
  377. /* move cursor to a given y, x position */
  378. move_cursor(row, col)
  379. int row, col;
  380. {
  381.   move (row, col);
  382. }
  383.  
  384.  
  385. /* Outputs message to top line of screen                */
  386. msg_print(str_buff)
  387. char *str_buff;
  388. {
  389.   register int old_len;
  390.   char in_char;
  391.   register int do_flush = 0;
  392.  
  393.   /* stop the character if s/he is in a run */
  394.   if (find_flag)
  395.     {
  396.       find_flag = FALSE;
  397.       move_light (char_row, char_col, char_row, char_col);
  398.     }
  399.  
  400.   if (msg_flag)
  401.     {
  402.       old_len = strlen(old_msg[last_message]) + 1;
  403.       put_buffer(" -more-", MSG_LINE, old_len);
  404.       /* let sigint handler know that we are waiting for a space */
  405.       wait_for_more = 1;
  406.       do
  407.     {
  408.       inkey(&in_char);
  409.     }
  410.       while ((in_char != ' ') && (in_char != '\033'));
  411.       wait_for_more = 0;
  412.       do_flush = 1;
  413.     }
  414.   move(MSG_LINE, 0);
  415.   clrtoeol();
  416.   if (do_flush)
  417.     put_qio();
  418.   put_buffer(str_buff, MSG_LINE, 0);
  419.  
  420.   if (!repeating_old_msg)
  421.     {
  422.       /* increment last message pointer */
  423.       last_message++;
  424.       if (last_message == SAVED_MSGS)
  425.     last_message = 0;
  426.       last_displayed_msg = last_message;
  427.       (void) strncpy(old_msg[last_message], str_buff, VTYPESIZ);
  428.       old_msg[last_message][VTYPESIZ - 1] = '\0';
  429.     }
  430.   msg_flag = TRUE;
  431. }
  432.  
  433.  
  434. /* repeat an old message */
  435. repeat_msg ()
  436. {
  437.   repeating_old_msg = 1;
  438.   /* if message still visible, decrement counter to display previous one */
  439.   if (save_msg_flag)
  440.     {
  441.       if (last_displayed_msg == 0)
  442.     last_displayed_msg = SAVED_MSGS;
  443.       last_displayed_msg--;
  444.       msg_flag = FALSE;
  445.       msg_print (old_msg[last_displayed_msg]);
  446.     }
  447.   else  /* display current message */
  448.     msg_print (old_msg[last_displayed_msg]);
  449.   repeating_old_msg = 0;
  450. }
  451.  
  452. /* Prompts (optional) and returns ord value of input char    */
  453. /* Function returns false if <ESCAPE> is input    */
  454. get_com(prompt, command)
  455. char *prompt;
  456. char *command;
  457. {
  458.   int com_val;
  459.   int res;
  460.  
  461.   if (strlen(prompt) > 1)
  462.     prt(prompt, 0, 0);
  463.   inkey(command);
  464.   com_val = (*command);
  465.   switch(com_val)
  466.     {
  467.     case 0: case 27:
  468.       res = FALSE;
  469.       break;
  470.     default:
  471.       res = TRUE;
  472.       break;
  473.     }
  474.   erase_line(MSG_LINE, 0);
  475.   msg_flag = FALSE;
  476.   return(res);
  477. }
  478.  
  479.  
  480. /* Gets a string terminated by <RETURN>                */
  481. /* Function returns false if <ESCAPE>, CNTL/(Y, C, Z) is input    */
  482. int get_string(in_str, row, column, slen)
  483. char *in_str;
  484. int row, column, slen;
  485. {
  486.   register int start_col, end_col, i;
  487.   char x;
  488.   char tmp[2];
  489.   int flag, abort;
  490.  
  491.   abort = FALSE;
  492.   flag  = FALSE;
  493.   in_str[0] = '\0';
  494.   tmp[1] = '\0';
  495.   put_buffer(pad(in_str, " ", slen), row, column);
  496.   put_buffer("\0", row, column);
  497.   start_col = column;
  498.   end_col = column + slen - 1;
  499.   do
  500.     {
  501.       inkey(&x);
  502.       switch(x)
  503.     {
  504.     case 27:
  505.       abort = TRUE;
  506.       break;
  507.     case 10: case 13:
  508.       flag  = TRUE;
  509.       break;
  510.     case 127: case 8:
  511.       if (column > start_col)
  512.         {
  513.           column--;
  514.           put_buffer(" \b", row, column);
  515.           in_str[strlen(in_str)-1] = '\0';
  516.         }
  517.       break;
  518.     default:
  519.       tmp[0] = x;
  520.       put_buffer(tmp, row, column);
  521.       (void) strcat(in_str, tmp);
  522.       column++;
  523.       if (column > end_col)
  524.         flag = TRUE;
  525.       break;
  526.     }
  527.     }
  528.   while ((!flag) && (!abort));
  529.   if (abort)
  530.     return(FALSE);
  531.   else
  532.     {            /* Remove trailing blanks    */
  533.       i = strlen(in_str);
  534.       if (i > 0)
  535.     {
  536.       while ((in_str[i] == ' ') && (i > 0))
  537.         i--;
  538.       in_str[i+1] = '\0';
  539.     }
  540.     }
  541.   return(TRUE);
  542. }
  543.  
  544.  
  545. /* Return integer value of hex string            -RAK-    */
  546. int get_hex_value(row, col, slen)
  547. int row, col, slen;
  548. {
  549.   vtype tmp_str;
  550.   int hex_value;
  551.  
  552.   hex_value = 0;
  553.   if (get_string(tmp_str, row, col, slen))
  554.     if (strlen(tmp_str) <= 8)
  555.       {
  556.     (void) sscanf(tmp_str, "%x", &hex_value);
  557.       }
  558.   return(hex_value);
  559. }
  560.  
  561.  
  562. /* Pauses for user response before returning        -RAK-    */
  563. pause_line(prt_line)
  564. int prt_line;
  565. {
  566.   char dummy;
  567.  
  568.   prt("[Press any key to continue]", prt_line, 23);
  569.   inkey(&dummy);
  570.   erase_line(23, 0);
  571. }
  572.  
  573.  
  574. /* Pauses for user response before returning        -RAK-    */
  575. /* NOTE: Delay is for players trying to roll up "perfect"    */
  576. /*    characters.  Make them wait a bit...            */
  577. pause_exit(prt_line, delay)
  578. int prt_line;
  579. int delay;
  580. {
  581.   char dummy;
  582.  
  583.   prt("[Press any key to continue, or Q to exit]", prt_line, 10);
  584.   inkey(&dummy);
  585.   switch(dummy)
  586.     {
  587.     case 'Q':
  588.       erase_line(prt_line, 0);
  589. #ifndef MSDOS        /* PCs are slow enough as is  -dgk */
  590.       if (delay > 0)  (void) sleep((unsigned)delay);
  591. #endif
  592.       exit_game();
  593.       break;
  594.     default:
  595.       break;
  596.     }
  597.   erase_line(prt_line, 0);
  598. }
  599.  
  600.  
  601. /* pad a string with fill characters to specified length */
  602. char *pad(string, fill, filllength)
  603. char *string;
  604. char *fill;
  605. int filllength;
  606. {
  607.   register int length, i;
  608.  
  609.   (void) strcpy(pad_output, string);
  610.   length = strlen(pad_output);
  611.   for (i = length; i < filllength; i++)
  612.     pad_output[i] = *fill;
  613.   pad_output[i] = '\0';
  614.   return(pad_output);
  615. }
  616.  
  617. int confirm()
  618. {
  619.   char command;
  620.  
  621.   if (get_com("Are you sure?", &command))
  622.     switch(command)
  623.       {
  624.       case 'y': case 'Y':
  625.     return TRUE;
  626.     
  627.       default:
  628.     return FALSE;
  629.       }
  630.   return FALSE;
  631. }
  632.  
  633.