From 3878f38d8c76f2289be1f53bbecf9cda95e43067 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 16 May 2016 19:59:09 -0400 Subject: TITANIC: Move replacement string arrays into TTparser, added NUMBERS array --- devtools/create_titanic/create_titanic_dat.cpp | 122 ++++++++++++++++++++++--- engines/titanic/support/simple_file.cpp | 11 +++ engines/titanic/support/simple_file.h | 5 + engines/titanic/titanic.cpp | 41 +-------- engines/titanic/titanic.h | 21 ----- engines/titanic/true_talk/tt_parser.cpp | 69 +++++++++++--- engines/titanic/true_talk/tt_parser.h | 32 ++++++- 7 files changed, 215 insertions(+), 86 deletions(-) diff --git a/devtools/create_titanic/create_titanic_dat.cpp b/devtools/create_titanic/create_titanic_dat.cpp index 2f6050846a..ca55f7c5cf 100644 --- a/devtools/create_titanic/create_titanic_dat.cpp +++ b/devtools/create_titanic/create_titanic_dat.cpp @@ -49,7 +49,7 @@ */ #define VERSION_NUMBER 1 -#define HEADER_SIZE 0x280 +#define HEADER_SIZE 0x290 Common::File inputFile, outputFile; Common::PEResources res; @@ -110,6 +110,90 @@ static const char *const ROOM_NAMES[34] = { "SgtLobby", "SGTState", "Titania", "TopOfWell", "PlayersRoom" }; +struct NumberEntry { + const char *_text; + int _value; + uint _flags; +}; + +const NumberEntry NUMBERS[76] = { + { "a", 1, 3 }, + { "and", 0, 1 }, + { "negative", 0, 10 }, + { "minus", 0, 10 }, + { "below zeor", 0, 8 }, + { "degrees below zero", 0, 8 }, + { "nil", 0, 2 }, + { "zero", 0, 2 }, + { "one", 1, 0x12 }, + { "two", 2, 0x12 }, + { "three", 3, 0x12 }, + { "four", 4, 0x12 }, + { "five", 5, 0x12 }, + { "six", 6, 0x12 }, + { "seven", 7, 0x12 }, + { "eight", 8, 0x12 }, + { "nine", 9, 0x12 }, + { "0", 0, 2 }, + { "1", 1, 2 }, + { "2", 2, 2 }, + { "3", 3, 2 }, + { "4", 4, 2 }, + { "5", 5, 2 }, + { "6", 6, 2 }, + { "7", 7, 2 }, + { "8", 8, 2 }, + { "9", 9, 2 }, + { "first", 1, 2 }, + { "second", 2, 2 }, + { "third", 3, 2 }, + { "fourth", 4, 2 }, + { "fifth", 5, 2 }, + { "sixth", 6, 2 }, + { "seventh", 7, 2 }, + { "eighth", 8, 2 }, + { "ninth", 9, 2 }, + { "ten", 10, 2 }, + { "eleven", 11, 2 }, + { "twelve", 12, 2 }, + { "thirteen", 13, 2 }, + { "fourteen", 14, 2 }, + { "fifteen", 15, 2 }, + { "sixteen", 16, 2 }, + { "seventeen", 17, 2 }, + { "eighteen", 18, 2 }, + { "nineteen", 19, 2 }, + { "tenth", 10, 2 }, + { "eleventh", 11, 2 }, + { "twelfth", 12, 2 }, + { "thirteenth", 13, 2 }, + { "fourteenth", 14, 2 }, + { "fifteenth", 15, 2 }, + { "sixteenth", 16, 2 }, + { "seventeenth", 17, 2 }, + { "eighteenth", 18, 2 }, + { "nineteenth", 19, 2 }, + { "twenty", 20, 0x12 }, + { "thirty", 30, 0x12 }, + { "forty", 40, 0x12 }, + { "fourty", 40, 0x12 }, + { "fifty", 50, 0x12 }, + { "sixty", 60, 0x12 }, + { "seventy", 70, 0x12 }, + { "eighty", 80, 0x12 }, + { "ninety", 90, 0x12 }, + { "twentieth", 20, 2 }, + { "thirtieth", 30, 2 }, + { "fortieth", 40, 2 }, + { "fiftieth", 50, 2 }, + { "sixtieth", 60, 2 }, + { "seventieth", 70, 2 }, + { "eightieth", 80, 2 }, + { "ninetieth", 90, 2 }, + { "hundred", 100, 4 }, + { "hundredth", 100, 6 } +}; + void NORETURN_PRE error(const char *s, ...) { printf("%s\n", s); exit(1); @@ -209,6 +293,21 @@ void writeResource(const char *sectionStr, const char *resId) { writeResource(nameBuffer, file); } +void writeNumbers() { + outputFile.seek(dataOffset); + + // Iterate through writing each string + for (int idx = 0; idx < 76; ++idx) { + outputFile.writeString(NUMBERS[idx]._text); + outputFile.writeLong(NUMBERS[idx]._value); + outputFile.writeLong(NUMBERS[idx]._flags); + } + + uint size = outputFile.size() - dataOffset; + writeEntryHeader("TEXT/NUMBERS", dataOffset, size); + dataOffset += size; +} + void writeHeader() { // Write out magic string const char *MAGIC_STR = "SVTN"; @@ -219,16 +318,6 @@ void writeHeader() { } void writeData() { - writeStringArray("TEXT/ITEM_DESCRIPTIONS", ITEM_DESCRIPTIONS, 46); - writeStringArray("TEXT/ITEM_NAMES", ITEM_NAMES, 46); - writeStringArray("TEXT/ITEM_IDS", ITEM_IDS, 40); - writeStringArray("TEXT/ROOM_NAMES", ROOM_NAMES, 34); - - writeStringArray("TEXT/PHRASES", 0x21B7C8, 376); - writeStringArray("TEXT/REPLACEMENTS1", 0x21BDB0, 218); - writeStringArray("TEXT/REPLACEMENTS2", 0x21C120, 1576); - writeStringArray("TEXT/REPLACEMENTS3", 0x21D9C8, 82); - writeResource("Bitmap", "BACKDROP"); writeResource("Bitmap", "EVILTWIN"); writeResource("Bitmap", "RESTORED"); @@ -250,6 +339,17 @@ void writeData() { writeResource("TEXT", "STVOCAB.TXT"); writeResource("TEXT", "JRQUOTES.TXT"); writeResource("TEXT", 155); + + writeStringArray("TEXT/ITEM_DESCRIPTIONS", ITEM_DESCRIPTIONS, 46); + writeStringArray("TEXT/ITEM_NAMES", ITEM_NAMES, 46); + writeStringArray("TEXT/ITEM_IDS", ITEM_IDS, 40); + writeStringArray("TEXT/ROOM_NAMES", ROOM_NAMES, 34); + + writeStringArray("TEXT/PHRASES", 0x21B7C8, 376); + writeStringArray("TEXT/REPLACEMENTS1", 0x21BDB0, 218); + writeStringArray("TEXT/REPLACEMENTS2", 0x21C120, 1576); + writeStringArray("TEXT/REPLACEMENTS3", 0x21D9C8, 82); + writeNumbers(); } int main(int argc, char *argv[]) { diff --git a/engines/titanic/support/simple_file.cpp b/engines/titanic/support/simple_file.cpp index f4351f920f..45b5c8a7cb 100644 --- a/engines/titanic/support/simple_file.cpp +++ b/engines/titanic/support/simple_file.cpp @@ -25,6 +25,17 @@ namespace Titanic { +CString readStringFromStream(Common::SeekableReadStream *s) { + CString result; + char c; + while ((c = s->readByte()) != '\0') + result += c; + + return result; +} + +/*------------------------------------------------------------------------*/ + bool File::open(const Common::String &name) { if (!Common::File::open(name)) error("Could not open file - %s", name.c_str()); diff --git a/engines/titanic/support/simple_file.h b/engines/titanic/support/simple_file.h index cf89e5d72c..bca96a631a 100644 --- a/engines/titanic/support/simple_file.h +++ b/engines/titanic/support/simple_file.h @@ -269,6 +269,11 @@ public: Common::SeekableReadStream *readStream() const { return _inStream; } }; +/** + * General purpose support method for reading an ASCIIZ string from a stream + */ +CString readStringFromStream(Common::SeekableReadStream *s); + } // End of namespace Titanic #endif /* TITANIC_SIMPLE_FILE_H */ diff --git a/engines/titanic/titanic.cpp b/engines/titanic/titanic.cpp index 38d536cab6..da9be20808 100644 --- a/engines/titanic/titanic.cpp +++ b/engines/titanic/titanic.cpp @@ -103,7 +103,6 @@ void TitanicEngine::initialize() { setItemNames(); setRoomNames(); - setParserStrings(); _window->applicationStarting(); } @@ -131,60 +130,28 @@ Common::Error TitanicEngine::run() { return Common::kNoError; } -static CString readString(Common::SeekableReadStream *s) { - CString result; - char c; - while ((c = s->readByte()) != '\0') - result += c; - - return result; -} - void TitanicEngine::setItemNames() { Common::SeekableReadStream *r; r = g_vm->_filesManager->getResource("TEXT/ITEM_NAMES"); while (r->pos() < r->size()) - _itemNames.push_back(readString(r)); + _itemNames.push_back(readStringFromStream(r)); delete r; r = g_vm->_filesManager->getResource("TEXT/ITEM_DESCRIPTIONS"); while (r->pos() < r->size()) - _itemNames.push_back(readString(r)); + _itemNames.push_back(readStringFromStream(r)); delete r; r = g_vm->_filesManager->getResource("TEXT/ITEM_IDS"); while (r->pos() < r->size()) - _itemIds.push_back(readString(r)); + _itemIds.push_back(readStringFromStream(r)); delete r; } void TitanicEngine::setRoomNames() { Common::SeekableReadStream *r = g_vm->_filesManager->getResource("TEXT/ROOM_NAMES"); while (r->pos() < r->size()) - _roomNames.push_back(readString(r)); - delete r; -} - -void TitanicEngine::setParserStrings() { - Common::SeekableReadStream *r; - r = g_vm->_filesManager->getResource("TEXT/REPLACEMENTS1"); - while (r->pos() < r->size()) - _replacements1.push_back(readString(r)); - delete r; - - r = g_vm->_filesManager->getResource("TEXT/REPLACEMENTS2"); - while (r->pos() < r->size()) - _replacements2.push_back(readString(r)); - delete r; - - r = g_vm->_filesManager->getResource("TEXT/REPLACEMENTS3"); - while (r->pos() < r->size()) - _replacements3.push_back(readString(r)); - delete r; - - r = g_vm->_filesManager->getResource("TEXT/PHRASES"); - while (r->pos() < r->size()) - _phrases.push_back(readString(r)); + _roomNames.push_back(readStringFromStream(r)); delete r; } diff --git a/engines/titanic/titanic.h b/engines/titanic/titanic.h index 2b08f56f7d..768f3348b7 100644 --- a/engines/titanic/titanic.h +++ b/engines/titanic/titanic.h @@ -82,17 +82,6 @@ struct TitanicSavegameHeader { int _totalFrames; }; -enum NumberFlag { NF_2 = 2, NF_8 = 8, NF_10 = 0x10 }; - -struct NumberEntry { - CString _text; - int _value; - int _flags; - NumberEntry(const CString &text, int value, int flags) : - _text(text), _value(value), _flags(flags) {} -}; -typedef Common::Array NumberArray; - class TitanicEngine : public Engine { private: /** @@ -114,11 +103,6 @@ private: * Sets up the list of room names */ void setRoomNames(); - - /** - * Set the replacement strings and common phrases lists used by the praser - */ - void setParserStrings(); protected: const TitanicGameDescription *_gameDescription; int _loadSaveSlot; @@ -144,11 +128,6 @@ public: CString _itemObjects[TOTAL_ITEMS]; StringArray _itemIds; StringArray _roomNames; - StringArray _replacements1; - StringArray _replacements2; - StringArray _replacements3; - StringArray _phrases; - NumberArray _numbers; public: TitanicEngine(OSystem *syst, const TitanicGameDescription *gameDesc); virtual ~TitanicEngine(); diff --git a/engines/titanic/true_talk/tt_parser.cpp b/engines/titanic/true_talk/tt_parser.cpp index 9aa6c2ef7a..24361f9e03 100644 --- a/engines/titanic/true_talk/tt_parser.cpp +++ b/engines/titanic/true_talk/tt_parser.cpp @@ -27,23 +27,62 @@ namespace Titanic { +TTparser::TTparser(CScriptHandler *owner) : _owner(owner), _field4(0), + _input(nullptr), _fieldC(0), _field10(0), _field14(0), _field18(0) { + loadArrays(); +} + +void TTparser::loadArrays() { + Common::SeekableReadStream *r; + r = g_vm->_filesManager->getResource("TEXT/REPLACEMENTS1"); + while (r->pos() < r->size()) + _replacements1.push_back(readStringFromStream(r)); + delete r; + + r = g_vm->_filesManager->getResource("TEXT/REPLACEMENTS2"); + while (r->pos() < r->size()) + _replacements2.push_back(readStringFromStream(r)); + delete r; + + r = g_vm->_filesManager->getResource("TEXT/REPLACEMENTS3"); + while (r->pos() < r->size()) + _replacements3.push_back(readStringFromStream(r)); + delete r; + + r = g_vm->_filesManager->getResource("TEXT/PHRASES"); + while (r->pos() < r->size()) + _phrases.push_back(readStringFromStream(r)); + delete r; + + r = g_vm->_filesManager->getResource("TEXT/NUMBERS"); + while (r->pos() < r->size()) { + NumberEntry ne; + ne._text = readStringFromStream(r); + ne._value = r->readSint32LE(); + ne._flags = r->readUint32LE(); + _numbers.push_back(ne); + } + delete r; + +} + int TTparser::processInput(TTinput *input) { _input = input; if (normalize(input)) return 0; // Scan for and replace common slang and contractions with verbose versions - searchAndReplace(input->_normalizedLine, g_vm->_replacements1); - searchAndReplace(input->_normalizedLine, g_vm->_replacements2); + searchAndReplace(input->_normalizedLine, _replacements1); + searchAndReplace(input->_normalizedLine, _replacements2); // Check entire normalized line against common phrases to replace - for (uint idx = 0; idx < g_vm->_phrases.size(); idx += 2) { - if (!g_vm->_phrases[idx].compareTo(input->_normalizedLine)) - input->_normalizedLine = g_vm->_phrases[idx + 1]; + for (uint idx = 0; idx < _phrases.size(); idx += 2) { + if (!_phrases[idx].compareTo(input->_normalizedLine)) + input->_normalizedLine = _phrases[idx + 1]; } // Do a further search and replace of roman numerals to decimal - searchAndReplace(input->_normalizedLine, g_vm->_replacements3); + searchAndReplace(input->_normalizedLine, _replacements3); warning("TODO: TTparser::processInput"); return 0; @@ -321,17 +360,18 @@ int TTparser::searchAndReplace(TTstring &line, int startIndex, const StringArray return startIndex; } -bool TTparser::replaceNumbers(TTstring &line, int *startIndex) { +const NumberEntry *TTparser::replaceNumbers(TTstring &line, int *startIndex) { int lineSize = line.size(); int index = *startIndex; - if (index < 0 || index >= lineSize) - return true; + if (index < 0 || index >= lineSize) { + *startIndex = -1; + return nullptr; + } - NumberArray &numbers = g_vm->_numbers; NumberEntry *numEntry = nullptr; - for (uint idx = 0; idx < numbers.size(); ++idx) { - NumberEntry &ne = numbers[idx]; + for (uint idx = 0; idx < _numbers.size(); ++idx) { + NumberEntry &ne = _numbers[idx]; if (!strncmp(line.c_str() + index, ne._text.c_str(), ne._text.size())) { if ((ne._flags & NF_10) || (index + ne._text.size()) >= lineSize || line[index + ne._text.size()] == ' ') { @@ -352,7 +392,10 @@ bool TTparser::replaceNumbers(TTstring &line, int *startIndex) { while (*startIndex < lineSize && Common::isSpace(line[*startIndex])) ++*startIndex; - return *startIndex < lineSize; + if (*startIndex >= lineSize) + *startIndex = -1; + + return numEntry; } } // End of namespace Titanic diff --git a/engines/titanic/true_talk/tt_parser.h b/engines/titanic/true_talk/tt_parser.h index 22a2850516..7e4e97f1ff 100644 --- a/engines/titanic/true_talk/tt_parser.h +++ b/engines/titanic/true_talk/tt_parser.h @@ -24,13 +24,38 @@ #define TITANIC_TT_PARSER_H #include "titanic/true_talk/tt_input.h" +#include "titanic/true_talk/tt_string.h" namespace Titanic { +enum NumberFlag { NF_2 = 2, NF_8 = 8, NF_10 = 0x10 }; + class CScriptHandler; +struct NumberEntry { + CString _text; + int _value; + int _flags; + + NumberEntry() : _value(0), _flags(0) {} + NumberEntry(const CString &text, int value, int flags) : + _text(text), _value(value), _flags(flags) {} +}; +typedef Common::Array NumberArray; + class TTparser { private: + StringArray _replacements1; + StringArray _replacements2; + StringArray _replacements3; + StringArray _phrases; + NumberArray _numbers; +private: + /** + * Loads the various replacement string data arrays + */ + void loadArrays(); + /** * Normalizes a passed input, taking care of things like removing extra * spaces and lowercasing everything @@ -74,9 +99,9 @@ private: * a plain decimal representation. * @param line Line to check * @param startIndex Starting index in the start to check - * @returns True if end of line hasn't been reached yet + * @returns Pointer to matching number entry, if match occurred */ - static bool replaceNumbers(TTstring &line, int *startIndex); + const NumberEntry *replaceNumbers(TTstring &line, int *startIndex); public: CScriptHandler *_owner; int _field4; @@ -86,8 +111,7 @@ public: int _field14; int _field18; public: - TTparser(CScriptHandler *owner) : _owner(owner), _field4(0), - _input(nullptr), _fieldC(0), _field10(0), _field14(0), _field18(0) {} + TTparser(CScriptHandler *owner); /** * Gets passed a newly created input wrapper during conversation text processing -- cgit v1.2.3