aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorPaul Gilbert2019-06-16 21:39:47 -0700
committerPaul Gilbert2019-06-22 14:40:22 -0700
commit84dfa6d3b83e080f099ad606dc7fbeb40ebe4b97 (patch)
tree6f90969f77df66f0eff50365688930af49f5c0b3 /engines
parent004df0ef90f8a4b6367b529f66aeffe65e824977 (diff)
downloadscummvm-rg350-84dfa6d3b83e080f099ad606dc7fbeb40ebe4b97.tar.gz
scummvm-rg350-84dfa6d3b83e080f099ad606dc7fbeb40ebe4b97.tar.bz2
scummvm-rg350-84dfa6d3b83e080f099ad606dc7fbeb40ebe4b97.zip
GLK: ALAN2: Remove previously added code fragments
Diffstat (limited to 'engines')
-rw-r--r--engines/glk/alan2/acode.h289
-rw-r--r--engines/glk/alan2/alan2.cpp39
-rw-r--r--engines/glk/alan2/alan2.h66
-rw-r--r--engines/glk/alan2/decode.cpp120
-rw-r--r--engines/glk/alan2/decode.h80
-rw-r--r--engines/glk/alan2/execute.cpp944
-rw-r--r--engines/glk/alan2/execute.h171
-rw-r--r--engines/glk/alan2/interpreter.cpp778
-rw-r--r--engines/glk/alan2/interpreter.h59
-rw-r--r--engines/glk/alan2/parse.cpp969
-rw-r--r--engines/glk/alan2/parse.h185
-rw-r--r--engines/glk/alan2/rules.cpp88
-rw-r--r--engines/glk/alan2/rules.h51
-rw-r--r--engines/glk/alan2/saveload.cpp218
-rw-r--r--engines/glk/alan2/saveload.h55
-rw-r--r--engines/glk/module.mk6
16 files changed, 3 insertions, 4115 deletions
diff --git a/engines/glk/alan2/acode.h b/engines/glk/alan2/acode.h
deleted file mode 100644
index 5b5a5be990..0000000000
--- a/engines/glk/alan2/acode.h
+++ /dev/null
@@ -1,289 +0,0 @@
-/* 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 GLK_ALAN2_ACODE
-#define GLK_ALAN2_ACODE
-
-#include "common/scummsys.h"
-
-namespace Glk {
-namespace Alan2 {
-
-typedef size_t Aptr; // Type for an ACODE memory address
-typedef uint32 Aword; // Type for an ACODE word
-typedef uint32 Aaddr; // Type for an ACODE address
-typedef uint32 Abool; // Type for an ACODE Boolean value
-typedef int32 Aint; // Type for an ACODE Integer value
-typedef int CodeValue; // Definition for the packing process
-
-// Constants for the Acode file, words/block & bytes/block
-#define BLOCKLEN 256L
-#define BLOCKSIZE (BLOCKLEN*sizeof(Aword))
-
-
-// Definitions for the packing process
-#define VALUEBITS 16
-
-#define EOFChar 256
-#define TOPVALUE (((CodeValue)1<<VALUEBITS) - 1) // Highest value possible
-
-// Half and quarter points in the code value range
-#define ONEQUARTER (TOPVALUE / 4 + 1) // Point after first quarter
-#define HALF (2 * ONEQUARTER) // Point after first half
-#define THREEQUARTER (3 * ONEQUARTER) // Point after third quarter
-
-
-// AMACHINE Word Classes
-typedef int WrdKind;
-#define WRD_SYN 0 // 1 - Synonym
-#define WRD_ADJ 1 // 2 - Adjective
-#define WRD_ALL 2 // 4 - All
-#define WRD_BUT 3 // 8 - But
-#define WRD_CONJ 4 // 16 - Conjunction
-#define WRD_PREP 5 // 32 - Preposition
-#define WRD_DIR 6 // 64 - Direction
-#define WRD_IT 7 // 128 - It
-#define WRD_NOISE 8 // 256 - Noise word
-#define WRD_NOUN 9 // 512 - Noun
-#define WRD_ACT 10 // 1024 - Actor
-#define WRD_THEM 11 // 2048 - Them
-#define WRD_VRB 12 // 4096 - Verb
-#define WRD_CLASSES 13
-
-
-
-// Syntax element classifications
-#define EOS (-2) // End Of Syntax
-
-// Syntax element flag bits
-#define MULTIPLEBIT 0x1
-#define OMNIBIT 0x2
-
-
-// Parameter Classes
-enum ClaKind { // NOTE! These must have the same order as
- CLA_OBJ = 1 << 0, // the name classes in NAM.H
- CLA_CNT = 1 << 1,
- CLA_ACT = 1 << 2,
- CLA_NUM = 1 << 3,
- CLA_STR = 1 << 4,
- CLA_COBJ = 1 << 5,
- CLA_CACT = 1 << 6
-};
-
-
-// Verb Qualifiers
-enum QualClass {
- Q_DEFAULT,
- Q_AFTER,
- Q_BEFORE,
- Q_ONLY
-};
-
-
-// The AMACHINE Operations
-enum OpClass {
- C_CONST,
- C_STMOP,
- C_CURVAR
-};
-
-enum InstClass {
- I_PRINT, // Print a string from the text file
- I_QUIT,
- I_LOOK,
- I_SAVE,
- I_RESTORE,
- I_LIST, // List contents of a container
- I_EMPTY,
- I_SCORE,
- I_VISITS,
- I_SCHEDULE,
- I_CANCEL,
- I_LOCATE,
- I_MAKE,
- I_SET, // Set a numeric attribute to the
- // value on top of stack
- I_STRSET, // Set a string valued attribute to a
- // copy of the string on top of stack,
- // deallocate current contents first
- I_GETSTR, // Get a string contents from text
- // file, create a copy and push it
- // on top of stack
- I_INCR, // Increment an attribute
- I_DECR, // Decrement a numeric attribute
- I_USE,
- I_IN,
- I_DESCRIBE,
- I_SAY,
- I_SAYINT,
- I_SAYSTR,
- I_IF,
- I_ELSE,
- I_ENDIF,
- I_ATTRIBUTE,
- I_STRATTR, // Push a copy of a string attribute
- I_HERE,
- I_NEAR,
- I_WHERE,
- I_AND,
- I_OR,
- I_NE,
- I_EQ,
- I_STREQ, // String compare
- I_STREXACT,
- I_LE,
- I_GE,
- I_LT,
- I_GT,
- I_PLUS,
- I_MINUS,
- I_MULT,
- I_DIV,
- I_NOT,
- I_UMINUS,
- I_RND,
- I_SUM, // SUM-aggregate
- I_MAX, // MAX-aggregate
- I_COUNT, // COUNT-aggregate
- I_RETURN,
- I_SYSTEM,
- I_RESTART, // INTRODUCED: v2.7
- I_BTW, // INTRODUCED: v2.8
- I_CONTAINS, // -""-
- I_DEPSTART, // -""-
- I_DEPCASE, // -""-
- I_DEPEXEC, // -""-
- I_DEPELSE, // -""-
- I_DEPEND // -""-
-};
-
-
-enum VarClass {
- V_PARAM,
- V_CURLOC,
- V_CURACT,
- V_CURVRB,
- V_SCORE
-};
-
-
-#define I_CLASS(x) ((x)>>28)
-#define I_OP(x) ((x&0x8000000)?(x)|0x0f0000000:(x)&0x0fffffff)
-
-
-struct AcdHdr {
-// Important info
- char vers[4]; // 01 - Version of compiler
- Aword size; // 02 - Size of ACD-file in Awords
-// Options
- Abool pack; // 03 - Is the text packed ?
- Aword paglen; // 04 - Length of a page
- Aword pagwidth; // 05 - and width
- Aword debug; // 06 - Option debug
-// Data structures
- Aaddr dict; // 07 - Dictionary
- Aaddr oatrs; // 08 - Object default attributes
- Aaddr latrs; // 09 - Location default attributes
- Aaddr aatrs; // 0a - Actor default attributes
- Aaddr acts; // 0b - Actor table
- Aaddr objs; // 0c - Object table
- Aaddr locs; // 0d - Location table
- Aaddr stxs; // 0e - Syntax table
- Aaddr vrbs; // 0f - Verb table
- Aaddr evts; // 10 - Event table
- Aaddr cnts; // 11 - Container table
- Aaddr ruls; // 12 - Rule table
- Aaddr init; // 13 - String init table
- Aaddr start; // 14 - Start code
- Aword msgs; // 15 - Messages table
-// Miscellaneous
- Aword objmin, objmax; // 16 - Interval for object codes
- Aword actmin, actmax; // 18 - Interval for actor codes
- Aword cntmin, cntmax; // 1a - Interval for container codes
- Aword locmin, locmax; // 1c - Interval for location codes
- Aword dirmin, dirmax; // 1e - Interval for direction codes
- Aword evtmin, evtmax; // 20 - Interval for event codes
- Aword rulmin, rulmax; // 22 - Interval for rule codes
- Aword maxscore; // 24 - Maximum score
- Aaddr scores; // 25 - Score table
- Aaddr freq; // 26 - Address to Char freq's for coding
- Aword acdcrc; // 27 - Checksum for acd code (excl. hdr)
- Aword txtcrc; // 28 - Checksum for text data file
-};
-
-// Error message numbers
-enum MsgKind {
- M_HUH, // Obsolete
- M_WHAT,
- M_WHAT_ALL,
- M_WHAT_IT,
- M_WHAT_THEM,
- M_MULTIPLE,
- M_WANT,
- M_NOUN,
- M_AFTER_BUT,
- M_BUT_ALL,
- M_NOT_MUCH,
- M_WHICH_ONE,
- M_NO_SUCH,
- M_NO_WAY,
- M_CANT0,
- M_CANT,
- M_NOTHING, // Obsolete
- M_SEEOBJ1,
- M_SEEOBJ2,
- M_SEEOBJ3,
- M_SEEOBJ4,
- M_SEEACT,
- M_CONTAINS1,
- M_CONTAINS2,
- M_CONTAINS3,
- M_CONTAINS4,
- M_CONTAINS5,
- M_EMPTY1,
- M_EMPTY2,
- M_SCORE1,
- M_SCORE2,
- M_UNKNOWN_WORD,
- M_MORE,
- M_AGAIN,
- M_SAVEWHERE,
- M_SAVEOVERWRITE,
- M_SAVEFAILED,
- M_SAVEMISSING,
- M_SAVEVERS,
- M_SAVENAME,
- M_RESTOREFROM,
- M_REALLY, // CHANGED: v2.7 from M_RESTART
- M_QUITACTION, // INTRODUCED: v2.7, so M_ARTICLE moved
- M_ARTICLE, // INTRODUCED: v2.6 but replaced the M_NOMSG
- MSGMAX
-};
-
-#define M_ARTICLE26 M_QUITACTION
-#define M_MSGMAX26 M_ARTICLE
-
-} // End of namespace Alan2
-} // End of namespace Glk
-
-#endif
diff --git a/engines/glk/alan2/alan2.cpp b/engines/glk/alan2/alan2.cpp
index 492d425d98..1889c696cd 100644
--- a/engines/glk/alan2/alan2.cpp
+++ b/engines/glk/alan2/alan2.cpp
@@ -21,10 +21,6 @@
*/
#include "glk/alan2/alan2.h"
-#include "glk/alan2/decode.h"
-#include "glk/alan2/execute.h"
-#include "glk/alan2/interpreter.h"
-#include "glk/alan2/saveload.h"
#include "common/config-manager.h"
#include "common/translation.h"
#include "common/error.h"
@@ -36,25 +32,16 @@
namespace Glk {
namespace Alan2 {
-Alan2 *_vm = nullptr;
+Alan2 *g_vm = nullptr;
Alan2::Alan2(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gameDesc),
vm_exited_cleanly(false) {
- _vm = this;
- looking = false;
- dscrstkp = 0;
+ g_vm = this;
}
void Alan2::runGame() {
Common::String gameFileName = _gameFile.getName();
- // TODO: Initialize these properly
- int tmp = 0;
- _decode = new Decode(nullptr, nullptr);
- _execute = new Execute();
- _saveLoad = new SaveLoad(gameFileName, nullptr, nullptr, nullptr, nullptr, &tmp);
- _interpreter = new Interpreter(_execute, _saveLoad, _stack);
-
if (!is_gamefile_valid())
return;
@@ -85,27 +72,5 @@ bool Alan2::is_gamefile_valid() {
return true;
}
-void Alan2::output(const Common::String str) {
- // TODO
-}
-
-void Alan2::printMessage(MsgKind msg) {
- // TODO
-}
-
-void Alan2::printError(MsgKind msg) {
- // TODO
-}
-
-void Alan2::paragraph() {
- if (col != 1)
- newLine();
- newLine();
-}
-
-void Alan2::newLine() {
- // TODO
-}
-
} // End of namespace Alan2
} // End of namespace Glk
diff --git a/engines/glk/alan2/alan2.h b/engines/glk/alan2/alan2.h
index a8e500a0dd..3b5c778d95 100644
--- a/engines/glk/alan2/alan2.h
+++ b/engines/glk/alan2/alan2.h
@@ -26,20 +26,10 @@
#include "common/scummsys.h"
#include "common/stack.h"
#include "glk/glk_api.h"
-#include "glk/alan2/acode.h"
-#include "glk/alan2/types.h"
namespace Glk {
namespace Alan2 {
-typedef Common::FixedStack<Aptr, 100> Alan2Stack;
-class Decode;
-class Execute;
-class Interpreter;
-class SaveLoad;
-
-#define N_EVTS 100
-
/**
* Alan2 game interpreter
*/
@@ -78,63 +68,9 @@ public:
*/
virtual Common::Error writeGameData(Common::WriteStream *ws) override;
- /**
- * Output a string to the screen
- */
- void output(const Common::String str);
-
- /**
- * Print a message from the message table
- */
- void printMessage(MsgKind msg);
-
- /**
- * Print an error from the message table, force new player input and abort
- */
- void printError(MsgKind msg);
-
- /**
- * Make a new paragraph, i.e one empty line (one or two newlines)
- */
- void paragraph();
-
- /**
- * Print the the status line on the top of the screen
- */
- void statusLine();
-
- /**
- * Make a newline, but check for screen full
- */
- void newLine();
-
- // Engine variables
- Alan2Stack *_stack;
- int pc;
- ParamElem *params;
- Aword *memory; // The Amachine memory
- int memTop; // Top of memory
- CurVars cur; // Amachine variables
- int col;
- bool fail;
- int scores[100]; // FIXME: type + size
- AcdHdr *header;
- bool _needSpace; // originally "needsp"
-
- EvtElem *evts; // Event table pointer
- bool looking; // LOOKING? flag
- int dscrstkp; // Describe-stack pointer
- Common::File *_txtFile;
- bool _anyOutput;
- winid_t _bottomWindow;
-
- Decode *_decode;
- Execute *_execute;
- Interpreter *_interpreter;
- SaveLoad *_saveLoad;
};
-extern Alan2 *_vm;
+extern Alan2 *g_vm;
} // End of namespace Alan2
} // End of namespace Glk
diff --git a/engines/glk/alan2/decode.cpp b/engines/glk/alan2/decode.cpp
deleted file mode 100644
index 58e814f97f..0000000000
--- a/engines/glk/alan2/decode.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-/* 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/alan2/decode.h"
-
-namespace Glk {
-namespace Alan2 {
-
-int Decode::inputBit() {
- int bit;
-
- if (!_bitsToGo) { // More bits available ?
- _decodeBuffer = _txtFile->readByte(); // No, so get more
- if (_txtFile->eos()) {
- _garbageBits++;
-
- if (_garbageBits > VALUEBITS - 2)
- error("Error in encoded data file.");
- } else
- _bitsToGo = 8; // Another Char, 8 new bits
- }
-
- bit = _decodeBuffer & 1; // Get next bit
- _decodeBuffer = _decodeBuffer >> 1; // and remove it
- _bitsToGo--;
-
- return bit;
-}
-
-void Decode::startDecoding() {
- _bitsToGo = 0;
- _garbageBits = 0;
-
- _value = 0;
- for (int i = 0; i < VALUEBITS; i++)
- _value = 2 * _value + inputBit();
-
- _low = 0;
- _high = TOPVALUE;
-}
-
-int Decode::decodeChar() {
- const long range = (long)(_high - _low) + 1;
- const uint f = (((long)(_value - _low) + 1) * _freq[0] - 1) / range;
- int symbol;
-
- // Find the symbol
- for (symbol = 1; _freq[symbol] > f; symbol++);
-
- _high = _low + range * _freq[symbol - 1] / _freq[0] - 1;
- _low = _low + range * _freq[symbol] / _freq[0];
-
- for (;;) {
- if (_high < HALF) {
- // Do nothing
- } else if (_low >= HALF) {
- _value = _value - HALF;
- _low = _low - HALF;
- _high = _high - HALF;
- } else if (_low >= ONEQUARTER && _high < THREEQUARTER) {
- _value = _value - ONEQUARTER;
- _low = _low - ONEQUARTER;
- _high = _high - ONEQUARTER;
- } else
- break;
-
- // Scale up the range
- _low = 2 * _low;
- _high = 2 * _high + 1;
- _value = 2 * _value + inputBit();
- }
-
- return symbol - 1;
-}
-
-DecodeInfo *Decode::pushDecode() {
- DecodeInfo *info = new DecodeInfo();
-
- info->fpos = _txtFile->pos();
- info->buffer = _decodeBuffer;
- info->bits = _bitsToGo;
- info->value = _value;
- info->high = _high;
- info->low = _low;
-
- return info;
-}
-
-void Decode::popDecode (DecodeInfo *info) {
- _txtFile->seek(info->fpos, SEEK_CUR);
- _decodeBuffer = info->buffer;
- _bitsToGo = info->bits;
- _value = info->value;
- _high = info->high;
- _low = info->low;
-
- delete info;
-}
-
-} // End of namespace Alan2
-} // End of namespace Glk
diff --git a/engines/glk/alan2/decode.h b/engines/glk/alan2/decode.h
deleted file mode 100644
index 75a35dc945..0000000000
--- a/engines/glk/alan2/decode.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* 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 GLK_ALAN2_DECODE
-#define GLK_ALAN2_DECODE
-
-#include "glk/alan2/alan2.h"
-#include "glk/alan2/acode.h"
-#include "common/file.h"
-
-namespace Glk {
-namespace Alan2 {
-
-// Structure for saved decode info
-struct DecodeInfo {
- long fpos;
- int buffer;
- int bits;
- CodeValue value;
- CodeValue high;
- CodeValue low;
-};
-
-class Decode {
-public:
- Decode(Common::File *txtFile, Aword *freq): _txtFile(txtFile), _freq(freq) {}
- void startDecoding();
- int decodeChar();
-
- /**
- * Save so much about the decoding process, so it is possible to restore
- * and continue later.
- */
- DecodeInfo *pushDecode();
-
- /**
- * Restore enough info about the decoding process, so it is possible to
- * continue after having decoded something else.
- */
- void popDecode(DecodeInfo *info);
-
- int inputBit();
-
-private:
- // Bit output
- int _decodeBuffer; // Bits to be input
- int _bitsToGo; // Bits still in buffer
- int _garbageBits; // Bits past EOF
-
- Aword *_freq;
- Common::File *_txtFile;
-
- // Current state of decoding
- CodeValue _value; // Currently seen code value
- CodeValue _low, _high; // Current code region
-};
-
-} // End of namespace Alan2
-} // End of namespace Glk
-
-#endif
diff --git a/engines/glk/alan2/execute.cpp b/engines/glk/alan2/execute.cpp
deleted file mode 100644
index 4fc0acb33b..0000000000
--- a/engines/glk/alan2/execute.cpp
+++ /dev/null
@@ -1,944 +0,0 @@
-/* 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 "common/stack.h"
-#include "glk/alan2/alan2.h"
-#include "glk/alan2/decode.h"
-#include "glk/alan2/execute.h"
-#include "glk/alan2/interpreter.h"
-#include "glk/alan2/saveload.h"
-#include "glk/alan2/types.h"
-#include "glk/alan2/util.h"
-#include "common/debug.h"
-#include "common/file.h"
-
-namespace Glk {
-namespace Alan2 {
-
-#define WIDTH 80
-
-// Is there an exit from one location to another ?
-bool Execute::exitto(int to, int from) {
- if (_locs[from - LOCMIN].exts == 0)
- return false; // No exits
-
- for (ExtElem *ext = (ExtElem *)addrTo(_locs[from - LOCMIN].exts); !endOfTable(ext); ext++)
- if ((int)ext->next == to)
- return true;
-
- return false;
-}
-
-int Execute::count(int cnt) {
- int j = 0;
-
- for (uint i = OBJMIN; i <= OBJMAX; i++)
- if (in(i, cnt))
- j++; // Then it's in this container also
-
- return j;
-}
-
-int Execute::sumAttributes(Aword atr, Aword cnt) {
- int sum = 0;
-
- for (uint i = OBJMIN; i <= OBJMAX; i++) {
- if (_objs[i - OBJMIN].loc == cnt) { // Then it's in this container
- if (_objs[i - OBJMIN].cont != 0) // This is also a container!
- sum = sum + sumAttributes(atr, i);
- sum = sum + attribute(i, atr);
- }
- }
-
- return sum;
-}
-
-bool Execute::checkContainerLimit(Aword cnt, Aword obj) {
- LimElem *lim;
- Aword props;
-
- _vm->fail = true;
- if (!isCnt(cnt))
- error("Checking limits for a non-container.");
-
- // Find the container properties
- if (isObj(cnt))
- props = _objs[cnt - OBJMIN].cont;
- else if (isAct(cnt))
- props = _acts[cnt - ACTMIN].cont;
- else
- props = cnt;
-
-
- if (_cnts[props - CNTMIN].lims != 0) { /* Any limits at all? */
- for (lim = (LimElem *)addrTo(_cnts[props - CNTMIN].lims); !endOfTable(lim); lim++) {
- if (lim->atr == 0) {
- if (count(cnt) >= (int)lim->val) {
- _vm->_interpreter->interpret(lim->stms);
- return true; // Limit check failed
- }
- } else {
- if (sumAttributes(lim->atr, cnt) + attribute(obj, lim->atr) > lim->val) {
- _vm->_interpreter->interpret(lim->stms);
- return true;
- }
- }
- }
- }
-
- _vm->fail = false;
-
- return false;
-}
-
-void Execute::print(Aword fpos, Aword len) {
- char str[2 * WIDTH]; // String buffer
- int outlen = 0; // Current output length
- int ch = 0;
- int i;
- long savfp = 0; // Temporary saved text file position
- bool printFlag = false; // Printing already?
- bool savedPrintFlag = printFlag;
- DecodeInfo *info = nullptr; // Saved decoding info
-
-
- if (len == 0)
- return;
-
- if (isHere(HERO)) { // Check if the player will see it
- if (printFlag) { // Already printing?
- // Save current text file position and/or decoding info
- if (_vm->header->pack)
- info = _vm->_decode->pushDecode();
- else
- savfp = _vm->_txtFile->pos();
- }
-
- printFlag = true; // We're printing now!
- _vm->_txtFile->seek(fpos, SEEK_CUR); // Position to start of text
- if (_vm->header->pack)
- _vm->_decode->startDecoding();
-
- for (outlen = 0; outlen != (int)len; outlen = outlen + strlen(str)) {
- // Fill the buffer from the beginning
- for (i = 0; i <= WIDTH || (i > WIDTH && ch != ' '); i++) {
- if (outlen + i == (int)len) // No more characters?
- break;
- if (_vm->header->pack)
- ch = _vm->_decode->decodeChar();
- else
- ch = _vm->_txtFile->readSByte();
- if (ch == EOFChar) // Or end of text?
- break;
- str[i] = ch;
- }
-
- str[i] = '\0';
-
- // TODO
- /*
-#if ISO == 0
- fromIso(str, str);
-#endif
- */
- _vm->output(str);
- }
-
- // And restore
- printFlag = savedPrintFlag;
- if (printFlag) {
- if (_vm->header->pack)
- _vm->_decode->popDecode(info);
- else
- _vm->_txtFile->seek(savfp, SEEK_CUR);
- }
- }
-}
-
-void Execute::sys(Aword fpos, Aword len) {
- char *command;
-
- getstr(fpos, len); // Returns address to string on stack
- command = (char *)_vm->_stack->pop();
-
- warning("Request to execute system command %s", command);
- free(command);
-}
-
-void Execute::getstr(Aword fpos, Aword len) {
- char *buf = new char[len + 1];
-
- _vm->_stack->push((Aptr) buf); // Push the address to the string
- _vm->_txtFile->seek(fpos, SEEK_CUR); // Position to start of text
- if (_vm->header->pack)
- _vm->_decode->startDecoding();
- while (len--) {
- if (_vm->header->pack)
- *(buf++) = _vm->_decode->decodeChar();
- else
- *(buf++) = _vm->_txtFile->readSByte();
- }
- *buf = '\0';
-}
-
-void Execute::score(Aword sc) {
- char buf[80];
-
- if (sc == 0) {
- _vm->printMessage(M_SCORE1);
- sprintf(buf, "%d", _vm->cur.score);
- _vm->output(buf);
- _vm->printMessage(M_SCORE2);
- sprintf(buf, "%ld.", (unsigned long)_vm->header->maxscore);
- _vm->output(buf);
- } else {
- _vm->cur.score += _vm->scores[sc - 1];
- _vm->scores[sc - 1] = 0;
- }
-}
-
-void Execute::visits(Aword v) {
- _vm->cur.visits = v;
-}
-
-bool Execute::confirm(MsgKind msgno) {
- char buf[80];
-
- // This is a bit of a hack since we really want to compare the input,
- // it could be affirmative, but for now any input is NOT!
- _vm->printMessage(msgno);
-
- // TODO
-#if 0
- //_vm->glk_request_line_event(_bottomWindow, buf, 80 - 1, 0);
-
-#ifdef USE_READLINE
- if (!readline(buf)) return true;
-#else
- if (gets(buf) == nullptr) return true;
-#endif
-
-#endif
- _vm->col = 1;
-
- return (buf[0] == '\0');
-}
-
-
-void Execute::quit() {
- char buf[80];
-// char choices[10];
-
- _vm->paragraph();
-
- while (true) {
- _vm->col = 1;
- _vm->statusLine();
- _vm->printMessage(M_QUITACTION);
-
- // TODO
-#if 0
-#ifdef USE_READLINE
- if (!readline(buf)) terminate(0);
-#else
- if (gets(buf) == nullptr) terminate(0);
-#endif
-#endif
-
- if (strcmp(buf, "restart") == 0) {
- //longjmp(restart_label, true); // TODO
- } else if (strcmp(buf, "restore") == 0) {
- _vm->_saveLoad->restore();
- return;
- } else if (strcmp(buf, "quit") == 0) {
- _vm->quitGame();
- }
- }
- error("Fallthrough in QUIT");
-}
-
-void Execute::restart() {
- _vm->paragraph();
- if (confirm(M_REALLY)) {
- //longjmp(restart_label, true); // TODO
- } else
- return;
-
- error("Fallthrough in RESTART");
-}
-
-void Execute::eventchk() {
- while (etop != 0 && eventq[etop - 1].time == _vm->cur.tick) {
- etop--;
- if (isLoc(eventq[etop].where))
- _vm->cur.loc = eventq[etop].where;
- else
- _vm->cur.loc = where(eventq[etop].where);
-
- // TODO
-#if 0
- if (trcflg) {
- debug("\n<EVENT %d (at ", eventq[etop].event);
- debugsay(_vm->cur.loc);
- debug("):>\n");
- }
-#endif
- _vm->_interpreter->interpret(_vm->evts[eventq[etop].event - EVTMIN].code);
- }
-}
-
-void Execute::cancl(Aword evt) {
- int i;
-
- for (i = etop - 1; i >= 0; i--) {
- if (eventq[i].event == (int)evt) {
- while (i < etop - 1) {
- eventq[i].event = eventq[i + 1].event;
- eventq[i].time = eventq[i + 1].time;
- eventq[i].where = eventq[i + 1].where;
- i++;
- }
-
- etop--;
- return;
- }
- }
-}
-
-void Execute::schedule(Aword evt, Aword whr, Aword aft) {
- int i;
- int time;
-
- cancl(evt);
- // Check for overflow
- if (etop == N_EVTS)
- error("Out of event space.");
-
- time = _vm->cur.tick+aft;
-
- // Bubble this event down
- for (i = etop; i >= 1 && eventq[i-1].time <= time; i--) {
- eventq[i].event = eventq[i-1].event;
- eventq[i].time = eventq[i-1].time;
- eventq[i].where = eventq[i-1].where;
- }
-
- eventq[i].time = time;
- eventq[i].where = whr;
- eventq[i].event = evt;
- etop++;
-}
-
-Aptr Execute::getAttribute(Aaddr atradr, Aaddr atr) {
- AtrElem *at = (AtrElem *)addrTo(atradr);
- return at[atr - 1].val;
-}
-
-void Execute::setAttribute(Aaddr atradr, Aword atr, Aword val) {
- AtrElem *at = (AtrElem *)addrTo(atradr);
- at[atr - 1].val = val;
-}
-
-void Execute::make(Aword id, Aword atr, Aword val) {
- if (isObj(id))
- setAttribute(_objs[id - OBJMIN].atrs, atr, val);
- else if (isLoc(id))
- setAttribute(_locs[id - LOCMIN].atrs, atr, val);
- else if (isAct(id))
- setAttribute(_acts[id - ACTMIN].atrs, atr, val);
- else
- error("Can't MAKE item (%ld).", (unsigned long)id);
-}
-
-void Execute::set(Aword id, Aword atr, Aword val) {
- if (isObj(id))
- setAttribute(_objs[id - OBJMIN].atrs, atr, val);
- else if (isLoc(id)) {
- setAttribute(_locs[id - LOCMIN].atrs, atr, val);
- _locs[id - LOCMIN].describe = 0;
- } else if (isAct(id))
- setAttribute(_acts[id - ACTMIN].atrs, atr, val);
- else
- error("Can't SET item (%ld).", (unsigned long)id);
-}
-
-void Execute::setstr(Aword id, Aword atr, Aword str) {
- free((char *)attribute(id, atr));
- set(id, atr, str);
-}
-
-void Execute::incAttribute(Aaddr atradr, Aword atr, Aword step) {
- AtrElem *at = (AtrElem *) addrTo(atradr);
- at[atr - 1].val += step;
-}
-
-void Execute::incLocation(Aword loc, Aword atr, Aword step) {
- incAttribute(_locs[loc - LOCMIN].atrs, atr, step);
- _locs[loc - LOCMIN].describe = 0;
-}
-
-void Execute::incObject(Aword obj, Aword atr, Aword step) {
- incAttribute(_objs[obj - OBJMIN].atrs, atr, step);
-}
-
-void Execute::incract(Aword act, Aword atr, Aword step) {
- incAttribute(_acts[act - ACTMIN].atrs, atr, step);
-}
-
-void Execute::incr(Aword id, Aword atr, Aword step) {
- if (isObj(id))
- incObject(id, atr, step);
- else if (isLoc(id))
- incLocation(id, atr, step);
- else if (isAct(id))
- incract(id, atr, step);
- else
- error("Can't INCR item (%ld).", (unsigned long)id);
-}
-
-void Execute::decr(Aword id, Aword atr, Aword step) {
- if (isObj(id))
- incObject(id, atr, -(int)step);
- else if (isLoc(id))
- incLocation(id, atr, -(int)step);
- else if (isAct(id))
- incract(id, atr, -(int)step);
- else
- error("Can't DECR item (%ld).", (unsigned long)id);
-}
-
-Aptr Execute::attribute(Aword id, Aword atr) {
- if (isObj(id))
- return getAttribute(_objs[id - OBJMIN].atrs, atr);
- else if (isLoc(id))
- return getAttribute(_locs[id - LOCMIN].atrs, atr);
- else if (isAct(id))
- return getAttribute(_acts[id - ACTMIN].atrs, atr);
- else if (isLit(id)) {
- if (atr == 1)
- return litValues[id - LITMIN].value;
- else
- error("Unknown attribute for literal (%ld).", (unsigned long)atr);
- } else
- error("Can't ATTRIBUTE item (%ld).", (unsigned long) id);
-}
-
-Aptr Execute::strattr(Aword id, Aword atr) {
- Common::String result = (char *)attribute(id, atr);
- return (Aptr)result.c_str();
-}
-
-Aword Execute::objloc(Aword obj) {
- if (isCnt(_objs[obj - OBJMIN].loc)) { // In something ?
- if (isObj(_objs[obj - OBJMIN].loc) || isAct(_objs[obj - OBJMIN].loc))
- return(where(_objs[obj - OBJMIN].loc));
- else // Containers not anywhere is where the hero is!
- return(where(HERO));
- } else {
- return(_objs[obj - OBJMIN].loc);
- }
-}
-
-Aword Execute::actloc(Aword act) {
- return(_acts[act - ACTMIN].loc);
-}
-
-Aword Execute::where(Aword id) {
- if (isObj(id))
- return objloc(id);
- else if (isAct(id))
- return actloc(id);
- else
- error("Can't WHERE item (%ld).", (unsigned long) id);
-}
-
-Aint Execute::agrmax(Aword atr, Aword whr) {
- Aword i;
- uint max = 0;
-
- for (i = OBJMIN; i <= OBJMAX; i++) {
- if (isLoc(whr)) {
- if (where(i) == whr && attribute(i, atr) > max)
- max = attribute(i, atr);
- } else if (_objs[i - OBJMIN].loc == whr && attribute(i, atr) > max)
- max = attribute(i, atr);
- }
-
- return(max);
-}
-
-Aint Execute::agrsum(Aword atr, Aword whr) {
- Aword i;
- uint sum = 0;
-
- for (i = OBJMIN; i <= OBJMAX; i++) {
- if (isLoc(whr)) {
- if (where(i) == whr)
- sum += attribute(i, atr);
- } else if (_objs[i-OBJMIN].loc == whr)
- sum += attribute(i, atr);
- }
-
- return(sum);
-}
-
-Aint Execute::agrcount(Aword whr) {
- Aword i;
- Aword countVal = 0;
-
- for (i = OBJMIN; i <= OBJMAX; i++) {
- if (isLoc(whr)) {
- if (where(i) == whr)
- countVal++;
- } else if (_objs[i-OBJMIN].loc == whr)
- countVal++;
- }
-
- return(countVal);
-}
-
-void Execute::locobj(Aword obj, Aword whr) {
- if (isCnt(whr)) { // Into a container
- if (whr == obj)
- error("Locating something inside itself.");
- if (checkContainerLimit(whr, obj))
- return;
- else
- _objs[obj-OBJMIN].loc = whr;
- } else {
- _objs[obj-OBJMIN].loc = whr;
- // Make sure the location is described since it's changed
- _locs[whr-LOCMIN].describe = 0;
- }
-}
-
-void Execute::locact(Aword act, Aword whr) {
- Aword prevact = _vm->cur.act;
- Aword prevloc = _vm->cur.loc;
-
- _vm->cur.loc = whr;
- _acts[act - ACTMIN].loc = whr;
-
- if (act == HERO) {
- if (_locs[_acts[act - ACTMIN].loc-LOCMIN].describe % (_vm->cur.visits+1) == 0)
- look();
- else {
- if (_vm->_anyOutput)
- _vm->paragraph();
-
- say(where(HERO));
- _vm->printMessage(M_AGAIN);
- _vm->newLine();
- dscrobjs();
- dscracts();
- }
-
- _locs[where(HERO)-LOCMIN].describe++;
- _locs[where(HERO)-LOCMIN].describe %= (_vm->cur.visits+1);
- } else
- _locs[whr-LOCMIN].describe = 0;
-
- if (_locs[_vm->cur.loc-LOCMIN].does != 0) {
- _vm->cur.act = act;
- _vm->_interpreter->interpret(_locs[_vm->cur.loc-LOCMIN].does);
- _vm->cur.act = prevact;
- }
-
- if (_vm->cur.act != (int)act)
- _vm->cur.loc = prevloc;
-}
-
-
-void Execute::locate(Aword id, Aword whr) {
- if (isObj(id))
- locobj(id, whr);
- else if (isAct(id))
- locact(id, whr);
- else
- error("Can't LOCATE item (%ld).", (unsigned long)id);
-}
-
-Abool Execute::objhere(Aword obj) {
- if (isCnt(_objs[obj - OBJMIN].loc)) { // In something?
- if (isObj(_objs[obj - OBJMIN].loc) || isAct(_objs[obj - OBJMIN].loc))
- return(isHere(_objs[obj - OBJMIN].loc));
- else // If the container wasn't anywhere, assume where HERO is!
- return((int)where(HERO) == _vm->cur.loc);
- } else
- return((int)_objs[obj - OBJMIN].loc == _vm->cur.loc);
-}
-
-Aword Execute::acthere(Aword act) {
- return (int)_acts[act - ACTMIN].loc == _vm->cur.loc;
-}
-
-Abool Execute::isHere(Aword id) {
- if (isObj(id))
- return objhere(id);
- else if (isAct(id))
- return acthere(id);
- else
- error("Can't HERE item (%ld).", (unsigned long)id);
-}
-
-Aword Execute::objnear(Aword obj) {
- if (isCnt(_objs[obj-OBJMIN].loc)) { // In something?
- if (isObj(_objs[obj-OBJMIN].loc) || isAct(_objs[obj-OBJMIN].loc))
- return(isNear(_objs[obj-OBJMIN].loc));
- else // If the container wasn't anywhere, assume here, so not nearby!
- return(false);
- } else {
- return(exitto(where(obj), _vm->cur.loc));
- }
-}
-
-Aword Execute::actnear(Aword act) {
- return(exitto(where(act), _vm->cur.loc));
-}
-
-
-Abool Execute::isNear(Aword id) {
- if (isObj(id))
- return objnear(id);
- else if (isAct(id))
- return actnear(id);
- else
- error("Can't NEAR item (%ld).", (unsigned long) id);
-}
-
-Abool Execute::in(Aword obj, Aword cnt) {
- if (!isObj(obj))
- return(false);
- if (!isCnt(cnt))
- error("IN in a non-container.");
-
- return(_objs[obj - OBJMIN].loc == cnt);
-}
-
-void Execute::sayarticle(Aword id) {
- if (!isObj(id))
- error("Trying to say article of something *not* an object.");
- if (_objs[id - OBJMIN].art != 0)
- _vm->_interpreter->interpret(_objs[id - OBJMIN].art);
- else
- _vm->printMessage(M_ARTICLE);
-}
-
-void Execute::say(Aword id) {
- if (isHere(HERO)) {
- if (isObj(id))
- _vm->_interpreter->interpret(_objs[id - OBJMIN].dscr2);
- else if (isLoc(id))
- _vm->_interpreter->interpret(_locs[id - LOCMIN].nams);
- else if (isAct(id))
- _vm->_interpreter->interpret(_acts[id - ACTMIN].nam);
- else if (isLit(id)) {
- if (isNum(id))
- _vm->output(Common::String::format("%ld", litValues[id - LITMIN].value));
- else
- _vm->output((char *)litValues[id - LITMIN].value);
- } else
- error("Can't SAY item (%ld).", (unsigned long)id);
- }
-}
-
-void Execute::dscrloc(Aword loc) {
- if (_locs[loc - LOCMIN].dscr != 0)
- _vm->_interpreter->interpret(_locs[loc - LOCMIN].dscr);
-}
-
-void Execute::dscrobj(Aword obj) {
- _objs[obj - OBJMIN].describe = false;
- if (_objs[obj - OBJMIN].dscr1 != 0)
- _vm->_interpreter->interpret(_objs[obj - OBJMIN].dscr1);
- else {
- _vm->printMessage(M_SEEOBJ1);
- sayarticle(obj);
- say(obj);
- _vm->printMessage(M_SEEOBJ4);
- if (_objs[obj - OBJMIN].cont != 0)
- list(obj);
- }
-}
-
-
-void Execute::dscract(Aword act) {
- ScrElem *scr = nullptr;
-
- if (_acts[act - ACTMIN].script != 0) {
- for (scr = (ScrElem *) addrTo(_acts[act - ACTMIN].scradr); !endOfTable(scr); scr++)
- if (scr->code == _acts[act - ACTMIN].script)
- break;
- if (endOfTable(scr))
- scr = nullptr;
- }
-
- if (scr != nullptr && scr->dscr != 0)
- _vm->_interpreter->interpret(scr->dscr);
- else if (_acts[act - ACTMIN].dscr != 0)
- _vm->_interpreter->interpret(_acts[act - ACTMIN].dscr);
- else {
- _vm->_interpreter->interpret(_acts[act - ACTMIN].nam);
- _vm->printMessage(M_SEEACT);
- }
-
- _acts[act - ACTMIN].describe = false;
-}
-
-void Execute::describe(Aword id) {
- for (uint i = 0; i < _describeStack.size(); i++) {
- _describeStack.push(id);
-
- if (isObj(id))
- dscrobj(id);
- else if (isLoc(id))
- dscrloc(id);
- else if (isAct(id))
- dscract(id);
- else
- error("Can't DESCRIBE item (%ld).", (unsigned long)id);
- }
-
- _describeStack.pop();
-}
-
-void Execute::use(Aword act, Aword scr) {
- if (!isAct(act))
- error("Item is not an Actor (%ld).", (unsigned long) act);
-
- _acts[act - ACTMIN].script = scr;
- _acts[act - ACTMIN].step = 0;
-}
-
-void Execute::list(Aword cnt) {
- uint i;
- Aword props;
- Aword prevobj = 0;
- bool found = false;
- bool multiple = false;
-
- // Find container properties
- if (isObj(cnt))
- props = _objs[cnt-OBJMIN].cont;
- else if (isAct(cnt))
- props = _acts[cnt-ACTMIN].cont;
- else
- props = cnt;
-
- for (i = OBJMIN; i <= OBJMAX; i++) {
- if (in(i, cnt)) { // Yes, it's in this container
- if (!found) {
- found = true;
- if (_cnts[props-CNTMIN].header != 0)
- _vm->_interpreter->interpret(_cnts[props-CNTMIN].header);
- else {
- _vm->printMessage(M_CONTAINS1);
- if (_cnts[props-CNTMIN].nam != 0) // It has it's own name
- _vm->_interpreter->interpret(_cnts[props-CNTMIN].nam);
- else
- say(_cnts[props-CNTMIN].parent); // It is actually an object or actor
-
- _vm->printMessage(M_CONTAINS2);
- }
- } else {
- if (multiple) {
- _vm->_needSpace = false;
- _vm->printMessage(M_CONTAINS3);
- }
-
- multiple = true;
- sayarticle(prevobj);
- say(prevobj);
- }
-
- prevobj = i;
- }
- }
-
- if (found) {
- if (multiple)
- _vm->printMessage(M_CONTAINS4);
-
- sayarticle(prevobj);
- say(prevobj);
- _vm->printMessage(M_CONTAINS5);
- } else {
- if (_cnts[props-CNTMIN].empty != 0)
- _vm->_interpreter->interpret(_cnts[props-CNTMIN].empty);
- else {
- _vm->printMessage(M_EMPTY1);
-
- if (_cnts[props-CNTMIN].nam != 0) // It has it's own name
- _vm->_interpreter->interpret(_cnts[props-CNTMIN].nam);
- else
- say(_cnts[props-CNTMIN].parent); // It is actually an actor or object
-
- _vm->printMessage(M_EMPTY2);
- }
- }
-
- _vm->_needSpace = true;
-}
-
-void Execute::empty(Aword cnt, Aword whr) {
- for (uint i = OBJMIN; i <= OBJMAX; i++)
- if (in(i, cnt))
- locate(i, whr);
-}
-
-void Execute::dscrobjs() {
- uint i;
- int prevobj = 0;
- bool found = false;
- bool multiple = false;
-
- // First describe everything here with its own description
- for (i = OBJMIN; i <= OBJMAX; i++) {
- if ((int)_objs[i - OBJMIN].loc == _vm->cur.loc && _objs[i - OBJMIN].describe && _objs[i - OBJMIN].dscr1)
- describe(i);
- }
-
- // Then list everything else here
- for (i = OBJMIN; i <= OBJMAX; i++) {
- if ((int)_objs[i - OBJMIN].loc == _vm->cur.loc && _objs[i - OBJMIN].describe) {
- if (!found) {
- _vm->printMessage(M_SEEOBJ1);
- sayarticle(i);
- say(i);
- found = true;
- } else {
- if (multiple) {
- _vm->_needSpace = false;
- _vm->printMessage(M_SEEOBJ2);
- sayarticle(prevobj);
- say(prevobj);
- }
-
- multiple = true;
- }
-
- prevobj = i;
- }
- }
-
- if (found) {
- if (multiple) {
- _vm->printMessage(M_SEEOBJ3);
- sayarticle(prevobj);
- say(prevobj);
- }
-
- _vm->printMessage(M_SEEOBJ4);
- }
-
- // Set describe flag for all objects
- for (i = OBJMIN; i <= OBJMAX; i++)
- _objs[i-OBJMIN].describe = true;
-}
-
-
-void Execute::dscracts() {
- for (uint i = HERO+1; i <= ACTMAX; i++)
- if ((int)_acts[i-ACTMIN].loc == _vm->cur.loc &&
- _acts[i-ACTMIN].describe)
- describe(i);
-
- // Set describe flag for all actors
- for (uint i = HERO; i <= ACTMAX; i++)
- _acts[i-ACTMIN].describe = true;
-}
-
-void Execute::look() {
- uint i;
- _vm->looking = true;
-
- // Set describe flag for all objects and actors
- for (i = OBJMIN; i <= OBJMAX; i++)
- _objs[i-OBJMIN].describe = true;
- for (i = ACTMIN; i <= ACTMAX; i++)
- _acts[i-ACTMIN].describe = true;
-
- if (_vm->_anyOutput)
- _vm->paragraph();
-
- //glk_set_style(style_Subheader); // TODO
- _vm->_needSpace = false;
- say(_vm->cur.loc);
-
- _vm->_needSpace = false;
- _vm->output(".");
-
- //glk_set_style(style_Normal); // TODO
- _vm->newLine();
- _vm->_needSpace = false;
- describe(_vm->cur.loc);
- dscrobjs();
- dscracts();
- _vm->looking = false;
-}
-
-Aword Execute::rnd(Aword from, Aword to) {
- if (to == from)
- return to;
- else if (to > from)
- return to; // TODO
- //return (rand()/10)%(to-from+1)+from;
- else
- return to; // TODO
- //return (rand()/10)%(from-to+1)+to;
-}
-
-// Between
-Abool Execute::btw(Aint val, Aint low, Aint high) {
- if (high > low)
- return low <= val && val <= high;
- else
- return high <= val && val <= low;
-}
-
-// TODO: Replace this with Common::String functionality
-Aword Execute::contains(Aptr string, Aptr substring) {
- Common::String str = (char *)string;
- char *substr = (char *)substring;
- bool result = str.contains(substr);
-
- free((char *)string);
- free((char *)substring);
-
- return result;
-}
-
-// TODO: Replace this with Common::String functionality
-// Compare two strings approximately, ignore case
-Abool Execute::streq(char *a, char *b) {
- Common::String str1 = a;
- Common::String str2 = b;
- bool result = str1.equalsIgnoreCase(str2);
-
- free(a);
- free(b);
-
- return result;
-}
-
-} // End of namespace Alan2
-} // End of namespace Glk
diff --git a/engines/glk/alan2/execute.h b/engines/glk/alan2/execute.h
deleted file mode 100644
index 9f04ca5ae5..0000000000
--- a/engines/glk/alan2/execute.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/* 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 GLK_ALAN2_EXECUTE
-#define GLK_ALAN2_EXECUTE
-
-#include "glk/alan2/acode.h"
-#include "glk/alan2/rules.h"
-#include "common/list.h"
-
-namespace Glk {
-namespace Alan2 {
-
-class Execute {
-public:
- Execute() {}
-
- void sys(Aword fpos, Aword len);
- bool confirm(MsgKind msgno);
- Aptr attribute(Aword item, Aword atr);
- void say(Aword item);
- void saynum(Aword num);
- void saystr(char *str);
- Aptr strattr(Aword id, Aword atr);
- void setstr(Aword id, Aword atr, Aword str);
- void getstr(Aword fpos, Aword len);
- void print(Aword fpos, Aword len);
- void look();
- void make(Aword id, Aword atr, Aword val);
- void set(Aword id, Aword atr, Aword val);
- void incr(Aword id, Aword atr, Aword step);
- void decr(Aword id, Aword atr, Aword step);
- void use(Aword act, Aword scr);
- void describe(Aword id);
- void list(Aword cnt);
- void locate(Aword id, Aword whr);
- void empty(Aword cnt, Aword whr);
- void score(Aword sc);
- void visits(Aword v);
-
- /**
- * Check if any events are pending. If so execute them.
- */
- void eventchk();
- void schedule(Aword evt, Aword whr, Aword aft);
- void cancl(Aword evt);
-
- void quit();
- void restart();
- void sayint(Aword val);
- Aword rnd(Aword from, Aword to);
- Abool btw(Aint val, Aint from, Aint to);
- Aword contains(Aptr string, Aptr substring);
- Abool streq(char a[], char b[]);
- Abool in(Aword obj, Aword cnt);
- Aword where(Aword item);
- Aint agrmax(Aword atr, Aword whr);
- Aint agrsum(Aword atr, Aword whr);
- Aint agrcount(Aword whr);
- Abool isHere(Aword item);
- Abool isNear(Aword item);
-
-private:
- bool exitto(int to, int from);
-
- /**
- * Count the number of items in a container.
- *
- * @param cnt The container to count
- */
- int count(int cnt);
-
- /**
- * Sum the values of one attribute in a container. Recursively.
- *
- * @param atr The attribute to sum over
- * @param cnt the container to sum
- */
- int sumAttributes(Aword atr, Aword cnt);
-
- /**
- * Checks if a limit for a container is exceeded.
- *
- * @param cnt Container code
- * @param obj The object to add
- */
- bool checkContainerLimit(Aword cnt, Aword obj);
-
- /**
- * Get an attribute value from an attribute list
- *
- * @param atradr ACODE address to attribute table
- * @param atr The attribute to read
- */
- Aptr getAttribute(Aaddr atradr, Aaddr atr);
-
- /**
- * Set a particular attribute to a value.
- *
- * @param atradr ACODE address to attribute table
- * @param atr Attribute code
- * @param val New value
- */
- void setAttribute(Aaddr atradr, Aword atr, Aword val);
-
- /**
- * Increment a particular attribute by a value.
- *
- * @param atradr ACODE address to attribute table
- * @param atr Attribute code
- * @param step Step to increment by
- */
- void incAttribute(Aaddr atradr, Aword atr, Aword step);
- void incLocation(Aword loc, Aword atr, Aword step);
- void incObject(Aword obj, Aword atr, Aword step);
- void incract(Aword act, Aword atr, Aword step);
- Aword objloc(Aword obj);
- Aword actloc(Aword act);
- void locobj(Aword obj, Aword whr);
- void locact(Aword act, Aword whr);
- Abool objhere(Aword obj);
- Aword acthere(Aword act);
- Aword objnear(Aword obj);
- Aword actnear(Aword act);
- void sayarticle(Aword id);
- void dscrloc(Aword loc);
- void dscrobj(Aword obj);
- void dscract(Aword act);
-
- /**
- * Description of current location
- */
- void dscrobjs();
-
- void dscracts();
-
- // The event queue
- EvtqElem *eventq; // Event queue
- int etop; // Event queue top pointer
-
- // Amachine data structures
- ActElem *_acts; // Actor table pointer
- LocElem *_locs; // Location table pointer
- ObjElem *_objs; // Object table pointer
- CntElem *_cnts; // Container table pointer
- Common::Stack<Aword> _describeStack;
-};
-
-} // End of namespace Alan2
-} // End of namespace Glk
-
-#endif
diff --git a/engines/glk/alan2/interpreter.cpp b/engines/glk/alan2/interpreter.cpp
deleted file mode 100644
index b8906d2c6e..0000000000
--- a/engines/glk/alan2/interpreter.cpp
+++ /dev/null
@@ -1,778 +0,0 @@
-/* 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/alan2/acode.h"
-#include "glk/alan2/alan2.h"
-#include "glk/alan2/execute.h"
-#include "glk/alan2/interpreter.h"
-#include "glk/alan2/saveload.h"
-#include "glk/alan2/types.h"
-#include "common/debug.h"
-
-namespace Glk {
-namespace Alan2 {
-
-// TODO: Refactor these into debug flags
-const bool trcflg = false;
-const bool stpflg = false;
-
-void Interpreter::if_(Aword v) {
- int lev = 1;
- Aword i;
-
- if (!v) {
- // Skip to next ELSE or ENDIF on same level
- while (true) {
- i = _vm->memory[_vm->pc++];
- if (I_CLASS(i) == (Aword)C_STMOP) {
- switch (I_OP(i)) {
- case I_ELSE:
- if (lev == 1)
- return;
- break;
- case I_IF:
- lev++;
- break;
- case I_ENDIF:
- lev--;
- if (lev == 0)
- return;
- break;
- default:
- break;
- }
- }
- }
- }
-}
-
-void Interpreter::else_() {
- int lev = 1;
- Aword i;
-
- while (true) {
- // Skip to ENDIF on the same level
- i = _vm->memory[_vm->pc++];
- if (I_CLASS(i) == (Aword)C_STMOP) {
- switch (I_OP(i)) {
- case I_ENDIF:
- lev--;
- if (lev == 0)
- return;
- break;
- case I_IF:
- lev++;
- break;
- default:
- break;
- }
- }
- }
-}
-
-void Interpreter::depstart() {
- // A DEPSTART was executed, so skip across the redundant DEPCASE to
- // start at the first expression
- _vm->pc++;
-}
-
-void Interpreter::swap() {
- Aptr v1 = _stack->pop();
- Aptr v2 = _stack->pop();
-
- _stack->push(v1);
- _stack->push(v2);
-}
-
-void Interpreter::depexec(Aword v) {
- int lev = 1;
- Aword i;
-
- if (!v) {
- // The expression was not true, skip to next CASE on the same
- // level which could be a DEPCASE or DEPELSE
- while (true) {
- i = _vm->memory[_vm->pc++];
- if (I_CLASS(i) == (Aword)C_STMOP) {
- switch (I_OP(i)) {
- case I_DEPSTART:
- lev++;
- break;
- case I_DEPEND:
- if (lev == 1)
- return;
- lev--;
- break;
- case I_DEPCASE:
- case I_DEPELSE:
- if (lev == 1)
- return;
- break;
- default:
- break;
- }
- }
- }
- }
-}
-
-void Interpreter::depcase() {
- int lev = 1;
- Aword i;
-
- // Skip to end of DEPENDING block (next DEPEND on same level) because
- // we have just executed a DEPCASE/DEPELSE statement as a result of a DEPCASE
- // catching
-
- while (true) {
- i = _vm->memory[_vm->pc++];
- if (I_CLASS(i) == (Aword)C_STMOP) {
- switch (I_OP(i)) {
- case I_DEPSTART:
- lev++;
- break;
- case I_DEPEND:
- lev--;
- if (lev == 0) return;
- break;
- default:
- break;
- }
- }
- }
-}
-
-void Interpreter::curVar(Aword i) {
- switch (I_OP(i)) {
- case V_PARAM:
- if (stpflg)
- debug("PARAM \t%5ld\t\t(%d)", _stack->top(), _vm->params[_stack->top() - 1].code);
- _stack->push(_vm->params[_stack->pop() - 1].code);
- break;
- case V_CURLOC:
- if (stpflg)
- debug("CURLOC \t\t\t(%d)", _vm->cur.loc);
- _stack->push(_vm->cur.loc);
- break;
- case V_CURACT:
- if (stpflg)
- debug("CURACT \t\t\t(%d)", _vm->cur.act);
- _stack->push(_vm->cur.act);
- break;
- case V_CURVRB:
- if (stpflg)
- debug("CURVRB \t\t\t(%d)", _vm->cur.vrb);
- _stack->push(_vm->cur.vrb);
- break;
- case V_SCORE:
- if (stpflg)
- debug("CURSCORE \t\t\t(%d)", _vm->cur.score);
- _stack->push(_vm->cur.score);
- break;
- default:
- error("Unknown CURVAR instruction.");
- }
-}
-
-void Interpreter::adaptOldOpcodes(Aword i) {
- switch (I_OP(i)) {
- case I_AND:
- case I_OR:
- case I_NE:
- case I_EQ:
- case I_STREQ:
- case I_STREXACT:
- case I_LE:
- case I_GE:
- case I_LT:
- case I_GT:
- case I_PLUS:
- case I_MINUS:
- case I_MULT:
- case I_DIV:
- if (_vm->header->vers[0] == 2 && _vm->header->vers[1] == 7) // Check for 2.7 version
- swap();
- }
-}
-
-void Interpreter::stMop(Aword i, Aaddr oldpc) {
- Aptr arg1, arg2, arg3, lh, rh;
-
- adaptOldOpcodes(i);
-
- switch (I_OP(i)) {
- case I_PRINT:
- arg1 = _stack->pop(); // fpos
- arg2 = _stack->pop(); // len
- if (stpflg) {
- debug("PRINT \t%5ld, %5ld\t\"", arg1, arg2);
- _vm->col = 34; // To format it better!
- }
- _execute->print(arg1, arg2);
- if (stpflg)
- debug("\"");
- break;
- case I_SYSTEM:
- arg1 = _stack->pop(); // fpos
- arg2 = _stack->pop(); // len
- if (stpflg) {
- debug("SYSTEM \t%5ld, %5ld\t\"", arg1, arg2);
- _vm->col = 34; // To format it better!
- }
- _execute->sys(arg1, arg2);
- break;
- case I_GETSTR:
- arg1 = _stack->pop(); // fpos
- arg2 = _stack->pop(); // len
- if (stpflg)
- debug("GETSTR\t%5ld, %5ld", arg1, arg2);
- _execute->getstr(arg1, arg2);
- if (stpflg)
- debug("\t(%ld)", _stack->top());
- break;
- case I_QUIT:
- if (stpflg)
- debug("QUIT");
- _execute->quit();
- break;
- case I_LOOK:
- if (stpflg)
- debug("LOOK");
- _execute->look();
- break;
- case I_SAVE:
- if (stpflg)
- debug("SAVE");
- _saveLoad->save();
- break;
- case I_RESTORE:
- if (stpflg)
- debug("RESTORE");
- _saveLoad->restore();
- break;
- case I_RESTART:
- if (stpflg)
- debug("RESTART");
- _execute->restart();
- break;
- case I_LIST:
- arg1 = _stack->pop(); // cnt
- if (stpflg)
- debug("LIST \t%5ld", arg1);
- _execute->list(arg1);
- break;
- case I_EMPTY:
- arg1 = _stack->pop(); // cnt
- arg2 = _stack->pop(); // whr
- if (stpflg)
- debug("EMPTY \t%5ld, %5ld", arg1, arg2);
- _execute->empty(arg1, arg2);
- break;
- case I_SCORE:
- arg1 = _stack->pop(); // score
- if (stpflg)
- debug("SCORE \t%5ld\t\t(%d)", arg1, _vm->scores[arg1 - 1]);
- _execute->score(arg1);
- break;
- case I_VISITS:
- arg1 = _stack->pop(); // visits
- if (stpflg)
- debug("VISITS \t%5ld", arg1);
- _execute->visits(arg1);
- break;
- case I_SCHEDULE:
- arg1 = _stack->pop(); // evt
- arg2 = _stack->pop(); // whr
- arg3 = _stack->pop(); // aft
- if (stpflg)
- debug("SCHEDULE \t%5ld, %5ld, %5ld", arg1, arg2, arg3);
- _execute->schedule(arg1, arg2, arg3);
- break;
- case I_CANCEL:
- arg1 = _stack->pop(); // evt
- if (stpflg)
- debug("CANCEL \t%5ld", arg1);
- _execute->cancl(arg1);
- break;
- case I_MAKE:
- arg1 = _stack->pop(); // id
- arg2 = _stack->pop(); // atr
- arg3 = _stack->pop(); // val
- if (stpflg) {
- debug("MAKE \t%5ld, %5ld, ", arg1, arg2);
- if (arg3)
- debug("TRUE");
- else
- debug("FALSE");
- }
- _execute->make(arg1, arg2, arg3);
- break;
- case I_SET:
- arg1 = _stack->pop(); // id
- arg2 = _stack->pop(); // atr
- arg3 = _stack->pop(); // val
- if (stpflg)
- debug("SET \t%5ld, %5ld, %5ld", arg1, arg2, arg3);
- _execute->set(arg1, arg2, arg3);
- break;
- case I_STRSET:
- arg1 = _stack->pop(); // id
- arg2 = _stack->pop(); // atr
- arg3 = _stack->pop(); // str
- if (stpflg)
- debug("STRSET\t%5ld, %5ld, %5ld", arg1, arg2, arg3);
- _execute->setstr(arg1, arg2, arg3);
- break;
- case I_INCR:
- arg1 = _stack->pop(); // id
- arg2 = _stack->pop(); // atr
- arg3 = _stack->pop(); // step
- if (stpflg)
- debug("INCR\t%5ld, %5ld, %5ld", arg1, arg2, arg3);
- _execute->incr(arg1, arg2, arg3);
- break;
- case I_DECR:
- arg1 = _stack->pop(); // id
- arg2 = _stack->pop(); // atr
- arg3 = _stack->pop(); // step
- if (stpflg)
- debug("DECR\t%5ld, %5ld, %5ld", arg1, arg2, arg3);
- _execute->decr(arg1, arg2, arg3);
- break;
- case I_ATTRIBUTE:
- arg1 = _stack->pop(); // id
- arg2 = _stack->pop(); // atr
- if (stpflg)
- debug("ATTRIBUTE %5ld, %5ld", arg1, arg2);
- _stack->push(_execute->attribute(arg1, arg2));
- if (stpflg)
- debug("\t(%ld)", _stack->top());
- break;
- case I_STRATTR:
- arg1 = _stack->pop(); // id
- arg2 = _stack->pop(); // atr
- if (stpflg)
- debug("STRATTR \t%5ld, %5ld", arg1, arg2);
- _stack->push(_execute->strattr(arg1, arg2));
- if (stpflg)
- debug("\t(%ld)", _stack->top());
- break;
- case I_LOCATE:
- arg1 = _stack->pop(); // id
- arg2 = _stack->pop(); // whr
- if (stpflg)
- debug("LOCATE \t%5ld, %5ld", arg1, arg2);
- _execute->locate(arg1, arg2);
- break;
- case I_WHERE:
- arg1 = _stack->pop(); // id
- if (stpflg)
- debug("WHERE \t%5ld", arg1);
- _stack->push(_execute->where(arg1));
- if (stpflg)
- debug("\t\t(%ld)", _stack->top());
- break;
- case I_HERE:
- arg1 = _stack->pop(); // id
- if (stpflg)
- debug("HERE \t%5ld", arg1);
- _stack->push(_execute->isHere(arg1));
- if (stpflg) {
- if (_stack->top())
- debug("\t(TRUE)");
- else
- debug("\t(FALSE)");
- }
- break;
- case I_NEAR:
- arg1 = _stack->pop(); // id
- if (stpflg)
- debug("NEAR \t%5ld", arg1);
- _stack->push(_execute->isNear(arg1));
- if (stpflg) {
- if (_stack->top())
- debug("\t(TRUE)");
- else
- debug("\t(FALSE)");
- }
- break;
- case I_USE:
- arg1 = _stack->pop(); // act
- arg2 = _stack->pop(); // scr
- if (stpflg)
- debug("USE \t%5ld, %5ld", arg1, arg2);
- _execute->use(arg1, arg2);
- break;
- case I_IN:
- arg1 = _stack->pop(); // obj
- arg2 = _stack->pop(); // cnt
- if (stpflg)
- debug("IN \t%5ld, %5ld ", arg1, arg2);
- _stack->push(_execute->in(arg1, arg2));
- if (stpflg) {
- if (_stack->top()) debug("\t(TRUE)"); else debug("\t(FALSE)");
- }
- break;
- case I_DESCRIBE:
- arg1 = _stack->pop(); // id
- if (stpflg) {
- debug("DESCRIBE \t%5ld\t", arg1);
- _vm->col = 34; // To format it better!
- }
- _execute->describe(arg1);
- break;
- case I_SAY:
- arg1 = _stack->pop(); // id
- if (stpflg)
- debug("SAY \t%5ld\t\t\"", arg1);
- _execute->say(arg1);
- if (stpflg)
- debug("\"");
- break;
- case I_SAYINT:
- arg1 = _stack->pop(); // val
- if (stpflg)
- debug("SAYINT\t%5ld\t\t\"", arg1);
- _execute->sayint(arg1);
- if (stpflg)
- debug("\"");
- break;
- case I_SAYSTR:
- arg1 = _stack->pop(); // adr
- if (stpflg)
- debug("SAYSTR\t%5ld\t\t\"", arg1);
- _execute->saystr((char *)arg1);
- if (stpflg)
- debug("\"");
- break;
- case I_IF:
- arg1 = _stack->pop(); // v
- if (stpflg) {
- debug("IF \t");
- if (arg1) debug(" TRUE"); else debug("FALSE");
- }
- if_(arg1);
- break;
- case I_ELSE:
- if (stpflg)
- debug("ELSE");
- else_();
- break;
- case I_ENDIF:
- if (stpflg)
- debug("ENDIF");
- break;
- case I_AND:
- rh = _stack->pop();
- lh = _stack->pop();
- if (stpflg) {
- debug("AND \t");
- if (lh) debug("TRUE, "); else debug("FALSE, ");
- if (rh) debug("TRUE"); else debug("FALSE");
- }
- _stack->push(lh && rh);
- if (stpflg) {
- if (_stack->top()) debug("\t(TRUE)"); else debug("\t(FALSE)");
- }
- break;
- case I_OR:
- rh = _stack->pop();
- lh = _stack->pop();
- if (stpflg) {
- debug("OR \t");
- if (lh) debug("TRUE, "); else debug("FALSE, ");
- if (rh) debug("TRUE"); else debug("FALSE");
- }
- _stack->push(lh || rh);
- if (stpflg) {
- if (_stack->top())
- debug("\t(TRUE)");
- else
- debug("\t(FALSE)");
- }
- break;
- case I_NE:
- rh = _stack->pop();
- lh = _stack->pop();
- if (stpflg)
- debug("NE \t%5ld, %5ld", lh, rh);
- _stack->push(lh != rh);
- if (stpflg) {
- if (_stack->top()) debug("\t(TRUE)"); else debug("\t(FALSE)");
- }
- break;
- case I_EQ:
- rh = _stack->pop();
- lh = _stack->pop();
- if (stpflg)
- debug("EQ \t%5ld, %5ld", lh, rh);
- _stack->push(lh == rh);
- if (stpflg) {
- if (_stack->top())
- debug("\t(TRUE)");
- else
- debug("\t(FALSE)");
- }
- break;
- case I_STREQ:
- rh = _stack->pop();
- lh = _stack->pop();
- if (stpflg)
- debug("STREQ \t%5ld, %5ld", lh, rh);
- _stack->push(_execute->streq((char *)lh, (char *)rh));
- if (stpflg) {
- if (_stack->top()) debug("\t(TRUE)"); else debug("\t(FALSE)");
- }
- break;
- case I_STREXACT:
- rh = _stack->pop();
- lh = _stack->pop();
- if (stpflg)
- debug("STREXACT \t%5ld, %5ld", lh, rh);
- _stack->push(strcmp((char *)lh, (char *)rh) == 0);
- if (stpflg) {
- if (_stack->top()) debug("\t(TRUE)"); else debug("\t(FALSE)");
- }
- free((void *)lh);
- free((void *)rh);
- break;
- case I_LE:
- rh = _stack->pop();
- lh = _stack->pop();
- if (stpflg)
- debug("LE \t%5ld, %5ld", lh, rh);
- _stack->push(lh <= rh);
- if (stpflg) {
- if (_stack->top()) debug("\t(TRUE)"); else debug("\t(FALSE)");
- }
- break;
- case I_GE:
- rh = _stack->pop();
- lh = _stack->pop();
- if (stpflg)
- debug("GE \t%5ld, %5ld", lh, rh);
- _stack->push(lh >= rh);
- if (stpflg) {
- if (_stack->top()) debug("\t(TRUE)"); else debug("\t(FALSE)");
- }
- break;
- case I_LT:
- rh = _stack->pop();
- lh = _stack->pop();
- if (stpflg)
- debug("LT \t%5ld, %5ld", lh, rh);
- _stack->push((signed int)lh < (signed int)rh);
- if (stpflg) {
- if (_stack->top()) debug("\t(TRUE)"); else debug("\t(FALSE)");
- }
- break;
- case I_GT:
- rh = _stack->pop();
- lh = _stack->pop();
- if (stpflg)
- debug("GT \t%5ld, %5ld", lh, rh);
- _stack->push(lh > rh);
- if (stpflg) {
- if (_stack->top()) debug("\t(TRUE)"); else debug("\t(FALSE)");
- }
- break;
- case I_PLUS:
- rh = _stack->pop();
- lh = _stack->pop();
- if (stpflg)
- debug("PLUS \t%5ld, %5ld", lh, rh);
- _stack->push(lh + rh);
- if (stpflg)
- debug("\t(%ld)", _stack->top());
- break;
- case I_MINUS:
- rh = _stack->pop();
- lh = _stack->pop();
- if (stpflg)
- debug("MINUS \t%5ld, %5ld", lh, rh);
- _stack->push(lh - rh);
- if (stpflg)
- debug("\t(%ld)", _stack->top());
- break;
- case I_MULT:
- rh = _stack->pop();
- lh = _stack->pop();
- if (stpflg)
- debug("MULT \t%5ld, %5ld", lh, rh);
- _stack->push(lh * rh);
- if (stpflg)
- debug("\t(%ld)", _stack->top());
- break;
- case I_DIV:
- rh = _stack->pop();
- lh = _stack->pop();
- if (stpflg)
- debug("DIV \t%5ld, %5ld", lh, rh);
- _stack->push(lh / rh);
- if (stpflg)
- debug("\t(%ld)", _stack->top());
- break;
- case I_NOT:
- arg1 = _stack->pop(); // val
- if (stpflg) {
- debug("NOT \t");
- if (arg1) debug("TRUE"); else debug("FALSE");
- }
- _stack->push(!arg1);
- if (stpflg) {
- if (_stack->top()) debug("\t\t(TRUE)"); else debug("\t\t(FALSE)");
- }
- break;
- case I_MAX:
- arg1 = _stack->pop(); // atr
- arg2 = _stack->pop(); // whr
- if (stpflg)
- debug("MAX \t%5ld, %5ld", arg1, arg2);
- _stack->push(_execute->agrmax(arg1, arg2));
- if (stpflg)
- debug("\t(%ld)", _stack->top());
- break;
- case I_SUM:
- arg1 = _stack->pop(); // atr
- arg2 = _stack->pop(); // whr
- if (stpflg)
- debug("SUM \t%5ld, %5ld", arg1, arg2);
- _stack->push(_execute->agrsum(arg1, arg2));
- if (stpflg)
- debug("\t(%ld)", _stack->top());
- break;
- case I_COUNT:
- arg1 = _stack->pop(); // whr
- if (stpflg)
- debug("COUNT \t%5ld", arg1);
- _stack->push(_execute->agrcount(arg1));
- if (stpflg)
- debug("\t(%ld)", _stack->top());
- break;
- case I_RND:
- arg1 = _stack->pop(); // from
- arg2 = _stack->pop(); // to
- if (stpflg)
- debug("RANDOM \t%5ld, %5ld", arg1, arg2);
- _stack->push(_execute->rnd(arg1, arg2));
- if (stpflg)
- debug("\t(%ld)", _stack->top());
- break;
- case I_BTW:
- arg1 = _stack->pop(); // high
- arg2 = _stack->pop(); // low
- arg3 = _stack->pop(); // val
- if (stpflg)
- debug("BETWEEN \t%5ld, %5ld, %5ld", arg1, arg2, arg3);
- _stack->push(_execute->btw(arg1, arg2, arg3));
- if (stpflg)
- debug("\t(%ld)", _stack->top());
- break;
- case I_CONTAINS:
- arg1 = _stack->pop(); // substring
- arg2 = _stack->pop(); // string
- if (stpflg)
- debug("CONTAINS \t%5ld, %5ld", arg2, arg1);
- _stack->push(_execute->contains(arg2, arg1));
- if (stpflg)
- debug("\t(%ld)", _stack->top());
- break;
- case I_DEPSTART:
- if (stpflg)
- debug("DEPSTART");
- depstart();
- break;
- case I_DEPCASE:
- if (stpflg)
- debug("DEPCASE");
- depcase();
- break;
- case I_DEPEXEC:
- arg1 = _stack->pop(); // v
- if (stpflg) {
- debug("DEPEXEC \t");
- if (arg1) debug(" TRUE"); else debug("FALSE");
- }
- depexec(arg1);
- break;
- case I_DEPELSE:
- if (stpflg)
- debug("DEPELSE");
- depcase();
- break;
- case I_DEPEND:
- if (stpflg)
- debug("DEPEND");
- break;
- case I_RETURN:
- if (stpflg)
- debug("RETURN\n--------------------------------------------------\n");
- _vm->pc = oldpc;
- return;
- default:
- error("Unknown STMOP instruction.");
- }
-
- if (_vm->fail) {
- _vm->pc = oldpc;
- return; // TODO: Return true/false, and stop execution if necessary
- }
-}
-
-void Interpreter::interpret(Aaddr adr) {
- Aaddr oldpc = _vm->pc;
- Aword i;
-
- if (stpflg)
- debug("\n++++++++++++++++++++++++++++++++++++++++++++++++++");
-
- _vm->pc = adr;
-
- while(true) {
- if (stpflg)
- debug("\n%4x: ", _vm->pc);
-
- if (_vm->pc > _vm->memTop)
- error("Interpreting outside program.");
-
- i = _vm->memory[_vm->pc++];
-
- switch (I_CLASS(i)) {
- case C_CONST:
- if (stpflg)
- debug("PUSH \t%5d", I_OP(i));
- _stack->push(I_OP(i));
- break;
- case C_CURVAR:
- curVar(i);
- break;
- case C_STMOP:
- stMop(i, oldpc);
- break;
- default:
- error("Unknown instruction class.");
- }
- }
-}
-
-} // End of namespace Alan2
-} // End of namespace Glk
diff --git a/engines/glk/alan2/interpreter.h b/engines/glk/alan2/interpreter.h
deleted file mode 100644
index cbc9bcbb15..0000000000
--- a/engines/glk/alan2/interpreter.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* 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 GLK_ALAN2_INTERPRETER
-#define GLK_ALAN2_INTERPRETER
-
-#include "glk/alan2/acode.h"
-#include "glk/alan2/alan2.h"
-
-namespace Glk {
-namespace Alan2 {
-
-class Execute;
-class SaveLoad;
-
-class Interpreter {
-public:
- Interpreter(Execute *execute, SaveLoad *saveLoad, Alan2Stack *stack) : _execute(execute), _saveLoad(saveLoad), _stack(stack) {}
- void interpret(Aaddr adr);
-
-private:
- void if_(Aword v);
- void else_();
- void depstart();
- void swap();
- void depexec(Aword v);
- void depcase();
- void curVar(Aword i);
- void stMop(Aword i, Aaddr oldpc);
- void adaptOldOpcodes(Aword i);
-
- Execute *_execute;
- SaveLoad *_saveLoad;
- Alan2Stack *_stack;
-};
-
-} // End of namespace Alan2
-} // End of namespace Glk
-
-#endif
diff --git a/engines/glk/alan2/parse.cpp b/engines/glk/alan2/parse.cpp
deleted file mode 100644
index 8e6427d09c..0000000000
--- a/engines/glk/alan2/parse.cpp
+++ /dev/null
@@ -1,969 +0,0 @@
-/* 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 "common/stack.h"
-#include "glk/alan2/alan2.h"
-#include "glk/alan2/execute.h"
-#include "glk/alan2/interpreter.h"
-#include "glk/alan2/parse.h"
-#include "glk/alan2/types.h"
-#include "glk/alan2/util.h"
-#include "common/debug.h"
-#include "common/file.h"
-#include "decode.h"
-
-namespace Glk {
-namespace Alan2 {
-
-uint32 litCount = 0;
-
-// All procedures for getting a command and turning it into a list of
-// dictionary entries are placed here.
-
-Parser::Parser() {
- wrds[0] = EOF;
- plural = false;
-
- // TODO
-}
-
-void Parser::unknown(char *inputStr) {
- Common::String str = Common::String::format("'%s'?", inputStr);
-
- // TODO
-#if 0
-#if ISO == 0
- fromIso(str, str);
-#endif
-#endif
-
- _vm->output(str);
- eol = true;
- _vm->printError(M_UNKNOWN_WORD);
-}
-
-int Parser::lookup(char *wrd) {
- for (int i = 0; !endOfTable(&dict[i]); i++) {
- if (strcmp(wrd, (char *)addrTo(dict[i].wrd)) == 0)
- return i;
- }
-
- unknown(wrd);
- return EOF;
-}
-
-char *Parser::gettoken(char *tokenBuffer) {
- static char *marker;
- static char oldch;
-
- if (tokenBuffer == nullptr)
- *marker = oldch;
- else
- marker = tokenBuffer;
-
- while (*marker != '\0' && Common::isSpace(*marker) && *marker != '\n') marker++;
- tokenBuffer = marker;
-
- if (Common::isAlpha(*marker))
- while (*marker && (Common::isAlpha(*marker) || Common::isDigit(*marker) || *marker == '\'')) marker++;
- else if (Common::isDigit(*marker))
- while (Common::isDigit(*marker)) marker++;
- else if (*marker == '\"') {
- marker++;
- while (*marker != '\"') marker++;
- marker++;
- } else if (*marker == '\0' || *marker == '\n')
- return nullptr;
- else
- marker++;
-
- oldch = *marker;
- *marker = '\0';
-
- return tokenBuffer;
-}
-
-void Parser::agetline() {
- // static char buf[LISTLEN + 1]; // The input buffer
- // static char isobuf[LISTLEN + 1]; // The input buffer in ISO
-
- _vm->paragraph();
-
- // TODO
-#if 0
-
- do {
-#if defined(HAVE_ANSI) || defined(GLK)
- statusline();
-#endif
- debug("> ");
-
-#if 0
- if (logflg)
- fprintf(logfil, "> ");
-#endif
-
-#ifdef USE_READLINE
- if (!readline(buf)) {
- newline();
- quit();
- }
-#else
- if (fgets(buf, LISTLEN, stdin) == nullptr) {
- newline();
- quit();
- }
-#endif
-
- getPageSize();
- anyOutput = FALSE;
-
- if (logflg)
- fprintf(logfil, "%s\n", buf);
-
-#if ISO == 0
- toIso(isobuf, buf, NATIVECHARSET);
-#else
- strcpy(isobuf, buf);
-#endif
-
- token = gettoken(isobuf);
-
- if (token != nullptr && strcmp("debug", token) == 0 && _vm->header->debug) {
- dbgflg = true;
- debug();
- token = nullptr;
- }
- } while (token == nullptr);
-
- eol = false;
- lin = 1;
-
-#endif
-}
-
-void Parser::scan() {
- uint i;
- // int w;
-
- agetline();
- wrds[0] = 0;
-
- for (i = 0; i < litCount; i++)
- if (litValues[i].type == TYPSTR && litValues[i].value != 0)
- free((char *) litValues[i].value);
-
- litCount = 0;
-
- do {
- if (Common::isAlpha(token[0])) {
- Common::String tmp = token;
- tmp.toLowercase();
- strcpy(token, tmp.c_str());
-
- // w = lookup(token);
-
- // TODO
- //if (!isNoise(w))
- // wrds[i++] = w;
- } else if (Common::isDigit(token[0])) {
- if (litCount > MAXPARAMS)
- error("Too many parameters.");
-
- wrds[i++] = dictsize + litCount; // Word outside dictionary = literal
- litValues[litCount].type = TYPNUM;
- litValues[litCount++].value = atoi(token);
- } else if (token[0] == '\"') {
- if (litCount > MAXPARAMS)
- error("Too many parameters.");
-
- wrds[i++] = dictsize + litCount; // Word outside dictionary = literal
- litValues[litCount].type = TYPSTR;
-
- // Remove the string quotes while copying
- Common::String tmp = token;
- tmp.deleteChar(0);
- tmp.deleteLastChar();
- char *str = scumm_strdup(tmp.c_str());
-
- litValues[litCount++].value = (Aptr) str;
- } else if (token[0] == ',') {
- //wrds[i++] = conjWord; // TODO
- } else
- unknown(token);
-
- wrds[i] = EOF;
- eol = (token = gettoken(nullptr)) == nullptr;
- } while (!eol);
-}
-
-void Parser::nonverb() {
- if (isDir(wrds[wrdidx])) {
- wrdidx++;
- if (wrds[wrdidx] != EOF && !isConj(wrds[wrdidx]))
- _vm->printError(M_WHAT);
-// TODO
-#if 0
- else
- go(dict[wrds[wrdidx-1]].code);
-#endif
-
- if (wrds[wrdidx] != EOF)
- wrdidx++;
- } else
- _vm->printError(M_WHAT);
-}
-
-Aword Parser::where(Aword id) {
- if (isObj(id))
- return objloc(id);
- else if (isAct(id))
- return acts[id - ACTMIN].loc;
- else
- error("Can't WHERE item (%ld).", (unsigned long)id);
-}
-
-Aword Parser::objloc(Aword obj) {
- if (isCnt(objs[obj - OBJMIN].loc)) // In something ?
- if (isObj(objs[obj - OBJMIN].loc) || isAct(objs[obj - OBJMIN].loc))
- return where(objs[obj - OBJMIN].loc);
- else // Containers not anywhere is where the hero is!
- return where(HERO);
- else
- return(objs[obj - OBJMIN].loc);
-}
-
-Abool Parser::objhere(Aword obj) {
- if (isCnt(objs[obj - OBJMIN].loc)) { // In something?
- if (isObj(objs[obj - OBJMIN].loc) || isAct(objs[obj - OBJMIN].loc))
- return isHere(objs[obj - OBJMIN].loc);
- else // If the container wasn't anywhere, assume where HERO is!
- return (int)where(HERO) == _vm->cur.loc;
- } else
- return((int)objs[obj - OBJMIN].loc == _vm->cur.loc);
-}
-
-
-Abool Parser::isHere(Aword id) {
- if (isObj(id))
- return objhere(id);
- else if (isAct(id))
- return (int)acts[id - ACTMIN].loc == _vm->cur.loc;
- else
- error("Can't HERE item (%ld).", (unsigned long)id);
-}
-
-// ----------------------------------------------------------------------------
-
-void Parser::buildall(ParamElem list[]) {
- uint o, i = 0;
- bool found = false;
-
- for (o = OBJMIN; o <= OBJMAX; o++) {
- if (isHere(o)) {
- found = true;
- list[i].code = o;
- list[i++].firstWord = (Aword)EOF;
- }
- }
-
- if (!found)
- _vm->printError(M_WHAT_ALL);
- else
- list[i].code = (Aword)EOF;
-}
-
-void Parser::listCopy(ParamElem a[], ParamElem b[]) {
- int i;
-
- for (i = 0; b[i].code != (Aword)EOF; i++)
- a[i] = b[i];
-
- a[i].code = (Aword)EOF;
-}
-
-bool Parser::listContains(ParamElem l[], Aword e) {
- int i;
-
- for (i = 0; l[i].code != (Aword)EOF && l[i].code != e; i++);
-
- return (l[i].code == e);
-}
-
-void Parser::listIntersection(ParamElem a[], ParamElem b[]) {
- int i, last = 0;
-
- for (i = 0; a[i].code != (Aword)EOF; i++)
- if (listContains(b, a[i].code))
- a[last++] = a[i];
-
- a[last].code = (Aword)EOF;
-}
-
-void Parser::listCopyFromDictionary(ParamElem p[], Aword r[]) {
- int i;
-
- for (i = 0; r[i] != (Aword)EOF; i++) {
- p[i].code = r[i];
- p[i].firstWord = (Aword)EOF;
- }
-
- p[i].code = (Aword)EOF;
-}
-
-int Parser::listLength(ParamElem a[]) {
- int i = 0;
-
- while (a[i].code != (Aword)EOF)
- i++;
-
- return (i);
-}
-
-void Parser::listCompact(ParamElem a[]) {
- int i, j;
-
- for (i = 0, j = 0; a[j].code != (Aword)EOF; j++)
- if (a[j].code != 0)
- a[i++] = a[j];
-
- a[i].code = (Aword)EOF;
-}
-
-void Parser::listMerge(ParamElem a[], ParamElem b[]) {
- int i, last;
-
- for (last = 0; a[last].code != (Aword)EOF; last++); // Find end of list
-
- for (i = 0; b[i].code != (Aword)EOF; i++) {
- if (!listContains(a, b[i].code)) {
- a[last++] = b[i];
- a[last].code = (Aword)EOF;
- }
- }
-}
-
-void Parser::listSubtract(ParamElem a[], ParamElem b[]) {
- for (int i = 0; a[i].code != (Aword)EOF; i++)
- if (listContains(b, a[i].code))
- a[i].code = 0; // Mark empty
-
- listCompact(a);
-}
-
-void Parser::unambig(ParamElem plst[]) {
- int i;
- bool found = false; // Adjective or noun found?
- static ParamElem *refs; // Entities referenced by word
- static ParamElem *savlst; // Saved list for backup at EOF
- int firstWord, lastWord; // The words the player used
-
- if (refs == nullptr)
- refs = new ParamElem[MAXENTITY + 1];
-
- if (savlst == nullptr)
- savlst = new ParamElem[MAXENTITY + 1];
-
- if (isLiteral(wrds[wrdidx])) {
- // Transform the word into a reference to the literal value
- plst[0].code = wrds[wrdidx++] - dictsize + LITMIN;
- plst[0].firstWord = (Aword)EOF; // No words used!
- plst[1].code = (Aword)EOF;
- return;
- }
-
- plst[0].code = (Aword)EOF; // Make empty
-
- if (isIt(wrds[wrdidx])) {
- wrdidx++;
-
- // Use last object in previous command!
- for (i = listLength(pparams)-1; i >= 0 && (pparams[i].code == 0 || pparams[i].code >= LITMIN); i--);
-
- if (i < 0)
- _vm->printError(M_WHAT_IT);
-
- if (!isHere(pparams[i].code)) {
- params[0].code = pparams[i].code;
- params[0].firstWord = (Aword)EOF;
- params[1].code = (Aword)EOF;
- _vm->printError(M_NO_SUCH);
- }
-
- plst[0] = pparams[i];
- plst[0].firstWord = (Aword)EOF; // No words used!
- plst[1].code = (Aword)EOF;
- return;
- }
-
- firstWord = wrdidx;
-
- while (wrds[wrdidx] != EOF && isAdj(wrds[wrdidx])) {
- // If this word can be a noun and there is no noun following break loop
- if (isNoun(wrds[wrdidx]) && (wrds[wrdidx+1] == EOF || !isNoun(wrds[wrdidx+1])))
- break;
-
- listCopyFromDictionary(refs, (Aword *)addrTo(dict[wrds[wrdidx]].adjrefs));
- listCopy(savlst, plst); // To save it for backtracking
-
- if (found)
- listIntersection(plst, refs);
- else {
- listCopy(plst, refs);
- found = true;
- }
-
- wrdidx++;
- }
-
- if (wrds[wrdidx] != EOF) {
- if (isNoun(wrds[wrdidx])) {
- listCopyFromDictionary(refs, (Aword *)addrTo(dict[wrds[wrdidx]].nounrefs));
- if (found)
- listIntersection(plst, refs);
- else {
- listCopy(plst, refs);
- found = true;
- }
-
- wrdidx++;
- } else
- _vm->printError(M_NOUN);
- } else if (found) {
- if (isNoun(wrds[wrdidx-1])) {
- // Perhaps the last word was also a noun?
- listCopy(plst, savlst); // Restore to before last adjective
- listCopyFromDictionary(refs, (Aword *)addrTo(dict[wrds[wrdidx-1]].nounrefs));
-
- if (plst[0].code == (Aword)EOF)
- listCopy(plst, refs);
- else
- listIntersection(plst, refs);
- } else
- _vm->printError(M_NOUN);
- }
-
- lastWord = wrdidx - 1;
-
- // Allow remote objects, but resolve ambiguities by presence
- if (listLength(plst) > 1) {
- for (i=0; plst[i].code != (Aword)EOF; i++)
- if (!isHere(plst[i].code))
- plst[i].code = 0;
-
- listCompact(plst);
- }
-
- if (listLength(plst) > 1 || (found && listLength(plst) == 0)) {
- params[0].code = 0; /* Just make it anything != EOF */
- params[0].firstWord = firstWord; /* Remember words for errors below */
- params[0].lastWord = lastWord;
- params[1].code = (Aword)EOF; /* But be sure to terminate */
-
- if (listLength(plst) > 1)
- _vm->printError(M_WHICH_ONE);
- else if (found && listLength(plst) == 0)
- _vm->printError(M_NO_SUCH);
- } else {
- plst[0].firstWord = firstWord;
- plst[0].lastWord = lastWord;
- }
-}
-
-void Parser::simple(ParamElem olst[]) {
- static ParamElem *tlst = nullptr;
- int savidx = wrdidx;
- bool savplur = false;
- int i;
-
- if (tlst == nullptr)
- tlst = new ParamElem[MAXENTITY + 1];
-
- tlst[0].code = (Aword)EOF;
-
- for (;;) {
- if (isThem(wrds[wrdidx])) {
- plural = true;
-
- for (i = 0; pmlst[i].code != (Aword)EOF; i++)
- if (!isHere(pmlst[i].code))
- pmlst[i].code = 0;
-
- listCompact(pmlst);
-
- if (listLength(pmlst) == 0)
- _vm->printError(M_WHAT_THEM);
-
- listCopy(olst, pmlst);
- olst[0].firstWord = (Aword)EOF; // No words used
- wrdidx++;
- } else {
- unambig(olst); // Look for unambigous noun phrase
-
- if (listLength(olst) == 0) { // Failed!
- listCopy(olst, tlst);
- wrdidx = savidx;
- plural = savplur;
- return;
- }
- }
-
- listMerge(tlst, olst);
-
- if (wrds[wrdidx] != EOF
- && (isConj(wrds[wrdidx])
- && (isAdj(wrds[wrdidx+1]) || isNoun(wrds[wrdidx+1])))) {
- // More parameters in a conjunction separated list ?
- savplur = plural;
- savidx = wrdidx;
- wrdidx++;
- plural = true;
- } else {
- listCopy(olst, tlst);
- return;
- }
- }
-}
-
-void Parser::complex(ParamElem olst[]) {
- // Above this procedure we can use the is* tests, but not below since
- // they work on words.Below all is converted to indices into the
- // entity tables.Particularly this goes for literals...
-
- static ParamElem *alst = nullptr;
-
- if (alst == nullptr)
- alst = new ParamElem[MAXENTITY + 1];
-
- if (isAll(wrds[wrdidx])) {
- plural = true;
- buildall(alst); // Build list of all objects
- wrdidx++;
- if (wrds[wrdidx] != EOF && isBut(wrds[wrdidx])) {
- wrdidx++;
- simple(olst);
-
- if (listLength(olst) == 0)
- _vm->printError(M_AFTER_BUT);
-
- listSubtract(alst, olst);
- if (listLength(alst) == 0)
- _vm->printError(M_NOT_MUCH);
- }
-
- listCopy(olst, alst);
- allLength = listLength(olst);
- } else
- simple(olst); // Look for simple noun group
-}
-
-bool Parser::claCheck(ClaElem *cla) {
- bool ok = false;
-
- if ((cla->classes & (Aword)CLA_OBJ) != 0)
- ok = ok || isObj(params[cla->code - 1].code);
- if ((cla->classes & (Aword)CLA_CNT) != 0)
- ok = ok || isCnt(params[cla->code - 1].code);
- if ((cla->classes & (Aword)CLA_ACT) != 0)
- ok = ok || isAct(params[cla->code - 1].code);
- if ((cla->classes & (Aword)CLA_NUM) != 0)
- ok = ok || isNum(params[cla->code - 1].code);
- if ((cla->classes & (Aword)CLA_STR) != 0)
- ok = ok || isStr(params[cla->code - 1].code);
- if ((cla->classes & (Aword)CLA_COBJ) != 0)
- ok = ok || (isCnt(params[cla->code - 1].code) && isObj(params[cla->code - 1].code));
- if ((cla->classes & (Aword)CLA_CACT) != 0)
- ok = ok || (isCnt(params[cla->code - 1].code) && isAct(params[cla->code - 1].code));
-
- return ok;
-}
-
-void Parser::resolve(ParamElem plst[]) {
- if (allLength > 0)
- return; // ALL has already done this
-
- // Resolve ambiguities by presence
- for (int i = 0; plst[i].code != (Aword)EOF; i++) {
- if (plst[i].code < LITMIN) { // Literals are always 'here'
- if (!isHere(plst[i].code)) {
- params[0] = plst[i]; // Copy error param as first one for message
- params[1].code = (Aword)EOF; // But be sure to terminate
- _vm->printError(M_NO_SUCH);
- }
- }
- }
-}
-
-bool Parser::endOfTable(StxElem *addr) {
- Aword *x = (Aword *)addr;
- return *x == (Aword)EOF;
-}
-
-bool Parser::endOfTable(ElmElem *addr) {
- Aword *x = (Aword *)addr;
- return *x == (Aword)EOF;
-}
-
-bool Parser::endOfTable(ClaElem *addr) {
- Aword *x = (Aword *)addr;
- return *x == (Aword)EOF;
-}
-
-bool Parser::endOfTable(VrbElem *addr) {
- Aword *x = (Aword *)addr;
- return *x == (Aword)EOF;
-}
-
-bool Parser::endOfTable(AltElem *addr) {
- Aword *x = (Aword *)addr;
- return *x == (Aword)EOF;
-}
-
-bool Parser::endOfTable(ChkElem *addr) {
- Aword *x = (Aword *)addr;
- return *x == (Aword)EOF;
-}
-
-bool Parser::endOfTable(WrdElem *addr) {
- Aword *x = (Aword *)addr;
- return *x == (Aword)EOF;
-}
-
-AltElem *Parser::findalt(Aword vrbsadr, Aword param) {
- VrbElem *vrb;
- AltElem *alt;
-
- if (vrbsadr == 0)
- return nullptr;
-
- for (vrb = (VrbElem *)addrTo(vrbsadr); !endOfTable(vrb); vrb++) {
- if ((int)vrb->code == _vm->cur.vrb) {
- for (alt = (AltElem *)addrTo(vrb->alts); !endOfTable(alt); alt++)
- if (alt->param == param || alt->param == 0)
- return alt;
- return nullptr;
- }
- }
-
- return nullptr;
-}
-
-bool Parser::trycheck(Aaddr adr, bool act) {
- ChkElem *chk = (ChkElem *)addrTo(adr);
-
- if (chk->exp == 0) {
- _vm->_interpreter->interpret(chk->stms);
- return false;
- } else {
- while (!endOfTable(chk)) {
- _vm->_interpreter->interpret(chk->exp);
- if (!(Abool)_vm->_stack->pop()) {
- if (act)
- _vm->_interpreter->interpret(chk->stms);
- return false;
- }
- chk++;
- }
- return true;
- }
-}
-
-bool Parser::possible() {
- AltElem *alt[MAXPARAMS + 2]; // List of alt-pointers, one for each param
- int i; // Parameter index
-
- _vm->fail = false;
- alt[0] = findalt(_vm->header->vrbs, 0);
-
- // Perform global checks
- if (alt[0] != 0 && alt[0]->checks != 0) {
- if (!trycheck(alt[0]->checks, false))
- return false;
- if (_vm->fail)
- return false;
- }
-
- // Now CHECKs in this location
- alt[1] = findalt(locs[_vm->cur.loc - LOCMIN].vrbs, 0);
- if (alt[1] != 0 && alt[1]->checks != 0)
- if (!trycheck(alt[1]->checks, false))
- return false;
-
- for (i = 0; params[i].code != (Aword)EOF; i++) {
- alt[i + 2] = findalt(objs[params[i].code - OBJMIN].vrbs, i + 1);
- // CHECKs in a possible parameter
- if (alt[i + 2] != 0 && alt[i + 2]->checks != 0)
- if (!trycheck(alt[i + 2]->checks, false))
- return false;
- }
-
- for (i = 0; i < 2 || params[i - 2].code != (Aword)EOF; i++)
- if (alt[i] != 0 && alt[i]->action != 0)
- break;
- if (i >= 2 && params[i - 2].code == (Aword)EOF)
- // Didn't find any code for this verb/object combination
- return false;
- else
- return true;
-}
-
-void Parser::tryMatch(ParamElem mlstArr[]) {
- ElmElem *elms; // Pointer to element list
- StxElem *stx; // Pointer to syntax list
- ClaElem *cla; // Pointer to class definitions
- bool anyPlural = false; // Any parameter that was plural?
- int i, p;
- static ParamElem *tlst = nullptr; // List of params found by complex()
- static bool *checked = nullptr; // Corresponding parameter checked?
-
- if (tlst == nullptr) {
- tlst = new ParamElem[MAXENTITY + 1];
- checked = new bool[MAXENTITY + 1];
- }
-
- for (stx = stxs; !endOfTable(stx); stx++)
- if ((int)stx->code == vrbcode)
- break;
-
- if (endOfTable(stx))
- _vm->printError(M_WHAT);
-
- elms = (ElmElem *) addrTo(stx->elms);
-
- while (true) {
- // End of input?
- if (wrds[wrdidx] == EOF || isConj(wrds[wrdidx])) {
- while (!endOfTable(elms) && elms->code != (Aword)EOS)
- elms++;
-
- if (endOfTable(elms))
- _vm->printError(M_WHAT);
- else
- break;
- } else {
- // A preposition?
- if (isPrep(wrds[wrdidx])) {
- while (!endOfTable(elms) && elms->code != dict[wrds[wrdidx]].code)
- elms++;
-
- if (endOfTable(elms))
- _vm->printError(M_WHAT);
- else
- wrdidx++;
- } else {
- // Must be a parameter!
- while (!endOfTable(elms) && elms->code != 0)
- elms++;
-
- if (endOfTable(elms))
- _vm->printError(M_WHAT);
-
- // Get it!
- plural = false;
- complex(tlst);
-
- if (listLength(tlst) == 0) // No object!?
- _vm->printError(M_WHAT);
-
- if ((elms->flags & OMNIBIT) == 0) // Omnipotent parameter?
- resolve(tlst); // If its not an omnipotent parameter, resolve by presence
-
- if (plural) {
- if ((elms->flags & MULTIPLEBIT) == 0) // Allowed multiple?
- _vm->printError(M_MULTIPLE);
- else {
- // Mark this as the multiple position in which to insert
- // actual parameter values later
- params[paramidx++].code = 0;
- listCopy(mlstArr, tlst);
- anyPlural = true;
- }
- } else
- params[paramidx++] = tlst[0];
-
- params[paramidx].code = (Aword)EOF;
- }
-
- elms = (ElmElem *) addrTo(elms->next);
- }
- }
-
- // Now perform class checks
- if (elms->next == 0) // No verb code, verb not declared!
- _vm->printError(M_CANT0);
-
- for (p = 0; params[p].code != (Aword)EOF; p++) /* Mark all parameters unchecked */
- checked[p] = false;
-
- for (cla = (ClaElem *) addrTo(elms->next); !endOfTable(cla); cla++) {
- if (params[cla->code - 1].code == 0) {
- // This was a multiple parameter, so check all and remove failing
- for (i = 0; mlstArr[i].code != (Aword)EOF; i++) {
- params[cla->code-1] = mlstArr[i];
- if (!claCheck(cla)) {
- // Multiple could be both an explicit list of params and an ALL
- if (allLength == 0) {
- char marker[80];
- // It wasn't ALL, we need to say something about it, so
- // prepare a printout with $1/2/3
- sprintf(marker, "($%ld)", (unsigned long) cla->code);
- _vm->output(marker);
- _vm->_interpreter->interpret(cla->stms);
- _vm->paragraph();
- }
-
- mlstArr[i].code = 0; // In any case remove it from the list
- }
- }
-
- params[cla->code - 1].code = 0;
- } else {
- if (!claCheck(cla)) {
- _vm->_interpreter->interpret(cla->stms);
- _vm->printError(MSGMAX); // Return to player without saying anything
- }
- }
-
- checked[cla->code - 1] = true; // Remember that it's already checked
- }
-
- // Now check the rest of the parameters, must be objects
- for (p = 0; params[p].code != (Aword)EOF; p++) {
- if (!checked[p]) {
- if (params[p].code == 0) {
- // This was a multiple parameter, check all and remove failing
- for (i = 0; mlstArr[i].code != (Aword)EOF; i++) {
- if (mlstArr[i].code != 0 && !isObj(mlstArr[i].code)) // Skip any empty slots
- mlstArr[i].code = 0;
- }
- } else if (!isObj(params[p].code))
- _vm->printError(M_CANT0);
- }
- }
-
- // Set verb code
- _vm->cur.vrb = ((Aword *) cla)[1]; // Take first word after end of table!
-
- // Finally, if ALL was used, try to find out what was applicable
- if (allLength > 0) {
- for (p = 0; params[p].code != 0; p++); // Find multiple marker
-
- for (i = 0; i < allLength; i++) {
- if (mlstArr[i].code != 0) { // Already empty?
- params[p] = mlstArr[i];
-
- if (!possible())
- mlstArr[i].code = 0; // Remove this from list
- }
- }
-
- params[p].code = 0; // Restore multiple marker
- listCompact(mlstArr);
-
- if (listLength(mlstArr) == 0) {
- params[0].code = (Aword)EOF;
- _vm->printError(M_WHAT_ALL);
- }
- } else if (anyPlural) {
- listCompact(mlstArr);
-
- // If there where multiple parameters but non left, exit without a
- // word, assuming we have already said enough
- if (listLength(mlstArr) == 0)
- _vm->printError(MSGMAX);
- }
-
- plural = anyPlural; // Remember that we found plural objects
-}
-
-void Parser::match(ParamElem *mlstArr) {
- tryMatch(mlstArr); // try to understand what the user said
-
- if (wrds[wrdidx] != EOF && !isConj(wrds[wrdidx]))
- _vm->printError(M_WHAT);
- if (wrds[wrdidx] != EOF) // More on this line?
- wrdidx++; // If so skip the AND
-}
-
-void Parser::action(ParamElem plst[]) {
- int i, mpos;
- char marker[10];
-
- if (plural) {
- // The code == 0 means this is a multiple position. We must loop
- // over this position (and replace it by each present in the plst)
- for (mpos = 0; params[mpos].code != 0; mpos++); // Find multiple position
-
- sprintf(marker, "($%d)", mpos + 1); // Prepare a printout with $1/2/3
-
- for (i = 0; plst[i].code != (Aword)EOF; i++) {
- params[mpos] = plst[i];
- _vm->output(marker);
- //do_it(); // TODO
-
- if (plst[i + 1].code != (Aword)EOF)
- _vm->paragraph();
- }
-
- params[mpos].code = 0;
- } //else // TODO
- //do_it();
-}
-
-void Parser::parse() {
- if (mlst == nullptr) { // Allocate large enough paramlists
- mlst = new ParamElem[MAXENTITY + 1];
- mlst[0].code = (Aword)EOF;
- pmlst = new ParamElem[MAXENTITY + 1];
- params = new ParamElem[MAXENTITY + 1];
- params[0].code = (Aword)EOF;
- pparams = new ParamElem[MAXENTITY + 1];
- }
-
- if (wrds[wrdidx] == EOF) {
- wrdidx = 0;
- scan();
- } else if (false/*anyOutput*/) // TODO
- _vm->paragraph();
-
- allLength = 0;
- paramidx = 0;
- listCopy(pparams, params);
- params[0].code = (Aword)EOF;
- listCopy(pmlst, mlst);
- mlst[0].code = (Aword)EOF;
-
- if (isVerb(wrds[wrdidx])) {
- vrbwrd = wrds[wrdidx];
- vrbcode = dict[vrbwrd].code;
- wrdidx++;
- match(mlst);
- action(mlst); // mlst contains possible multiple params
- } else {
- params[0].code = (Aword)EOF;
- pmlst[0].code = (Aword)EOF;
- nonverb();
- }
-}
-
-} // End of namespace Alan2
-} // End of namespace Glk
diff --git a/engines/glk/alan2/parse.h b/engines/glk/alan2/parse.h
deleted file mode 100644
index c5b223baa0..0000000000
--- a/engines/glk/alan2/parse.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/* 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 GLK_ALAN2_PARSE
-#define GLK_ALAN2_PARSE
-
-namespace Glk {
-namespace Alan2 {
-
-#define LISTLEN 100
-
-class Parser {
-public:
- Parser();
-
- /**
- * Parse a new player command
- */
- void parse();
-
-private:
- void unknown(char *inputStr);
- int lookup(char *wrd);
- char *gettoken(char *tokenBuffer);
- void agetline();
- void scan();
-
- /**
- * Search for a non-verb command
- */
- void nonverb();
-
- Abool objhere(Aword obj);
- Aword objloc(Aword obj);
- Abool isHere(Aword id);
- Aword where(Aword id);
-
- /**
- * Build a list of objects matching 'all'
- */
- void buildall(ParamElem list[]);
-
- void listCopy(ParamElem a[], ParamElem b[]);
- bool listContains(ParamElem l[], Aword e);
- void listIntersection(ParamElem a[], ParamElem b[]);
-
- /**
- * Copy the refs (in dictionary) to a paramList
- */
- void listCopyFromDictionary(ParamElem p[], Aword r[]);
-
- int listLength(ParamElem a[]);
-
- /**
- * Compact a list, i.e remove any nullptr elements
- */
- void listCompact(ParamElem a[]);
-
- /**
- * Merge the paramElems of one list into the first
- */
- void listMerge(ParamElem a[], ParamElem b[]);
-
- /**
- * Subtract two lists
- */
- void listSubtract(ParamElem a[], ParamElem b[]);
-
- /**
- * Match an unambigous object reference
- */
- void unambig(ParamElem plst[]);
-
- /**
- * Match a simple verb command
- */
- void simple(ParamElem olst[]);
-
- /**
- * Match a complex verb command
- */
- void complex(ParamElem olst[]);
-
- bool claCheck(ClaElem *cla);
-
- /**
- * In case the syntax did not indicate omnipotent powers (allowed
- * access to remote object), we need to remove non - present parameters
- */
- void resolve(ParamElem plst[]);
-
- bool endOfTable(StxElem *addr);
- bool endOfTable(ElmElem *addr);
- bool endOfTable(ClaElem *addr);
- bool endOfTable(VrbElem *addr);
- bool endOfTable(AltElem *addr);
- bool endOfTable(ChkElem *addr);
- bool endOfTable(WrdElem *addr);
-
- /**
- * Find the verb alternative wanted in a verb list and return
- * the address to it.
- *
- * @param vrbsadr Address to start of list
- * @param param Which parameter to match
- */
- AltElem *findalt(Aword vrbsadr, Aword param);
-
- /**
- * Tries a check, returns TRUE if it passed, FALSE otherwise
- *
- * @param adr ACODE address to check table
- * @param act Act if it fails?
- */
- bool trycheck(Aaddr adr, bool act);
-
- /**
- * Check if current action is possible according to the CHECKs.
- */
- bool possible();
-
- void tryMatch(ParamElem mlstArr[]);
- void match(ParamElem *mlstArr);
-
- /**
- * Execute all activities commanded. Handles possible multiple actions
- * such as THEM or lists of objects.
- */
- void action(ParamElem plst[]);
-
- // TODO: Initialize / move these
- int wrds[LISTLEN / 2]; // List of parsed words
- int wrdidx; // and an index into it
-
- bool plural;
-
- // Syntax Parameters
- int paramidx; // Index in params
- ParamElem *params; // List of params
- static ParamElem *pparams; // Previous parameter list
- static ParamElem *mlst; // Multiple objects list
- static ParamElem *pmlst; // Previous multiple list
-
- StxElem *stxs; // Syntax table pointer
- LocElem *locs; // Location table pointer
-
- // Literals
- LitElem litValues[MAXPARAMS + 1];
-
- // What did the user say?
- int vrbwrd; // The word he used
- int vrbcode; // The code for that verb
-
- bool eol; // Looking at End of line? Yes, initially
- char *token;
-
- WrdElem *dict; // Dictionary pointer
- int dictsize;
-
- int allLength; // No. of objects matching 'all'
-};
-
-} // End of namespace Alan2
-} // End of namespace Glk
-
-#endif
diff --git a/engines/glk/alan2/rules.cpp b/engines/glk/alan2/rules.cpp
deleted file mode 100644
index 973bd2389c..0000000000
--- a/engines/glk/alan2/rules.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/* 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/alan2/acode.h"
-#include "glk/alan2/interpreter.h"
-#include "glk/alan2/rules.h"
-#include "glk/alan2/types.h"
-#include "common/debug.h"
-
-namespace Glk {
-namespace Alan2 {
-
-// TODO: Refactor these into debug flags
-const bool trcflg = false;
-const bool stpflg = false;
-
-void Rules::parseRules() {
- bool change = true;
- int i;
-
- for (i = 1; !endOfTable(&_ruls[i - 1]); i++)
- _ruls[i - 1].run = false;
-
- while (change) {
- change = false;
- for (i = 1; !endOfTable(&_ruls[i - 1]); i++) {
- if (!_ruls[i - 1].run) {
- if (trcflg) {
- debug("\n<RULE %d (at ", i); // TODO: Debug output formatting?
- //debugsay(cur.loc); // TODO
- if (!stpflg)
- debug("), Evaluating");
- else
- debug("), Evaluating:>\n");
- }
-
- _interpreter->interpret(_ruls[i - 1].exp);
-
- if (_stack->pop()) {
- change = true;
- _ruls[i - 1].run = true;
-
- if (trcflg) {
- if (!stpflg) {
- debug(", Executing:>\n");
- } else {
- debug("\nRULE %d (at ", i);
- //debugsay(cur.loc); // TODO
- debug("), Executing:>\n");
- }
- }
-
- _interpreter->interpret(_ruls[i - 1].stms);
-
- } else if (trcflg && !stpflg) {
- debug(":>\n");
- }
- }
- }
- }
-}
-
-bool Rules::endOfTable(RulElem *addr) {
- Aword *x = (Aword *)addr;
- return *x == (Aword)EOF;
-}
-
-} // End of namespace Alan2
-} // End of namespace Glk
diff --git a/engines/glk/alan2/rules.h b/engines/glk/alan2/rules.h
deleted file mode 100644
index 194c7d0733..0000000000
--- a/engines/glk/alan2/rules.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* 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 GLK_ALAN2_RULES
-#define GLK_ALAN2_RULES
-
-#include "common/stack.h"
-#include "glk/alan2/alan2.h"
-#include "glk/alan2/types.h"
-
-namespace Glk {
-namespace Alan2 {
-
-class Interpreter;
-
-class Rules {
-public:
- Rules(RulElem *rules, Alan2Stack *stack, Interpreter *interpreter) : _ruls(rules), _stack(stack), _interpreter(interpreter) {}
- void parseRules();
-
-private:
- bool endOfTable(RulElem *addr);
-
- RulElem *_ruls;
- Alan2Stack *_stack;
- Interpreter *_interpreter;
-};
-
-} // End of namespace Alan2
-} // End of namespace Glk
-
-#endif
diff --git a/engines/glk/alan2/saveload.cpp b/engines/glk/alan2/saveload.cpp
deleted file mode 100644
index 838c2588a1..0000000000
--- a/engines/glk/alan2/saveload.cpp
+++ /dev/null
@@ -1,218 +0,0 @@
-/* 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 "common/savefile.h"
-#include "glk/alan2/acode.h"
-#include "glk/alan2/alan2.h"
-#include "glk/alan2/saveload.h"
-#include "glk/alan2/types.h"
-
-namespace Glk {
-namespace Alan2 {
-
-void SaveLoad::save() {
- uint i;
- Common::SaveFileManager *saveFileMan = _vm->getSaveFileManager();
- Common::OutSaveFile *saveFile = nullptr;
- Common::String str;
- AtrElem *atr;
-
- // TODO
-#if 0
- frefid_t fref = glk_fileref_create_by_prompt(fileusage_SavedGame, filemode_Write, 0);
- if (fref == nullptr)
- _vm->printError(M_SAVEFAILED);
-
- strcpy(str, garglk_fileref_get_name(fref));
- glk_fileref_destroy(fref);
-#endif
-
- if (str.empty())
- str = _prevSaveName;
-
- _vm->col = 1;
-
- // TODO
-#if 0
- if ((savfil = fopen(str, READ_MODE)) != nullptr)
- // It already existed
- if (!confirm(M_SAVEOVERWRITE))
- _vm->printError(MSGMAX); // Return to player without saying anything
-
- if ((savfil = fopen(str, WRITE_MODE)) == nullptr)
- _vm->printError(M_SAVEFAILED);
-#endif
-
- saveFile = saveFileMan->openForSaving(str);
-
- _prevSaveName = str;
-
- // Save version of interpreter and name of game
- saveFile->write(_vm->header->vers, sizeof(Aword));
- saveFile->writeString(_gameName);
- saveFile->writeByte('\0');
- // Save current values
- saveFile->write(&_vm->cur, sizeof(_vm->cur));
-
- // Save actors
- for (i = ACTMIN; i <= ACTMAX; i++) {
- saveFile->writeUint32LE(_actors[i - ACTMIN].loc);
- saveFile->writeUint32LE(_actors[i - ACTMIN].script);
- saveFile->writeUint32LE(_actors[i - ACTMIN].step);
- saveFile->writeUint32LE(_actors[i - ACTMIN].count);
- if (_actors[i - ACTMIN].atrs)
- for (atr = (AtrElem *)addrTo(_actors[i - ACTMIN].atrs); !endOfTable(atr); atr++)
- saveFile->writeUint32LE(atr->val);
- }
-
- // Save locations
- for (i = LOCMIN; i <= LOCMAX; i++) {
- saveFile->writeUint32LE(_locations[i - LOCMIN].describe);
- if (_locations[i - LOCMIN].atrs)
- for (atr = (AtrElem *)addrTo(_locations[i - LOCMIN].atrs); !endOfTable(atr); atr++)
- saveFile->writeUint32LE(atr->val);
- }
-
- // Save objects
- for (i = OBJMIN; i <= OBJMAX; i++) {
- saveFile->writeUint32LE(_objects[i - OBJMIN].loc);
- if (_objects[i - OBJMIN].atrs)
- for (atr = (AtrElem *)addrTo(_objects[i - OBJMIN].atrs); !endOfTable(atr); atr++)
- saveFile->writeUint32LE(atr->val);
- }
-
- // Save the event queue
- _events[*_eventTop].time = 0; // Mark the top
- for (i = 0; i < (uint)*_eventTop + 1; i++)
- saveFile->write(&_events[i], sizeof(_events[0]));
-
- // Save scores
- for (i = 0; _vm->scores[i] != EOF; i++)
- saveFile->writeUint32LE(_vm->scores[i]);
-
- delete saveFile;
-}
-
-void SaveLoad::restore() {
- uint i;
- Common::SaveFileManager *saveFileMan = _vm->getSaveFileManager();
- Common::InSaveFile *saveFile = nullptr;
- Common::String str;
- AtrElem *atr;
- char savedVersion[4];
- char savedName[256];
-
- // TODO
-#if 0
- frefid_t fref = glk_fileref_create_by_prompt(fileusage_SavedGame, filemode_Read, 0);
- if (fref == nullptr)
- _vm->printError(M_SAVEFAILED);
-
- strcpy(str, garglk_fileref_get_name(fref));
- glk_fileref_destroy(fref);
-#endif
-
- _vm->col = 1;
-
- if (str.empty())
- str = _prevSaveName; // Use the name temporarily
-
- if ((saveFile = saveFileMan->openForLoading(str)) == nullptr) {
- _vm->printError(M_SAVEMISSING);
- return;
- }
-
- _prevSaveName = str; // Save it for future use
-
- saveFile->read(savedVersion, sizeof(Aword));
-
- // 4f - save file version check doesn't seem to work on PC's!
- if (strncmp(savedVersion, _vm->header->vers, 4)) {
- delete saveFile;
- _vm->printError(M_SAVEVERS);
- return;
- }
-
- i = 0;
-
- while ((savedName[i++] = saveFile->readByte()) != '\0');
-
- if (savedName != _gameName) {
- delete saveFile;
- _vm->printError(M_SAVENAME);
- return;
- }
-
- // Restore current values
- saveFile->read(&_vm->cur, sizeof(_vm->cur));
-
- // Restore actors
- for (i = ACTMIN; i <= ACTMAX; i++) {
- _actors[i - ACTMIN].loc = saveFile->readUint32LE();
- _actors[i - ACTMIN].script = saveFile->readUint32LE();
- _actors[i - ACTMIN].step = saveFile->readUint32LE();
- _actors[i - ACTMIN].count = saveFile->readUint32LE();
-
- if (_actors[i - ACTMIN].atrs)
- for (atr = (AtrElem *)addrTo(_actors[i - ACTMIN].atrs); !endOfTable(atr); atr++)
- atr->val = saveFile->readUint32LE();
- }
-
- // Restore locations
- for (i = LOCMIN; i <= LOCMAX; i++) {
- _locations[i - LOCMIN].describe = saveFile->readUint32LE();
- if (_locations[i - LOCMIN].atrs)
- for (atr = (AtrElem *)addrTo(_locations[i - LOCMIN].atrs); !endOfTable(atr); atr++)
- atr->val = saveFile->readUint32LE();
- }
-
- // Restore objects
- for (i = OBJMIN; i <= OBJMAX; i++) {
- _objects[i - OBJMIN].loc = saveFile->readUint32LE();
- if (_objects[i - OBJMIN].atrs)
- for (atr = (AtrElem *)addrTo(_objects[i - OBJMIN].atrs); !endOfTable(atr); atr++)
- atr->val = saveFile->readUint32LE();
- }
-
- // Restore the event queue
- *_eventTop = 0;
- do {
- saveFile->read(&_events[*_eventTop], sizeof(_events[0]));
- (*_eventTop)++;
- } while (_events[*_eventTop - 1].time != 0);
-
- (*_eventTop)--;
-
- // Restore scores
- for (i = 0; _vm->scores[i] != EOF; i++)
- _vm->scores[i] = saveFile->readUint32LE();
-
- delete saveFile;
-}
-
-bool SaveLoad::endOfTable(AtrElem *addr) {
- Aword *x = (Aword *)addr;
- return *x == (Aword)EOF;
-}
-
-} // End of namespace Alan2
-} // End of namespace Glk
diff --git a/engines/glk/alan2/saveload.h b/engines/glk/alan2/saveload.h
deleted file mode 100644
index 32a02bb5c4..0000000000
--- a/engines/glk/alan2/saveload.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* 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 GLK_ALAN2_SAVELOAD
-#define GLK_ALAN2_SAVELOAD
-
-#include "common/scummsys.h"
-#include "glk/alan2/types.h"
-
-namespace Glk {
-namespace Alan2 {
-
-class SaveLoad {
-public:
- SaveLoad(Common::String &gameName, ActElem *actors, LocElem *locations, ObjElem *objects, EvtqElem *events, int *eventTop) :
- _gameName(gameName), _actors(actors), _locations(locations), _objects(objects), _events(events), _eventTop(eventTop) {}
- void save();
- void restore();
-private:
- bool endOfTable(AtrElem *addr);
-
- Common::String _prevSaveName;
-
- // Save state related variables
- Common::String _gameName;
- ActElem *_actors;
- LocElem *_locations;
- ObjElem *_objects;
- EvtqElem *_events;
- int *_eventTop;
-};
-
-} // End of namespace Alan2
-} // End of namespace Glk
-
-#endif
diff --git a/engines/glk/module.mk b/engines/glk/module.mk
index 19dc6c9d97..bfda72d34a 100644
--- a/engines/glk/module.mk
+++ b/engines/glk/module.mk
@@ -32,13 +32,7 @@ MODULE_OBJS := \
advsys/glk_interface.o \
advsys/vm.o \
alan2/alan2.o \
- alan2/decode.o \
alan2/detection.o \
- alan2/execute.o \
- alan2/interpreter.o \
- alan2/parse.o \
- alan2/rules.o \
- alan2/saveload.o \
frotz/bitmap_font.o \
frotz/config.o \
frotz/detection.o \