GLK: ADVSYS: Added input line split up and tokenizing
This commit is contained in:
parent
9c0771552d
commit
4e74751e7e
5 changed files with 162 additions and 18 deletions
|
@ -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()) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ void GlkInterface::print(int number) {
|
|||
print(s);
|
||||
}
|
||||
|
||||
Common::String GlkInterface::getLine() {
|
||||
Common::String GlkInterface::readLine() {
|
||||
// TODO: Stub
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ protected:
|
|||
/**
|
||||
* Get an input line
|
||||
*/
|
||||
Common::String getLine();
|
||||
Common::String readLine();
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue