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 extern zword get_max_width(zword);
26
27 static int depth = -1;
28
29 static struct {
30 zword xsize;
31 zword table;
32 zword width;
33 zword total;
34 } redirect[MAX_NESTING];
35
36
37 /*
38 * memory_open
39 *
40 * Begin output redirection to the memory of the Z-machine.
41 *
42 */
memory_open(zword table,zword xsize,bool buffering)43 void memory_open(zword table, zword xsize, bool buffering)
44 {
45 if (++depth < MAX_NESTING) {
46 if (!buffering)
47 xsize = 0xffff;
48 else {
49 if ((short)xsize >= 0)
50 xsize = get_max_width(xsize);
51 else
52 xsize = -xsize;
53 }
54 storew(table, 0);
55 redirect[depth].table = table;
56 redirect[depth].width = 0;
57 redirect[depth].total = 0;
58 redirect[depth].xsize = xsize;
59 ostream_memory = TRUE;
60 } else
61 runtime_error(ERR_STR3_NESTING);
62 } /* memory_open */
63
64
65 /*
66 * memory_new_line
67 *
68 * Redirect a newline to the memory of the Z-machine.
69 *
70 */
memory_new_line(void)71 void memory_new_line(void)
72 {
73 zword size;
74 zword addr;
75
76 redirect[depth].total += redirect[depth].width;
77 redirect[depth].width = 0;
78
79 addr = redirect[depth].table;
80
81 LOW_WORD(addr, size)
82 addr += 2;
83
84 if (redirect[depth].xsize != 0xffff) {
85 redirect[depth].table = addr + size;
86 size = 0;
87
88 } else
89 storeb((zword) (addr + (size++)), 13);
90
91 storew(redirect[depth].table, size);
92 } /* memory_new_line */
93
94
95 /*
96 * memory_word
97 *
98 * Redirect a string of characters to the memory of the Z-machine.
99 *
100 */
memory_word(const zchar * s)101 void memory_word(const zchar * s)
102 {
103 zword size;
104 zword addr;
105 zchar c;
106
107 if (z_header.version == V6) {
108 int width = os_string_width(s);
109
110 if (redirect[depth].xsize != 0xffff)
111 if (redirect[depth].width + width >
112 redirect[depth].xsize) {
113 if (*s == ' ' || *s == ZC_INDENT ||
114 *s == ZC_GAP)
115 width = os_string_width(++s);
116 memory_new_line();
117 }
118 redirect[depth].width += width;
119 }
120 addr = redirect[depth].table;
121 LOW_WORD(addr, size)
122 addr += 2;
123
124 while ((c = *s++) != 0)
125 storeb((zword) (addr + (size++)), translate_to_zscii(c));
126
127 storew(redirect[depth].table, size);
128 } /* memory_word */
129
130
131 /*
132 * memory_close
133 *
134 * End of output redirection.
135 *
136 */
memory_close(void)137 void memory_close(void)
138 {
139 if (depth >= 0) {
140 if (redirect[depth].xsize != 0xffff)
141 memory_new_line();
142 if (z_header.version == V6) {
143
144 z_header.line_width = (redirect[depth].xsize != 0xffff) ?
145 redirect[depth].total : redirect[depth].width;
146
147 SET_WORD(H_LINE_WIDTH, z_header.line_width)
148 }
149 if (depth == 0)
150 ostream_memory = FALSE;
151 depth--;
152 }
153 } /* memory_close */
154