diff options
Diffstat (limited to 'engines/titanic/true_talk/tt_quotes.cpp')
-rw-r--r-- | engines/titanic/true_talk/tt_quotes.cpp | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/engines/titanic/true_talk/tt_quotes.cpp b/engines/titanic/true_talk/tt_quotes.cpp new file mode 100644 index 0000000000..c690ac8780 --- /dev/null +++ b/engines/titanic/true_talk/tt_quotes.cpp @@ -0,0 +1,145 @@ +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/algorithm.h" +#include "titanic/true_talk/tt_quotes.h" +#include "titanic/titanic.h" + +namespace Titanic { + +TTquotes::TTquotes() : _loaded(false), _dataP(nullptr), _dataSize(0), + _field544(0) { + Common::fill(&_tags[0], &_tags[256], 0); +} + +TTquotes::~TTquotes() { + delete[] _dataP; +} + +void TTquotes::load() { + Common::SeekableReadStream *r = g_vm->_filesManager->getResource("TEXT/JRQUOTES.TXT"); + size_t size = r->readUint32LE(); + _loaded = true; + + _dataSize = _field544 = size; + _dataP = new char[size + 0x10]; + + for (int idx = 0; idx < 256; ++idx) + _tags[idx] = r->readUint32LE(); + + for (int charIdx = 0; charIdx < 26; ++charIdx) { + TTquotesLetter &letter = _alphabet[charIdx]; + int count = r->readUint32LE(); + + // Load the list of entries for the given letter + letter._entries.resize(count); + for (int idx = 0; idx < count; ++idx) { + letter._entries[idx]._tagIndex = r->readByte(); + letter._entries[idx]._maxSize = r->readByte(); + letter._entries[idx]._strP = _dataP + r->readUint32LE(); + } + } + + // Read in buffer and then decode it + r->read((byte *)_dataP, _dataSize); + for (size_t idx = 0; idx < _dataSize; idx += 4) + WRITE_LE_UINT32((byte *)_dataP + idx, READ_LE_UINT32((const byte *)_dataP + idx) ^ 0xA55A5AA5); + + delete r; +} + +int TTquotes::find(const char *str) const { + if (!str || !*str) + return 0; + + // Find start and end of string + const char *startP = str, *endP = str; + while (*endP) + ++endP; + + do { + int tagId = find(startP, endP); + if (tagId) + return tagId; + + // Move to next following space or end of string + while (*startP && *startP != ' ') + ++startP; + // If it's a space, then move past it to start of next word + while (*startP && *startP == ' ') + ++startP; + + } while (*startP); + + // No match + return 0; +} + +int TTquotes::find(const char *startP, const char *endP) const { + int size = endP - startP; + if (size < 3) + return 0; + + uint index = MIN((uint)(*startP - 'a'), (uint)25); + const TTquotesLetter &letter = _alphabet[index]; + if (letter._entries.empty()) + // No entries for the letter, so exit immediately + return 0; + + int maxSize = size + 4; + + for (uint idx = 0; idx < letter._entries.size(); ++idx) { + const TTquotesEntry &entry = letter._entries[idx]; + if (entry._maxSize > maxSize) + continue; + + const char *srcP = startP; + const char *destP = entry._strP; + int srcIndex = index != 25 ? 1 : 0, destIndex = 0; + if (*destP) { + do { + if (!srcP[srcIndex]) { + break; + } else if (srcP[srcIndex] == '*') { + ++srcIndex; + } else if (destP[destIndex] == '-') { + ++destIndex; + if (srcP[srcIndex] == ' ') + ++srcIndex; + } else if (srcP[srcIndex] != destP[destIndex]) { + break; + } else { + ++destIndex; + ++srcIndex; + } + } while (destP[destIndex]); + + if (!destP[destIndex] && (srcP[srcIndex] <= '*' || + (srcP[srcIndex] == 's' && srcP[srcIndex + 1] <= '*'))) + return _tags[entry._tagIndex]; + } + } + + return 0; +} + +} // End of namespace Titanic |