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