Initial commit
This commit is contained in:
584
engines/titanic/true_talk/tt_vocab.cpp
Normal file
584
engines/titanic/true_talk/tt_vocab.cpp
Normal file
@@ -0,0 +1,584 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/true_talk/tt_vocab.h"
|
||||
#include "titanic/true_talk/script_handler.h"
|
||||
#include "titanic/true_talk/tt_action.h"
|
||||
#include "titanic/true_talk/tt_adj.h"
|
||||
#include "titanic/true_talk/tt_major_word.h"
|
||||
#include "titanic/true_talk/tt_picture.h"
|
||||
#include "titanic/true_talk/tt_pronoun.h"
|
||||
#include "titanic/titanic.h"
|
||||
#include "titanic/translation.h"
|
||||
#include "common/file.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
TTvocab::TTvocab(VocabMode vocabMode): _headP(nullptr), _tailP(nullptr),
|
||||
_word(nullptr), _vocabMode(vocabMode) {
|
||||
load("STVOCAB");
|
||||
}
|
||||
|
||||
TTvocab::~TTvocab() {
|
||||
if (_headP) {
|
||||
_headP->deleteSiblings();
|
||||
delete _headP;
|
||||
_headP = _tailP = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
int TTvocab::load(const CString &name) {
|
||||
SimpleFile *file = g_vm->_exeResources._owner->openResource(name);
|
||||
int result = 0;
|
||||
bool skipFlag;
|
||||
|
||||
while (!result && !file->eos()) {
|
||||
skipFlag = false;
|
||||
WordClass wordClass = (WordClass)file->readNumber();
|
||||
TTstring space(" ");
|
||||
|
||||
switch (wordClass) {
|
||||
case WC_UNKNOWN: {
|
||||
if (_word)
|
||||
result = _word->readSyn(file);
|
||||
skipFlag = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case WC_ACTION: {
|
||||
TTaction *word = new TTaction(space, WC_UNKNOWN, 0, 0, 0);
|
||||
result = word->load(file);
|
||||
_word = word;
|
||||
break;
|
||||
}
|
||||
|
||||
case WC_THING: {
|
||||
TTpicture *word = new TTpicture(space, WC_UNKNOWN, 0, 0, 0, 0, 0);
|
||||
result = word->load(file);
|
||||
_word = word;
|
||||
break;
|
||||
}
|
||||
|
||||
case WC_ABSTRACT:
|
||||
case WC_ADVERB: {
|
||||
TTmajorWord *word = new TTmajorWord(space, WC_UNKNOWN, 0, 0);
|
||||
result = word->load(file, wordClass);
|
||||
_word = word;
|
||||
break;
|
||||
}
|
||||
|
||||
case WC_ARTICLE:
|
||||
case WC_CONJUNCTION:
|
||||
case WC_PREPOSITION: {
|
||||
TTword *word = new TTword(space, WC_UNKNOWN, 0);
|
||||
result = word->load(file, wordClass);
|
||||
_word = word;
|
||||
break;
|
||||
}
|
||||
|
||||
case WC_ADJECTIVE: {
|
||||
TTadj *word = new TTadj(space, WC_UNKNOWN, 0, 0, 0);
|
||||
result = word->load(file);
|
||||
_word = word;
|
||||
break;
|
||||
}
|
||||
|
||||
case WC_PRONOUN: {
|
||||
TTpronoun *word = new TTpronoun(space, WC_UNKNOWN, 0, 0, 0);
|
||||
result = word->load(file);
|
||||
_word = word;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
result = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!skipFlag && _word) {
|
||||
if (result) {
|
||||
// Something wrong occurred, so delete word
|
||||
delete _word;
|
||||
_word = nullptr;
|
||||
} else {
|
||||
// Add the word to the master vocab list
|
||||
addWord(_word);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close resource and return result
|
||||
delete file;
|
||||
return result;
|
||||
}
|
||||
|
||||
void TTvocab::addWord(TTword *word) {
|
||||
TTword *existingWord = g_language == Common::DE_DEU ? nullptr :
|
||||
findWord(word->_text);
|
||||
|
||||
if (existingWord) {
|
||||
if (word->_synP) {
|
||||
// Move over the synonym
|
||||
existingWord->appendNode(word->_synP);
|
||||
word->_synP = nullptr;
|
||||
}
|
||||
|
||||
_word = nullptr;
|
||||
if (word)
|
||||
delete word;
|
||||
} else if (_tailP) {
|
||||
_tailP->_nextP = word;
|
||||
_tailP = word;
|
||||
} else {
|
||||
if (!_headP)
|
||||
_headP = word;
|
||||
|
||||
_tailP = word;
|
||||
}
|
||||
}
|
||||
|
||||
TTword *TTvocab::findWord(const TTstring &str) {
|
||||
TTsynonym *tempNode = new TTsynonym();
|
||||
bool flag = false;
|
||||
TTword *word = _headP;
|
||||
|
||||
while (word && !flag) {
|
||||
if (_vocabMode != VOCAB_MODE_EN || strcmp(word->c_str(), str)) {
|
||||
if (word->findSynByName(str, tempNode, _vocabMode))
|
||||
flag = true;
|
||||
else
|
||||
word = word->_nextP;
|
||||
} else {
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
delete tempNode;
|
||||
return word;
|
||||
}
|
||||
|
||||
TTword *TTvocab::getWord(TTstring &str, TTword **srcWord) const {
|
||||
TTword *word = getPrimeWord(str, srcWord);
|
||||
|
||||
if (!word) {
|
||||
TTstring tempStr(str);
|
||||
if (tempStr.size() > 2) {
|
||||
word = getSuffixedWord(tempStr, srcWord);
|
||||
|
||||
if (!word)
|
||||
word = getPrefixedWord(tempStr, srcWord);
|
||||
}
|
||||
}
|
||||
|
||||
return word;
|
||||
}
|
||||
|
||||
TTword *TTvocab::getPrimeWord(TTstring &str, TTword **srcWord) const {
|
||||
TTsynonym tempSyn;
|
||||
char c = str.charAt(0);
|
||||
TTword *newWord = nullptr;
|
||||
TTword *vocabP;
|
||||
|
||||
if (Common::isDigit(c)) {
|
||||
// Number
|
||||
vocabP = _headP;
|
||||
newWord = new TTword(str, WC_ABSTRACT, 300);
|
||||
} else {
|
||||
// Standard word
|
||||
for (vocabP = _headP; vocabP; vocabP = vocabP->_nextP) {
|
||||
if (_vocabMode == VOCAB_MODE_EN && !strcmp(str.c_str(), vocabP->c_str())) {
|
||||
newWord = vocabP->copy();
|
||||
newWord->_nextP = nullptr;
|
||||
newWord->setSyn(nullptr);
|
||||
break;
|
||||
} else if (vocabP->findSynByName(str, &tempSyn, _vocabMode)) {
|
||||
// Create a copy of the word and the found synonym
|
||||
TTsynonym *newSyn = new TTsynonym(tempSyn);
|
||||
newSyn->_nextP = newSyn->_priorP = nullptr;
|
||||
newWord = vocabP->copy();
|
||||
newWord->_nextP = nullptr;
|
||||
newWord->setSyn(newSyn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (srcWord)
|
||||
// Pass out the pointer to the original word
|
||||
*srcWord = vocabP;
|
||||
|
||||
// Return the new copy of the word
|
||||
return newWord;
|
||||
}
|
||||
|
||||
TTword *TTvocab::getSuffixedWord(TTstring &str, TTword **srcWord) const {
|
||||
TTstring tempStr(str);
|
||||
TTword *word = nullptr;
|
||||
|
||||
if (g_language == Common::DE_DEU) {
|
||||
static const char *const SUFFIXES[11] = {
|
||||
"est", "em", "en", "er", "es", "et", "st",
|
||||
"s", "e", "n", "t"
|
||||
};
|
||||
|
||||
for (int idx = 0; idx < 11; ++idx) {
|
||||
if (tempStr.hasSuffix(SUFFIXES[idx])) {
|
||||
tempStr.deleteSuffix(strlen(SUFFIXES[idx]));
|
||||
word = getPrimeWord(tempStr, srcWord);
|
||||
if (word)
|
||||
break;
|
||||
tempStr = str;
|
||||
}
|
||||
}
|
||||
|
||||
if (word)
|
||||
word->setSynStr(str);
|
||||
return word;
|
||||
}
|
||||
|
||||
if (tempStr.hasSuffix("s")) {
|
||||
tempStr.deleteSuffix(1);
|
||||
word = getPrimeWord(tempStr);
|
||||
|
||||
if (!word) {
|
||||
if (!tempStr.hasSuffix("e")) {
|
||||
tempStr = str;
|
||||
} else {
|
||||
tempStr.deleteLastChar();
|
||||
word = getPrimeWord(tempStr);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (tempStr.hasSuffix("ing")) {
|
||||
tempStr.deleteSuffix(3);
|
||||
word = getPrimeWord(tempStr);
|
||||
|
||||
if (word) {
|
||||
if (word->_wordClass == 1) {
|
||||
delete word;
|
||||
word = nullptr;
|
||||
} else {
|
||||
delete word;
|
||||
word = new TTadj(str, WC_ADJECTIVE, 0, 0, 0);
|
||||
}
|
||||
} else {
|
||||
tempStr += "e";
|
||||
word = getPrimeWord(tempStr);
|
||||
|
||||
if (word) {
|
||||
if (word->_wordClass != 1) {
|
||||
delete word;
|
||||
word = new TTadj(str, WC_ADJECTIVE, 0, 0, 0);
|
||||
}
|
||||
} else {
|
||||
tempStr.deleteSuffix(2);
|
||||
word = getPrimeWord(tempStr);
|
||||
|
||||
if (word) {
|
||||
if (word->_wordClass != 1) {
|
||||
delete word;
|
||||
word = new TTadj(str, WC_ADJECTIVE, 0, 0, 0);
|
||||
}
|
||||
} else {
|
||||
tempStr = str;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (tempStr.hasSuffix("ed")) {
|
||||
tempStr.deleteSuffix(1);
|
||||
word = getPrimeWord(tempStr);
|
||||
|
||||
if (!word) {
|
||||
tempStr.deleteSuffix(1);
|
||||
word = getPrimeWord(tempStr);
|
||||
}
|
||||
|
||||
if (word) {
|
||||
if (word->_wordClass == WC_ACTION) {
|
||||
TTaction *action = dynamic_cast<TTaction *>(word);
|
||||
assert(action);
|
||||
action->setVal(1);
|
||||
}
|
||||
} else {
|
||||
tempStr = str;
|
||||
}
|
||||
|
||||
} else if (tempStr.hasSuffix("ly")) {
|
||||
tempStr.deleteSuffix(2);
|
||||
word = getPrimeWord(tempStr);
|
||||
|
||||
if (word) {
|
||||
delete word;
|
||||
word = new TTword(str, WC_ADVERB, 0);
|
||||
} else {
|
||||
tempStr = str;
|
||||
}
|
||||
|
||||
} else if (tempStr.hasSuffix("er")) {
|
||||
tempStr.deleteSuffix(1);
|
||||
word = getPrimeWord(tempStr);
|
||||
|
||||
if (word) {
|
||||
if (word->_wordClass == WC_ADJECTIVE) {
|
||||
TTadj *adj = static_cast<TTadj *>(word);
|
||||
int val1 = word->proc15();
|
||||
int val2 = word->proc15();
|
||||
|
||||
if (val2 < 5) {
|
||||
if (--val1 > 0) {
|
||||
adj->adjFn1(val1);
|
||||
}
|
||||
} else {
|
||||
if (++val1 < 11) {
|
||||
adj->adjFn1(val1);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tempStr.deleteSuffix(1);
|
||||
word = getPrimeWord(tempStr);
|
||||
|
||||
if (word) {
|
||||
if (word->_wordClass == WC_ADJECTIVE) {
|
||||
TTadj *adj = dynamic_cast<TTadj *>(word);
|
||||
int val1 = word->proc15();
|
||||
int val2 = word->proc15();
|
||||
|
||||
if (val2 < 5) {
|
||||
if (--val1 > 0) {
|
||||
adj->adjFn1(val1);
|
||||
}
|
||||
} else {
|
||||
if (++val1 < 11) {
|
||||
adj->adjFn1(val1);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tempStr.deleteSuffix(1);
|
||||
word = getPrimeWord(tempStr);
|
||||
|
||||
if (word && word->_wordClass == WC_ADJECTIVE) {
|
||||
TTadj *adj = dynamic_cast<TTadj *>(word);
|
||||
int val1 = word->proc15();
|
||||
int val2 = word->proc15();
|
||||
|
||||
if (val2 < 5) {
|
||||
if (--val1 > 0) {
|
||||
adj->adjFn1(val1);
|
||||
}
|
||||
} else {
|
||||
if (++val1 < 11) {
|
||||
adj->adjFn1(val1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (tempStr.hasSuffix("est")) {
|
||||
tempStr.deleteSuffix(2);
|
||||
word = getPrimeWord(tempStr);
|
||||
|
||||
if (word) {
|
||||
if (word->_wordClass == WC_ADJECTIVE) {
|
||||
TTadj *adj = static_cast<TTadj *>(word);
|
||||
int val1 = word->proc15();
|
||||
int val2 = word->proc15();
|
||||
|
||||
if (val2 < 5) {
|
||||
if (--val1 > 0) {
|
||||
adj->adjFn1(val1);
|
||||
}
|
||||
} else {
|
||||
if (++val1 < 11) {
|
||||
adj->adjFn1(val1);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tempStr.deleteSuffix(1);
|
||||
word = getPrimeWord(tempStr);
|
||||
|
||||
if (word) {
|
||||
if (word->_wordClass == WC_ADJECTIVE) {
|
||||
TTadj *adj = dynamic_cast<TTadj *>(word);
|
||||
int val1 = word->proc15();
|
||||
int val2 = word->proc15();
|
||||
|
||||
if (val2 < 5) {
|
||||
if (--val1 > 0) {
|
||||
adj->adjFn1(val1);
|
||||
}
|
||||
} else {
|
||||
if (++val1 < 11) {
|
||||
adj->adjFn1(val1);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tempStr.deleteSuffix(1);
|
||||
word = getPrimeWord(tempStr);
|
||||
|
||||
if (word) {
|
||||
TTadj *adj = dynamic_cast<TTadj *>(word);
|
||||
int val1 = word->proc15();
|
||||
int val2 = word->proc15();
|
||||
|
||||
if (val2 < 5) {
|
||||
if (--val1 > 0) {
|
||||
adj->adjFn1(val1);
|
||||
}
|
||||
} else {
|
||||
if (++val1 < 11) {
|
||||
adj->adjFn1(val1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (tempStr.hasSuffix("s*")) {
|
||||
tempStr.deleteSuffix(2);
|
||||
word = getPrimeWord(tempStr);
|
||||
|
||||
if (word) {
|
||||
if (word->_wordClass == WC_PRONOUN || word->_wordClass == WC_ADVERB) {
|
||||
delete word;
|
||||
TTstring isStr("is");
|
||||
word = getPrimeWord(isStr);
|
||||
} else {
|
||||
switch (word->_id) {
|
||||
case 200:
|
||||
if (word->proc10() == 2) {
|
||||
delete word;
|
||||
word = new TTpronoun(tempStr, WC_PRONOUN, 601, 0, 5);
|
||||
} else if (word->proc10() == 1) {
|
||||
delete word;
|
||||
word = new TTpronoun(tempStr, WC_PRONOUN, 601, 0, 4);
|
||||
}
|
||||
break;
|
||||
|
||||
case 201:
|
||||
delete word;
|
||||
word = new TTpronoun(tempStr, WC_PRONOUN, 601, 0, 5);
|
||||
break;
|
||||
|
||||
case 202:
|
||||
case 203:
|
||||
if (word->proc10() == 2) {
|
||||
delete word;
|
||||
word = new TTpronoun(tempStr, WC_PRONOUN, 601, 0, 5);
|
||||
} else {
|
||||
int val = word->proc10() == 1 ? 0 : 4;
|
||||
delete word;
|
||||
word = new TTpronoun(tempStr, WC_PRONOUN, 601, 0, val);
|
||||
}
|
||||
break;
|
||||
|
||||
case 204:
|
||||
delete word;
|
||||
word = new TTpronoun(tempStr, WC_PRONOUN, 601, 0, 6);
|
||||
break;
|
||||
|
||||
default:
|
||||
delete word;
|
||||
word = new TTpronoun(tempStr, WC_PRONOUN, 601, 0, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (word)
|
||||
word->setSynStr(str);
|
||||
|
||||
return word;
|
||||
}
|
||||
|
||||
TTword *TTvocab::getPrefixedWord(TTstring &str, TTword **srcWord) const {
|
||||
TTstring tempStr(str);
|
||||
TTword *word = nullptr;
|
||||
int prefixLen = 0;
|
||||
|
||||
if (tempStr.hasPrefix("pre")) {
|
||||
prefixLen = 3;
|
||||
} else if (tempStr.hasPrefix("re") || tempStr.hasPrefix("co")) {
|
||||
prefixLen = 2;
|
||||
} else if (tempStr.hasPrefix("inter") || tempStr.hasPrefix("multi")) {
|
||||
prefixLen = 5;
|
||||
} else if (tempStr.hasPrefix("over") || tempStr.hasPrefix("post") || tempStr.hasPrefix("self")) {
|
||||
prefixLen = 4;
|
||||
}
|
||||
|
||||
if (prefixLen) {
|
||||
// Known prefix found, so scan for word without prefix
|
||||
tempStr.deletePrefix(prefixLen);
|
||||
word = getPrimeWord(tempStr);
|
||||
if (word)
|
||||
tempStr = str;
|
||||
|
||||
} else if (tempStr.hasPrefix("anti") || tempStr.hasPrefix("counter")) {
|
||||
prefixLen = tempStr[0] == 'a' ? 4 : 7;
|
||||
|
||||
tempStr.deletePrefix(prefixLen);
|
||||
word = getPrimeWord(tempStr);
|
||||
if (!word)
|
||||
tempStr = str;
|
||||
else if (word->_wordClass == 8) {
|
||||
delete word;
|
||||
word = nullptr;
|
||||
}
|
||||
|
||||
} else if (tempStr.hasPrefix("hyper") || tempStr.hasPrefix("super") ||
|
||||
tempStr.hasPrefix("ultra")) {
|
||||
tempStr.deletePrefix(5);
|
||||
word = getPrimeWord(tempStr);
|
||||
|
||||
if (!word)
|
||||
tempStr = str;
|
||||
else if (word->_wordClass == WC_ADJECTIVE) {
|
||||
TTadj *adj = static_cast<TTadj *>(word);
|
||||
int val1 = word->proc15();
|
||||
int val2 = word->proc15();
|
||||
|
||||
if (val2 < 5) {
|
||||
if (--val1 > 0)
|
||||
adj->adjFn1(val1);
|
||||
} else if (++val1 < 11) {
|
||||
adj->adjFn1(val1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (word) {
|
||||
// Set the original word on either the found word or synonym
|
||||
if (word->hasSynonyms())
|
||||
word->setSynStr(str);
|
||||
else
|
||||
word->_text = str;
|
||||
}
|
||||
|
||||
return word;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
Reference in New Issue
Block a user