54cef78c60a9f6ad078b31ced9e61e94e6d35593
[projects/chimara/chimara.git] / interpreters / frotz / stream.c
1 /* stream.c - IO stream implementation
2  *      Copyright (c) 1995-1997 Stefan Jokisch
3  *
4  * This file is part of Frotz.
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include "frotz.h"
22
23 /* glkify */
24 zchar console_read_input (int max, zchar *buf, zword timeout, bool continued)
25 {
26     return os_read_line(max, buf, timeout, max, continued);
27 }
28 zchar console_read_key (zword timeout)
29 {
30     return os_read_key(timeout, 0);
31 }
32
33 /* extern bool handle_hot_key (zword); */
34
35 extern bool validate_click (void);
36
37 extern void replay_open (void);
38 extern void replay_close (void);
39 extern void memory_open (zword, zword, bool);
40 extern void memory_close (void);
41 extern void record_open (void);
42 extern void record_close (void);
43 extern void script_open (void);
44 extern void script_close (void);
45
46 extern void memory_word (const zchar *);
47 extern void memory_new_line (void);
48 extern void record_write_key (zchar);
49 extern void record_write_input (const zchar *, zchar);
50 extern void script_char (zchar);
51 extern void script_word (const zchar *);
52 extern void script_new_line (void);
53 extern void script_write_input (const zchar *, zchar);
54 extern void script_erase_input (const zchar *);
55 extern void script_mssg_on (void);
56 extern void script_mssg_off (void);
57 extern void screen_char (zchar);
58 extern void screen_word (const zchar *);
59 extern void screen_new_line (void);
60 extern void screen_write_input (const zchar *, zchar);
61 extern void screen_erase_input (const zchar *);
62 extern void screen_mssg_on (void);
63 extern void screen_mssg_off (void);
64
65 extern zword replay_read_key (void);
66 extern zword replay_read_input (zchar *);
67
68 extern int direct_call (zword);
69
70 /*
71  * scrollback_char
72  *
73  * Write a single character to the scrollback buffer.
74  *
75  */
76
77 void scrollback_char (zchar c)
78 {
79
80     if (c == ZC_INDENT)
81         { scrollback_char (' '); scrollback_char (' '); scrollback_char (' '); return; }
82     if (c == ZC_GAP)
83         { scrollback_char (' '); scrollback_char (' '); return; }
84
85     os_scrollback_char (c);
86
87 }/* scrollback_char */
88
89 /*
90  * scrollback_word
91  *
92  * Write a string to the scrollback buffer.
93  *
94  */
95
96 void scrollback_word (const zchar *s)
97 {
98     int i;
99
100     for (i = 0; s[i] != 0; i++)
101
102         if (s[i] == ZC_NEW_FONT || s[i] == ZC_NEW_STYLE)
103             i++;
104         else
105             scrollback_char (s[i]);
106
107 }/* scrollback_word */
108
109 /*
110  * scrollback_write_input
111  *
112  * Send an input line to the scrollback buffer.
113  *
114  */
115
116 void scrollback_write_input (const zchar *buf, zchar key)
117 {
118     int i;
119
120     for (i = 0; buf[i] != 0; i++)
121         scrollback_char (buf[i]);
122
123     if (key == ZC_RETURN)
124         scrollback_char ('\n');
125
126 }/* scrollback_write_input */
127
128 /*
129  * scrollback_erase_input
130  *
131  * Remove an input line from the scrollback buffer.
132  *
133  */
134
135 void scrollback_erase_input (const zchar *buf)
136 {
137     int width;
138     int i;
139
140     for (i = 0, width = 0; buf[i] != 0; i++)
141         width++;
142
143     os_scrollback_erase (width);
144
145 }/* scrollback_erase_input */
146
147 /*
148  * stream_mssg_on
149  *
150  * Start printing a "debugging" message.
151  *
152  */
153
154 void stream_mssg_on (void)
155 {
156
157     flush_buffer ();
158
159     if (ostream_screen)
160             screen_mssg_on ();
161     if (ostream_script && enable_scripting)
162         script_mssg_on ();
163
164     message = TRUE;
165
166 }/* stream_mssg_on */
167
168 /*
169  * stream_mssg_off
170  *
171  * Stop printing a "debugging" message.
172  *
173  */
174
175 void stream_mssg_off (void)
176 {
177
178     flush_buffer ();
179
180     if (ostream_screen)
181         screen_mssg_off ();
182     if (ostream_script && enable_scripting)
183         script_mssg_off ();
184
185     message = FALSE;
186
187 }/* stream_mssg_off */
188
189 /*
190  * z_output_stream, open or close an output stream.
191  *
192  *      zargs[0] = stream to open (positive) or close (negative)
193  *      zargs[1] = address to redirect output to (stream 3 only)
194  *      zargs[2] = width of redirected output (stream 3 only, optional)
195  *
196  */
197
198 void z_output_stream (void)
199 {
200
201     flush_buffer ();
202
203     switch ((short) zargs[0]) {
204
205     case  1: ostream_screen = TRUE;
206              break;
207     case -1: ostream_screen = FALSE;
208              break;
209     case  2: if (!ostream_script) script_open ();
210              break;
211     case -2: if (ostream_script) script_close ();
212              break;
213     case  3: memory_open (zargs[1], zargs[2], zargc >= 3);
214              break;
215     case -3: memory_close ();
216              break;
217     case  4: if (!ostream_record) record_open ();
218              break;
219     case -4: if (ostream_record) record_close ();
220              break;
221
222     }
223
224 }/* z_output_stream */
225
226 /*
227  * stream_char
228  *
229  * Send a single character to the output stream.
230  *
231  */
232
233 void stream_char (zchar c)
234 {
235
236     if (ostream_screen)
237         screen_char (c);
238     if (ostream_script && enable_scripting)
239         script_char (c);
240     if (enable_scripting)
241         scrollback_char (c);
242
243 }/* stream_char */
244
245 /*
246  * stream_word
247  *
248  * Send a string of characters to the output streams.
249  *
250  */
251
252 void stream_word (const zchar *s)
253 {
254
255     if (ostream_memory && !message)
256
257         memory_word (s);
258
259     else {
260
261         if (ostream_screen)
262             screen_word (s);
263         if (ostream_script && enable_scripting)
264             script_word (s);
265         if (enable_scripting)
266             scrollback_word (s);
267     }
268
269 }/* stream_word */
270
271 /*
272  * stream_new_line
273  *
274  * Send a newline to the output streams.
275  *
276  */
277
278 void stream_new_line (void)
279 {
280
281     if (ostream_memory && !message)
282
283         memory_new_line ();
284
285     else {
286
287         if (ostream_screen)
288             screen_new_line ();
289         if (ostream_script && enable_scripting)
290             script_new_line ();
291         if (enable_scripting)
292             os_scrollback_char ('\n');
293
294     }
295
296 }/* stream_new_line */
297
298 /*
299  * z_input_stream, select an input stream.
300  *
301  *      zargs[0] = input stream to be selected
302  *
303  */
304
305 void z_input_stream (void)
306 {
307
308     flush_buffer ();
309
310     if (zargs[0] == 0 && istream_replay)
311         replay_close ();
312     if (zargs[0] == 1 && !istream_replay)
313         replay_open ();
314
315 }/* z_input_stream */
316
317 /*
318  * stream_read_key
319  *
320  * Read a single keystroke from the current input stream.
321  *
322  */
323
324 zchar stream_read_key ( zword timeout, zword routine, bool hot_keys )
325 {
326     zchar key = ZC_BAD;
327
328     flush_buffer ();
329
330     /* Read key from current input stream */
331
332 continue_input:
333
334     do {
335
336         if (istream_replay)
337             key = replay_read_key ();
338         else
339             key = console_read_key (timeout);
340
341     } while (key == ZC_BAD);
342
343     /* Verify mouse clicks */
344
345 /* glkify
346     if (key == ZC_SINGLE_CLICK || key == ZC_DOUBLE_CLICK)
347         if (!validate_click ())
348             goto continue_input;
349 */
350
351     /* Copy key to the command file */
352
353     if (ostream_record && !istream_replay)
354         record_write_key (key);
355
356     /* Handle timeouts */
357
358     if (key == ZC_TIME_OUT)
359         if (direct_call (routine) == 0)
360             goto continue_input;
361
362 /* glkify
363     // Handle hot keys
364
365     if (hot_keys && key >= ZC_HKEY_MIN && key <= ZC_HKEY_MAX) {
366
367         if (h_version == V4 && key == ZC_HKEY_UNDO)
368             goto continue_input;
369         if (!handle_hot_key (key))
370             goto continue_input;
371
372         return ZC_BAD;
373
374     }
375 */
376
377     /* Return key */
378
379     return key;
380
381 }/* stream_read_key */
382
383 /*
384  * stream_read_input
385  *
386  * Read a line of input from the current input stream.
387  *
388  */
389
390 zchar stream_read_input ( int max, zchar *buf,
391                           zword timeout, zword routine,
392                           bool hot_keys,
393                           bool no_scripting )
394 {
395     zchar key = ZC_BAD;
396     bool no_scrollback = no_scripting;
397
398     if (h_version == V6 && story_id == UNKNOWN && !ostream_script)
399         no_scrollback = FALSE;
400
401     flush_buffer ();
402
403     /* Remove initial input from the transscript file or from the screen */
404
405     if (ostream_script && enable_scripting && !no_scripting)
406         script_erase_input (buf);
407 //glkify    if (enable_scripting && !no_scrollback)
408 //glkify        scrollback_erase_input (buf);
409 //glkify    if (istream_replay)
410 //glkify        screen_erase_input (buf);
411
412     /* Read input line from current input stream */
413
414 continue_input:
415
416     do {
417
418         if (istream_replay)
419             key = replay_read_input (buf);
420         else
421             key = console_read_input (max, buf, timeout, key != ZC_BAD);
422
423     } while (key == ZC_BAD);
424
425     /* Verify mouse clicks */
426
427 /* glkify
428     if (key == ZC_SINGLE_CLICK || key == ZC_DOUBLE_CLICK)
429         if (!validate_click ())
430             goto continue_input;
431 */
432
433     /* Copy input line to the command file */
434
435     if (ostream_record && !istream_replay)
436         record_write_input (buf, key);
437
438     /* Handle timeouts */
439
440     if (key == ZC_TIME_OUT)
441         if (direct_call (routine) == 0)
442             goto continue_input;
443
444 /* glkify
445     // Handle hot keys
446
447     if (hot_keys && key >= ZC_HKEY_MIN && key <= ZC_HKEY_MAX) {
448
449         if (!handle_hot_key (key))
450             goto continue_input;
451
452         return ZC_BAD;
453
454     }
455 */
456
457     /* Copy input line to transscript file or to the screen */
458
459     if (ostream_script && enable_scripting && !no_scripting)
460         script_write_input (buf, key);
461 //glkify    if (enable_scripting && !no_scrollback)
462 //glkify        scrollback_write_input (buf, key);
463 //glkify    if (istream_replay)
464 //glkify        screen_write_input (buf, key);
465
466     /* Return terminating key */
467
468     return key;
469
470 }/* stream_read_input */