diff options
| -rw-r--r-- | engines/glk/advsys/game.cpp | 12 | ||||
| -rw-r--r-- | engines/glk/advsys/game.h | 25 | ||||
| -rw-r--r-- | engines/glk/advsys/vm.cpp | 57 | ||||
| -rw-r--r-- | engines/glk/advsys/vm.h | 27 | 
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(); | 
