/* 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, bool 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 */