Update interpreters to latest Garglk codebase
[projects/chimara/chimara.git] / interpreters / frotz / redirect.c
1 /* redirect.c - Output redirection to Z-machine memory
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include "frotz.h"
22
23 #define MAX_NESTING 16
24
25 /* TOR: glkify -- this is for V6 only */
26 static zword get_max_width (zword win) { return 80; }
27
28 static int depth = -1;
29
30 static struct {
31     zword xsize;
32     zword table;
33     zword width;
34     zword total;
35 } redirect[MAX_NESTING];
36
37 /*
38  * memory_open
39  *
40  * Begin output redirection to the memory of the Z-machine.
41  *
42  */
43
44 void memory_open (zword table, zword xsize, bool buffering)
45 {
46
47     if (++depth < MAX_NESTING) {
48
49         if (!buffering)
50             xsize = 0xffff;
51         if (buffering && (short) xsize <= 0)
52             xsize = get_max_width ((zword) (- (short) xsize));
53
54         storew (table, 0);
55
56         redirect[depth].table = table;
57         redirect[depth].width = 0;
58         redirect[depth].total = 0;
59         redirect[depth].xsize = xsize;
60
61         ostream_memory = TRUE;
62
63    } else runtime_error (ERR_STR3_NESTING);
64
65 }/* memory_open */
66
67 /*
68  * memory_new_line
69  *
70  * Redirect a newline to the memory of the Z-machine.
71  *
72  */
73
74 void memory_new_line (void)
75 {
76     zword size;
77     zword addr;
78
79     redirect[depth].total += redirect[depth].width;
80     redirect[depth].width = 0;
81
82     addr = redirect[depth].table;
83
84     LOW_WORD (addr, size)
85     addr += 2;
86
87     if (redirect[depth].xsize != 0xffff) {
88
89         redirect[depth].table = addr + size;
90         size = 0;
91
92     } else storeb ((zword) (addr + (size++)), 13);
93
94     storew (redirect[depth].table, size);
95
96 }/* memory_new_line */
97
98 /*
99  * memory_word
100  *
101  * Redirect a string of characters to the memory of the Z-machine.
102  *
103  */
104
105 void memory_word (const zchar *s)
106 {
107     zword size;
108     zword addr;
109     zchar c;
110
111     if (h_version == V6) {
112
113         int width = os_string_width (s);
114
115         if (redirect[depth].xsize != 0xffff)
116
117             if (redirect[depth].width + width > redirect[depth].xsize) {
118
119                 if (*s == ' ' || *s == ZC_INDENT || *s == ZC_GAP)
120                     width = os_string_width (++s);
121
122                 memory_new_line ();
123
124             }
125
126         redirect[depth].width += width;
127
128     }
129
130     addr = redirect[depth].table;
131
132     LOW_WORD (addr, size)
133     addr += 2;
134
135     while ((c = *s++) != 0)
136         storeb ((zword) (addr + (size++)), translate_to_zscii (c));
137
138     storew (redirect[depth].table, size);
139
140 }/* memory_word */
141
142 /*
143  * memory_close
144  *
145  * End of output redirection.
146  *
147  */
148
149 void memory_close (void)
150 {
151
152     if (depth >= 0) {
153
154         if (redirect[depth].xsize != 0xffff)
155             memory_new_line ();
156
157         if (h_version == V6) {
158
159             h_line_width = (redirect[depth].xsize != 0xffff) ?
160                 redirect[depth].total : redirect[depth].width;
161
162             SET_WORD (H_LINE_WIDTH, h_line_width)
163
164         }
165
166         if (depth == 0)
167             ostream_memory = FALSE;
168
169         depth--;
170
171     }
172
173 }/* memory_close */