diff options
| author | Paul Gilbert | 2019-06-10 22:40:13 -0700 | 
|---|---|---|
| committer | Paul Gilbert | 2019-06-12 21:30:41 -0700 | 
| commit | 4e74751e7e40e0a3ddada4b4266c845004d2498d (patch) | |
| tree | ffbdb38cb311e79cb6a9184d8fa9e00ebeb262fa | |
| parent | 9c0771552d97f8e8aec1ba93d7ff689b0e58a64c (diff) | |
| download | scummvm-rg350-4e74751e7e40e0a3ddada4b4266c845004d2498d.tar.gz scummvm-rg350-4e74751e7e40e0a3ddada4b4266c845004d2498d.tar.bz2 scummvm-rg350-4e74751e7e40e0a3ddada4b4266c845004d2498d.zip  | |
GLK: ADVSYS: Added input line split up and tokenizing
| -rw-r--r-- | engines/glk/advsys/advsys.cpp | 11 | ||||
| -rw-r--r-- | engines/glk/advsys/glk_interface.cpp | 2 | ||||
| -rw-r--r-- | engines/glk/advsys/glk_interface.h | 2 | ||||
| -rw-r--r-- | engines/glk/advsys/vm.cpp | 114 | ||||
| -rw-r--r-- | engines/glk/advsys/vm.h | 51 | 
5 files changed, 162 insertions, 18 deletions
diff --git a/engines/glk/advsys/advsys.cpp b/engines/glk/advsys/advsys.cpp index 0c63ff8dfb..3f50d84237 100644 --- a/engines/glk/advsys/advsys.cpp +++ b/engines/glk/advsys/advsys.cpp @@ -26,20 +26,11 @@  namespace Glk {  namespace AdvSys { -bool getInput() { -	// TODO: Stub -	return false; -} -  bool singleAction() {  	// TODO: Stub  	return false;  } -bool nextAction() { -	// TODO: STub -	return false; -}  void AdvSys::runGame() {  	if (!initialize()) { @@ -60,7 +51,7 @@ void AdvSys::runGame() {  			// Get and parse a single line  			if (getInput()) {  				if (singleAction()) { -					while (!shouldQuit() && nextAction() && singleAction()) {} +					while (!shouldQuit() && nextCommand() && singleAction()) {}  				}  			}  		} diff --git a/engines/glk/advsys/glk_interface.cpp b/engines/glk/advsys/glk_interface.cpp index 800d70836e..6ec5a08547 100644 --- a/engines/glk/advsys/glk_interface.cpp +++ b/engines/glk/advsys/glk_interface.cpp @@ -39,7 +39,7 @@ void GlkInterface::print(int number) {  	print(s);  } -Common::String GlkInterface::getLine() { +Common::String GlkInterface::readLine() {  	// TODO: Stub  	return "";  } diff --git a/engines/glk/advsys/glk_interface.h b/engines/glk/advsys/glk_interface.h index 44f3db9939..95dcfa8fc5 100644 --- a/engines/glk/advsys/glk_interface.h +++ b/engines/glk/advsys/glk_interface.h @@ -56,7 +56,7 @@ protected:  	/**  	 * Get an input line  	 */ -	Common::String getLine(); +	Common::String readLine();  public:  	/**  	 * Constructor diff --git a/engines/glk/advsys/vm.cpp b/engines/glk/advsys/vm.cpp index 53950fc5a4..21f79d596b 100644 --- a/engines/glk/advsys/vm.cpp +++ b/engines/glk/advsys/vm.cpp @@ -21,6 +21,7 @@   */  #include "glk/advsys/vm.h" +#include "common/translation.h"  namespace Glk {  namespace AdvSys { @@ -83,7 +84,8 @@ OpcodeMethod VM::_METHODS[0x34] = {  };  VM::VM(OSystem *syst, const GlkGameDescription &gameDesc) : GlkInterface(syst, gameDesc), Game(), -		_fp(_stack), _pc(0), _status(IN_PROGRESS) { +		_fp(_stack), _pc(0), _status(IN_PROGRESS), _actor(-1), _action(-1), _dObject(-1), +		_ndObjects(-1), _iObject(-1) {  	Common::fill(&_nouns[0], &_nouns[20], 0);  	Common::fill(&_nounWords[0], &_nounWords[20], -1);  	Common::fill(&_adjectives[0], &_adjectives[20], (int *)nullptr); @@ -302,8 +304,8 @@ void VM::opSNLIT() {  }  void VM::opYORN() { -	Common::String line = getLine(); -	_stack.top() = line[0] == 'Y' || line[0] == 'y' ? TRUE : NIL; +	Common::String line = readLine(); +	_stack.top() = !line.empty() && (line[0] == 'Y' || line[0] == 'y') ? TRUE : NIL;  }  void VM::opSAVE() { @@ -364,13 +366,13 @@ void VM::opPNOUN() {  	for (int *aPtr = _adjectives[noun - 1]; *aPtr; ++aPtr, space = true) {  		if (space)  			str += " "; -		str += _wordText[_adjectiveWords[aPtr - _adjectiveLists]]; +		str += _words[_adjectiveWords[aPtr - _adjectiveLists]]._text;  	}  	// Add the noun  	if (space)  		str += " "; -	str += _wordText[_nounWords[noun - 1]]; +	str += _words[_nounWords[noun - 1]]._text;  	print(str);  } @@ -412,5 +414,107 @@ void VM::opVOWEL() {  	// No implementation  } +bool VM::getInput() { +	if (!parseInput()) +		return false; + +	setVariable(V_ACTOR, _actor); +	setVariable(V_ACTION, _action); +	setVariable(V_DOBJECT, _dObject); +	setVariable(V_NDOBJECTS, _ndObjects); +	setVariable(V_IOBJECT, _iObject); +	return true; +} + +bool VM::nextCommand() { +	if (getVariable(V_NDOBJECTS) > 1) { +		setVariable(V_ACTOR, _actor); +		setVariable(V_ACTION, _action); +		setVariable(V_DOBJECT, getVariable(V_DOBJECT) + 1); +		setVariable(V_NDOBJECTS, getVariable(V_NDOBJECTS) - 1); +		setVariable(V_IOBJECT, _iObject); +		return true; +	} else { +		return false; +	} +} + +bool VM::parseInput() { +	int noun1 = 0, cnt1 = 0, noun2 = 0, cnt2 = 0; +	int preposition = 0; +	bool flag = false; + +	// Initialize the parser result fields +	_actor = _action = _dObject = _iObject = 0; +	_ndObjects = 0; + +	// Get the input line +	if (!getLine()) +		return false; + +	// TODO: stub +	return false; +} + +bool VM::getLine() { +	// Let the user type in an input line +	Common::String line = readLine(); +	if (shouldQuit()) +		return false; + +	skipSpaces(line); +	if (line.empty()) { +		print(_("Speak up! I can't hear you!\n")); +		return false; +	} + +	// Get the words of the line +	_words.clear(); +	while (!line.empty()) { +		if (!getWord(line)) +			return false; +	} + +	return true; +} + +bool VM::getWord(Common::String &line) { +	// Find the end of the word +	const char *wordP = line.c_str(); +	for (; *wordP && !isWhitespace(*wordP); ++wordP) {} + +	// Copy out the next word +	InputWord iw; +	iw._text = Common::String(line.c_str(), wordP); +	iw._text.toLowercase(); + +	// Remove the word from the line +	line = Common::String(wordP); +	skipSpaces(line); + +	// Look up the word +	iw._number = findWord(iw._text); + +	if (iw._number) { +		_words.push_back(iw); +		return false; +	} else { +		Common::String msg = Common::String::format(_("I don't know the word \"%s\".\n"), iw._text.c_str()); +		print(msg); +		return true; +	} +} + +bool VM::isWhitespace(char c) { +	return c == ' ' || c == ',' || c == '.'; +} + +bool VM::skipSpaces(Common::String &str) { +	while (!str.empty() && isWhitespace(str[0])) +		str.deleteChar(0); + +	return !str.empty(); +} +  } // End of namespace AdvSys  } // End of namespace Glk diff --git a/engines/glk/advsys/vm.h b/engines/glk/advsys/vm.h index b5c5b48463..d235bd878d 100644 --- a/engines/glk/advsys/vm.h +++ b/engines/glk/advsys/vm.h @@ -187,6 +187,12 @@ public:   * Main VM for AdvSys   */  class VM : public GlkInterface, public Game { +	struct InputWord { +		Common::String _text; +		int _number; + +		InputWord() : _number(0) {} +	};  private:  	// Execution fields  	static OpcodeMethod _METHODS[0x34]; @@ -201,7 +207,13 @@ private:  	int _adjectiveWords[100];  	int _nouns[20];  	int _nounWords[20]; -	Common::String _wordText[100]; +	int _actor; +	int _action; +	int _dObject; +	int _ndObjects; +	int _iObject; +	Common::Array<InputWord> _words; +	InputWord *_wordPtr;  private:  	/**  	 * Execute a single opcode within the script @@ -221,6 +233,33 @@ private:  	int readCodeWord() {  		return getCodeWord(_pc += 2);  	} + +	/** +	 * Gets an input line and parse it +	 */ +	bool parseInput(); + +	/** +	 * Gets an input line and splits it up into the words array +	 */ +	bool getLine(); + +	/** +	 * Get the next word of a passed input line +	 * @param line		Input line +	 * @returns			True if a valid word was extracted +	 */ +	bool getWord(Common::String &line); + +	/** +	 * Returns true if a passed character is a skippable whitespace +	 */ +	static bool isWhitespace(char c); + +	/** +	 * Skips over spaces in a passed string +	 */ +	static bool skipSpaces(Common::String &str);  private:  	void opBRT();  	void opBRF(); @@ -286,6 +325,16 @@ public:  	 * @returns         Script result code  	 */  	ExecutionResult execute(int offset); + +	/** +	 * Get an input line and parse it +	 */ +	bool getInput(); + +	/** +	 * Get the next command (next direct object) +	 */ +	bool nextCommand();  };  } // End of namespace AdvSys  | 
