SHERLOCK: Make journal entries multilingual

Spanish needs to be checked
Spanish also needs to be copy and slightly changed for SH1
Also fixed Journal button text for French + Spanish
Fixes bug #7019
This commit is contained in:
Martin Kiewitz 2016-02-07 16:22:56 +01:00
parent e50f93f298
commit 15be58dfb5
5 changed files with 337 additions and 39 deletions

View File

@ -27,6 +27,180 @@
namespace Sherlock {
static const char *const fixedJournalTextEN[] = {
// Holmes asked/said...
"Holmes asked me, ",
"Holmes asked the Inspector, ",
"Holmes asked %s, ",
"Holmes said to me, ",
"Holmes said to the Inspector, ",
"Holmes said to %s, ",
// I asked/said...
"I replied, ",
"The reply was, ",
// Holmes/I/The Inspector/Person asked/said (without "Then" prefix)
"Holmes asked, ",
"Holmes said, ",
"I asked, ",
"I said, ",
"The Inspector asked, ",
"The Inspector said, ",
"%s asked, ",
"%s said, ",
// Then Holmes/I/The Inspector/Person asked/said
"Then Holmes asked, ",
"Then Holmes said, ",
"Then I asked, ",
"Then I said, ",
"Then the Inspector asked, ",
"Then the Inspector said, ",
"Then %s asked, ",
"Then %s said, "
};
static const char *const fixedJournalTextDE[] = {
// Holmes asked/said...
"Holmes fragte mich, ",
"Holmes fragte Inspektor Lestrade, ",
"Holmes fragte %s, ",
"Holmes sagte mir, ",
"Holmes sagte Inspektor Lestrade, ",
"Holmes sagte %s, ",
// I asked/said...
"Ich antwortete, ",
"Die Antwort lautete, ",
// Holmes/I/The Inspector/Person asked/said (without "Then" prefix)
"Holmes fragte, ", // original: "fragte Holmes"
"Holmes sagte, ", // original: "sagte Holmes"
"Ich fragte, ", // original: "fragte Ich"
"Ich sagte, ", // original: "sagte Ich"
"Der Inspektor fragte, ",
"Der Inspektor sagte, ",
"%s fragte, ",
"%s sagte, ",
// Then Holmes/I/The Inspector/Person asked/said
"Dann fragte Holmes, ",
"Dann sagte Holmes, ",
"Dann fragte ich, ", // original: "Dann sagte Ich"
"Dann sagte ich, ", // original: "Dann sagte Ich"
"Dann fragte der Inspektor, ",
"Dann sagte der Inspektor, ",
"Dann fragte %s, ",
"Dann sagte %s, "
};
// Only used for Sherlock Holmes 2, so special characters should use the SH2 charset
// small a w/ accent grave: 0x85 / octal 205
// small e w/ accent acute: 0x82 / octal 202
// small e w/ accent grave: 0x8A / octal 212
// small e w/ circonflexe: 0x88 / octal 210
// small cedilla: 0x87 / octal 207
static const char *const fixedJournalTextFR[] = {
// Holmes asked/said...
"Holmes me demanda, ", // original: "Holmes m'a demand\202, "
"Holmes demanda \205 l'inspecteur, ", // original: "Holmes a demand\202 \205 l'inspecteur, "
"Holmes demanda \205 %s, ", // original: "Holmes a demand\202 \205 %s, "
"Holmes me dit, ", // original: "Holmes m'a dit, "
"Holmes dit \205 l'inspecteur, ", // original: "Holmes a dit \205 l'inspecteur, "
"Holmes dit \205 %s, ", // original: "Holmes a dit \205 %s, "
// I asked/said...
"Je r\202pondis, ", // original: "J'ai r\202pondu, ",
"La r\202ponse fut, ",
// Holmes/I/The Inspector/Person asked/said (without "Then" prefix)
"Holmes demanda, ", // original: "Holmes a demand\202, "
"Holmes dit, ",
"Je demandai, ", // original: "J'ai demand\202, "
"Je dis, ", // original: "J'ai dit, "
"L'inspecteur demanda, ", // original: ""L'inspecteur a demand\202, "
"L'inspecteur dit, ",
"%s demanda, ", // original: "%s a demand\202, "
"%s dit, ",
// Then Holmes/I/The Inspector/Person asked/said
"Alors Holmes demanda, ", // original: it seems "puis"/"then" was not used/removed. They instead added a space character, so sentences looked weird
"Alors Holmes dit, ",
"Alors je demandai, ",
"Alors je dis, ",
"Alors l'inspecteur demanda, ",
"Alors l'inspecteur dit, ",
"Alors %s demanda, ",
"Alors %s dit, "
};
// Attention: Special characters are NOT the same in Sherlock Holmes 1+2
// That's why we need 2 tables for Spanish.
// Sherlock Holmes 2:
// small a w/ accent bottom to top : 0xA0 / octal 240
// small i w/ accent bottom to top : 0xA1 / octal 241
// small o w/ accent bottom to top : 0xA2 / octal 242
// small u w/ accent bottom to top : 0xA3 / octal 243
// small n w/ wavy line : 0xA4 / octal 244
// inverted question mark : 0xA8 / octal 250
static const char *const fixedJournalTextES2[] = {
// Holmes asked/said...
"Holmes me pidi\242, ",
"Holmes pregunt\242 el inspector, ",
"Holmes pregunt\242 %s, ",
"Holmes me dijo, ",
"Holmes dijo el inspector, ",
"Holmes dijo %s, ",
// I asked/said...
"Yo respond\241, ",
"La respuesta fue, ",
// Holmes/I/The Inspector/Person asked/said (without "Then" prefix)
"Holmes pregunt\242, ",
"Holmes dijo, ",
"Yo pregunt\242, ",
"Yo dije, ",
"El inspector pregunt\242, ",
"El inspector dijo, ",
"%s pregunt\242, ",
"%s dijo, ",
// Then Holmes/I/The Inspector/Person asked/said
"Entonces Holmes pregunt\242, ",
"Entonces Holmes dijo, ",
"Entonces yo pregunt\242, ",
"Entonces yo dije, ",
"Entonces el Inspector pregunt\242, ",
"Entonces el Inspector dijo, ",
"Entonces %s pregunt\242, ",
"Entonces %s dijo, "
};
FixedText::FixedText(SherlockEngine *vm) {
_vm = vm;
// Figure out which fixed texts to use
Common::Language curLanguage = _vm->getLanguage();
switch (curLanguage) {
case Common::EN_ANY:
// Used by Sherlock Holmes 1+2
_fixedJournalTextArray = fixedJournalTextEN;
break;
case Common::DE_DEU:
// Used by Sherlock Holmes 1+2
_fixedJournalTextArray = fixedJournalTextDE;
break;
case Common::FR_FRA:
// Used by Sherlock Holmes 2
_fixedJournalTextArray = fixedJournalTextFR;
break;
case Common::ES_ESP:
// Used by Sherlock Holmes 1+2
// Because of different extended charsets, we need to use 2 tables
if (vm->getGameID() == GType_SerratedScalpel)
_fixedJournalTextArray = fixedJournalTextES2; // TODO check translation and then create ES1
else
_fixedJournalTextArray = fixedJournalTextES2;
break;
default:
// Default to English
_fixedJournalTextArray = fixedJournalTextEN;
break;
}
}
FixedText *FixedText::init(SherlockEngine *vm) {
if (vm->getGameID() == GType_SerratedScalpel)
return new Scalpel::ScalpelFixedText(vm);
@ -34,5 +208,8 @@ FixedText *FixedText::init(SherlockEngine *vm) {
return new Tattoo::TattooFixedText(vm);
}
const char *FixedText::getJournalText(int fixedJournalTextId) {
return _fixedJournalTextArray[fixedJournalTextId];
}
} // End of namespace Sherlock

View File

@ -39,13 +39,44 @@ enum FixedTextActionId {
kFixedTextAction_Use
};
enum FixedJournalTextId {
// Holmes asked/said...
kFixedJournalText_HolmesAskedMe = 0,
kFixedJournalText_HolmesAskedTheInspector,
kFixedJournalText_HolmesAskedPerson,
kFixedJournalText_HolmesSaidToMe,
kFixedJournalText_HolmesSaidToTheInspector,
kFixedJournalText_HolmesSaidToPerson,
// I asked/said
kFixedJournalText_IReplied,
kFixedJournalText_TheReplyWas,
// Holmes/I/The Inspector/Person asked/said (without "Then" prefix)
kFixedJournalText_HolmesAsked,
kFixedJournalText_HolmesSaid,
kFixedJournalText_IAsked,
kFixedJournalText_ISaid,
kFixedJournalText_TheInspectorAsked,
kFixedJournalText_TheInspectorSaid,
kFixedJournalText_PersonAsked,
kFixedJournalText_PersonSaid,
// Then Holmes/I/The Inspector/Person asked/said
kFixedJournalText_ThenHolmesAsked,
kFixedJournalText_ThenHolmesSaid,
kFixedJournalText_ThenIAsked,
kFixedJournalText_ThenISaid,
kFixedJournalText_ThenTheInspectorAsked,
kFixedJournalText_ThenTheInspectorSaid,
kFixedJournalText_ThenPersonAsked,
kFixedJournalText_ThenPersonSaid
};
class SherlockEngine;
class FixedText {
protected:
SherlockEngine *_vm;
FixedText(SherlockEngine *vm) : _vm(vm) {}
FixedText(SherlockEngine *vm);
public:
static FixedText *init(SherlockEngine *vm);
virtual ~FixedText() {}
@ -59,6 +90,14 @@ public:
* Get action message
*/
virtual const Common::String getActionMessage(FixedTextActionId actionId, int messageIndex) = 0;
/**
* Gets journal text
*/
const char *getJournalText(int fixedJournalTextId);
private:
const char *const *_fixedJournalTextArray;
};
} // End of namespace Sherlock

