1 /* files.c - Transscription, recording and playback
2 * Copyright (c) 1995-1997 Stefan Jokisch
4 * Changes for Rockbox copyright 2009 Torne Wuff
6 * This file is part of Frotz.
8 * Frotz is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * Frotz is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * 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 char script_name
[MAX_PATH
];
32 char command_name
[MAX_PATH
];
35 extern char latin1_to_ibm
[];
38 static int script_width
= 0;
47 * Open the transscript file. 'AMFV' makes this more complicated as it
48 * turns transscription on/off several times to exclude some text from
49 * the transscription file. This wasn't a problem for the original V4
50 * interpreters which always sent transscription to the printer, but it
51 * means a problem to modern interpreters that offer to open a new file
52 * every time transscription is turned on. Our solution is to append to
53 * the old transscription file in V1 to V4, and to ask for a new file
58 void script_open (void)
60 static bool script_valid
= FALSE
;
62 char new_name
[MAX_PATH
];
64 h_flags
&= ~SCRIPTING_FLAG
;
66 if (h_version
>= V5
|| !script_valid
) {
68 if (!os_read_file_name (new_name
, script_name
, FILE_SCRIPT
))
71 strcpy (script_name
, new_name
);
75 /* Opening in "at" mode doesn't work for script_erase_input... */
77 if ((sfp
= rb
->open (script_name
, O_RDWR
|O_CREAT
)) != -1) {
79 fseek (sfp
, 0, SEEK_END
);
81 h_flags
|= SCRIPTING_FLAG
;
84 ostream_script
= TRUE
;
88 } else print_string ("Cannot open file\n");
92 SET_WORD (H_FLAGS
, h_flags
)
99 * Stop transscription.
103 void script_close (void)
106 h_flags
&= ~SCRIPTING_FLAG
;
107 SET_WORD (H_FLAGS
, h_flags
)
109 fclose (sfp
); ostream_script
= FALSE
;
117 * Write a newline to the transscript file.
121 void script_new_line (void)
124 if (fputc ('\n', sfp
) == EOF
)
129 }/* script_new_line */
134 * Write a single character to the transscript file.
138 void script_char (zchar c
)
141 if (c
== ZC_INDENT
&& script_width
!= 0)
145 { script_char (' '); script_char (' '); script_char (' '); return; }
147 { script_char (' '); script_char (' '); return; }
150 if (c
>= ZC_LATIN1_MIN
)
151 c
= latin1_to_ibm
[c
- ZC_LATIN1_MIN
];
154 fputc (c
, sfp
); script_width
++;
161 * Write a string to the transscript file.
165 void script_word (const zchar
*s
)
170 if (*s
== ZC_INDENT
&& script_width
!= 0)
173 for (i
= 0, width
= 0; s
[i
] != 0; i
++)
175 if (s
[i
] == ZC_NEW_STYLE
|| s
[i
] == ZC_NEW_FONT
)
177 else if (s
[i
] == ZC_GAP
)
179 else if (s
[i
] == ZC_INDENT
)
184 if (f_setup
.script_cols
!= 0 && script_width
+ width
> f_setup
.script_cols
) {
186 if (*s
== ' ' || *s
== ZC_INDENT
|| *s
== ZC_GAP
)
193 for (i
= 0; s
[i
] != 0; i
++)
195 if (s
[i
] == ZC_NEW_FONT
|| s
[i
] == ZC_NEW_STYLE
)
205 * Send an input line to the transscript file.
209 void script_write_input (const zchar
*buf
, zchar key
)
214 for (i
= 0, width
= 0; buf
[i
] != 0; i
++)
217 if (f_setup
.script_cols
!= 0 && script_width
+ width
> f_setup
.script_cols
)
220 for (i
= 0; buf
[i
] != 0; i
++)
221 script_char (buf
[i
]);
223 if (key
== ZC_RETURN
)
226 }/* script_write_input */
231 * Remove an input line from the transscript file.
235 void script_erase_input (const zchar
*buf
)
240 for (i
= 0, width
= 0; buf
[i
] != 0; i
++)
243 fseek (sfp
, -width
, SEEK_CUR
); script_width
-= width
;
245 }/* script_erase_input */
250 * Start sending a "debugging" message to the transscript file.
254 void script_mssg_on (void)
257 if (script_width
!= 0)
260 script_char (ZC_INDENT
);
262 }/* script_mssg_on */
267 * Stop writing a "debugging" message.
271 void script_mssg_off (void)
276 }/* script_mssg_off */
281 * Open a file to record the player's input.
285 void record_open (void)
287 char new_name
[MAX_PATH
];
289 if (os_read_file_name (new_name
, command_name
, FILE_RECORD
)) {
291 strcpy (command_name
, new_name
);
293 if ((rfp
= rb
->open (new_name
, O_WRONLY
|O_CREAT
|O_TRUNC
)) != -1)
294 ostream_record
= TRUE
;
296 print_string ("Cannot open file\n");
305 * Stop recording the player's input.
309 void record_close (void)
312 fclose (rfp
); ostream_record
= FALSE
;
320 * Helper function for record_char.
324 static void record_code (int c
, bool force_encoding
)
327 if (force_encoding
|| c
== '[' || c
< 0x20 || c
> 0x7e) {
333 for (i
= 10000; i
!= 0; i
/= 10)
334 if (c
>= i
|| i
== 1)
335 fputc ('0' + (c
/ i
) % 10, rfp
);
339 } else fputc (c
, rfp
);
346 * Write a character to the command file.
350 static void record_char (zchar c
)
353 if (c
!= ZC_RETURN
) {
354 if (c
< ZC_HKEY_MIN
|| c
> ZC_HKEY_MAX
) {
355 record_code (translate_to_zscii (c
), FALSE
);
356 if (c
== ZC_SINGLE_CLICK
|| c
== ZC_DOUBLE_CLICK
) {
357 record_code (mouse_x
, TRUE
);
358 record_code (mouse_y
, TRUE
);
360 } else record_code (1000 + c
- ZC_HKEY_MIN
, TRUE
);
368 * Copy a keystroke to the command file.
372 void record_write_key (zchar key
)
377 if (fputc ('\n', rfp
) == EOF
)
380 }/* record_write_key */
385 * Copy a line of input to a command file.
389 void record_write_input (const zchar
*buf
, zchar key
)
393 while ((c
= *buf
++) != 0)
398 if (fputc ('\n', rfp
) == EOF
)
401 }/* record_write_input */
406 * Open a file of commands for playback.
410 void replay_open (void)
412 char new_name
[MAX_PATH
];
414 if (os_read_file_name (new_name
, command_name
, FILE_PLAYBACK
)) {
416 strcpy (command_name
, new_name
);
418 if ((pfp
= rb
->open (new_name
, O_RDONLY
)) != -1) {
420 set_more_prompts (read_yes_or_no ("Do you want MORE prompts"));
422 istream_replay
= TRUE
;
424 } else print_string ("Cannot open file\n");
433 * Stop playback of commands.
437 void replay_close (void)
440 set_more_prompts (TRUE
);
442 fclose (pfp
); istream_replay
= FALSE
;
450 * Helper function for replay_key and replay_line.
454 static int replay_code (void)
458 if ((c
= fgetc (pfp
)) == '[') {
464 while ((c2
= fgetc (pfp
)) != EOF
&& c2
>= '0' && c2
<= '9')
465 c
= 10 * c
+ c2
- '0';
467 return (c2
== ']') ? c
: EOF
;
476 * Read a character from the command file.
480 static zchar
replay_char (void)
484 if ((c
= replay_code ()) != EOF
) {
490 c
= translate_from_zscii (c
);
492 if (c
== ZC_SINGLE_CLICK
|| c
== ZC_DOUBLE_CLICK
) {
493 mouse_x
= replay_code ();
494 mouse_y
= replay_code ();
499 } else return ZC_HKEY_MIN
+ c
- 1000;
506 } else return ZC_BAD
;
513 * Read a keystroke from a command file.
517 zchar
replay_read_key (void)
521 key
= replay_char ();
523 if (fgetc (pfp
) != '\n') {
530 }/* replay_read_key */
535 * Read a line of input from a command file.
539 zchar
replay_read_input (zchar
*buf
)
547 if (c
== ZC_BAD
|| is_terminator (c
))
556 if (fgetc (pfp
) != '\n') {
563 }/* replay_read_input */