aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2018-11-10 17:54:35 -0800
committerPaul Gilbert2018-12-08 19:05:59 -0800
commit8316c1a5b28f0a185df32d8bbafd08374a0aed32 (patch)
tree117d9e1968103d315eed7d377634c272370e95e9
parent1aaf2fd145e30937e8cd4c6736bee448f2b05a2c (diff)
downloadscummvm-rg350-8316c1a5b28f0a185df32d8bbafd08374a0aed32.tar.gz
scummvm-rg350-8316c1a5b28f0a185df32d8bbafd08374a0aed32.tar.bz2
scummvm-rg350-8316c1a5b28f0a185df32d8bbafd08374a0aed32.zip
GLK: FROTZ: Beginnings of initialization
-rw-r--r--engines/gargoyle/frotz/buffer.cpp104
-rw-r--r--engines/gargoyle/frotz/buffer.h72
-rw-r--r--engines/gargoyle/frotz/frotz.cpp12
-rw-r--r--engines/gargoyle/frotz/frotz.h44
-rw-r--r--engines/gargoyle/frotz/frotz_types.h164
-rw-r--r--engines/gargoyle/module.mk1
6 files changed, 392 insertions, 5 deletions
diff --git a/engines/gargoyle/frotz/buffer.cpp b/engines/gargoyle/frotz/buffer.cpp
new file mode 100644
index 0000000000..15ec771bfc
--- /dev/null
+++ b/engines/gargoyle/frotz/buffer.cpp
@@ -0,0 +1,104 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program 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.
+ *
+ * This program 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "gargoyle/frotz/buffer.h"
+#include "gargoyle/frotz/frotz.h"
+#include "common/algorithm.h"
+#include "common/textconsole.h"
+
+namespace Gargoyle {
+namespace Frotz {
+
+// TODO: Replace these method stubs with correct calls
+void stream_char(zchar) {}
+void stream_word(const zchar *) {}
+void stream_new_line(void) {}
+
+Buffer::Buffer() : _bufPos(0), _locked(false), _prevC('\0') {
+ Common::fill(&_buffer[0], &_buffer[TEXT_BUFFER_SIZE], '\0');
+}
+
+void Buffer::flush() {
+ /* Make sure we stop when flush_buffer is called from flush_buffer.
+ * Note that this is difficult to avoid as we might print a newline
+ * during flush_buffer, which might cause a newline interrupt, that
+ * might execute any arbitrary opcode, which might flush the buffer.
+ */
+ if (_locked || empty())
+ return;
+
+ // Send the buffer to the output streams
+ _buffer[_bufPos] = '\0';
+
+ _locked = true;
+ stream_word(_buffer);
+ _locked = false;
+
+ // Reset the buffer
+ _bufPos = 0;
+ _prevC = '\0';
+}
+
+void Buffer::printChar(zchar c) {
+ static bool flag = false;
+
+ if (g_vm->_message || g_vm->_ostream_memory || g_vm->_enableBuffering) {
+ if (!flag) {
+ // Characters 0 and ZC_RETURN are special cases
+ if (c == ZC_RETURN) {
+ newLine();
+ return;
+ }
+ if (c == 0)
+ return;
+
+ // Flush the buffer before a whitespace or after a hyphen
+ if (c == ' ' || c == ZC_INDENT || c == ZC_GAP || (_prevC == '-' && c != '-'))
+ flush();
+
+ // Set the flag if this is part one of a style or font change
+ if (c == ZC_NEW_FONT || c == ZC_NEW_STYLE)
+ flag = true;
+
+ // Remember the current character code
+ _prevC = c;
+ } else {
+ flag = false;
+ }
+
+ // Insert the character into the buffer
+ _buffer[_bufPos++] = c;
+
+ if (_bufPos == TEXT_BUFFER_SIZE)
+ error("Text buffer overflow");
+ } else {
+ stream_char(c);
+ }
+}
+
+void Buffer::newLine() {
+ flush();
+ stream_new_line();
+}
+
+} // End of namespace Scott
+} // End of namespace Gargoyle
diff --git a/engines/gargoyle/frotz/buffer.h b/engines/gargoyle/frotz/buffer.h
new file mode 100644
index 0000000000..608e087f3d
--- /dev/null
+++ b/engines/gargoyle/frotz/buffer.h
@@ -0,0 +1,72 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program 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.
+ *
+ * This program 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GARGOYLE_FROTZ_BUFFER
+#define GARGOYLE_FROTZ_BUFFER
+
+#include "gargoyle/frotz/frotz_types.h"
+
+namespace Gargoyle {
+namespace Frotz {
+
+#define TEXT_BUFFER_SIZE 200
+
+/**
+ * Text buffer class
+ */
+class Buffer {
+public:
+ zchar _buffer[TEXT_BUFFER_SIZE];
+ size_t _bufPos;
+ bool _locked;
+ zchar _prevC;
+public:
+ /**
+ * Constructor
+ */
+ Buffer();
+
+ /**
+ * Copy the contents of the text buffer to the output streams.
+ */
+ void flush();
+
+ /**
+ * High level output function.
+ */
+ void printChar(zchar c);
+
+ /**
+ * High level newline function.
+ */
+ void newLine();
+
+ /**
+ * Returns true if the buffer is empty
+ */
+ bool empty() const { return !_bufPos; }
+};
+
+} // End of namespace Frotz
+} // End of namespace Gargoyle
+
+#endif
diff --git a/engines/gargoyle/frotz/frotz.cpp b/engines/gargoyle/frotz/frotz.cpp
index c13f5b284d..e7c6972ec4 100644
--- a/engines/gargoyle/frotz/frotz.cpp
+++ b/engines/gargoyle/frotz/frotz.cpp
@@ -26,7 +26,17 @@
namespace Gargoyle {
namespace Frotz {
-Frotz::Frotz(OSystem *syst, const GargoyleGameDescription *gameDesc) : Glk(syst, gameDesc) {
+Frotz *g_vm;
+
+Frotz::Frotz(OSystem *syst, const GargoyleGameDescription *gameDesc) : Glk(syst, gameDesc),
+ _storyId(STORY_UNKNOWN), _storySize(0), _sp(nullptr), _fp(nullptr), _frameCount(0),
+ _ostream_screen(true), _ostream_script(false), _ostream_memory(false),
+ _ostream_record(false), _istream_replay(false), _message(false),
+ _cwin(0), _mwin(0), _mouse_x(0), _mouse_y(0), _menu_selected(0),
+ _enableWrapping(false), _enableScripting(true), _enableScrolling(false),
+ _enableBuffering(false), _reserveMem(0) {
+ g_vm = this;
+ Common::fill(&_stack[0], &_stack[STACK_SIZE], 0);
}
void Frotz::runGame(Common::SeekableReadStream *gameFile) {
diff --git a/engines/gargoyle/frotz/frotz.h b/engines/gargoyle/frotz/frotz.h
index 8aa2ce73b3..6ed226ac84 100644
--- a/engines/gargoyle/frotz/frotz.h
+++ b/engines/gargoyle/frotz/frotz.h
@@ -33,10 +33,44 @@ namespace Frotz {
* Frotz interpreter for Z-code games
*/
class Frotz : public Glk {
-private:
- /**
- *
- */
+public:
+ UserOptions _options;
+ Header _header;
+
+ // Story file name, id number and size
+ Common::String _storyName;
+ Story _storyId;
+ size_t _storySize;
+
+ // Stack data
+ zword _stack[STACK_SIZE];
+ zword *_sp;
+ zword *_fp;
+ zword _frameCount;
+
+ // IO streams
+ bool _ostream_screen;
+ bool _ostream_script;
+ bool _ostream_memory;
+ bool _ostream_record;
+ bool _istream_replay;
+ bool _message;
+
+ // Current window and mouse data
+ int _cwin;
+ int _mwin;
+ int _mouse_y;
+ int _mouse_x;
+ int _menu_selected;
+
+ // Window attributes
+ bool _enableWrapping;
+ bool _enableScripting;
+ bool _enableScrolling;
+ bool _enableBuffering;
+
+ // Size of memory to reserve (in bytes)
+ size_t _reserveMem;
public:
/**
* Constructor
@@ -59,6 +93,8 @@ public:
virtual Common::Error saveGameState(int slot, const Common::String &desc) override;
};
+extern Frotz *g_vm;
+
} // End of namespace Frotz
} // End of namespace Gargoyle
diff --git a/engines/gargoyle/frotz/frotz_types.h b/engines/gargoyle/frotz/frotz_types.h
index d4a6d8c25e..6fee562a8e 100644
--- a/engines/gargoyle/frotz/frotz_types.h
+++ b/engines/gargoyle/frotz/frotz_types.h
@@ -24,13 +24,177 @@
#define GARGOYLE_FROTZ_FROTZ_TYPES
#include "gargoyle/glk_types.h"
+#include "common/algorithm.h"
namespace Gargoyle {
namespace Frotz {
+#define MAX_UNDO_SLOTS 500
+#define STACK_SIZE 20
+
+/* There are four error reporting modes: never report errors;
+ * report only the first time a given error type occurs;
+ * report every time an error occurs;
+ * or treat all errors as fatal errors, killing the interpreter.
+ * I strongly recommend "report once" as the default. But you can compile in a
+ * different default by changing the definition of ERR_DEFAULT_REPORT_MODE.
+ */
+enum ErrorReport {
+ ERR_REPORT_NEVER = 0,
+ ERR_REPORT_ONCE = 1,
+ ERR_REPORT_ALWAYS = 2,
+ ERR_REPORT_FATAL = 3,
+
+ ERR_DEFAULT_REPORT_MODE = ERR_REPORT_NEVER
+};
+
+/**
+ * Character codes
+ */
+enum ZCode {
+ ZC_TIME_OUT = 0x00,
+ ZC_NEW_STYLE = 0x01,
+ ZC_NEW_FONT = 0x02,
+ ZC_BACKSPACE = 0x08,
+ ZC_INDENT = 0x09,
+ ZC_GAP = 0x0b,
+ ZC_RETURN = 0x0d,
+ ZC_HKEY_MIN = 0x0e,
+ ZC_HKEY_RECORD = 0x0e,
+ ZC_HKEY_PLAYBACK = 0x0f,
+ ZC_HKEY_SEED = 0x10,
+ ZC_HKEY_UNDO = 0x11,
+ ZC_HKEY_RESTART = 0x12,
+ ZC_HKEY_QUIT = 0x13,
+ ZC_HKEY_DEBUG = 0x14,
+ ZC_HKEY_HELP = 0x15,
+ ZC_HKEY_MAX = 0x15,
+ ZC_ESCAPE = 0x1b,
+ ZC_ASCII_MIN = 0x20,
+ ZC_ASCII_MAX = 0x7e,
+ ZC_BAD = 0x7f,
+ ZC_ARROW_MIN = 0x81,
+ ZC_ARROW_UP = 0x81,
+ ZC_ARROW_DOWN = 0x82,
+ ZC_ARROW_LEFT = 0x83,
+ ZC_ARROW_RIGHT = 0x84,
+ ZC_ARROW_MAX = 0x84,
+ ZC_FKEY_MIN = 0x85,
+ ZC_FKEY_MAX = 0x90,
+ ZC_NUMPAD_MIN = 0x91,
+ ZC_NUMPAD_MAX = 0x9a,
+ ZC_SINGLE_CLICK = 0x9b,
+ ZC_DOUBLE_CLICK = 0x9c,
+ ZC_MENU_CLICK = 0x9d,
+ ZC_LATIN1_MIN = 0xa0,
+ ZC_LATIN1_MAX = 0xff
+};
+
+enum Story {
+ STORY_BEYOND_ZORK,
+ STORY_SHERLOCK,
+ STORY_ZORK_ZERO,
+ STORY_SHOGUN,
+ STORY_ARTHUR,
+ STORY_JOURNEY,
+ STORY_LURKING_HORROR,
+ STORY_UNKNOWN
+};
+
typedef byte zbyte;
+typedef char zchar;
typedef uint16 zword;
+/**
+ * User options
+ */
+struct UserOptions {
+ int _attribute_assignment;
+ int _attribute_testing;
+ int _context_lines;
+ int _object_locating;
+ int _object_movement;
+ int _left_margin;
+ int _right_margin;
+ bool _ignore_errors;
+ bool _piracy;
+ int _undo_slots;
+ int _expand_abbreviations;
+ int _script_cols;
+ bool _save_quetzal;
+ int _err_report_mode;
+ bool _sound;
+
+ UserOptions() : _attribute_assignment(0), _attribute_testing(0),
+ _context_lines(0), _object_locating(0), _object_movement(0),
+ _left_margin(0), _right_margin(0), _ignore_errors(false), _piracy(false),
+ _undo_slots(MAX_UNDO_SLOTS), _expand_abbreviations(0), _script_cols(80),
+ _save_quetzal(true),
+ _err_report_mode(ERR_DEFAULT_REPORT_MODE), _sound(true) {
+ }
+};
+
+/**
+ * Story file header data
+ */
+struct Header {
+ zbyte _version;
+ zbyte _config;
+ zword _release;
+ zword _resident_size;
+ zword _start_pc;
+ zword _dictionary;
+ zword _objects;
+ zword _globals;
+ zword _dynamic_size;
+ zword _flags;
+ zbyte _serial[6];
+ zword _abbreviations;
+ zword _file_size;
+ zword _checksum;
+ zbyte _interpreter_number;
+ zbyte _interpreter_version;
+ zbyte _screen_rows;
+ zbyte _screen_cols;
+ zword _screen_width;
+ zword _screen_height;
+ zbyte _font_height = 1;
+ zbyte _font_width = 1;
+ zword _functions_offset;
+ zword _strings_offset;
+ zbyte _default_background;
+ zbyte _default_foreground;
+ zword _terminating_keys;
+ zword _line_width;
+ zbyte _standard_high;
+ zbyte _standard_low;
+ zword _alphabet;
+ zword _extension_table;
+ zbyte _user_name[8];
+
+ zword _hx_table_size;
+ zword _hx_mouse_x;
+ zword _hx_mouse_y;
+ zword _hx_unicode_table;
+ zword _hx_flags;
+ zword _hx_fore_colour;
+ zword _hx_back_colour;
+
+ Header() : _version(0), _config(0), _release(0), _resident_size(0), _start_pc(0),
+ _dictionary(0), _objects(0), _globals(0), _dynamic_size(0), _flags(0),
+ _abbreviations(0), _file_size(0), _checksum(0), _interpreter_number(0),
+ _interpreter_version(0), _screen_rows(0), _screen_cols(0), _screen_width(0),
+ _screen_height(0), _font_height(1), _font_width(1), _functions_offset(0),
+ _strings_offset(0), _default_background(0), _default_foreground(0),
+ _terminating_keys(0), _line_width(0), _standard_high(1), _standard_low(1),
+ _alphabet(0), _extension_table(0),
+ _hx_table_size(0), _hx_mouse_x(0), _hx_mouse_y(0), _hx_unicode_table(0),
+ _hx_flags(0), _hx_fore_colour(0), _hx_back_colour(0) {
+ Common::fill(&_serial[0], &_serial[6], '\0');
+ Common::fill(&_user_name[0], &_user_name[8], '\0');
+ }
+};
+
} // End of namespace Frotz
} // End of namespace Gargoyle
diff --git a/engines/gargoyle/module.mk b/engines/gargoyle/module.mk
index 8e16bfe7f9..85bd055332 100644
--- a/engines/gargoyle/module.mk
+++ b/engines/gargoyle/module.mk
@@ -20,6 +20,7 @@ MODULE_OBJS := \
window_pair.o \
window_text_buffer.o \
window_text_grid.o \
+ frotz/buffer.o \
frotz/detection.o \
frotz/detection_tables.o \
frotz/frotz.o \