TITANIC: Implement TTparser searchAndReplace methods

This commit is contained in:
Paul Gilbert 2016-05-15 23:15:24 -04:00
parent 053ff7ab75
commit b37da849c9
5 changed files with 158 additions and 16 deletions

View File

@ -49,20 +49,74 @@
*/
#define VERSION_NUMBER 1
#define HEADER_SIZE 0x280
Common::File inputFile, outputFile;
Common::PEResources res;
uint headerOffset = 6;
uint dataOffset = 0x200;
uint dataOffset = HEADER_SIZE;
#define SEGMENT_OFFSET 0x401C00
static const char *const ITEM_NAMES[46] = {
"LeftArmWith", "LeftArmWithout", "RightArmWith", "RightArmWithout", "BridgeRed",
"BridgeYellow", "BridgeBlue", "BridgeGreen", "Parrot", "CentralCore", "BrainGreen",
"BrainYellow", "BrainRed", "BrainBlue", "ChickenGreasy", "ChickenPlain", "ChickenPurple",
"ChickenRed", "ChickenYellow", "CrushedTV", "Ear", "Ear1", "Eyeball", "Eyeball1",
"Feather", "Lemon", "GlassEmpty", "GlassPurple", "GlassRed", "GlassYellow", "Hammer",
"Hose", "HoseEnd", "LiftHead", "LongStick", "Magazine", "Mouth", "MusicKey", "Napkin",
"Nose", "Perch", "PhonoCylinder", "PhonoCylinder1", "PhonoCylinder2", "PhonoCylinder3",
"Photo"
};
static const char *const ITEM_DESCRIPTIONS[46] = {
"The Maitre d'Bot's left arm holding a key", "The Maitre d'Bot's left arm",
"The Maitre d'Bot's right arm holding Titania's auditory center",
"The Maitre d'Bot's right arm", "Red Fuse", "Yellow Fuse", "Blue Fuse",
"Green Fuse", "The Parrot", "Titania's central intelligence core",
"Titania's auditory center", "Titania's olfactory center",
"Titania's speech center", "Titania's vision center", "rather greasy chicken",
"very plain chicken", "chicken smeared with starling pur$e",
"chicken covered with tomato sauce", "chicken coated in mustard sauce",
"A crushed television set", "Titania's ear", "Titania's ear", "Titania's eye",
"Titania's eye", "A parrot feather", "A nice fat juicy lemon",
"An empty beer glass", "A beer glass containing pur$ed flock of starlings",
"A beer glass containing tomato sauce", "A beer glass containing mustard sauce",
"A hammer", "A hose", "The other end of a hose", "The LiftBot's head",
"A rather long stick", "A magazine", "Titania's mouth", "A key",
"A super-absorbent napkin", "Titania's nose", "A perch", "A phonograph cylinder",
"A phonograph cylinder", "A phonograph cylinder", "A phonograph cylinder",
"A photograph"
};
static const char *const ITEM_IDS[40] = {
"MaitreD Left Arm", "MaitreD Right Arm", "OlfactoryCentre", "AuditoryCentre",
"SpeechCentre", "VisionCentre", "CentralCore", "Perch", "SeasonBridge",
"FanBridge", "BeamBridge", "ChickenBridge", "CarryParrot", "Chicken",
"CrushedTV", "Feathers", "Lemon", "BeerGlass", "BigHammer", "Ear1", "Ear 2",
"Eye1", "Eye2", "Mouth", "Nose", "NoseSpare", "Hose", "DeadHoseSpare",
"HoseEnd", "DeadHoseEndSpare", "BrokenLiftbotHead", "LongStick", "Magazine",
"Napkin", "Phonograph Cylinder", "Phonograph Cylinder 1", "Phonograph Cylinder 2",
"Phonograph Cylinder 3", "Photograph", "Music System Key"
};
static const char *const ROOM_NAMES[34] = {
"1stClassLobby", "1stClassRestaurant", "1stClassState",
"2ndClassLobby", "secClassState", "Arboretum", "FrozenArboretum",
"Bar", "BilgeRoom", "BilgeRoomWith", "BottomOfWell", "Bridge",
"CreatorsChamber", "CreatorsChamberOn", "Dome", "Home", "Lift",
"EmbLobby", "MoonEmbLobby", "MusicRoomLobby", "MusicRoom",
"ParrotLobby", "Pellerator", "PromenadeDeck", "SculptureChamber",
"SecClassLittleLift", "ServiceElevator", "SGTLeisure", "SGTLittleLift",
"SgtLobby", "SGTState", "Titania", "TopOfWell", "PlayersRoom"
};
void NORETURN_PRE error(const char *s, ...) {
printf("%s\n", s);
exit(1);
}
void writeEntryHeader(const char *name, uint offset, uint size) {
assert(headerOffset < 0x200);
assert(headerOffset < HEADER_SIZE);
outputFile.seek(headerOffset);
outputFile.writeLong(offset);
outputFile.writeLong(size);
@ -72,7 +126,7 @@ void writeEntryHeader(const char *name, uint offset, uint size) {
}
void writeFinalEntryHeader() {
assert(headerOffset <= 0x1F8);
assert(headerOffset <= (HEADER_SIZE - 8));
outputFile.seek(headerOffset);
outputFile.writeLong(0);
outputFile.writeLong(0);
@ -103,6 +157,19 @@ void writeStringArray(const char *name, uint offset, int count) {
delete[] offsets;
}
void writeStringArray(const char *name, const char *const *strings, int count) {
outputFile.seek(dataOffset);
// Iterate through writing each string
for (int idx = 0; idx < count; ++idx) {
outputFile.writeString(strings[idx]);
}
uint size = outputFile.size() - dataOffset;
writeEntryHeader(name, dataOffset, size);
dataOffset += size;
}
Common::WinResourceID getResId(uint id) {
return Common::WinResourceID(id);
}
@ -152,10 +219,15 @@ void writeHeader() {
}
void writeData() {
writeStringArray("TEXT/STRINGS1", 0x21B7C8, 376);
writeStringArray("TEXT/STRINGS2", 0x21BDB0, 218);
writeStringArray("TEXT/STRINGS3", 0x21C120, 1576);
writeStringArray("TEXT/STRINGS4", 0x21D9C8, 82);
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");

View File

@ -24,6 +24,7 @@
#define TITANIC_STRING_H
#include "common/scummsys.h"
#include "common/array.h"
#include "common/str.h"
namespace Titanic {
@ -101,6 +102,8 @@ public:
static CString format(const char *fmt, ...);
};
typedef Common::Array<CString> StringArray;
} // End of namespace Titanic
#endif /* TITANIC_STRING_H */

View File

@ -31,6 +31,8 @@ int TTparser::processInput(TTinput *input) {
if (normalize(input))
return 0;
// Scan for and replace common slang and contractions with verbose versions
warning("TODO: TTparser::processInput");
return 0;
}
@ -53,7 +55,7 @@ int TTparser::normalize(TTinput *input) {
} else if (Common::isUpper(c)) {
(*destLine) += toupper(c);
} else if (Common::isDigit(c)) {
if (c == '0' && isSpecialCommand(srcLine, index)) {
if (c == '0' && isEmoticon(srcLine, index)) {
input->set38(10);
} else {
// Iterate through all the digits of the number
@ -78,7 +80,7 @@ int TTparser::normalize(TTinput *input) {
break;
case ':':
commandVal = isSpecialCommand(srcLine, index);
commandVal = isEmoticon(srcLine, index);
if (commandVal) {
input->set38(commandVal);
index += 2;
@ -88,7 +90,7 @@ int TTparser::normalize(TTinput *input) {
break;
case ';':
commandVal = isSpecialCommand(srcLine, index);
commandVal = isEmoticon(srcLine, index);
if (commandVal == 6) {
input->set38(7);
index += 2;
@ -100,7 +102,7 @@ int TTparser::normalize(TTinput *input) {
case '<':
++index;
commandVal = isSpecialCommand(srcLine, index);
commandVal = isEmoticon(srcLine, index);
if (commandVal == 6) {
input->set38(12);
} else {
@ -111,7 +113,7 @@ int TTparser::normalize(TTinput *input) {
case '>':
++index;
commandVal = isSpecialCommand(srcLine, index);
commandVal = isEmoticon(srcLine, index);
if (commandVal == 6 || commandVal == 9) {
input->set38(11);
} else {
@ -150,7 +152,7 @@ int TTparser::normalize(TTinput *input) {
return 0;
}
int TTparser::isSpecialCommand(const TTstring &str, int &index) {
int TTparser::isEmoticon(const TTstring &str, int &index) {
if (str[index] != ':' && str[index] != ';')
return 0;
@ -258,8 +260,53 @@ bool TTparser::normalizeContraction(const TTstring &srcLine, int srcIndex, TTstr
break;
}
// TODO
return false;
}
void TTparser::searchAndReplace(TTstring &line, const StringArray &strings) {
int charIndex = 0;
while (charIndex >= 0)
charIndex = searchAndReplace(line, charIndex, strings);
}
int TTparser::searchAndReplace(TTstring &line, int startIndex, const StringArray &strings) {
int lineSize = line.size();
if (startIndex >= lineSize)
return -1;
for (uint idx = 0; idx < strings.size(); idx += 2) {
const CString &origStr = strings[idx];
const CString &replacementStr = strings[idx + 1];
if (!strncmp(line.c_str() + startIndex, origStr.c_str(), strings[idx].size())) {
// Ensure that that a space follows the match, or the end of string,
// so the end of the string doesn't match on parts of larger words
char c = line[startIndex + strings[idx].size()];
if (c == ' ' || c == '\0') {
// Replace the text in the line with it's replacement
line = CString(line.c_str(), line.c_str() + startIndex) + replacementStr +
CString(line.c_str() + startIndex + origStr.size());
startIndex += replacementStr.size();
break;
}
}
}
// Skip to the end of the current word
while (startIndex < lineSize && line[startIndex] != ' ')
++startIndex;
if (startIndex == lineSize)
return -1;
// ..and all spaces following it until the start of the next word
while (startIndex < lineSize && line[startIndex] == ' ')
++startIndex;
if (startIndex == lineSize)
return -1;
// Return index of the start of the next word
return startIndex;
}
} // End of namespace Titanic

View File

@ -46,7 +46,27 @@ private:
/**
* Checks for what is likely special developer cheat codes
*/
static int isSpecialCommand(const TTstring &str, int &index);
static int isEmoticon(const TTstring &str, int &index);
/**
* Checks if any word within a passed line has an entry in the list of replacements,
* and if found, replaces it with it's equivalent replacement string
* @param line Line to check
* @param strings List of strings to check for. Strings come in pairs, with the
* first being the string to match, and the second the replacement
*/
static void searchAndReplace(TTstring &line, const StringArray &strings);
/**
* Checks the string starting at a given index for any word in the passed string array,
* and if found, replaces it in the line with it's replacement
* @param line Line to check
* @param startIndex Starting index in the start to check
* @param strings List of strings to check for. Strings come in pairs, with the
* first being the string to match, and the second the replacement
* @returns Index of the start of the following word
*/
static int searchAndReplace(TTstring &line, int startIndex, const StringArray &strings);
public:
CScriptHandler *_owner;
int _field4;

View File

@ -58,7 +58,7 @@ public:
TTstring &operator+=(const TTstring &str);
TTstring &operator+=(char c);
const char &operator[](uint index) {
const char &operator[](int index) {
return *(c_str() + index);
}