Cosmos/Demos/zMachine/Frotz.Net/source/Desktop/FrotzBase/Frotz/Generic/stream.cs
2016-06-09 10:34:36 -04:00

403 lines
No EOL
11 KiB
C#

/* stream.c - IO stream implementation
* 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
*/
using zword = System.UInt16;
using zbyte = System.Byte;
using System;
using Frotz;
using Frotz.Constants;
namespace Frotz.Generic {
internal static class Stream {
/*
* scrollback_char
*
* Write a single character to the scrollback buffer.
*
*/
internal static void scrollback_char(zword c) {
if (c == CharCodes.ZC_INDENT) { scrollback_char(' '); scrollback_char(' '); scrollback_char(' '); return; }
if (c == CharCodes.ZC_GAP) { scrollback_char(' '); scrollback_char(' '); return; }
os_.scrollback_char(c);
}/* scrollback_char */
/*
* scrollback_word
*
* Write a string to the scrollback buffer.
*
*/
internal static void scrollback_word(zword[] s) {
// for (i = 0; s[i] != 0; i++)
for (int i = 0; i < s.Length; i++) {
if (s[i] == CharCodes.ZC_NEW_FONT || s[i] == CharCodes.ZC_NEW_STYLE)
i++;
else
scrollback_char(s[i]);
}
}/* scrollback_word */
/*
* scrollback_write_input
*
* Send an input line to the scrollback buffer.
*
*/
internal static void scrollback_write_input(zword[] buf, zword key) {
int i;
for (i = 0; buf[i] != 0; i++)
scrollback_char(buf[i]);
if (key == CharCodes.ZC_RETURN)
scrollback_char('\n');
}/* scrollback_write_input */
/*
* scrollback_erase_input
*
* Remove an input line from the scrollback buffer.
*
*/
internal static void scrollback_erase_input(zword[] buf) {
int width;
int i;
for (i = 0, width = 0; buf[i] != 0; i++)
width++;
os_.scrollback_erase(width);
}/* scrollback_erase_input */
/*
* stream_mssg_on
*
* Start printing a "debugging" message.
*
*/
internal static void stream_mssg_on ()
{
Buffer.flush_buffer ();
if (main.ostream_screen)
Screen.screen_mssg_on ();
if (main.ostream_script && main.enable_scripting)
Files.script_mssg_on ();
main.message = true;
}/* stream_mssg_on */
/*
* stream_mssg_off
*
* Stop printing a "debugging" message.
*
*/
internal static void stream_mssg_off ()
{
Buffer.flush_buffer ();
if (main.ostream_screen)
Screen.screen_mssg_off ();
if (main.ostream_script && main.enable_scripting)
Files.script_mssg_off ();
main.message = false;
}/* stream_mssg_off */
/*
* z_output_stream, open or close an output stream.
*
* zargs[0] = stream to open (positive) or close (negative)
* zargs[1] = address to redirect output to (stream 3 only)
* zargs[2] = width of redirected output (stream 3 only, optional)
*
*/
internal static void z_output_stream() {
Buffer.flush_buffer();
switch ((short)Process.zargs[0]) {
case 1: main.ostream_screen = true;
break;
case -1: main.ostream_screen = false;
break;
case 2: if (!main.ostream_script) Files.script_open();
break;
case -2: if (main.ostream_script) Files.script_close();
break;
case 3: Redirect.memory_open(Process.zargs[1], Process.zargs[2], Process.zargc >= 3);
break;
case -3: Redirect.memory_close();
break;
case 4: if (!main.ostream_record) Files.record_open();
break;
case -4: if (main.ostream_record) Files.record_close();
break;
}
}/* z_output_stream */
/*
* stream_char
*
* Send a single character to the output stream.
*
*/
internal static void stream_char(zword c) {
if (main.ostream_screen)
Screen.screen_char(c);
if (main.ostream_script && main.enable_scripting)
Files.script_char(c);
if (main.enable_scripting)
scrollback_char(c);
}/* stream_char */
/*
* stream_word
*
* Send a string of characters to the output streams.
*
*/
internal static void stream_word(zword[] s) {
if (main.ostream_memory && !main.message)
Redirect.memory_word(s);
else {
if (main.ostream_screen)
Screen.screen_word(s);
if (main.ostream_script && main.enable_scripting)
Files.script_word(s);
if (main.enable_scripting)
Stream.scrollback_word(s);
}
}/* stream_word */
/*
* stream_new_line
*
* Send a newline to the output streams.
*
*/
internal static void stream_new_line() {
if (main.ostream_memory && !main.message)
Redirect.memory_new_line();
else {
if (main.ostream_screen)
Screen.screen_new_line();
if (main.ostream_script && main.enable_scripting)
Files.script_new_line();
if (main.enable_scripting)
os_.scrollback_char('\n');
}
}/* stream_new_line */
/*
* z_input_stream, select an input stream.
*
* zargs[0] = input stream to be selected
*
*/
internal static void z_input_stream ()
{
Buffer.flush_buffer ();
if (Process.zargs[0] == 0 && main.istream_replay)
Files.replay_close ();
if (Process.zargs[0] == 1 && !main.istream_replay)
Files.replay_open ();
}/* z_input_stream */
/*
* stream_read_key
*
* Read a single keystroke from the current input stream.
*
*/
internal static zword stream_read_key(zword timeout, zword routine,
bool hot_keys) {
zword key = CharCodes.ZC_BAD;
Buffer.flush_buffer();
/* Read key from current input stream */
continue_input:
do {
if (main.istream_replay)
key = Files.replay_read_key();
else
key = Screen.console_read_key(timeout);
} while (key == CharCodes.ZC_BAD);
/* Verify mouse clicks */
if (key == CharCodes.ZC_SINGLE_CLICK || key == CharCodes.ZC_DOUBLE_CLICK)
if (!Screen.validate_click())
goto continue_input;
/* Copy key to the command file */
if (main.ostream_record && !main.istream_replay)
Files.record_write_key(key);
/* Handle timeouts */
if (key == CharCodes.ZC_TIME_OUT)
if (Process.direct_call(routine) == 0)
goto continue_input;
/* Handle hot keys */
if (hot_keys && key >= CharCodes.ZC_HKEY_MIN && key <= CharCodes.ZC_HKEY_MAX) {
if (main.h_version == ZMachine.V4 && key == CharCodes.ZC_HKEY_UNDO)
goto continue_input;
if (!Hotkey.handle_hot_key(key))
goto continue_input;
}
/* Return key */
return key;
}/* stream_read_key */
/*
* stream_read_input
*
* Read a line of input from the current input stream.
*
*/
internal static zword stream_read_input(int max, zword[] buf,// zword* buf,
zword timeout, zword routine,
bool hot_keys,
bool no_scripting) {
zword key = CharCodes.ZC_BAD;
bool no_scrollback = no_scripting;
if (main.h_version == ZMachine.V6 && main.story_id == Story.UNKNOWN && !main.ostream_script)
no_scrollback = false;
Buffer.flush_buffer();
/* Remove initial input from the transscript file or from the screen */
if (main.ostream_script && main.enable_scripting && !no_scripting)
Files.script_erase_input(buf);
if (main.enable_scripting && !no_scrollback)
Stream.scrollback_erase_input(buf);
if (main.istream_replay)
Screen.screen_erase_input(buf);
/* Read input line from current input stream */
continue_input:
do {
if (main.istream_replay)
key = Files.replay_read_input(buf);
else
key = Screen.console_read_input(max, buf, timeout, key != CharCodes.ZC_BAD);
} while (key == CharCodes.ZC_BAD);
/* Verify mouse clicks */
if (key == CharCodes.ZC_SINGLE_CLICK || key == CharCodes.ZC_DOUBLE_CLICK)
if (!Screen.validate_click())
goto continue_input;
/* Copy input line to the command file */
if (main.ostream_record && !main.istream_replay)
Files.record_write_input(buf, key);
/* Handle timeouts */
if (key == CharCodes.ZC_TIME_OUT)
if (Process.direct_call(routine) == 0)
goto continue_input;
/* Handle hot keys */
if (hot_keys && key >= CharCodes.ZC_HKEY_MIN && key <= CharCodes.ZC_HKEY_MAX) {
if (!Hotkey.handle_hot_key(key))
goto continue_input;
return CharCodes.ZC_BAD;
}
/* Copy input line to transscript file or to the screen */
if (main.ostream_script && main.enable_scripting && !no_scripting)
Files.script_write_input(buf, key);
if (main.enable_scripting && !no_scrollback)
scrollback_write_input(buf, key);
if (main.istream_replay)
Screen.screen_write_input(buf, key);
/* Return terminating key */
return key;
}/* stream_read_input */
}
}