1 /* files.c - Transscription, recording and playback
2 * Copyright (c) 1995-1997 Stefan Jokisch
4 * This file is part of Frotz.
6 * Frotz is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * Frotz is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
25 extern void set_more_prompts (bool);
27 extern bool is_terminator (zchar);
29 extern bool read_yes_or_no (const char *);
31 static int script_width = 0;
33 static FILE *sfp = NULL;
34 static FILE *rfp = NULL;
35 static FILE *pfp = NULL;
40 * Open the transscript file. 'AMFV' makes this more complicated as it
41 * turns transscription on/off several times to exclude some text from
42 * the transscription file. This wasn't a problem for the original V4
43 * interpreters which always sent transscription to the printer, but it
44 * means a problem to modern interpreters that offer to open a new file
45 * every time transscription is turned on. Our solution is to append to
46 * the old transscription file in V1 to V4, and to ask for a new file
51 static bool script_valid = FALSE;
53 void script_open (void)
56 h_flags &= ~SCRIPTING_FLAG;
58 if (h_version < V5 && script_valid)
59 sfp = frotzreopen(FILE_SCRIPT);
61 sfp = frotzopenprompt(FILE_SCRIPT);
65 fseek (sfp, 0, SEEK_END);
67 h_flags |= SCRIPTING_FLAG;
70 ostream_script = TRUE;
74 } else print_string ("Cannot open file\n");
76 SET_WORD (H_FLAGS, h_flags)
83 * Stop transscription.
87 void script_close (void)
90 h_flags &= ~SCRIPTING_FLAG;
91 SET_WORD (H_FLAGS, h_flags)
93 fclose (sfp); ostream_script = FALSE;
100 * Write a newline to the transscript file.
104 void script_new_line (void)
107 if (fputc ('\n', sfp) == EOF)
112 }/* script_new_line */
117 * Write a single character to the transscript file.
121 void script_char (zchar c)
124 if (c == ZC_INDENT && script_width != 0)
128 { script_char (' '); script_char (' '); script_char (' '); return; }
130 { script_char (' '); script_char (' '); return; }
132 fputwc (c, sfp); script_width++;
139 * Write a string to the transscript file.
143 void script_word (const zchar *s)
148 if (*s == ZC_INDENT && script_width != 0)
151 for (i = 0, width = 0; s[i] != 0; i++)
153 if (s[i] == ZC_NEW_STYLE || s[i] == ZC_NEW_FONT)
155 else if (s[i] == ZC_GAP)
157 else if (s[i] == ZC_INDENT)
162 if (option_script_cols != 0 && script_width + width > option_script_cols) {
164 if (*s == ' ' || *s == ZC_INDENT || *s == ZC_GAP)
171 for (i = 0; s[i] != 0; i++)
173 if (s[i] == ZC_NEW_FONT || s[i] == ZC_NEW_STYLE)
183 * Send an input line to the transscript file.
187 void script_write_input (const zchar *buf, zchar key)
192 for (i = 0, width = 0; buf[i] != 0; i++)
195 if (option_script_cols != 0 && script_width + width > option_script_cols)
198 for (i = 0; buf[i] != 0; i++)
199 script_char (buf[i]);
201 if (key == ZC_RETURN)
204 }/* script_write_input */
209 * Remove an input line from the transscript file.
213 void script_erase_input (const zchar *buf)
218 for (i = 0, width = 0; buf[i] != 0; i++)
221 fseek (sfp, -width, SEEK_CUR); script_width -= width;
223 }/* script_erase_input */
228 * Start sending a "debugging" message to the transscript file.
232 void script_mssg_on (void)
235 if (script_width != 0)
238 script_char (ZC_INDENT);
240 }/* script_mssg_on */
245 * Stop writing a "debugging" message.
249 void script_mssg_off (void)
254 }/* script_mssg_off */
259 * Open a file to record the player's input.
263 void record_open (void)
265 if ((rfp = frotzopenprompt(FILE_RECORD)) != NULL)
266 ostream_record = TRUE;
268 print_string ("Cannot open file\n");
274 * Stop recording the player's input.
278 void record_close (void)
281 fclose (rfp); ostream_record = FALSE;
288 * Helper function for record_char.
292 static void record_code (int c, bool force_encoding)
295 if (force_encoding || c == '[' || c < 0x20 || c > 0x7e) {
301 for (i = 10000; i != 0; i /= 10)
302 if (c >= i || i == 1)
303 fputc ('0' + (c / i) % 10, rfp);
307 } else fputc (c, rfp);
314 * Write a character to the command file.
318 static void record_char (zchar c)
321 if (c != ZC_RETURN) {
322 if (c < ZC_HKEY_MIN || c > ZC_HKEY_MAX) {
323 record_code (translate_to_zscii (c), FALSE);
324 if (c == ZC_SINGLE_CLICK || c == ZC_DOUBLE_CLICK) {
325 record_code (mouse_x, TRUE);
326 record_code (mouse_y, TRUE);
328 } else record_code (1000 + c - ZC_HKEY_MIN, TRUE);
336 * Copy a keystroke to the command file.
340 void record_write_key (zchar key)
345 if (fputc ('\n', rfp) == EOF)
348 }/* record_write_key */
353 * Copy a line of input to a command file.
357 void record_write_input (const zchar *buf, zchar key)
361 while ((c = *buf++) != 0)
366 if (fputc ('\n', rfp) == EOF)
369 }/* record_write_input */
374 * Open a file of commands for playback.
378 void replay_open (void)
380 if ((pfp = frotzopenprompt(FILE_PLAYBACK)) != NULL)
381 istream_replay = TRUE;
383 print_string ("Cannot open file\n");
389 * Stop playback of commands.
393 void replay_close (void)
395 fclose (pfp); istream_replay = FALSE;
401 * Helper function for replay_key and replay_line.
405 static int replay_code (void)
409 if ((c = fgetc (pfp)) == '[') {
415 while ((c2 = fgetc (pfp)) != EOF && c2 >= '0' && c2 <= '9')
416 c = 10 * c + c2 - '0';
418 return (c2 == ']') ? c : EOF;
427 * Read a character from the command file.
431 static zchar replay_char (void)
435 if ((c = replay_code ()) != EOF) {
441 c = translate_from_zscii (c);
443 if (c == ZC_SINGLE_CLICK || c == ZC_DOUBLE_CLICK) {
444 mouse_x = replay_code ();
445 mouse_y = replay_code ();
450 } else return ZC_HKEY_MIN + c - 1000;
457 } else return ZC_BAD;
464 * Read a keystroke from a command file.
468 zchar replay_read_key (void)
472 key = replay_char ();
474 if (fgetc (pfp) != '\n') {
481 }/* replay_read_key */
486 * Read a line of input from a command file.
490 zchar replay_read_input (zchar *buf)
498 if (c == ZC_BAD || is_terminator (c))
507 if (fgetc (pfp) != '\n') {
514 }/* replay_read_input */