Make open() posix compliant api-wise. A few calls (those with O_CREAT) need the addit...
[kugel-rb.git] / apps / plugins / frotz / files.c
blob7ca916186c7a93bd7501a51466338e16575665e3
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
23 #include "frotz.h"
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];
34 #ifdef __MSDOS__
35 extern char latin1_to_ibm[];
36 #endif
38 static int script_width = 0;
40 int sfp = -1;
41 int rfp = -1;
42 int pfp = -1;
45 * script_open
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+.
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))
69 goto done;
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, 0666)) != -1) {
79 fseek (sfp, 0, SEEK_END);
81 h_flags |= SCRIPTING_FLAG;
83 script_valid = TRUE;
84 ostream_script = TRUE;
86 script_width = 0;
88 } else print_string ("Cannot open file\n");
90 done:
92 SET_WORD (H_FLAGS, h_flags)
94 }/* script_open */
97 * script_close
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;
110 sfp = -1;
112 }/* script_close */
115 * script_new_line
117 * Write a newline to the transscript file.
121 void script_new_line (void)
124 if (fputc ('\n', sfp) == EOF)
125 script_close ();
127 script_width = 0;
129 }/* script_new_line */
132 * script_char
134 * Write a single character to the transscript file.
138 void script_char (zchar c)
141 if (c == ZC_INDENT && script_width != 0)
142 c = ' ';
144 if (c == ZC_INDENT)
145 { script_char (' '); script_char (' '); script_char (' '); return; }
146 if (c == ZC_GAP)
147 { script_char (' '); script_char (' '); return; }
149 #ifdef __MSDOS__
150 if (c >= ZC_LATIN1_MIN)
151 c = latin1_to_ibm[c - ZC_LATIN1_MIN];
152 #endif
154 fputc (c, sfp); script_width++;
156 }/* script_char */
159 * script_word
161 * Write a string to the transscript file.
165 void script_word (const zchar *s)
167 int width;
168 int i;
170 if (*s == ZC_INDENT && script_width != 0)
171 script_char (*s++);
173 for (i = 0, width = 0; s[i] != 0; i++)
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;
184 if (f_setup.script_cols != 0 && script_width + width > f_setup.script_cols) {
186 if (*s == ' ' || *s == ZC_INDENT || *s == ZC_GAP)
187 s++;
189 script_new_line ();
193 for (i = 0; s[i] != 0; i++)
195 if (s[i] == ZC_NEW_FONT || s[i] == ZC_NEW_STYLE)
196 i++;
197 else
198 script_char (s[i]);
200 }/* script_word */
203 * script_write_input
205 * Send an input line to the transscript file.
209 void script_write_input (const zchar *buf, zchar key)
211 int width;
212 int i;
214 for (i = 0, width = 0; buf[i] != 0; i++)
215 width++;
217 if (f_setup.script_cols != 0 && script_width + width > f_setup.script_cols)
218 script_new_line ();
220 for (i = 0; buf[i] != 0; i++)
221 script_char (buf[i]);
223 if (key == ZC_RETURN)
224 script_new_line ();
226 }/* script_write_input */
229 * script_erase_input
231 * Remove an input line from the transscript file.
235 void script_erase_input (const zchar *buf)
237 int width;
238 int i;
240 for (i = 0, width = 0; buf[i] != 0; i++)
241 width++;
243 fseek (sfp, -width, SEEK_CUR); script_width -= width;
245 }/* script_erase_input */
248 * script_mssg_on
250 * Start sending a "debugging" message to the transscript file.
254 void script_mssg_on (void)
257 if (script_width != 0)
258 script_new_line ();
260 script_char (ZC_INDENT);
262 }/* script_mssg_on */
265 * script_mssg_off
267 * Stop writing a "debugging" message.
271 void script_mssg_off (void)
274 script_new_line ();
276 }/* script_mssg_off */
279 * record_open
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, 0666)) != -1)
294 ostream_record = TRUE;
295 else
296 print_string ("Cannot open file\n");
300 }/* record_open */
303 * record_close
305 * Stop recording the player's input.
309 void record_close (void)
312 fclose (rfp); ostream_record = FALSE;
313 rfp = -1;
315 }/* record_close */
318 * record_code
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) {
329 int i;
331 fputc ('[', rfp);
333 for (i = 10000; i != 0; i /= 10)
334 if (c >= i || i == 1)
335 fputc ('0' + (c / i) % 10, rfp);
337 fputc (']', rfp);
339 } else fputc (c, rfp);
341 }/* record_code */
344 * record_char
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);
363 }/* record_char */
366 * record_write_key
368 * Copy a keystroke to the command file.
372 void record_write_key (zchar key)
375 record_char (key);
377 if (fputc ('\n', rfp) == EOF)
378 record_close ();
380 }/* record_write_key */
383 * record_write_input
385 * Copy a line of input to a command file.
389 void record_write_input (const zchar *buf, zchar key)
391 zchar c;
393 while ((c = *buf++) != 0)
394 record_char (c);
396 record_char (key);
398 if (fputc ('\n', rfp) == EOF)
399 record_close ();
401 }/* record_write_input */
404 * replay_open
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");
428 }/* replay_open */
431 * replay_close
433 * Stop playback of commands.
437 void replay_close (void)
440 set_more_prompts (TRUE);
442 fclose (pfp); istream_replay = FALSE;
443 pfp = -1;
445 }/* replay_close */
448 * replay_code
450 * Helper function for replay_key and replay_line.
454 static int replay_code (void)
456 int c;
458 if ((c = fgetc (pfp)) == '[') {
460 int c2;
462 c = 0;
464 while ((c2 = fgetc (pfp)) != EOF && c2 >= '0' && c2 <= '9')
465 c = 10 * c + c2 - '0';
467 return (c2 == ']') ? c : EOF;
469 } else return c;
471 }/* replay_code */
474 * replay_char
476 * Read a character from the command file.
480 static zchar replay_char (void)
482 int c;
484 if ((c = replay_code ()) != EOF) {
486 if (c != '\n') {
488 if (c < 1000) {
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 ();
497 return c;
499 } else return ZC_HKEY_MIN + c - 1000;
502 ungetc ('\n', pfp);
504 return ZC_RETURN;
506 } else return ZC_BAD;
508 }/* replay_char */
511 * replay_read_key
513 * Read a keystroke from a command file.
517 zchar replay_read_key (void)
519 zchar key;
521 key = replay_char ();
523 if (fgetc (pfp) != '\n') {
525 replay_close ();
526 return ZC_BAD;
528 } else return key;
530 }/* replay_read_key */
533 * replay_read_input
535 * Read a line of input from a command file.
539 zchar replay_read_input (zchar *buf)
541 zchar c;
543 for (;;) {
545 c = replay_char ();
547 if (c == ZC_BAD || is_terminator (c))
548 break;
550 *buf++ = c;
554 *buf = 0;
556 if (fgetc (pfp) != '\n') {
558 replay_close ();
559 return ZC_BAD;
561 } else return c;
563 }/* replay_read_input */