diff --git a/engines/gargoyle/frotz/err.cpp b/engines/gargoyle/frotz/err.cpp new file mode 100644 index 00000000000..b25b75c0fcc --- /dev/null +++ b/engines/gargoyle/frotz/err.cpp @@ -0,0 +1,131 @@ +/* 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/err.h" +#include "gargoyle/frotz/frotz.h" +#include "common/textconsole.h" + +namespace Gargoyle { +namespace Frotz { + +const char *const Errors::ERR_MESSAGES[ERR_NUM_ERRORS] = { + "Text buffer overflow", + "Store out of dynamic memory", + "Division by zero", + "Illegal object", + "Illegal attribute", + "No such property", + "Stack overflow", + "Call to illegal address", + "Call to non-routine", + "Stack underflow", + "Illegal opcode", + "Bad stack frame", + "Jump to illegal address", + "Can't save while in interrupt", + "Nesting stream #3 too deep", + "Illegal window", + "Illegal window property", + "Print at illegal address", + "Illegal dictionary word length", + "@jin called with object 0", + "@get_child called with object 0", + "@get_parent called with object 0", + "@get_sibling called with object 0", + "@get_prop_addr called with object 0", + "@get_prop called with object 0", + "@put_prop called with object 0", + "@clear_attr called with object 0", + "@set_attr called with object 0", + "@test_attr called with object 0", + "@move_object called moving object 0", + "@move_object called moving into object 0", + "@remove_object called with object 0", + "@get_next_prop called with object 0" +}; + +Errors::Errors() { + Common::fill(&_count[0], &_count[ERR_NUM_ERRORS], 0); +} + +void Errors::runtimeError(int errNum) { + int wasfirst; + + if (errNum <= 0 || errNum > ERR_NUM_ERRORS) + return; + + if (g_vm->_options._err_report_mode == ERR_REPORT_FATAL + || (!g_vm->_options._ignore_errors && errNum <= ERR_MAX_FATAL)) { + g_vm->_buffer.flush(); + error(ERR_MESSAGES[errNum - 1]); + return; + } + + wasfirst = (_count[errNum - 1] == 0); + _count[errNum - 1]++; + + if ((g_vm->_options._err_report_mode == ERR_REPORT_ALWAYS) + || (g_vm->_options._err_report_mode == ERR_REPORT_ONCE && wasfirst)) { + long pc = g_vm->getPC(); + printString("Warning: "); + printString(ERR_MESSAGES[errNum - 1]); + printString(" (PC = "); + printLong(pc, 16); + printChar(')'); + + if (g_vm->_options._err_report_mode == ERR_REPORT_ONCE) { + printString(" (will ignore further occurrences)"); + } else { + printString(" (occurence "); + printLong(_count[errNum - 1], 10); + printChar(')'); + } + + newLine(); + } +} + +void Errors::printLong(uint value, int base) { + unsigned long i; + char c; + + for (i = (base == 10 ? 1000000000 : 0x10000000); i != 0; i /= base) + if (value >= i || i == 1) { + c = (value / i) % base; + printChar(c + (c <= 9 ? '0' : 'a' - 10)); + } +} + +void Errors::printChar(const char c) { + // TODO +} + +void Errors::printString(const char *str) { + // TODO +} + +void Errors::newLine() { + // TODO +} + +} // End of namespace Scott +} // End of namespace Gargoyle diff --git a/engines/gargoyle/frotz/err.h b/engines/gargoyle/frotz/err.h new file mode 100644 index 00000000000..f61d7269af2 --- /dev/null +++ b/engines/gargoyle/frotz/err.h @@ -0,0 +1,75 @@ +/* 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_ERR +#define GARGOYLE_FROTZ_ERR + +#include "gargoyle/frotz/frotz_types.h" + +namespace Gargoyle { +namespace Frotz { + +#define ERR_NUM_ERRORS 33 +#define ERR_MAX_FATAL 19 + +class Errors { +private: + static const char *const ERR_MESSAGES[ERR_NUM_ERRORS]; + int _count[ERR_NUM_ERRORS]; +public: + /** + * Constructor + */ + Errors(); + + /** + * An error has occurred. Ignore it, pass it to os_fatal or report + * it according to err_report_mode. + * @param errNum Numeric code for error (1 to ERR_NUM_ERRORS) + */ + void runtimeError(int errNum); + + /** + * Print an unsigned 32bit number in decimal or hex. + */ + void printLong(uint value, int base); + + /** + * Print a character + */ + void printChar(const char c); + + /** + * Print a string + */ + void printString(const char *str); + + /** + * Add a newline + */ + void newLine(); +}; + +} // End of namespace Frotz +} // End of namespace Gargoyle + +#endif diff --git a/engines/gargoyle/frotz/frotz.cpp b/engines/gargoyle/frotz/frotz.cpp index e7c6972ec42..2a7bcd02fc7 100644 --- a/engines/gargoyle/frotz/frotz.cpp +++ b/engines/gargoyle/frotz/frotz.cpp @@ -51,5 +51,10 @@ Common::Error Frotz::saveGameState(int slot, const Common::String &desc) { return Common::kNoError; } +uint Frotz::getPC() const { + // TODO + return 0; +} + } // End of namespace Scott } // End of namespace Gargoyle diff --git a/engines/gargoyle/frotz/frotz.h b/engines/gargoyle/frotz/frotz.h index 6ed226ac845..b0a7e1d2945 100644 --- a/engines/gargoyle/frotz/frotz.h +++ b/engines/gargoyle/frotz/frotz.h @@ -25,6 +25,8 @@ #include "gargoyle/glk.h" #include "gargoyle/frotz/frotz_types.h" +#include "gargoyle/frotz/buffer.h" +#include "gargoyle/frotz/err.h" namespace Gargoyle { namespace Frotz { @@ -36,6 +38,7 @@ class Frotz : public Glk { public: UserOptions _options; Header _header; + Buffer _buffer; // Story file name, id number and size Common::String _storyName; @@ -91,6 +94,11 @@ public: * Save the game */ virtual Common::Error saveGameState(int slot, const Common::String &desc) override; + + /** + * Get the current PC + */ + uint getPC() const; }; extern Frotz *g_vm; diff --git a/engines/gargoyle/module.mk b/engines/gargoyle/module.mk index 85bd0553324..8fdf82ac895 100644 --- a/engines/gargoyle/module.mk +++ b/engines/gargoyle/module.mk @@ -23,6 +23,7 @@ MODULE_OBJS := \ frotz/buffer.o \ frotz/detection.o \ frotz/detection_tables.o \ + frotz/err.o \ frotz/frotz.o \ scott/detection.o \ scott/scott.o