From 1fb931fbd950324754536ee0b33ed0b91f68c9a2 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 13 Nov 2018 19:47:07 -0800 Subject: GLK: Changing gargoyle folder to glk --- engines/glk/frotz/processor_buffer.cpp | 192 +++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 engines/glk/frotz/processor_buffer.cpp (limited to 'engines/glk/frotz/processor_buffer.cpp') diff --git a/engines/glk/frotz/processor_buffer.cpp b/engines/glk/frotz/processor_buffer.cpp new file mode 100644 index 0000000000..faec6ef33d --- /dev/null +++ b/engines/glk/frotz/processor_buffer.cpp @@ -0,0 +1,192 @@ +/* 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 "glk/frotz/processor.h" +#include "common/algorithm.h" +#include "common/textconsole.h" + +namespace Gargoyle { +namespace Frotz { + +const char *const Processor::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" +}; + +void Processor::flush_buffer() { + /* 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 || bufferEmpty()) + 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 Processor::print_char(zchar c) { + static bool flag = false; + + if (message || ostream_memory || enable_buffering) { + if (!flag) { + // Characters 0 and ZC_RETURN are special cases + if (c == ZC_RETURN) { + new_line(); + 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_buffer(); + + // 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 Processor::print_string(const char *s) { + char c; + + while ((c = *s++) != 0) { + if (c == '\n') + new_line(); + else + print_char(c); + } +} + +void Processor::print_long(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; + print_char(c + (c <= 9 ? '0' : 'a' - 10)); + } + } +} + +void Processor::new_line() { + flush_buffer(); + stream_new_line(); +} + +void Processor::runtimeError(ErrorCode errNum) { + int wasfirst; + + if (errNum <= 0 || errNum > ERR_NUM_ERRORS) + return; + + if (_err_report_mode == ERR_REPORT_FATAL + || (!_ignore_errors && errNum <= ERR_MAX_FATAL)) { + flush_buffer(); + error(ERR_MESSAGES[errNum - 1]); + return; + } + + wasfirst = (_errorCount[errNum - 1] == 0); + _errorCount[errNum - 1]++; + + if ((_err_report_mode == ERR_REPORT_ALWAYS) + || (_err_report_mode == ERR_REPORT_ONCE && wasfirst)) { + long pc; + GET_PC(pc); + print_string("Warning: "); + print_string(ERR_MESSAGES[errNum - 1]); + print_string(" (PC = "); + print_long(pc, 16); + print_char(')'); + + if (_err_report_mode == ERR_REPORT_ONCE) { + print_string(" (will ignore further occurrences)"); + } + else { + print_string(" (occurence "); + print_long(_errorCount[errNum - 1], 10); + print_char(')'); + } + + new_line(); + } +} + +} // End of namespace Scott +} // End of namespace Gargoyle -- cgit v1.2.3