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 |