Bugfix to talk data reading invalid data, and added French and German versions

svn-id: r29606
This commit is contained in:
Paul Gilbert 2007-11-22 10:15:20 +00:00
parent 40abab62af
commit ddaa391110
3 changed files with 333 additions and 49 deletions

View file

@ -47,6 +47,8 @@ uint16 dataSegment;
#define NUM_BYTES_VALIDATE 1024
#define ENGLISH_FILE_CHECKSUM 0xFD70
#define ITALIAN_FILE_CHECKSUM 0x109AD
#define FRENCH_FILE_CHECKSUM 0xD38C
#define GERMAN_FILE_CHECKSUM 0xD143
Common::Language processedLanguages[100];
int langIndex = 0;
@ -61,51 +63,56 @@ int actionIndex = 0;
uint16 talkOffsets[MAX_TALK_LISTS];
int talkOffsetIndex = 0;
#define NUM_LANGUAGES 2
#define NUM_LANGUAGES 4
struct AnimListRecord {
uint16 languages[NUM_LANGUAGES];
};
AnimListRecord animDataList[] = {
{{0x1830, 0x1830}}, // Copy protection header
{{0x1839, 0x1839}}, // Copy protection wording header
{{0x1842, 0x1842}}, // Copy protection numbers
{{0x184B, 0x184B}}, // Restart/Restore buttons
{{0x55C0, 0x5680}}, // Player midswing animation
{{0x55C9, 0x5689}}, // Player mid-level defend
{{0x55D2, 0x5692}}, // Player high-level strike
{{0x55DB, 0x569B}}, // Player high-level defend
{{0x55E4, 0x56A4}}, // Player low-level strike
{{0x55ED, 0x56AD}}, // Player low-level defend
{{0x55F6, 0x56B6}}, // Player fight animation
{{0x55FF, 0x56BF}}, // Pig fight animation
{{0x5608, 0x56C8}}, // Pig fight animation
{{0x5611, 0x56D1}}, // Player mid-level strike
{{0x5623, 0x56E3}}, // Pig fight animation
{{0x562C, 0x56EC}}, // Misc fight animation
{{0x5635, 0x56F5}}, // Pig fight animation
{{0x563E, 0x56FE}}, // Player recoiling from hit
{{0x5647, 0x5707}}, // Pig recoiling from hit
{{0x5650, 0x5710}}, // Pig dies
{{0x5810, 0x58D0}}, // Voice bubble
{{0x5915, 0x59D5}}, // Blacksmith hammering
{{0x59E4, 0x5AA4}}, // Ewan's standard animation
{{0x59ED, 0x5AAD}}, // Ewan's alternate animation
{{0x59FF, 0x5ABF}}, // Dragon breathing fire
{{0x5A08, 0x5AC8}}, // Dragon breathing fire 2
{{0x5A11, 0x5AD1}}, // Dragon breathing fire 3
{{0x5A1A, 0x5ADA}}, // Player turning winch in room #48
{{0x5A59, 0x5B19}}, // Player pulling lever in room #48
{{0x5A62, 0x5B22}}, // Minnow pulling lever in room #48
{{0x5AAA, 0x5B6A}}, // Goewin mixing potion
{{0x5C80, 0x5D40}}, // Player standard animation
{{0x5C95, 0x5D55}}, // Player operating rack
{{0x5CAA, 0x5D6A}}, // Selena animation
{{0x5CE9, 0x5DA9}}, // Blacksmith default
{{0x5D28, 0x5DE8}}, // Goewin animation
{{0, 0}}
{{0x1830, 0x1830, 0x1830, 0x1830}}, // Copy protection header
{{0x1839, 0x1839, 0x1839, 0x1839}}, // Copy protection wording header
{{0x1842, 0x1842, 0x1842, 0x1842}}, // Copy protection numbers
{{0x184B, 0x184B, 0x184B, 0x184B}}, // Restart/Restore buttons
{{0x55C0, 0x5680, 0x56A0, 0x56C0}}, // Player midswing animation
{{0x55C9, 0x5689, 0x56A9, 0x56C9}}, // Player mid-level defend
{{0x55D2, 0x5692, 0x56B2, 0x56D2}}, // Player high-level strike
{{0x55DB, 0x569B, 0x56BB, 0x56DB}}, // Player high-level defend
{{0x55E4, 0x56A4, 0x56C4, 0x56E4}}, // Player low-level strike
{{0x55ED, 0x56AD, 0x56CD, 0x56ED}}, // Player low-level defend
{{0x55F6, 0x56B6, 0x56D6, 0x56F6}}, // Player fight animation
{{0x55FF, 0x56BF, 0x56DF, 0x56FF}}, // Pig fight animation
{{0x5608, 0x56C8, 0x56E8, 0x5708}}, // Pig fight animation
{{0x5611, 0x56D1, 0x56F1, 0x5711}}, // Player mid-level strike
{{0x5623, 0x56E3, 0x5703, 0x5723}}, // Pig fight animation
{{0x562C, 0x56EC, 0x570C, 0x572C}}, // Misc fight animation
{{0x5635, 0x56F5, 0x5705, 0x5735}}, // Pig fight animation
{{0x563E, 0x56FE, 0x571E, 0x573E}}, // Player recoiling from hit
{{0x5647, 0x5707, 0x5727, 0x5747}}, // Pig recoiling from hit
{{0x5650, 0x5710, 0x5730, 0x5750}}, // Pig dies
{{0x5810, 0x58D0, 0x58F0, 0x5910}}, // Voice bubble
{{0x5915, 0x59D5, 0x59F5, 0x5a15}}, // Blacksmith hammering
{{0x59E4, 0x5AA4, 0x5AC4, 0x5ae4}}, // Ewan's standard animation
{{0x59ED, 0x5AAD, 0x5ACD, 0x5aed}}, // Ewan's alternate animation
{{0x59FF, 0x5ABF, 0x5ADF, 0x5aff}}, // Dragon breathing fire
{{0x5A08, 0x5AC8, 0x5AE8, 0x5b08}}, // Dragon breathing fire 2
{{0x5A11, 0x5AD1, 0x5AF1, 0x5b11}}, // Dragon breathing fire 3
{{0x5A1A, 0x5ADA, 0x5AFA, 0x5b1a}}, // Player turning winch in room #48
{{0x5A59, 0x5B19, 0x5B39, 0x5b59}}, // Player pulling lever in room #48
{{0x5A62, 0x5B22, 0x5B42, 0x5b62}}, // Minnow pulling lever in room #48
{{0x5AAA, 0x5B6A, 0x5B8A, 0x5baa}}, // Goewin mixing potion
{{0x5C80, 0x5D40, 0x5D60, 0x5d80}}, // Player standard animation
{{0x5C95, 0x5D55, 0x5D75, 0x5d95}}, // Player operating rack
{{0x5CAA, 0x5D6A, 0x5D8A, 0x5daa}}, // Selena animation
{{0x5CE9, 0x5DA9, 0x5DC9, 0x5de9}}, // Blacksmith default
{{0x5D28, 0x5DE8, 0x5E08, 0x5e28}}, // Goewin animation
{{0, 0, 0, 0}}
};
void errorExit(const char *msg) {
printf("%s\n", msg);
exit(1);
}
void add_anim_record(uint16 offset) {
for (int ctr = 0; ctr < animIndex; ++ctr)
if (animOffsets[ctr] == offset) return;
@ -119,6 +126,9 @@ void add_anim_record(uint16 offset) {
// language in at the start, so they'll be at fixed indexes
int index = 0;
if (language == IT_ITA) index = 1;
else if (language == FR_FRA) index = 2;
else if (language == DE_DEU) index = 3;
else if (language != EN_ANY) errorExit("add_anim_record: Unknown language");
AnimListRecord *p = &animDataList[0];
while (p->languages[index] != 0) {
@ -144,6 +154,9 @@ void read_basic_palette(byte *&data, uint16 &totalSize) {
totalSize = PALETTE_SIZE;
uint16 dataStart = 0xC0A7;
if (language == IT_ITA) dataStart = 0xC107;
else if (language == FR_FRA) dataStart = 0xC4B7;
else if (language == DE_DEU) dataStart = 0xC517;
else if (language != EN_ANY) errorExit("read_basic_palette: Unknown language");
lureExe.seek(dataStart);
data = (byte *) malloc(totalSize);
@ -168,6 +181,9 @@ void read_replacement_palette(byte *&data, uint16 &totalSize) {
void read_dialog_data(byte *&data, uint16 &totalSize) {
uint32 segmentStart = 0x1dcb0;
if (language == IT_ITA) segmentStart = 0x1ddd0;
else if (language == FR_FRA) segmentStart = 0x1e1a0;
else if (language == DE_DEU) segmentStart = 0x1e230;
else if (language != EN_ANY) errorExit("read_dialog_data: Unknown language");
totalSize = DIALOG_SIZE;
lureExe.seek(segmentStart);
@ -178,6 +194,9 @@ void read_dialog_data(byte *&data, uint16 &totalSize) {
void read_talk_dialog_data(byte *&data, uint16 &totalSize) {
uint32 segmentStart = 0x1de00;
if (language == IT_ITA) segmentStart = 0x1df20;
else if (language == FR_FRA) segmentStart = 0x1e2f0;
else if (language == DE_DEU) segmentStart = 0x1e380;
else if (language != EN_ANY) errorExit("read_talk_dialog_data: Unknown language");
totalSize = TALK_DIALOG_SIZE;
lureExe.seek(segmentStart);
@ -198,9 +217,23 @@ void read_room_data(byte *&data, uint16 &totalSize) {
uint16 dataStart = 0xbf40;
uint16 walkAreaOffset = 0x2eb1;
if (language == IT_ITA) {
switch (language) {
case EN_ANY:
break;
case IT_ITA:
dataStart = 0xc000;
walkAreaOffset = 0x2ec0;
break;
case FR_FRA:
dataStart = 0xc020;
walkAreaOffset = 0x2ed0;
break;
case DE_DEU:
dataStart = 0xc050;
walkAreaOffset = 0x2edf;
break;
default:
errorExit("read_room_data: Unknown language");
}
for (int index = 0; index < ROOM_NUM_ENTRIES; ++index) {
@ -305,11 +338,31 @@ uint16 italianTickProcOffsets[] = {
0xffff
};
uint16 frenchTickProcOffsets[] = {
0x457b, 0x5340, 0x6202, 0x661c, 0x692f, 0x75fb, 0x8008, 0x8018, 0x82f8, 0x8300,
0x8335, 0x8338, 0x8352, 0x8367, 0x839f, 0x8407, 0x84c4, 0x853d, 0x857e, 0x85b1,
0x85f1, 0x860c, 0x863f, 0x869e, 0x89cf, 0x8a2e, 0x8a5b, 0x8afb, 0x8b00, 0x8b1f,
0x8b3e, 0x8b43, 0x8b48, 0x8bb4, 0x8bed, 0x8c26, 0x8ebe, 0x9c41, 0x9cca,
0xffff
};
uint16 germanTickProcOffsets[] = {
0x4543, 0x5308, 0x61ca, 0x65e4, 0x68fa, 0x7591, 0x7f9e, 0x7fae, 0x8358, 0x8360,
0x8395, 0x8398, 0x83b2, 0x83c7, 0x83ff, 0x8467, 0x8524, 0x859d, 0x85de, 0x8611,
0x8651, 0x866c, 0x869f, 0x86fe, 0x8a2c, 0x8a8b, 0x8ab8, 0x8b58, 0x8b5d, 0x8b7c,
0x8b9b, 0x8ba0, 0x8ba5, 0x8c11, 0x8c4a, 0x8c83, 0x8f1a, 0x9c9b, 0x9d24,
0xffff
};
uint16 englishOffsets[4] = {0x5d98, 0x5eb8, 0x623e, 0x63b1};
uint16 italianOffsets[4] = {0x5e58, 0x5f78, 0x62fe, 0x6471};
uint16 frenchOffsets[4] = {0x5e78, 0x5f98, 0x631e, 0x6491};
uint16 germanOffsets[4] = {0x5ea8, 0x5fc8, 0x634e, 0x64c1};
uint16 englishLoadOffsets[] = {0x3afe, 0x41BD, 0x7167, 0x7172, 0x8617, 0x88ac, 0};
uint16 italianLoadOffsets[] = {0x3b46, 0x4205, 0x71af, 0x71ba, 0x8675, 0x890a, 0};
uint16 frenchLoadOffsets[] = {0x3ebc, 0x457B, 0x755b, 0x7566, 0x8a18, 0x8ca8, 0};
uint16 germanLoadOffsets[] = {0x3e84, 0x4543, 0x74f1, 0x74fc, 0x8a75, 0x8d05, 0};
void read_hotspot_data(byte *&data, uint16 &totalSize) {
uint16 startId[4] = {0x3e8, 0x408, 0x2710, 0x7530};
@ -329,11 +382,30 @@ void read_hotspot_data(byte *&data, uint16 &totalSize) {
uint16 *procList = &englishTickProcOffsets[0];
uint16 *loadOffsets = &englishLoadOffsets[0];
uint16 walkToOffset = 0xBC4B;
if (language == IT_ITA) {
switch (language) {
case EN_ANY:
break;
case IT_ITA:
offsets = &italianOffsets[0];
procList = &italianTickProcOffsets[0];
walkToOffset = 0xBD0B;
loadOffsets = &italianLoadOffsets[0];
break;
case FR_FRA:
offsets = &frenchOffsets[0];
procList = &frenchTickProcOffsets[0];
walkToOffset = 0xBD2B;
loadOffsets = &frenchLoadOffsets[0];
break;
case DE_DEU:
offsets = &germanOffsets[0];
procList = &germanTickProcOffsets[0];
walkToOffset = 0xBD5B;
loadOffsets = &germanLoadOffsets[0];
break;
default:
errorExit("read_hotspot_data: Unknown language");
break;
}
// Allocate enough space for output hotspot list
@ -553,6 +625,9 @@ void read_room_exits(byte *&data, uint16 &totalSize) {
uint16 dataStart = 0x2F61;
if (language == IT_ITA) dataStart = 0x2f70;
else if (language == FR_FRA) dataStart = 0x2f80;
else if (language == DE_DEU) dataStart = 0x2f8f;
else if (language != EN_ANY) errorExit("read_room_exits: Unknown language");
lureExe.seek(dataSegment + dataStart);
for (roomCtr = 0; roomCtr < NUM_ROOM_EXITS; ++roomCtr)
@ -622,6 +697,10 @@ void read_room_exit_joins(byte *&data, uint16 &totalSize) {
uint16 dataStart = 0xce30;
if (language == IT_ITA) dataStart = 0xcef0;
else if (language == FR_FRA) dataStart = 0xcf10;
else if (language == DE_DEU) dataStart = 0xcf40;
else if (language != EN_ANY) errorExit("read_room_exit_joins: Unknown language");
lureExe.seek(dataSegment + dataStart);
do {
@ -771,6 +850,9 @@ void read_anim_data(byte *&data, uint16 &totalSize) {
void read_script_data(byte *&data, uint16 &totalSize) {
uint32 scriptSegment = 0x1df00;
if (language == IT_ITA) scriptSegment = 0x1e020;
else if (language == FR_FRA) scriptSegment = 0x1e3f0;
else if (language == DE_DEU) scriptSegment = 0x1e480;
else if (language != EN_ANY) errorExit("read_script_data: Unknown language");
lureExe.seek(scriptSegment);
totalSize = SCRIPT_SEGMENT_SIZE;
@ -781,6 +863,9 @@ void read_script_data(byte *&data, uint16 &totalSize) {
void read_script2_data(byte *&data, uint16 &totalSize) {
uint32 scriptSegment = 0x19c70;
if (language == IT_ITA) scriptSegment = 0x19D90;
else if (language == FR_FRA) scriptSegment = 0x1a160;
else if (language == DE_DEU) scriptSegment = 0x1a1f0;
else if (language != EN_ANY) errorExit("read_script2_data: Unknown language");
lureExe.seek(scriptSegment);
totalSize = SCRIPT2_SEGMENT_SIZE;
@ -791,6 +876,9 @@ void read_script2_data(byte *&data, uint16 &totalSize) {
void read_hotspot_script_offsets(byte *&data, uint16 &totalSize) {
uint16 dataStart = 0x57e0;
if (language == IT_ITA) dataStart = 0x58a0;
else if (language == FR_FRA) dataStart = 0x58c0;
else if (language == DE_DEU) dataStart = 0x58f0;
else if (language != EN_ANY) errorExit("read_hotspot_script_offsets: Unknown language");
lureExe.seek(dataSegment + dataStart);
totalSize = HOTSPOT_SCRIPT_SIZE;
@ -799,7 +887,13 @@ void read_hotspot_script_offsets(byte *&data, uint16 &totalSize) {
}
void read_messages_segment(byte *&data, uint16 &totalSize) {
lureExe.seek(MESSAGES_SEGMENT);
uint32 scriptSegment = 0x20b60;
if (language == IT_ITA) scriptSegment = 0x20c80;
else if (language == FR_FRA) scriptSegment = 0x21050;
else if (language == DE_DEU) scriptSegment = 0x210E0;
else if (language != EN_ANY) errorExit("read_messages_segment: Unknown language");
lureExe.seek(scriptSegment);
totalSize = MESSAGES_SEGMENT_SIZE;
data = (byte *) malloc(totalSize);
lureExe.read(data, totalSize);
@ -856,6 +950,9 @@ void read_talk_headers(byte *&data, uint16 &totalSize) {
uint16 dataStart = 0x505c;
if (language == IT_ITA) dataStart = 0x511C;
else if (language == FR_FRA) dataStart = 0x513c;
else if (language == DE_DEU) dataStart = 0x515c;
else if (language != EN_ANY) errorExit("read_talk_headers: Unknown language");
lureExe.seek(dataSegment + dataStart);
lureExe.read(&entries[0], sizeof(TalkEntry) * TALK_NUM_ENTRIES);
@ -927,9 +1024,11 @@ struct TalkRecord {
uint16 responsesOffset;
};
#define NUM_GIVE_TALK_IDS 7
#define NUM_GIVE_TALK_IDS 6
uint16 englishGiveTalkIds[7] = {0xCF5E, 0xCF14, 0xCF90, 0xCFAA, 0xCFD0, 0xCFF6, 0xf010};
uint16 italianGiveTalkIds[7] = {0xD01E, 0xCFD4, 0xD050, 0xD06A, 0xD090, 0xD0B6, 0xf0d0};
uint16 frenchGiveTalkIds[7] = {0xD03E, 0xCFF4, 0xD070, 0xD08A, 0xD0B0, 0xD0D6, 0xf0f0};
uint16 germanGiveTalkIds[7] = {0xD06E, 0xD024, 0xD0A0, 0xD0BA, 0xD0E0, 0xD106, 0xf120};
void read_talk_data(byte *&data, uint16 &totalSize) {
uint16 responseOffset;
@ -938,6 +1037,9 @@ void read_talk_data(byte *&data, uint16 &totalSize) {
uint16 *giveTalkIds = &englishGiveTalkIds[0];
if (language == IT_ITA) giveTalkIds = &italianGiveTalkIds[0];
else if (language == FR_FRA) giveTalkIds = &frenchGiveTalkIds[0];
else if (language == DE_DEU) giveTalkIds = &germanGiveTalkIds[0];
else if (language != EN_ANY) errorExit("read_talk_data: Unknown language");
data = (byte *) malloc(MAX_DATA_SIZE);
uint16 *v = (uint16 *) data;
@ -1052,6 +1154,9 @@ void read_talk_data(byte *&data, uint16 &totalSize) {
void read_room_pathfinding_data(byte *&data, uint16 &totalSize) {
uint16 dataStart = 0x984A;
if (language == IT_ITA) dataStart = 0x990A;
else if (language == FR_FRA) dataStart = 0x992A;
else if (language == DE_DEU) dataStart = 0x995a;
else if (language != EN_ANY) errorExit("read_room_pathfinding_data: Unknown language");
lureExe.seek(dataSegment + dataStart);
totalSize = PATHFIND_SIZE;
@ -1108,6 +1213,9 @@ void read_room_exit_hotspots_data(byte *&data, uint16 &totalSize) {
uint16 dataStart = 0x2E57;
if (language == IT_ITA) dataStart = 0x2E66;
else if (language == FR_FRA) dataStart = 0x2e76;
else if (language == DE_DEU) dataStart = 0x2e85;
else if (language != EN_ANY) errorExit("read_room_exit_hotspots_data: Unknown language");
lureExe.seek(dataSegment + dataStart);
lureExe.read(rec, sizeof(RoomExitIndexedHotspotResource));
@ -1124,6 +1232,9 @@ void read_room_exit_hotspots_data(byte *&data, uint16 &totalSize) {
void save_fight_segment(byte *&data, uint16 &totalSize) {
uint32 fightSegment = 0x1C400;
if (language == IT_ITA) fightSegment = 0x1c520;
else if (language == FR_FRA) fightSegment = 0x1c8f0;
else if (language == DE_DEU) fightSegment = 0x1c980;
else if (language != EN_ANY) errorExit("save_fight_segment: Unknown language");
lureExe.seek(fightSegment);
totalSize = FIGHT_SEGMENT_SIZE;
@ -1140,7 +1251,7 @@ const char *englishTextStrings[NUM_TEXT_ENTRIES] = {
"Slow Text\x8B", "Sound on", "Sound off", "(nothing)", " for ", " to ", " on ",
"and then", "finish", "Are you sure (y/n)?",
"a ", "the ", "a ", "a ", "an ", "an ", "an ", "an ",
"You are carrying ", "nothing", "You have ", "groat", "groats",
"You are carrying ", "nothing", "You have ", "groat", "groats"
};
const char *italianTextStrings[NUM_TEXT_ENTRIES] = {
@ -1153,14 +1264,52 @@ const char *italianTextStrings[NUM_TEXT_ENTRIES] = {
"(niente)", " per ", " a ", " su ",
"e poi", "finito", "Sei sicuro (s/n)?",
NULL, "l' ", "la ", NULL, "le ", "i ", "il ", NULL,
"Stai portando ", "niente", "e hai ", "soldi", "soldis",
"Stai portando ", "niente", "e hai ", "soldi", "soldis"
};
const char frenchUnlockStr[] = {'D', '\x7f', 'v', 'e', 'r', 'r', 'o', 'u', 'i', 'l', 'l', 'e', '\0'};
const char frenchCreditsStr[] = {'C', 'r', '\x7f', 'd', 'i', 't', 's', '\0'};
const char *frenchTextStrings[NUM_TEXT_ENTRIES] = {
"Prends", NULL, "Pousse", "Tire", "Actionne", "Ouvre", "Ferme", "Verrouille",
frenchUnlockStr, "Utilise", "Donne", "Parle \0x81", "Dis \x81", NULL,
"Regarde", "Observe", "Regarde par", "Demande \x81", NULL, "Bois", "Statut",
"Va \x81", "Reviens", "Corromps", "Examine",
frenchCreditsStr, "Recommencer", "Sauvegarder", "Restituer", "Quitter",
"Texte rapide\x8b", "Texte lent \x8b", "Avec son", "Sans son",
"(rien)", " avec ", " \x81 ", " sur ", "et puis", "fin",
"Vous \x83tes s\x89r (o/n)?",
NULL, "la", "le", "l'", "les", NULL, NULL, NULL,
"Vous avez ", "rien", "et vous avez ", "sou", "sous"
};
const char *germanTextStrings[NUM_TEXT_ENTRIES] = {
"Nimm", NULL, "Schiebe", "Ziehe", "Bet\x8dtige", "\x90" "ffne", "Schlie\x92h" "e",
"Sperre", "Steck Schl\x8cssel in", "Benutze", "Gib", "Sprich mit", "Befehl an",
NULL, "Betrachte", "Betrachte", "Schau durch", "Verlange", NULL, "Trink",
"Status", "Geh zu", "Zur\x8c" "ck", "Besteche", "Untersuche",
"Mitwirkende", "Spiel neu starten", "Spiel sichern", "Gesichertes Spiel laden",
"Abbrechen", "Schneller Text\x8b",
"Langsamer Text\x8b", "Sound an", "Sound aus", "(nichts)", " nach ", " an ", " f\x8cr ",
"und dann", "Schlu\x92", "Sicher (j/n)?",
NULL, "keinen ", "keine ", "kein ", "der ", "die ", "das ", "den ",
"Du tr\x8dgst", "niets", "und du hast ", "silberm\x8cnzen", "silberm\x8cnzen"
};
int slen(const char *s) {
int total = 0;
while (*s++ != '\0') ++total;
return total;
}
void save_text_strings(byte *&data, uint16 &totalSize) {
int index;
const char **textStrings = &englishTextStrings[0];
if (language == IT_ITA) textStrings = &italianTextStrings[0];
else if (language == FR_FRA) textStrings = &frenchTextStrings[0];
else if (language == DE_DEU) textStrings = &germanTextStrings[0];
else if (language != EN_ANY) errorExit("save_text_strings: Unknown language");
// Calculate the total needed space
totalSize = sizeof(uint16);
@ -1188,6 +1337,9 @@ void save_text_strings(byte *&data, uint16 &totalSize) {
void save_sound_desc_data(byte *&data, uint16 &totalSize) {
uint16 dataStart = 0x5671;
if (language == IT_ITA) dataStart = 0x5731;
else if (language == FR_FRA) dataStart = 0x5751;
else if (language == DE_DEU) dataStart = 0x5781;
else if (language != EN_ANY) errorExit("save_sound_desc_data: Unknown language");
lureExe.seek(dataSegment + dataStart);
totalSize = SOUND_DESCS_SIZE;
@ -1264,9 +1416,101 @@ const DecoderEntry italianDecoders[] = {
{NULL, '\0'}
};
const DecoderEntry frenchDecoders[] = {
{"00", (char) 0x20}, {"0100", (char) 0x65}, {"0101", (char) 0x73}, {"0110", (char) 0x61}, {"01110", (char) 0x69},
{"011110", (char) 0x6E}, {"011111", (char) 0x72}, {"1000", (char) 0x6F}, {"10010", (char) 0x74},
{"100110", (char) 0x75}, {"100111", (char) 0x70}, {"10100", (char) 0x6C}, {"10101", (char) 0x6D},
{"101100", (char) 0x63}, {"101101", (char) 0x76}, {"101110", (char) 0x00}, {"1011110", (char) 0x2E},
{"1011111", (char) 0x7F}, {"110000", (char) 0xAA}, {"110001", (char) 0x27}, {"110010", (char) 0x64},
{"1100110", (char) 0xB8}, {"1100111", (char) 0x2C}, {"110100", (char) 0x62}, {"1101010", (char) 0x68},
{"11010110", (char) 0x66}, {"11010111", (char) 0xBE}, {"1101100", (char) 0x21}, {"1101101", (char) 0xB0},
{"1101110", (char) 0x67}, {"11011110", (char) 0xF2}, {"11011111", (char) 0xC5}, {"1110000", (char) 0xC0},
{"11100010", (char) 0x6A}, {"11100011", (char) 0xA5}, {"1110010", (char) 0xB1}, {"11100110", (char) 0x4C},
{"111001110", (char) 0x2D}, {"111001111", (char) 0x4A}, {"1110100", (char) 0xBD}, {"11101010", (char) 0x3F},
{"111010110", (char) 0x71}, {"111010111", (char) 0xB5}, {"11101100", (char) 0x81}, {"111011010", (char) 0x43},
{"111011011", (char) 0x45}, {"11101110", (char) 0x85}, {"111011110", (char) 0xC4}, {"1110111110", (char) 0x4D},
{"1110111111", (char) 0x79}, {"11110000", (char) 0xBC}, {"111100010", (char) 0xBA}, {"111100011", (char) 0xAF},
{"11110010", (char) 0x83}, {"111100110", (char) 0x53}, {"1111001110", (char) 0x56}, {"1111001111", (char) 0xA7},
{"11110100", (char) 0xA6}, {"111101010", (char) 0xB2}, {"1111010110", (char) 0xB7}, {"1111010111", (char) 0xD9},
{"111101100", (char) 0x41}, {"111101101", (char) 0xA3}, {"111101110", (char) 0x4E}, {"1111011110", (char) 0xB4},
{"11110111110", (char) 0x54}, {"11110111111", (char) 0x49}, {"111110000", (char) 0x4F}, {"111110001", (char) 0xBF},
{"111110010", (char) 0x47}, {"1111100110", (char) 0x50}, {"11111001110", (char) 0x7A}, {"11111001111", (char) 0x52},
{"111110100", (char) 0x44}, {"1111101010", (char) 0x55}, {"1111101011", (char) 0x51}, {"1111101100", (char) 0xE0},
{"1111101101", (char) 0xAC}, {"1111101110", (char) 0x78}, {"11111011110", (char) 0xC8}, {"11111011111", (char) 0x42},
{"1111110000", (char) 0xEE}, {"1111110001", (char) 0xC2}, {"1111110010", (char) 0x82}, {"11111100110", (char) 0x87},
{"11111100111", (char) 0x77}, {"1111110100", (char) 0xC7}, {"11111101010", (char) 0xEF}, {"11111101011", (char) 0x80},
{"1111110110", (char) 0xE4}, {"11111101110", (char) 0x89}, {"111111011110", (char) 0xE8}, {"111111011111", (char) 0xA9},
{"11111110000", (char) 0x46}, {"11111110001", (char) 0x48}, {"11111110010", (char) 0xDC},
{"111111100110", (char) 0xAE}, {"111111100111", (char) 0x88}, {"11111110100", (char) 0x6B},
{"111111101010", (char) 0x7E}, {"111111101011", (char) 0x31}, {"11111110110", (char) 0xC3},
{"111111101110", (char) 0xD8}, {"1111111011110", (char) 0x3B}, {"1111111011111", (char) 0xBB},
{"11111111000", (char) 0xCD}, {"111111110010", (char) 0x8A}, {"1111111100110", (char) 0xB3},
{"1111111100111", (char) 0x32}, {"111111110100", (char) 0xC1}, {"111111110101", (char) 0xD0},
{"111111110110", (char) 0x57}, {"1111111101110", (char) 0xB6}, {"1111111101111", (char) 0x25},
{"111111111000", (char) 0xA1}, {"1111111110010", (char) 0xDF}, {"1111111110011", (char) 0xEA},
{"111111111010", (char) 0x35}, {"1111111110110", (char) 0x3A}, {"11111111101110", (char) 0x36},
{"11111111101111", (char) 0x33}, {"1111111111000", (char) 0x39}, {"1111111111001", (char) 0xDB},
{"1111111111010", (char) 0xE6}, {"11111111110110", (char) 0x30}, {"111111111101110", (char) 0x22},
{"111111111101111", (char) 0x34}, {"11111111111000", (char) 0xE3}, {"11111111111001", (char) 0x37},
{"11111111111010", (char) 0x38}, {"111111111110110", (char) 0xD7}, {"111111111110111", (char) 0xCC},
{"11111111111100", (char) 0xD5}, {"111111111111010", (char) 0xE5}, {"1111111111110110", (char) 0x2F},
{"1111111111110111", (char) 0x4B}, {"111111111111100", (char) 0xE9}, {"1111111111111010", (char) 0x59},
{"1111111111111011", (char) 0x28}, {"1111111111111100", (char) 0x29}, {"1111111111111101", (char) 0x5A},
{"11111111111111100", (char) 0x86}, {"11111111111111101", (char) 0x58}, {"11111111111111110", (char) 0x84},
{"11111111111111111", (char) 0xA2},
{NULL, '\0'}
};
const DecoderEntry germanDecoders[] = {
{"000", (char) 0x20}, {"001", (char) 0x65}, {"0100", (char) 0x6E}, {"0101", (char) 0x61}, {"0110", (char) 0x72},
{"01110", (char) 0x69}, {"011110", (char) 0x74}, {"011111", (char) 0x73}, {"10000", (char) 0x68},
{"10001", (char) 0x6C}, {"10010", (char) 0x75}, {"100110", (char) 0x6D}, {"100111", (char) 0xB0},
{"10100", (char) 0x67}, {"101010", (char) 0x00}, {"101011", (char) 0x62}, {"101100", (char) 0x63},
{"101101", (char) 0x2C}, {"101110", (char) 0x6F}, {"1011110", (char) 0xAA}, {"1011111", (char) 0x77},
{"110000", (char) 0x64}, {"110001", (char) 0x2E}, {"110010", (char) 0x6B}, {"1100110", (char) 0x66},
{"1100111", (char) 0xDB}, {"110100", (char) 0x21}, {"1101010", (char) 0x7A}, {"11010110", (char) 0xC5},
{"11010111", (char) 0x8C}, {"1101100", (char) 0x49}, {"11011010", (char) 0xCD}, {"11011011", (char) 0xCC},
{"1101110", (char) 0x53}, {"11011110", (char) 0x45}, {"110111110", (char) 0x57}, {"110111111", (char) 0x8D},
{"1110000", (char) 0xB8}, {"11100010", (char) 0x47}, {"11100011", (char) 0x76}, {"1110010", (char) 0x92},
{"11100110", (char) 0xED}, {"111001110", (char) 0x44}, {"111001111", (char) 0x4D}, {"1110100", (char) 0x70},
{"11101010", (char) 0x48}, {"111010110", (char) 0xD0}, {"111010111", (char) 0xDC}, {"11101100", (char) 0xE8},
{"11101101", (char) 0x3F}, {"11101110", (char) 0x41}, {"111011110", (char) 0xDD}, {"1110111110", (char) 0x8F},
{"1110111111", (char) 0xF2}, {"11110000", (char) 0x42}, {"11110001", (char) 0xEE}, {"11110010", (char) 0x46},
{"111100110", (char) 0x4E}, {"1111001110", (char) 0x4C}, {"1111001111", (char) 0xE9}, {"11110100", (char) 0xEF},
{"111101010", (char) 0x54}, {"111101011", (char) 0xEB}, {"111101100", (char) 0x4B}, {"111101101", (char) 0xD1},
{"111101110", (char) 0xD9}, {"1111011110", (char) 0xD8}, {"1111011111", (char) 0x52}, {"111110000", (char) 0xEC},
{"111110001", (char) 0xE4}, {"111110010", (char) 0xD7}, {"1111100110", (char) 0x55}, {"1111100111", (char) 0xEA},
{"111110100", (char) 0xDF}, {"1111101010", (char) 0xE6}, {"1111101011", (char) 0x5A}, {"111110110", (char) 0x56},
{"1111101110", (char) 0xD5}, {"11111011110", (char) 0xD6}, {"11111011111", (char) 0xE0}, {"111111000", (char) 0x6A},
{"1111110010", (char) 0xA3}, {"1111110011", (char) 0xB1}, {"1111110100", (char) 0x2D}, {"1111110101", (char) 0xC8},
{"1111110110", (char) 0x50}, {"11111101110", (char) 0xE7}, {"111111011110", (char) 0x27},
{"111111011111", (char) 0xD4}, {"1111111000", (char) 0xCE}, {"11111110010", (char) 0x4F},
{"11111110011", (char) 0x79}, {"1111111010", (char) 0xC9}, {"11111110110", (char) 0xAF},
{"111111101110", (char) 0x4A}, {"111111101111", (char) 0xC2}, {"11111111000", (char) 0xC7},
{"111111110010", (char) 0x31}, {"111111110011", (char) 0xDA}, {"111111110100", (char) 0xA1},
{"111111110101", (char) 0x32}, {"111111110110", (char) 0xC4}, {"1111111101110", (char) 0xB5},
{"11111111011110", (char) 0x91}, {"11111111011111", (char) 0xE5}, {"111111111000", (char) 0x25},
{"1111111110010", (char) 0x35}, {"1111111110011", (char) 0x3A}, {"1111111110100", (char) 0x43},
{"1111111110101", (char) 0xE3}, {"1111111110110", (char) 0x36}, {"11111111101110", (char) 0x78},
{"11111111101111", (char) 0x90}, {"1111111111000", (char) 0xE2}, {"11111111110010", (char) 0x33},
{"11111111110011", (char) 0x8E}, {"1111111111010", (char) 0xA7}, {"11111111110110", (char) 0x34},
{"111111111101110", (char) 0x39}, {"111111111101111", (char) 0x30}, {"11111111111000", (char) 0x37},
{"11111111111001", (char) 0x38}, {"11111111111010", (char) 0x71}, {"111111111110110", (char) 0xB7},
{"111111111110111", (char) 0xBA}, {"11111111111100", (char) 0xB2}, {"111111111111010", (char) 0x3B},
{"1111111111110110", (char) 0xAE}, {"1111111111110111", (char) 0x22}, {"111111111111100", (char) 0x2F},
{"1111111111111010", (char) 0x51}, {"1111111111111011", (char) 0xA2}, {"1111111111111100", (char) 0xC3},
{"11111111111111010", (char) 0xBC}, {"11111111111111011", (char) 0x28}, {"111111111111111000", (char) 0x29},
{"111111111111111001", (char) 0x59}, {"11111111111111101", (char) 0xBB}, {"11111111111111110", (char) 0xBD},
{"11111111111111111", (char) 0xC0},
{NULL, '\0'}
};
void save_string_decoder_data(byte *&data, uint16 &totalSize) {
const DecoderEntry *list = &englishDecoders[0];
if (language == IT_ITA) list = &italianDecoders[0];
else if (language == FR_FRA) list = &frenchDecoders[0];
else if (language == DE_DEU) list = &germanDecoders[0];
else if (language != EN_ANY) errorExit("save_string_decoder_data: Unknown language");
totalSize = 1;
const DecoderEntry *pSrc = list;
@ -1543,6 +1787,14 @@ bool validate_executable() {
language = IT_ITA;
dataSegment = 0xACB0;
printf("Detected Italian version\n");
} else if (sumTotal == FRENCH_FILE_CHECKSUM) {
language = FR_FRA;
dataSegment = 0xB060;
printf("Detected French version\n");
} else if (sumTotal == GERMAN_FILE_CHECKSUM) {
language = DE_DEU;
dataSegment = 0xB0C0;
printf("Detected german version\n");
} else {
printf("Lure executable version not recognised. Checksum = %xh\n", sumTotal);
return false;

View file

@ -30,7 +30,7 @@
#include "common/util.h"
#define VERSION_MAJOR 1
#define VERSION_MINOR 24
#define VERSION_MINOR 25
#define DIALOG_SIZE 0x150
@ -54,7 +54,6 @@
#define NUM_ROOM_EXITS 50
#define MESSAGES_SEGMENT 0x20b60
#define MESSAGES_SEGMENT_SIZE 0x490
#define MAX_HOTSPOTS 0x100
@ -419,4 +418,6 @@ extern void add_talk_offset(uint16 offset);
extern Common::Language language;
extern uint16 dataSegment;
extern void errorExit(const char *msg);
#endif

View file

@ -64,6 +64,8 @@ struct JumpOffsetsRecord {
JumpOffsetsRecord jumpOffsets[] = {
{EN_ANY, {0x87be, 0x881c}},
{IT_ITA, {0x881c, 0x887a}},
{FR_FRA, {0x8bbf, 0x8c18}},
{DE_DEU, {0x8c1c, 0x8c75}},
{UNK_LANG, {0, 0}}
};
@ -140,6 +142,19 @@ uint16 process_action_sequence_entry(int supportIndex, byte *data, uint16 remain
if (startOffset == 0x7866) { startOffset = 0x740a; maxOffset = 0x7876; }
if (startOffset == 0x3600) { startOffset = 0x35c6; maxOffset = 0x3622; }
break;
case FR_FRA:
if (startOffset == 0x7eab) { startOffset = 0x7e7d; maxOffset = 0x7ed5; }
if (startOffset == 0x7a88) { startOffset = 0x793c; maxOffset = 0x7ab2; }
if (startOffset == 0x7328) { startOffset = 0x72ae; maxOffset = 0x7382; }
if (startOffset == 0x702f) { startOffset = 0x6f3d; maxOffset = 0x70a3; }
if (startOffset == 0x7886) { startOffset = 0x742a; maxOffset = 0x7896; }
case DE_DEU:
if (startOffset == 0x7edb) { startOffset = 0x7ead; maxOffset = 0x7f05; }
if (startOffset == 0x7ab8) { startOffset = 0x796c; maxOffset = 0x7ae2; }
if (startOffset == 0x7358) { startOffset = 0x72de; maxOffset = 0x73b2; }
if (startOffset == 0x705f) { startOffset = 0x6f6d; maxOffset = 0x70d3; }
if (startOffset == 0x78b6) { startOffset = 0x745a; maxOffset = 0x78c6; }
break;
default:
break;
}
@ -346,6 +361,10 @@ void read_action_sequence(byte *&data, uint16 &totalSize)
// Get a list of the offsets for each room
uint16 raOffset = 0x4D10;
if (language == IT_ITA) raOffset = 0x4dc0;
else if (language == FR_FRA) raOffset = 0x4df0;
else if (language == DE_DEU) raOffset = 0x4de0;
else if (language != EN_ANY) errorExit("read_action_sequence: Unknown language");
lureExe.seek(dataSegment + raOffset, SEEK_SET);
for (roomIndex = 0; roomIndex < RANDOM_ROOM_NUM_ENTRIES; ++roomIndex) {
randomActions[roomIndex].offset = lureExe.readWord();
@ -407,9 +426,18 @@ void read_action_sequence(byte *&data, uint16 &totalSize)
process_entry(0xbc55, data, totalSize);
process_entry(0x712c, data, totalSize);
break;
case FR_FRA:
process_entry(0x13c2, data, totalSize);
process_entry(0xbc75, data, totalSize);
process_entry(0x714c, data, totalSize);
break;
case DE_DEU:
process_entry(0x13c2, data, totalSize);
process_entry(0xbca5, data, totalSize);
process_entry(0x717c, data, totalSize);
break;
default:
printf("Unknown language\n");
exit(1);
errorExit("read_action_sequence: Unknown language");
}
// Process the script engine list
@ -422,6 +450,9 @@ void read_action_sequence(byte *&data, uint16 &totalSize)
uint16 hsOffset = 0x5d98;
if (language == IT_ITA) hsOffset = 0x5e58;
else if (language == FR_FRA) hsOffset = 0x5e78;
else if (language == DE_DEU) hsOffset = 0x5ea8;
else if (language != EN_ANY) errorExit("read_action_sequence: Unknown language");
hotspotIndex = 0;
for (;;) {