mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-31 05:11:08 +00:00
577 lines
No EOL
14 KiB
C#
577 lines
No EOL
14 KiB
C#
/* files.c - Transscription, recording and playback
|
|
* 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 Frotz;
|
|
using Frotz.Constants;
|
|
|
|
namespace Frotz.Generic
|
|
{
|
|
internal static class Files
|
|
{
|
|
internal static string script_name = General.DEFAULT_SCRIPT_NAME;
|
|
internal static string command_name = General.DEFAULT_COMMAND_NAME;
|
|
|
|
static int script_width = 0;
|
|
|
|
static System.IO.StreamWriter sfp = null;
|
|
static System.IO.StreamWriter rfp = null;
|
|
static System.IO.FileStream pfp = null;
|
|
|
|
#region Script
|
|
/*
|
|
* script_open
|
|
*
|
|
* Open the transscript file. 'AMFV' makes this more complicated as it
|
|
* turns transscription on/off several times to exclude some text from
|
|
* the transscription file. This wasn't a problem for the original V4
|
|
* interpreters which always sent transscription to the printer, but it
|
|
* means a problem to modern interpreters that offer to open a new file
|
|
* every time transscription is turned on. Our solution is to append to
|
|
* the old transscription file in V1 to V4, and to ask for a new file
|
|
* name in V5+.
|
|
*
|
|
*/
|
|
|
|
static bool script_valid = false;
|
|
internal static void script_open()
|
|
{
|
|
string new_name = null;
|
|
|
|
main.h_flags &= (zword)~ZMachine.SCRIPTING_FLAG;
|
|
|
|
if (main.h_version >= ZMachine.V5 || !script_valid)
|
|
{
|
|
if (os_.read_file_name(out new_name, General.DEFAULT_SCRIPT_NAME, FileTypes.FILE_SCRIPT) != true)
|
|
goto done;
|
|
|
|
script_name = new_name;
|
|
}
|
|
|
|
if ((sfp = new System.IO.StreamWriter(script_name, true)) != null)
|
|
{
|
|
|
|
main.h_flags |= ZMachine.SCRIPTING_FLAG;
|
|
|
|
script_valid = true;
|
|
main.ostream_script = true;
|
|
|
|
script_width = 0;
|
|
|
|
sfp.AutoFlush = true;
|
|
}
|
|
else Text.print_string("Cannot open file\n");
|
|
|
|
done:
|
|
|
|
FastMem.SET_WORD(ZMachine.H_FLAGS, main.h_flags);
|
|
}/* script_open */
|
|
|
|
/*
|
|
* script_close
|
|
*
|
|
* Stop transscription.
|
|
*
|
|
*/
|
|
|
|
internal static void script_close()
|
|
{
|
|
|
|
main.h_flags &= (ushort)~ZMachine.SCRIPTING_FLAG;
|
|
FastMem.SET_WORD(ZMachine.H_FLAGS, main.h_flags);
|
|
|
|
sfp.Close();
|
|
main.ostream_script = false;
|
|
}/* script_close */
|
|
|
|
/*
|
|
* script_new_line
|
|
*
|
|
* Write a newline to the transscript file.
|
|
*
|
|
*/
|
|
|
|
internal static void script_new_line()
|
|
{
|
|
sfp.WriteLine();
|
|
|
|
script_width = 0;
|
|
}/* script_new_line */
|
|
|
|
/*
|
|
* script_char
|
|
*
|
|
* Write a single character to the transscript file.
|
|
*
|
|
*/
|
|
|
|
internal static void script_char(zword c)
|
|
{
|
|
if (c == CharCodes.ZC_INDENT && script_width != 0)
|
|
c = ' ';
|
|
|
|
if (c == CharCodes.ZC_INDENT)
|
|
{ script_char(' '); script_char(' '); script_char(' '); return; }
|
|
if (c == CharCodes.ZC_GAP)
|
|
{ script_char(' '); script_char(' '); return; }
|
|
if (c > 0xff)
|
|
{ script_char('?'); return; }
|
|
|
|
sfp.Write((char)c);
|
|
script_width++;
|
|
}/* script_char */
|
|
|
|
/*
|
|
* script_word
|
|
*
|
|
* Write a string to the transscript file.
|
|
*
|
|
*/
|
|
|
|
internal static void script_word(zword[] s)
|
|
{
|
|
int width;
|
|
int i;
|
|
|
|
int pos = 0;
|
|
|
|
if (s[pos] == CharCodes.ZC_INDENT && script_width != 0)
|
|
{
|
|
script_char(s[pos++]);
|
|
}
|
|
|
|
for (i = pos, width = 0; i < s.Length && s[i] != 0; i++)
|
|
{
|
|
if (s[i] == CharCodes.ZC_NEW_STYLE || s[i] == CharCodes.ZC_NEW_FONT)
|
|
i++;
|
|
else if (s[i] == CharCodes.ZC_GAP)
|
|
width += 3;
|
|
else if (s[i] == CharCodes.ZC_INDENT)
|
|
width += 2;
|
|
else
|
|
width += 1;
|
|
}
|
|
|
|
if (main.option_script_cols != 0 && script_width + width > main.option_script_cols)
|
|
{
|
|
|
|
if (s[pos] == ' ' || s[pos] == CharCodes.ZC_INDENT || s[pos] == CharCodes.ZC_GAP)
|
|
pos++;
|
|
|
|
script_new_line();
|
|
}
|
|
|
|
for (i = pos; i < s.Length && s[i] != 0; i++)
|
|
|
|
if (s[i] == CharCodes.ZC_NEW_FONT || s[i] == CharCodes.ZC_NEW_STYLE)
|
|
i++;
|
|
else
|
|
script_char(s[i]);
|
|
}/* script_word */
|
|
|
|
/*
|
|
* script_write_input
|
|
*
|
|
* Send an input line to the transscript file.
|
|
*
|
|
*/
|
|
|
|
internal static void script_write_input(zword[] buf, zword key)
|
|
{
|
|
int width;
|
|
int i;
|
|
|
|
for (i = 0, width = 0; buf[i] != 0; i++)
|
|
width++;
|
|
|
|
if (main.option_script_cols != 0 && script_width + width > main.option_script_cols)
|
|
script_new_line();
|
|
|
|
for (i = 0; buf[i] != 0; i++)
|
|
script_char(buf[i]);
|
|
|
|
if (key == CharCodes.ZC_RETURN)
|
|
script_new_line();
|
|
|
|
}/* script_write_input */
|
|
|
|
/*
|
|
* script_erase_input
|
|
*
|
|
* Remove an input line from the transscript file.
|
|
*
|
|
*/
|
|
|
|
internal static void script_erase_input(zword[] buf)
|
|
{
|
|
int width;
|
|
int i;
|
|
|
|
for (i = 0, width = 0; buf[i] != 0; i++)
|
|
width++;
|
|
|
|
sfp.BaseStream.SetLength(sfp.BaseStream.Length - width);
|
|
script_width -= width;
|
|
}/* script_erase_input */
|
|
|
|
/*
|
|
* script_mssg_on
|
|
*
|
|
* Start sending a "debugging" message to the transscript file.
|
|
*
|
|
*/
|
|
|
|
internal static void script_mssg_on()
|
|
{
|
|
|
|
if (Files.script_width != 0)
|
|
script_new_line();
|
|
|
|
script_char(CharCodes.ZC_INDENT);
|
|
|
|
}/* script_mssg_on */
|
|
|
|
/*
|
|
* script_mssg_off
|
|
*
|
|
* Stop writing a "debugging" message.
|
|
*
|
|
*/
|
|
|
|
internal static void script_mssg_off()
|
|
{
|
|
|
|
script_new_line();
|
|
|
|
}/* script_mssg_off */
|
|
#endregion
|
|
|
|
#region Record
|
|
/*
|
|
* record_open
|
|
*
|
|
* Open a file to record the player's input.
|
|
*
|
|
*/
|
|
internal static void record_open()
|
|
{
|
|
string new_name = null;
|
|
|
|
if (os_.read_file_name(out new_name, command_name, FileTypes.FILE_RECORD) == true)
|
|
{
|
|
command_name = new_name;
|
|
|
|
if ((rfp = new System.IO.StreamWriter(command_name, false)) != null)
|
|
{
|
|
main.ostream_record = true;
|
|
rfp.AutoFlush = true;
|
|
}
|
|
else
|
|
{
|
|
Text.print_string("Cannot open file\n");
|
|
}
|
|
}
|
|
}/* record_open */
|
|
|
|
/*
|
|
* record_close
|
|
*
|
|
* Stop recording the player's input.
|
|
*
|
|
*/
|
|
|
|
internal static void record_close()
|
|
{
|
|
|
|
rfp.Close();
|
|
main.ostream_record = false;
|
|
|
|
}/* record_close */
|
|
|
|
///*
|
|
// * record_code
|
|
// *
|
|
// * Helper function for record_char.
|
|
// *
|
|
// */
|
|
|
|
private static void record_code(int c, bool force_encoding)
|
|
{
|
|
|
|
if (force_encoding || c == '[' || c < 0x20 || c > 0x7e)
|
|
{
|
|
int i;
|
|
|
|
rfp.Write('[');
|
|
|
|
for (i = 10000; i != 0; i /= 10)
|
|
if (c >= i || i == 1)
|
|
rfp.Write((char)('0' + (c / i) % 10));
|
|
|
|
rfp.Write(']');
|
|
|
|
}
|
|
else rfp.Write((char)c);
|
|
|
|
|
|
}/* record_code */
|
|
|
|
/*
|
|
* record_char
|
|
*
|
|
* Write a character to the command file.
|
|
*
|
|
*/
|
|
|
|
private static void record_char(zword c)
|
|
{
|
|
|
|
if (c != CharCodes.ZC_RETURN)
|
|
{
|
|
if (c < CharCodes.ZC_HKEY_MIN || c > CharCodes.ZC_HKEY_MAX)
|
|
{
|
|
record_code(Text.translate_to_zscii(c), false);
|
|
|
|
if (c == CharCodes.ZC_SINGLE_CLICK || c == CharCodes.ZC_DOUBLE_CLICK)
|
|
{
|
|
record_code(main.mouse_x, true);
|
|
record_code(main.mouse_y, true);
|
|
}
|
|
}
|
|
else record_code(1000 + c - CharCodes.ZC_HKEY_MIN, true);
|
|
}
|
|
|
|
}/* record_char */
|
|
|
|
/*
|
|
* record_write_key
|
|
*
|
|
* Copy a keystroke to the command file.
|
|
*
|
|
*/
|
|
|
|
internal static void record_write_key(zword key)
|
|
{
|
|
record_char(key);
|
|
|
|
rfp.Write('\n');
|
|
|
|
}/* record_write_key */
|
|
|
|
/*
|
|
* record_write_input
|
|
*
|
|
* Copy a line of input to a command file.
|
|
*
|
|
*/
|
|
|
|
internal static void record_write_input(zword[] buf, zword key)
|
|
{
|
|
//zword c;
|
|
|
|
for (int i = 0; i < buf.Length && buf[i] != 0; i++ )
|
|
{
|
|
record_char(buf[i]);
|
|
}
|
|
|
|
record_char (key);
|
|
|
|
rfp.Write('\n');
|
|
|
|
}/* record_write_input */
|
|
#endregion
|
|
|
|
#region Replay
|
|
|
|
/*
|
|
* replay_open
|
|
*
|
|
* Open a file of commands for playback.
|
|
*
|
|
*/
|
|
|
|
internal static void replay_open()
|
|
{
|
|
string new_name = null;
|
|
|
|
if (os_.read_file_name(out new_name, command_name, FileTypes.FILE_PLAYBACK))
|
|
{
|
|
command_name = new_name;
|
|
|
|
if ( (pfp = new System.IO.FileStream(new_name, System.IO.FileMode.Open)) != null) {
|
|
|
|
Screen.set_more_prompts (Input.read_yes_or_no ("Do you want MORE prompts"));
|
|
|
|
main.istream_replay = true;
|
|
|
|
} else Text.print_string ("Cannot open file\n");
|
|
|
|
}
|
|
|
|
|
|
}/* replay_open */
|
|
|
|
/*
|
|
* replay_close
|
|
*
|
|
* Stop playback of commands.
|
|
*
|
|
*/
|
|
|
|
internal static void replay_close()
|
|
{
|
|
|
|
Screen.set_more_prompts(true);
|
|
|
|
pfp.Close();
|
|
|
|
main.istream_replay = false;
|
|
|
|
}/* replay_close */
|
|
|
|
/*
|
|
* replay_code
|
|
*
|
|
* Helper function for replay_key and replay_line.
|
|
*
|
|
*/
|
|
|
|
static int replay_code ()
|
|
{
|
|
int c;
|
|
|
|
|
|
if ( (c = pfp.ReadByte()) == '[') {
|
|
|
|
int c2;
|
|
|
|
c = 0;
|
|
|
|
while ((c2 = pfp.ReadByte()) != -1 && c2 >= '0' && c2 <= '9')
|
|
c = 10 * c + c2 - '0';
|
|
|
|
return (c2 == ']') ? c : -1;
|
|
|
|
} else return c;
|
|
|
|
}/* replay_code */
|
|
|
|
/*
|
|
* replay_char
|
|
*
|
|
* Read a character from the command file.
|
|
*
|
|
*/
|
|
|
|
static zword replay_char ()
|
|
{
|
|
int c;
|
|
|
|
if ((c = replay_code ()) != -1) {
|
|
|
|
if (c != '\n') {
|
|
|
|
if (c < 1000)
|
|
{
|
|
|
|
c = Text.translate_from_zscii((byte)c);
|
|
|
|
if (c == CharCodes.ZC_SINGLE_CLICK || c == CharCodes.ZC_DOUBLE_CLICK)
|
|
{
|
|
main.mouse_x = (zword)replay_code();
|
|
main.mouse_y = (zword)replay_code();
|
|
}
|
|
|
|
return (zword)c;
|
|
|
|
}
|
|
else return (zword)(CharCodes.ZC_HKEY_MIN + c - 1000);
|
|
}
|
|
|
|
pfp.Position--;
|
|
pfp.WriteByte((byte)'\n');
|
|
|
|
return CharCodes.ZC_RETURN;
|
|
|
|
} else return CharCodes.ZC_BAD;
|
|
|
|
}/* replay_char */
|
|
|
|
/*
|
|
* replay_read_key
|
|
*
|
|
* Read a keystroke from a command file.
|
|
*
|
|
*/
|
|
|
|
internal static zword replay_read_key()
|
|
{
|
|
zword key = replay_char();
|
|
|
|
if (pfp.ReadByte() != '\n')
|
|
{
|
|
|
|
replay_close();
|
|
return CharCodes.ZC_BAD;
|
|
|
|
}
|
|
else return key;
|
|
|
|
}/* replay_read_key */
|
|
|
|
/*
|
|
* replay_read_input
|
|
*
|
|
* Read a line of input from a command file.
|
|
*
|
|
*/
|
|
|
|
internal static zword replay_read_input(zword[] buf)
|
|
{
|
|
zword c;
|
|
|
|
int pos = 0;
|
|
|
|
for (; ; )
|
|
{
|
|
|
|
c = replay_char();
|
|
|
|
if (c == CharCodes.ZC_BAD || Input.is_terminator(c))
|
|
break;
|
|
|
|
buf[pos++] = c;
|
|
}
|
|
|
|
pos = 0;
|
|
|
|
//if ( pfp.ReadByte() != '\n') {
|
|
// replay_close();
|
|
// return CharCodes.ZC_BAD;
|
|
|
|
//} else return c;
|
|
|
|
return c;
|
|
|
|
}/* replay_read_input */
|
|
#endregion
|
|
}
|
|
} |