spectrum2/backends/frotz/redirect.c
2011-09-15 14:11:24 +02:00

172 lines
3.2 KiB
C

/* redirect.c - Output redirection to Z-machine memory
* Copyright (c) 1995-1997 Stefan Jokisch
*
* This file is part of Frotz.
*
* Frotz is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Frotz is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include "frotz.h"
#define MAX_NESTING 16
extern zword get_max_width (zword);
static int depth = -1;
static struct {
zword xsize;
zword table;
zword width;
zword total;
} redirect[MAX_NESTING];
/*
* memory_open
*
* Begin output redirection to the memory of the Z-machine.
*
*/
void memory_open (zword table, zword xsize, int buffering)
{
if (++depth < MAX_NESTING) {
if (!buffering)
xsize = 0xffff;
if (buffering && (short) xsize <= 0)
xsize = get_max_width ((zword) (- (short) xsize));
storew (table, 0);
redirect[depth].table = table;
redirect[depth].width = 0;
redirect[depth].total = 0;
redirect[depth].xsize = xsize;
ostream_memory = TRUE;
} else runtime_error (ERR_STR3_NESTING);
}/* memory_open */
/*
* memory_new_line
*
* Redirect a newline to the memory of the Z-machine.
*
*/
void memory_new_line (void)
{
zword size;
zword addr;
redirect[depth].total += redirect[depth].width;
redirect[depth].width = 0;
addr = redirect[depth].table;
LOW_WORD (addr, size)
addr += 2;
if (redirect[depth].xsize != 0xffff) {
redirect[depth].table = addr + size;
size = 0;
} else storeb ((zword) (addr + (size++)), 13);
storew (redirect[depth].table, size);
}/* memory_new_line */
/*
* memory_word
*
* Redirect a string of characters to the memory of the Z-machine.
*
*/
void memory_word (const zchar *s)
{
zword size;
zword addr;
zchar c;
if (h_version == V6) {
int width = os_string_width (s);
if (redirect[depth].xsize != 0xffff)
if (redirect[depth].width + width > redirect[depth].xsize) {
if (*s == ' ' || *s == ZC_INDENT || *s == ZC_GAP)
width = os_string_width (++s);
memory_new_line ();
}
redirect[depth].width += width;
}
addr = redirect[depth].table;
LOW_WORD (addr, size)
addr += 2;
while ((c = *s++) != 0)
storeb ((zword) (addr + (size++)), translate_to_zscii (c));
storew (redirect[depth].table, size);
}/* memory_word */
/*
* memory_close
*
* End of output redirection.
*
*/
void memory_close (void)
{
if (depth >= 0) {
if (redirect[depth].xsize != 0xffff)
memory_new_line ();
if (h_version == V6) {
h_line_width = (redirect[depth].xsize != 0xffff) ?
redirect[depth].total : redirect[depth].width;
SET_WORD (H_LINE_WIDTH, h_line_width)
}
if (depth == 0)
ostream_memory = FALSE;
depth--;
}
}/* memory_close */