mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-31 21:30:19 +00:00
403 lines
No EOL
11 KiB
C#
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 */
|
|
}
|
|
} |