aboutsummaryrefslogtreecommitdiff
path: root/engines/glk/advsys
diff options
context:
space:
mode:
authorPaul Gilbert2019-06-12 21:45:54 -0700
committerPaul Gilbert2019-06-12 21:45:54 -0700
commit0e543b06823e629a007bad26f94d452bfb38abf1 (patch)
tree7b802ac177e94f957810bf9bb88088a7c3e23622 /engines/glk/advsys
parent9efb6d71e2ec91cbfa77b236406a9d680e8e44cf (diff)
downloadscummvm-rg350-0e543b06823e629a007bad26f94d452bfb38abf1.tar.gz
scummvm-rg350-0e543b06823e629a007bad26f94d452bfb38abf1.tar.bz2
scummvm-rg350-0e543b06823e629a007bad26f94d452bfb38abf1.zip
GLK: ADVSYS: Noun/adjectives setup and getNoun method
Diffstat (limited to 'engines/glk/advsys')
-rw-r--r--engines/glk/advsys/game.cpp12
-rw-r--r--engines/glk/advsys/game.h25
-rw-r--r--engines/glk/advsys/vm.cpp57
-rw-r--r--engines/glk/advsys/vm.h27
4 files changed, 74 insertions, 47 deletions
diff --git a/engines/glk/advsys/game.cpp b/engines/glk/advsys/game.cpp
index cd19623f5d..50b258d924 100644
--- a/engines/glk/advsys/game.cpp
+++ b/engines/glk/advsys/game.cpp
@@ -190,18 +190,6 @@ int Game::findWord(const Common::String &word) const {
return NIL;
}
-bool Game::match(int obj, int noun, int *adjectives) {
- if (!hasNoun(obj, noun))
- return false;
-
- for (int *adjPtr = adjectives; *adjPtr; ++adjPtr) {
- if (!hasAdjective(obj, *adjPtr))
- return false;
- }
-
- return true;
-}
-
int Game::checkVerb(const Common::Array<int> &verbs) {
// Iterate through the actions
for (int idx = 1; idx <= _actionCount; ++idx) {
diff --git a/engines/glk/advsys/game.h b/engines/glk/advsys/game.h
index 1b7c6f95b0..5920f412d5 100644
--- a/engines/glk/advsys/game.h
+++ b/engines/glk/advsys/game.h
@@ -170,16 +170,6 @@ private:
int findProperty(int obj, int prop) const;
/**
- * Returns true if an object has a given noun
- */
- bool hasNoun(int obj, int noun) const;
-
- /**
- * Returns true if an object has a given adjective
- */
- bool hasAdjective(int obj, int adjective) const;
-
- /**
* Returns true if an action has a given verb
*/
bool hasVerb(int act, const Common::Array<int> &verbs) const;
@@ -205,6 +195,16 @@ private:
* Read the next character for a string
*/
char readMsgChar();
+protected:
+ /**
+ * Returns true if an object has a given noun
+ */
+ bool hasNoun(int obj, int noun) const;
+
+ /**
+ * Returns true if an object has a given adjective
+ */
+ bool hasAdjective(int obj, int adjective) const;
public:
Common::Array<byte> _data;
int _residentOffset;
@@ -271,11 +271,6 @@ public:
}
/**
- * Match an object against a name and list of adjectives
- */
- bool match(int obj, int noun, int *adjectives);
-
- /**
* Check to see if this is a valid verb
*/
int checkVerb(const Common::Array<int> &verbs);
diff --git a/engines/glk/advsys/vm.cpp b/engines/glk/advsys/vm.cpp
index 54ab84c9c6..bbe958a11b 100644
--- a/engines/glk/advsys/vm.cpp
+++ b/engines/glk/advsys/vm.cpp
@@ -86,11 +86,6 @@ OpcodeMethod VM::_METHODS[0x34] = {
VM::VM(OSystem *syst, const GlkGameDescription &gameDesc) : GlkInterface(syst, gameDesc), Game(),
_fp(_stack), _pc(0), _status(IN_PROGRESS), _actor(-1), _action(-1), _dObject(-1),
_ndObjects(-1), _iObject(-1), _wordPtr(nullptr) {
- Common::fill(&_nouns[0], &_nouns[20], 0);
- Common::fill(&_nounWords[0], &_nounWords[20], -1);
- Common::fill(&_adjectives[0], &_adjectives[20], (int *)nullptr);
- Common::fill(&_adjectiveWords[0], &_adjectiveWords[100], -1);
- Common::fill(&_adjectiveLists[0], &_adjectiveLists[100], -1);
}
ExecutionResult VM::execute(int offset) {
@@ -354,7 +349,7 @@ void VM::opCLASS() {
void VM::opMATCH() {
int idx = _stack.pop() - 1;
- _stack.top() = match(_stack.top(), _nouns[idx], _adjectives[idx]) ? TRUE : NIL;
+ _stack.top() = match(_stack.top(), _nouns[idx]._noun, _nouns[idx]._adjective) ? TRUE : NIL;
}
void VM::opPNOUN() {
@@ -363,16 +358,16 @@ void VM::opPNOUN() {
// Add the adjectives
bool space = false;
- for (int *aPtr = _adjectives[noun - 1]; *aPtr; ++aPtr, space = true) {
+ for (const AdjectiveEntry *aPtr = &_adjectiveList[noun - 1]; aPtr->_list; ++aPtr, space = true) {
if (space)
str += " ";
- str += _words[_adjectiveWords[aPtr - _adjectiveLists]]._text;
+ str += _words[aPtr->_word]._text;
}
// Add the noun
if (space)
str += " ";
- str += _words[_nounWords[noun - 1]]._text;
+ str += _words[_nouns[noun - 1]._num]._text;
print(str);
}
@@ -447,6 +442,8 @@ bool VM::parseInput() {
// Initialize the parser result fields
_actor = _action = _dObject = _iObject = 0;
_ndObjects = 0;
+ _adjectiveList.clear();
+ _nouns.clear();
// Get the input line
if (!getLine())
@@ -514,15 +511,35 @@ bool VM::getWord(Common::String &line) {
}
}
-bool VM::getNoun() {
- // TODO: Stub
- return false;
+uint VM::getNoun() {
+ // Skip over optional article if present
+ if (_wordPtr != _words.end() && getWordType(*_wordPtr) == WT_ARTICLE)
+ ++_wordPtr;
+
+ // Get optional adjectives
+ uint alStart = _adjectiveList.size();
+ while (_wordPtr != _words.end() && getWordType(*_wordPtr) == WT_ADJECTIVE) {
+ AdjectiveEntry ae;
+ ae._list = *_wordPtr++;
+ ae._word = _wordPtr - _words.begin() - 1;
+ _adjectiveList.push_back(ae);
+ }
+ _adjectiveList.push_back(AdjectiveEntry());
+
+ // Add a noun entry to the list
+ Noun n;
+ n._adjective = &_adjectiveList[alStart];
+ n._noun = *_wordPtr++;
+ n._num = _wordPtr - _words.begin() - 1;
+ _nouns.push_back(n);
+
+ return _nouns.size();
}
bool VM::getVerb() {
_verbs.clear();
- if (_words.front() == NIL || getWordType(_words.front()) != WT_VERB) {
+ if (*_wordPtr == NIL || getWordType(*_wordPtr) != WT_VERB) {
parseError();
return false;
}
@@ -554,8 +571,20 @@ bool VM::getVerb() {
return true;
}
+bool VM::match(int obj, int noun, const VM::AdjectiveEntry *adjectives) {
+ if (!hasNoun(obj, noun))
+ return false;
+
+ for (const VM::AdjectiveEntry *adjPtr = adjectives; adjPtr->_list; ++adjPtr) {
+ if (!hasAdjective(obj, adjPtr->_list))
+ return false;
+ }
+
+ return true;
+}
+
void VM::parseError() {
- // TODO
+ print(_("I don't understand.\n"));
}
bool VM::isWhitespace(char c) {
diff --git a/engines/glk/advsys/vm.h b/engines/glk/advsys/vm.h
index d3b7bfc8f6..6a877c9ef0 100644
--- a/engines/glk/advsys/vm.h
+++ b/engines/glk/advsys/vm.h
@@ -204,6 +204,19 @@ class VM : public GlkInterface, public Game {
InputWord() : _number(0) {}
operator int() const { return _number; }
};
+ struct AdjectiveEntry {
+ int _list;
+ int _word;
+
+ AdjectiveEntry() : _list(0), _word(0) {}
+ };
+ struct Noun {
+ int _noun;
+ int _num;
+ AdjectiveEntry *_adjective;
+
+ Noun() : _noun(0), _num(0), _adjective(nullptr) {}
+ };
private:
// Execution fields
static OpcodeMethod _METHODS[0x34];
@@ -213,11 +226,6 @@ private:
FunctionPointer _fp;
// Parser fields
- int *_adjectives[20];
- int _adjectiveLists[100];
- int _adjectiveWords[100];
- int _nouns[20];
- int _nounWords[20];
int _actor;
int _action;
int _dObject;
@@ -226,6 +234,8 @@ private:
Common::Array<InputWord> _words;
Common::Array<InputWord>::iterator _wordPtr;
Common::Array<int> _verbs;
+ Common::Array<AdjectiveEntry> _adjectiveList;
+ Common::Array<Noun> _nouns;
private:
/**
* Execute a single opcode within the script
@@ -266,7 +276,7 @@ private:
/**
* Get a noun phrase and return the object it refers to
*/
- bool getNoun();
+ uint getNoun();
/**
* Get a verb phrase and return the action it refers to
@@ -274,6 +284,11 @@ private:
bool getVerb();
/**
+ * Match an object against a name and list of adjectives
+ */
+ bool match(int obj, int noun, const AdjectiveEntry *adjectives);
+
+ /**
* Called when a parsing error occurs
*/
void parseError();