diff options
author | Paul Gilbert | 2018-11-10 17:54:35 -0800 |
---|---|---|
committer | Paul Gilbert | 2018-12-08 19:05:59 -0800 |
commit | 8316c1a5b28f0a185df32d8bbafd08374a0aed32 (patch) | |
tree | 117d9e1968103d315eed7d377634c272370e95e9 | |
parent | 1aaf2fd145e30937e8cd4c6736bee448f2b05a2c (diff) | |
download | scummvm-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.cpp | 104 | ||||
-rw-r--r-- | engines/gargoyle/frotz/buffer.h | 72 | ||||
-rw-r--r-- | engines/gargoyle/frotz/frotz.cpp | 12 | ||||
-rw-r--r-- | engines/gargoyle/frotz/frotz.h | 44 | ||||
-rw-r--r-- | engines/gargoyle/frotz/frotz_types.h | 164 | ||||
-rw-r--r-- | engines/gargoyle/module.mk | 1 |
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 \ |