home *** CD-ROM | disk | FTP | other *** search
/ Team Palmtops 7 / Palmtops_numero07.iso / Epoc / Palmtime / files / FrotzS5_src.ZIP / FILES.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-10-12  |  9.3 KB  |  541 lines

  1. /*
  2.  * files.c
  3.  *
  4.  * Transscription, recording and playback
  5.  *
  6.  */
  7.  
  8. #include "frotz.h"
  9. #include "S5api.h"
  10.  
  11. #ifndef SEEK_SET
  12. #define SEEK_SET 0
  13. #define SEEK_CUR 1
  14. #define SEEK_END 2
  15. #endif
  16.  
  17. extern void set_more_prompts (struct sg *g, short);
  18.  
  19. extern short is_terminator (struct sg *g, short);
  20.  
  21. extern short read_yes_or_no (struct sg *g, const char *);
  22.  
  23. /*
  24.  * script_open
  25.  *
  26.  * Open the transscript file. 'AMFV' makes this more complicated as it
  27.  * turns transscription on/off several times to exclude some text from
  28.  * the transscription file. This wasn't a problem for the original V4
  29.  * interpreters which always sent transscription to the printer, but it
  30.  * means a problem to modern interpreters that offer to open a new file
  31.  * every time transscription is turned on. Our solution is to append to
  32.  * the old transscription file in V1 to V4, and to ask for a new file
  33.  * name in V5+.
  34.  *
  35.  */
  36.  
  37. void script_open (struct sg *g)
  38. {
  39.     char new_name[MAX_FILE_NAME + 1];
  40.  
  41.     g->h_flags &= ~SCRIPTING_FLAG;
  42.  
  43.     if (g->h_version >= V5 || !g->script_valid) {
  44.  
  45.     if (!os_read_file_name (g, new_name, g->script_name, FILE_SCRIPT))
  46.         goto done;
  47.  
  48.     Srvstrcpy (g->script_name, new_name);
  49.  
  50.     }
  51.  
  52.     /* Opening in "at" mode doesn't work for script_erase_input... */
  53.  
  54.     if ((g->sfp = SrvOpenRWText (g, g->script_name)) != NULL || (g->sfp = SrvOpenRWText(g, g->script_name)) != NULL) {
  55.  
  56.     SrvSeek (g, g->sfp, 0, SEEK_END);
  57.  
  58.     g->h_flags |= SCRIPTING_FLAG;
  59.  
  60.     g->script_valid = TRUE;
  61.     g->ostream_script = TRUE;
  62.  
  63.     g->script_width = 0;
  64.  
  65.     } else print_string (g, "Cannot open file\n");
  66.  
  67. done:
  68.  
  69.     SET_WORD (H_FLAGS, g->h_flags)
  70.  
  71. }/* script_open */
  72.  
  73. /*
  74.  * script_close
  75.  *
  76.  * Stop transscription.
  77.  *
  78.  */
  79.  
  80. void script_close (struct sg *g)
  81. {
  82.  
  83.     g->h_flags &= ~SCRIPTING_FLAG;
  84.     SET_WORD (H_FLAGS, g->h_flags)
  85.  
  86.     SrvClose (g, g->sfp); g->ostream_script = FALSE;
  87.  
  88. }/* script_close */
  89.  
  90. /*
  91.  * script_new_line
  92.  *
  93.  * Write a newline to the transscript file.
  94.  *
  95.  */
  96.  
  97. void script_new_line (struct sg *g)
  98. {
  99.  
  100.     if(SrvPutc (g, '\n', g->sfp) == 0)
  101.       script_close (g);
  102.  
  103.     g->script_width = 0;
  104.  
  105. }/* script_new_line */
  106.  
  107. /*
  108.  * script_char
  109.  *
  110.  * Write a single character to the transscript file.
  111.  *
  112.  */
  113.  
  114. void script_char (struct sg *g, zchar c)
  115. {
  116.  
  117.     if (c == ZC_INDENT && g->script_width != 0)
  118.     c = ' ';
  119.  
  120.     if (c == ZC_INDENT)
  121.     { script_char (g, ' '); script_char (g, ' '); script_char (g,' '); return; }
  122.     if (c == ZC_GAP)
  123.     { script_char (g, ' '); script_char (g, ' '); return; }
  124.  
  125.     SrvPutc (g, c, g->sfp); g->script_width++;
  126.  
  127. }/* script_char */
  128.  
  129. /*
  130.  * script_word
  131.  *
  132.  * Write a string to the transscript file.
  133.  *
  134.  */
  135.  
  136. void script_word (struct sg *g, const zchar *s)
  137. {
  138.     short width;
  139.     short i;
  140.  
  141.     if (*s == ZC_INDENT && g->script_width != 0)
  142.     script_char (g, *s++);
  143.  
  144.     for (i = 0, width = 0; s[i] != 0; i++)
  145.  
  146.     if (s[i] == ZC_NEW_STYLE || s[i] == ZC_NEW_FONT)
  147.         i++;
  148.     else if (s[i] == ZC_GAP)
  149.         width += 3;
  150.     else if (s[i] == ZC_INDENT)
  151.         width += 2;
  152.     else
  153.         width += 1;
  154.  
  155.     if (g->option_script_cols != 0 && g->script_width + width > g->option_script_cols) {
  156.  
  157.     if (*s == ' ' || *s == ZC_INDENT || *s == ZC_GAP)
  158.         s++;
  159.  
  160.     script_new_line (g);
  161.  
  162.     }
  163.  
  164.     for (i = 0; s[i] != 0; i++)
  165.  
  166.     if (s[i] == ZC_NEW_FONT || s[i] == ZC_NEW_STYLE)
  167.         i++;
  168.     else
  169.         script_char (g, s[i]);
  170.  
  171. }/* script_word */
  172.  
  173. /*
  174.  * script_write_input
  175.  *
  176.  * Send an input line to the transscript file.
  177.  *
  178.  */
  179.  
  180. void script_write_input (struct sg *g,const zchar *buf, zchar key)
  181. {
  182.     short width;
  183.     short i;
  184.  
  185.     for (i = 0, width = 0; buf[i] != 0; i++)
  186.     width++;
  187.  
  188.     if (g->option_script_cols != 0 && g->script_width + width > g->option_script_cols)
  189.     script_new_line (g);
  190.  
  191.     for (i = 0; buf[i] != 0; i++)
  192.     script_char (g, buf[i]);
  193.  
  194.     if (key == ZC_RETURN)
  195.     script_new_line (g);
  196.  
  197. }/* script_write_input */
  198.  
  199. /*
  200.  * script_erase_input
  201.  *
  202.  * Remove an input line from the transscript file.
  203.  *
  204.  */
  205.  
  206. void script_erase_input (struct sg *g,const zchar *buf)
  207. {
  208.     short width;
  209.     short i;
  210.  
  211.     for (i = 0, width = 0; buf[i] != 0; i++)
  212.     width++;
  213.  
  214.     SrvSeek (g,g->sfp, -width, SEEK_CUR); g->script_width -= width;
  215.  
  216. }/* script_erase_input */
  217.  
  218. /*
  219.  * script_mssg_on
  220.  *
  221.  * Start sending a "debugging" message to the transscript file.
  222.  *
  223.  */
  224.  
  225. void script_mssg_on (struct sg *g)
  226. {
  227.  
  228.     if (g->script_width != 0)
  229.     script_new_line (g);
  230.  
  231.     script_char (g, ZC_INDENT);
  232.  
  233. }/* script_mssg_on */
  234.  
  235. /*
  236.  * script_mssg_off
  237.  *
  238.  * Stop writing a "debugging" message.
  239.  *
  240.  */
  241.  
  242. void script_mssg_off (struct sg *g)
  243. {
  244.  
  245.     script_new_line (g);
  246.  
  247. }/* script_mssg_off */
  248.  
  249. /*
  250.  * record_open
  251.  *
  252.  * Open a file to record the player's input.
  253.  *
  254.  */
  255.  
  256. void record_open (struct sg *g)
  257. {
  258.     char new_name[MAX_FILE_NAME + 1];
  259.  
  260.     if (os_read_file_name (g, new_name, g->command_name, FILE_RECORD)) {
  261.  
  262.     Srvstrcpy (g->command_name, new_name);
  263.  
  264.     if ((g->rfp = SrvOpenWText(g, new_name)) != NULL)
  265.         g->ostream_record = TRUE;
  266.     else
  267.         print_string (g, "Cannot open file\n");
  268.  
  269.     }
  270.  
  271. }/* record_open */
  272.  
  273. /*
  274.  * record_close
  275.  *
  276.  * Stop recording the player's input.
  277.  *
  278.  */
  279.  
  280. void record_close (struct sg *g)
  281. {
  282.     SrvSetFileSize(g, g->rfp, -1);
  283.     SrvClose (g, g->rfp); g->ostream_record = FALSE;
  284.  
  285. }/* record_close */
  286.  
  287. /*
  288.  * record_code
  289.  *
  290.  * Helper function for record_char.
  291.  *
  292.  */
  293.  
  294. void record_code (struct sg *g, short c, short force_encoding)
  295. {
  296.  
  297.     if (force_encoding || c == '[' || c < 0x20 || c > 0x7e) {
  298.  
  299.     short i;
  300.  
  301.     SrvPutc (g, '[', g->rfp);
  302.  
  303.     for (i = 10000; i != 0; i /= 10)
  304.         if (c >= i || i == 1)
  305.         SrvPutc (g, '0' + (c / i) % 10, g->rfp);
  306.  
  307.     SrvPutc (g, ']', g->rfp);
  308.  
  309.     } else SrvPutc (g, c, g->rfp);
  310.  
  311. }/* record_code */
  312.  
  313. /*
  314.  * record_char
  315.  *
  316.  * Write a character to the command file.
  317.  *
  318.  */
  319.  
  320. void record_char (struct sg *g, short c)
  321. {
  322.  
  323.     if (c != ZC_RETURN)
  324.         {
  325.         switch(c)
  326.           {
  327.           case 18: case 16:
  328.           case 19: case 21:
  329.           case 14: case 24:
  330.           case 4:  return;
  331.           default:break;
  332.           }
  333.  
  334.         record_code (g, translate_to_zscii (g, c), FALSE);
  335.  
  336.         if (c == ZC_SINGLE_CLICK || c == ZC_DOUBLE_CLICK)
  337.             {
  338.             record_code (g, g->mouse_x, TRUE);
  339.             record_code (g, g->mouse_y, TRUE);
  340.             }
  341.         }
  342. }/* record_char */
  343.  
  344. /*
  345.  * record_write_key
  346.  *
  347.  * Copy a keystroke to the command file.
  348.  *
  349.  */
  350.  
  351. void record_write_key (struct sg *g, short key)
  352. {
  353.  
  354.     record_char (g, key);
  355.  
  356.     if (SrvPutc (g, '\n', g->rfp) == 0)
  357.       record_close (g);
  358.  
  359. }/* record_write_key */
  360.  
  361. /*
  362.  * record_write_input
  363.  *
  364.  * Copy a line of input to a command file.
  365.  *
  366.  */
  367.  
  368. void record_write_input (struct sg *g, const zchar *buf, zchar key)
  369. {
  370.     zchar c;
  371.  
  372.     while ((c = *buf++) != 0)
  373.     record_char (g, c);
  374.  
  375.     record_char (g, key);
  376.  
  377.     if (SrvPutc (g, '\n', g->rfp) == 0)
  378.       record_close (g);
  379.  
  380. }/* record_write_input */
  381.  
  382. /*
  383.  * replay_open
  384.  *
  385.  * Open a file of commands for playback.
  386.  *
  387.  */
  388.  
  389. void replay_open (struct sg *g)
  390. {
  391.     char new_name[MAX_FILE_NAME + 1];
  392.  
  393.     if (os_read_file_name (g, new_name, g->command_name, FILE_PLAYBACK)) {
  394.  
  395.     Srvstrcpy (g->command_name, new_name);
  396.  
  397.     if ((g->pfp = SrvOpenRText(g, new_name)) != NULL) {
  398.  
  399.         set_more_prompts (g, read_yes_or_no (g,"Do you want MORE prompts"));
  400.  
  401.         g->istream_replay = TRUE;
  402.  
  403.     } else print_string (g, "Cannot open file\n");
  404.  
  405.     }
  406.  
  407. }/* replay_open */
  408.  
  409. /*
  410.  * replay_close
  411.  *
  412.  * Stop playback of commands.
  413.  *
  414.  */
  415.  
  416. void replay_close (struct sg *g)
  417. {
  418.  
  419.     set_more_prompts (g, TRUE);
  420.  
  421.     SrvClose (g, g->pfp); g->istream_replay = FALSE;
  422.  
  423. }/* replay_close */
  424.  
  425. /*
  426.  * replay_code
  427.  *
  428.  * Helper function for replay_key and replay_line.
  429.  *
  430.  */
  431.  
  432. short replay_code (struct sg *g)
  433. {
  434.     short c;
  435.  
  436.     if ((c = SrvGetc (g, g->pfp)) == '[') {
  437.  
  438.     short c2;
  439.  
  440.     c = 0;
  441.  
  442.     while ((c2 = SrvGetc (g, g->pfp)) != 0 && c2 >= '0' && c2 <= '9')
  443.         c = 10 * c + c2 - '0';
  444.  
  445.     return (c2 == ']') ? c : 0;
  446.  
  447.     } else return c;
  448.  
  449. }/* replay_code */
  450.  
  451. /*
  452.  * replay_char
  453.  *
  454.  * Read a character from the command file.
  455.  *
  456.  */
  457.  
  458. zchar replay_char (struct sg *g)
  459. {
  460.     short c;
  461.  
  462.     if ((c = replay_code (g)) != 0) { // != EOF
  463.  
  464.     if (c != '\n')
  465.  
  466.         if (c < 1000) {
  467.  
  468.         c = translate_from_zscii (g, (unsigned char)c);
  469.  
  470.         if (c == ZC_SINGLE_CLICK || c == ZC_DOUBLE_CLICK) {
  471.             g->mouse_x = replay_code (g);
  472.             g->mouse_y = replay_code (g);
  473.         }
  474.  
  475.         return (unsigned char)c;
  476.  
  477.         }
  478.  
  479.     SrvSeek(g, g->pfp, -1, SEEK_CUR); // Back from \n -1
  480.  
  481.     return ZC_RETURN;
  482.  
  483.     } else return ZC_BAD;
  484.  
  485. }/* replay_char */
  486.  
  487. /*
  488.  * replay_read_key
  489.  *
  490.  * Read a keystroke from a command file.
  491.  *
  492.  */
  493.  
  494. zchar replay_read_key (struct sg *g)
  495. {
  496.     zchar key;
  497.  
  498.     key = replay_char (g);
  499.  
  500.     if (SrvGetc (g,g->pfp) != '\n') {
  501.  
  502.     replay_close (g);
  503.     return ZC_BAD;
  504.  
  505.     } else return key;
  506.  
  507. }/* replay_read_key */
  508.  
  509. /*
  510.  * replay_read_input
  511.  *
  512.  * Read a line of input from a command file.
  513.  *
  514.  */
  515.  
  516. zchar replay_read_input (struct sg *g,zchar *buf)
  517. {
  518.     zchar c;
  519.  
  520.     for (;;) {
  521.  
  522.     c = replay_char (g);
  523.  
  524.     if (c == ZC_BAD || is_terminator (g, c) || c == 0x7f)
  525.         break;
  526.  
  527.     *buf++ = c;
  528.  
  529.     }
  530.  
  531.     *buf = 0;
  532.  
  533.     if (SrvGetc (g,g->pfp) != '\n') {
  534.  
  535.     replay_close (g);
  536.     return ZC_BAD;
  537.  
  538.     } else return c;
  539.  
  540. }/* replay_read_input */
  541.