View File

@ -299,6 +299,7 @@ bool Journal::drawJournal(int direction, int howFar) {
}
void Journal::loadJournalFile(bool alreadyLoaded) {
FixedText &fixedText = *_vm->_fixedText;
People &people = *_vm->_people;
Screen &screen = *_vm->_screen;
Talk &talk = *_vm->_talk;
@ -381,20 +382,34 @@ void Journal::loadJournalFile(bool alreadyLoaded) {
// If Holmes has something to say first, then take care of it
if (!replyOnly) {
// Handle the grammar
journalString += "Holmes ";
bool asked = false;
if (talk[journalEntry._statementNum]._statement.hasSuffix("?"))
journalString += "asked ";
else
journalString += "said to ";
asked = true;
if (talk._talkTo == 1) {
journalString += "me";
if (asked)
journalString += fixedText.getJournalText(kFixedJournalText_HolmesAskedMe);
else
journalString += fixedText.getJournalText(kFixedJournalText_HolmesSaidToTheInspector);
} else if ((talk._talkTo == 2 && IS_SERRATED_SCALPEL) || (talk._talkTo == 18 && IS_ROSE_TATTOO)) {
journalString += "the Inspector";
if (asked)
journalString += fixedText.getJournalText(kFixedJournalText_HolmesAskedTheInspector);
else
journalString += fixedText.getJournalText(kFixedJournalText_HolmesSaidToMe);
} else {
journalString += people._characters[talk._talkTo]._name;
const char *text = nullptr;
if (asked)
text = fixedText.getJournalText(kFixedJournalText_HolmesAskedPerson);
else
text = fixedText.getJournalText(kFixedJournalText_HolmesSaidToPerson);
journalString += Common::String::format(text, people._characters[talk._talkTo]._name);
}
journalString += ", \"";
journalString += "\"";
// Add the statement
journalString += statement._statement;
@ -457,29 +472,46 @@ void Journal::loadJournalFile(bool alreadyLoaded) {
journalString += "\"\n";
if (talk._talkTo == 1)
journalString += "I replied, \"";
journalString += fixedText.getJournalText(kFixedJournalText_IReplied);
else
journalString += "The reply was, \"";
journalString += fixedText.getJournalText(kFixedJournalText_TheReplyWas);
} else {
if (talk._talkTo == 1)
journalString += "I";
else if (talk._talkTo == inspectorId)
journalString += "The Inspector";
else
journalString += people._characters[talk._talkTo]._name;
const byte *strP = replyP + 1;
byte v;
do {
v = *strP++;
} while (v && (v < opcodes[0]) && (v != '.') && (v != '!') && (v != '?'));
bool asked = false;
if (v == '?')
journalString += " asked, \"";
else
journalString += " said, \"";
asked = true;
if (talk._talkTo == 1) {
if (asked)
journalString += fixedText.getJournalText(kFixedJournalText_IAsked);
else
journalString += fixedText.getJournalText(kFixedJournalText_ISaid);
} else if (talk._talkTo == inspectorId) {
if (asked)
journalString += fixedText.getJournalText(kFixedJournalText_TheInspectorAsked);
else
journalString += fixedText.getJournalText(kFixedJournalText_TheInspectorSaid);
} else {
const char *text = nullptr;
if (asked)
text = fixedText.getJournalText(kFixedJournalText_PersonAsked);
else
text = fixedText.getJournalText(kFixedJournalText_PersonSaid);
journalString += Common::String::format(text, people._characters[talk._talkTo]._name);
}
}
journalString += "\"";
startOfReply = false;
}
@ -502,11 +534,13 @@ void Journal::loadJournalFile(bool alreadyLoaded) {
justChangedSpeaker = true;
}
bool addPrefixThen = false;
if (!startOfReply) {
if (!commentFlag && !commentJustPrinted)
journalString += "\"\n";
journalString += "Then ";
addPrefixThen = true; // "Then" should get added to the sentence
commentFlag = false;
} else if (!replyOnly) {
journalString += "\"\n";
@ -517,15 +551,6 @@ void Journal::loadJournalFile(bool alreadyLoaded) {
if (IS_ROSE_TATTOO)
replyP++;
if (c == 0)
journalString += "Holmes";
else if (c == 1)
journalString += "I";
else if (c == inspectorId)
journalString += "the Inspector";
else
journalString += people._characters[c]._name;
if (IS_SERRATED_SCALPEL && _vm->getLanguage() == Common::DE_DEU)
Scalpel::ScalpelTalk::skipBadText(replyP);
@ -535,10 +560,70 @@ void Journal::loadJournalFile(bool alreadyLoaded) {
v = *strP++;
} while (v && v < opcodes[0] && v != '.' && v != '!' && v != '?');
bool asked = false;
if (v == '?')
journalString += " asked, \"";
else
journalString += " said, \"";
asked = true;
if (c == 0) {
// Holmes
if (addPrefixThen) {
if (asked)
journalString += fixedText.getJournalText(kFixedJournalText_ThenHolmesAsked);
else
journalString += fixedText.getJournalText(kFixedJournalText_ThenHolmesSaid);
} else {
if (asked)
journalString += fixedText.getJournalText(kFixedJournalText_HolmesAsked);
else
journalString += fixedText.getJournalText(kFixedJournalText_HolmesSaid);
}
} else if (c == 1) {
// I (Watson)
if (addPrefixThen) {
if (asked)
journalString += fixedText.getJournalText(kFixedJournalText_ThenIAsked);
else
journalString += fixedText.getJournalText(kFixedJournalText_ThenISaid);
} else {
if (asked)
journalString += fixedText.getJournalText(kFixedJournalText_IAsked);
else
journalString += fixedText.getJournalText(kFixedJournalText_ISaid);
}
} else if (c == inspectorId) {
// The Inspector
if (addPrefixThen) {
if (asked)
journalString += fixedText.getJournalText(kFixedJournalText_ThenTheInspectorAsked);
else
journalString += fixedText.getJournalText(kFixedJournalText_ThenTheInspectorSaid);
} else {
if (asked)
journalString += fixedText.getJournalText(kFixedJournalText_TheInspectorAsked);
else
journalString += fixedText.getJournalText(kFixedJournalText_TheInspectorSaid);
}
} else {
// Person
const char *text = nullptr;
if (addPrefixThen) {
if (asked)
text = fixedText.getJournalText(kFixedJournalText_ThenPersonAsked);
else
text = fixedText.getJournalText(kFixedJournalText_ThenPersonSaid);
} else {
if (asked)
text = fixedText.getJournalText(kFixedJournalText_PersonAsked);
else
text = fixedText.getJournalText(kFixedJournalText_PersonSaid);
}
journalString += Common::String::format(text, people._characters[c]._name);
}
journalString += "\"";
} else {
if (IS_SERRATED_SCALPEL) {
// Control code, so move past it and any parameters

View File

@ -616,8 +616,6 @@ static const FixedTextActionEntry fixedTextES_Actions[] = {
// =========================================
// TODO:
// It seems there was a French version of Sherlock Holmes 2
static const FixedTextLanguageEntry fixedTextLanguages[] = {
{ Common::DE_DEU, fixedTextDE, fixedTextDE_Actions },
{ Common::ES_ESP, fixedTextES, fixedTextES_Actions },

View File

@ -426,7 +426,7 @@ static const char *const fixedTextFR[] = {
"Page %d",
"Fermer",
"Lessen", // <--
"Rechercher",
"Sauvegarder",
"Annuler ",
"Chercher avant",
@ -610,7 +610,7 @@ static const char *const fixedTextES[] = {
"P\240gina %d",
"Cerrar Diario",
"Lessen", // <-- not included?!?!
"Buscar en Diario",
"Salvar en Archivo",
"Detener B\243squeda",
"Buscar Hacia Atr\240s",
@ -755,7 +755,6 @@ static const char *const fixedTextES[] = {
"Cochero"
};
// TODO: There also was a Spanish version of Sherlock Holmes 2
static const FixedTextLanguageEntry fixedTextLanguages[] = {
{ Common::DE_DEU, fixedTextDE },
{ Common::ES_ESP, fixedTextES },