From f44874f0a67dab9a45018a16d6fc7bea3def54de Mon Sep 17 00:00:00 2001 From: athrxx Date: Wed, 27 Jul 2011 16:38:31 +0200 Subject: [PATCH] KYRA: add support for Russian Kyra 1 floppy fan translation --- devtools/create_kyradat/create_kyradat.cpp | 7 +- devtools/create_kyradat/create_kyradat.h | 4 +- devtools/create_kyradat/extract.cpp | 58 +++++++++---- devtools/create_kyradat/games.cpp | 90 +++++++++++++++++++++ devtools/create_kyradat/tables.cpp | 65 ++++++++++++++- dists/engine-data/kyra.dat | Bin 366727 -> 385091 bytes engines/kyra/detection_tables.h | 73 ++++++++--------- engines/kyra/items_lok.cpp | 7 ++ engines/kyra/kyra_lok.cpp | 4 + engines/kyra/kyra_v1.h | 1 + engines/kyra/resource.h | 1 + engines/kyra/script_lok.cpp | 5 +- engines/kyra/sequences_lok.cpp | 2 +- engines/kyra/staticres.cpp | 21 ++++- 14 files changed, 276 insertions(+), 62 deletions(-) diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp index 4dc8726d71a0..27cc82efd4f4 100644 --- a/devtools/create_kyradat/create_kyradat.cpp +++ b/devtools/create_kyradat/create_kyradat.cpp @@ -45,7 +45,7 @@ #include enum { - kKyraDatVersion = 77 + kKyraDatVersion = 78 }; const ExtractFilename extractFilenames[] = { @@ -119,6 +119,7 @@ const ExtractFilename extractFilenames[] = { // AUDIO filename table { k1AudioTracks, kTypeStringList, false }, + { k1AudioTracks2, kTypeStringList, false }, { k1AudioTracksIntro, kTypeStringList, false }, // AMULET anim @@ -341,6 +342,7 @@ const TypeTable languageTable[] = { { ES_ESP, 4 }, { IT_ITA, 5 }, { JA_JPN, 6 }, + { RU_RUS, 7 }, { -1, -1 } }; @@ -366,6 +368,7 @@ const TypeTable specialTable[] = { { kTalkieVersion, 1 }, { kDemoVersion, 2 }, { kTalkieDemoVersion, 3 }, + { kOldFloppy, 4 }, { -1, -1 } }; @@ -767,6 +770,8 @@ const char *getIdString(const int id) { return "k1CharacterImageFilenames"; case k1AudioTracks: return "k1AudioTracks"; + case k1AudioTracks2: + return "k1AudioTracks2"; case k1AudioTracksIntro: return "k1AudioTracksIntro"; case k1ItemNames: diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h index 22a6db4b39d3..983ba3c22820 100644 --- a/devtools/create_kyradat/create_kyradat.h +++ b/devtools/create_kyradat/create_kyradat.h @@ -131,6 +131,7 @@ enum kExtractID { k1ConfigStrings, k1AudioTracks, + k1AudioTracks2, k1AudioTracksIntro, k1CreditsStrings, @@ -275,7 +276,8 @@ enum kSpecial { kNoSpecial = 0, kTalkieVersion, kDemoVersion, - kTalkieDemoVersion + kTalkieDemoVersion, + kOldFloppy, }; enum kGame { diff --git a/devtools/create_kyradat/extract.cpp b/devtools/create_kyradat/extract.cpp index 6e39e3da7803..88452ab4fced 100644 --- a/devtools/create_kyradat/extract.cpp +++ b/devtools/create_kyradat/extract.cpp @@ -142,6 +142,18 @@ bool extractRaw(PAKFile &out, const ExtractInformation *info, const byte *data, } bool extractStrings(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id) { + // Skip tables for skipping English string left-overs in the hacky Russian fan translations + static const uint8 rusFanSkip_k2SeqplayStrings[] = { 1, 3, 5, 8, 10, 11, 13, 15, 17, 20, 22, 25, 26, 30, 33, 38, 40, 41, 44, 49, 51, 55, 104, 119, 121, 123 }; + static const uint8 rusFanSkip_k1IntroStrings[] = { 3, 5, 9, 11, 13, 16, 18, 21, 24, 32, 34, 36, 38, 41, 44, 49, 52, 55, 57, 59, 61, 64, 66, 69, 72, 75 }; + static const uint8 rusFanSkip_k1ThePoisonStrings[] = { 1, 4 }; + static const uint8 rusFanSkip_k1FullFlaskStrings[] = { 1, 2, 4, 5, 7 }; + static const uint8 rusFanSkip_k1WispJewelStrings[] = { 2 }; + static const uint8 rusFanSkip_k1GUIStrings[] = { 1, 3, 6, 8, 11, 13, 18 }; + uint32 rusFanSkipIdLen = 0; + const uint8 *rusFanSkipId = 0; + int rusFanEmptyId = 10000; + uint32 skipCount = 0; + int patch = 0; // FM Towns files that need addional patches if (info->platform == kPlatformFMTowns) { @@ -156,18 +168,36 @@ bool extractStrings(PAKFile &out, const ExtractInformation *info, const byte *da if (id == k2IngamePakFiles) patch = 4; - if (id == k2SeqplayStrings && info->lang == Common::RU_RUS) + if (info->lang == Common::RU_RUS) { patch = 5; + if (id == k2SeqplayStrings) { + rusFanSkipId = rusFanSkip_k2SeqplayStrings; + rusFanSkipIdLen = ARRAYSIZE(rusFanSkip_k2SeqplayStrings); + rusFanEmptyId = 81; + } else if (id == k1IntroStrings) { + rusFanSkipId = rusFanSkip_k1IntroStrings; + rusFanSkipIdLen = ARRAYSIZE(rusFanSkip_k1IntroStrings); + rusFanEmptyId = 30; + } else if (id == k1ThePoisonStrings) { + rusFanSkipId = rusFanSkip_k1ThePoisonStrings; + rusFanSkipIdLen = ARRAYSIZE(rusFanSkip_k1ThePoisonStrings); + } else if (id == k1FullFlaskString) { + rusFanSkipId = rusFanSkip_k1FullFlaskStrings; + rusFanSkipIdLen = ARRAYSIZE(rusFanSkip_k1FullFlaskStrings); + } else if (id == k1GUIStrings) { + rusFanSkipId = rusFanSkip_k1GUIStrings; + rusFanSkipIdLen = ARRAYSIZE(rusFanSkip_k1GUIStrings); + } else if (id == k1WispJewelStrings) { + rusFanSkipId = rusFanSkip_k1WispJewelStrings; + rusFanSkipIdLen = ARRAYSIZE(rusFanSkip_k1WispJewelStrings); + } + } // HACK if (id == k2SeqplayIntroTracks && info->game == kLol) return extractStringsWoSuffix(out, info, data, size, filename, id); } - // Skip English string left-overs in the hacky Russian fan translation - static const uint8 rusFanSkipId[] = { 1, 3, 5, 8, 10, 11, 13, 15, 17, 20, 22, 25, 26, 30, 33, 38, 40, 41, 44, 49, 51, 55, 104, 119, 121, 123 }; - uint32 skipCount = 0; - uint32 entries = 0; uint32 targetsize = size + 4; for (uint32 i = 0; i < size; ++i) { @@ -210,26 +240,26 @@ bool extractStrings(PAKFile &out, const ExtractInformation *info, const byte *da } } else if (patch == 5) { ++skipCount; - while (!data[++i]) { - if (skipCount == 81) { + while (!data[i + 1]) { + if (skipCount == rusFanEmptyId) { ++skipCount; ++entries; break; } - if (i == size) + if (++i == size) break; targetsize--; } - for (uint32 ii = 0; ii < ARRAYSIZE(rusFanSkipId); ++ii) { - // Skip English string left-overs in the hacky Russian fan translation + // Skip English string left-overs in the hacky Russian fan translation + for (uint32 ii = 0; ii < rusFanSkipIdLen; ++ii) { if (skipCount == rusFanSkipId[ii]) { ++skipCount; uint32 len = strlen((const char*) data + i); i += len; targetsize = targetsize - 1 - len; - while (!data[++i]) { - if (i == len) + while (!data[i + 1]) { + if (++i == len) break; targetsize--; } @@ -336,7 +366,7 @@ bool extractStrings(PAKFile &out, const ExtractInformation *info, const byte *da ++skipCount; while (!*input) { - if (skipCount == 81) { + if (skipCount == rusFanEmptyId) { *output++ = *input; ++skipCount; } @@ -344,7 +374,7 @@ bool extractStrings(PAKFile &out, const ExtractInformation *info, const byte *da break; } // Skip English string left-overs in the hacky Russian fan translation - for (uint32 ii = 0; ii < ARRAYSIZE(rusFanSkipId); ++ii) { + for (uint32 ii = 0; ii < rusFanSkipIdLen; ++ii) { if (skipCount == rusFanSkipId[ii]) { ++skipCount; input += strlen((const char*)input); diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp index a0db9e8ee17f..1a86ad4729b5 100644 --- a/devtools/create_kyradat/games.cpp +++ b/devtools/create_kyradat/games.cpp @@ -44,6 +44,7 @@ const Game kyra1Games[] = { { kKyra1, { FR_FRA, -1, -1 }, kPlatformPC, kNoSpecial, { "aa9d6d78d8b199deaf48efeca6d19af2", 0 } }, { kKyra1, { IT_ITA, -1, -1 }, kPlatformPC, kNoSpecial, { "5d7550306b369a3492f9f3402702477c", 0 } }, { kKyra1, { ES_ESP, -1, -1 }, kPlatformPC, kNoSpecial, { "9ff130d2558bcd674d4074849d93c362", 0 } }, + { kKyra1, { RU_RUS, -1, -1 }, kPlatformPC, kOldFloppy, { "3b4719e1f8a4d67813b7ada29774aead", 0 } }, // Talkie { kKyra1, { EN_ANY, -1, -1 }, kPlatformPC, kTalkieVersion, { "1ebc18f3e7fbb72474a55cb0fa089ed4", 0 } }, @@ -211,6 +212,93 @@ const int kyra1FloppyNeed[] = { k1NewGameString, k1ConfigStrings, k1AudioTracks, + k1AudioTracks2, + k1AudioTracksIntro, + -1 +}; + +const int kyra1FloppyOldNeed[] = { + k1KallakWritingSeq, + k1MalcolmTreeSeq, + k1WestwoodLogoSeq, + k1KyrandiaLogoSeq, + k1KallakMalcolmSeq, + k1ForestSeq, + k1IntroCPSStrings, + k1IntroCOLStrings, + k1IntroWSAStrings, + k1IntroStrings, + k1RoomList, + k1RoomFilenames, + k1CharacterImageFilenames, + k1DefaultShapes, + k1ItemNames, + k1TakenStrings, + k1PlacedStrings, + k1DroppedStrings, + k1AmuleteAnimSeq, + k1SpecialPalette1, + k1SpecialPalette2, + k1SpecialPalette3, + k1SpecialPalette4, + k1SpecialPalette5, + k1SpecialPalette6, + k1SpecialPalette7, + k1SpecialPalette8, + k1SpecialPalette9, + k1SpecialPalette10, + k1SpecialPalette11, + k1SpecialPalette12, + k1SpecialPalette13, + k1SpecialPalette14, + k1SpecialPalette15, + k1SpecialPalette16, + k1SpecialPalette17, + k1SpecialPalette18, + k1SpecialPalette19, + k1SpecialPalette20, + k1SpecialPalette21, + k1SpecialPalette22, + k1SpecialPalette23, + k1SpecialPalette24, + k1SpecialPalette25, + k1SpecialPalette26, + k1SpecialPalette27, + k1SpecialPalette28, + k1SpecialPalette29, + k1SpecialPalette30, + k1SpecialPalette31, + k1SpecialPalette32, + k1PutDownString, + k1WaitAmuletString, + k1BlackJewelString, + k1HealingTipString, + k1PoisonGoneString, + k1Healing1Shapes, + k1Healing2Shapes, + k1ThePoisonStrings, + k1FluteStrings, + k1PoisonDeathShapes, + k1FluteShapes, + k1Winter1Shapes, + k1Winter2Shapes, + k1Winter3Shapes, + k1DrinkShapes, + k1WispShapes, + k1MagicAnimShapes, + k1BranStoneShapes, + k1WispJewelStrings, + k1MagicJewelStrings, + k1FlaskFullString, + k1FullFlaskString, + k1OutroReunionSeq, + k1OutroHomeString, + k1VeryCleverString, + k1GUIStrings, + k1NewGameString, + k1ConfigStrings, + k1AudioTracks, + k1AudioTracks2, k1AudioTracksIntro, -1 }; @@ -298,6 +386,7 @@ const int kyra1CDNeed[] = { k1NewGameString, k1ConfigStrings, k1AudioTracks, + k1AudioTracks2, k1AudioTracksIntro, -1 }; @@ -941,6 +1030,7 @@ struct GameNeed { const GameNeed gameNeedTable[] = { { kKyra1, kPlatformPC, kNoSpecial, kyra1FloppyNeed }, + { kKyra1, kPlatformPC, kOldFloppy, kyra1FloppyOldNeed }, { kKyra1, kPlatformAmiga, kNoSpecial, kyra1AmigaNeed }, { kKyra1, kPlatformPC, kTalkieVersion, kyra1CDNeed }, diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp index 20f26635534a..40e528267a98 100644 --- a/devtools/create_kyradat/tables.cpp +++ b/devtools/create_kyradat/tables.cpp @@ -68,6 +68,7 @@ const ExtractEntrySearchData k1KyrandiaLogoSeqProvider[] = { const ExtractEntrySearchData k1KallakMalcolmSeqProvider[] = { { UNK_LANG, kPlatformPC, { 0x0000026B, 0x00002132, { { 0x51, 0x07, 0x32, 0xA2, 0x09, 0x47, 0x97, 0x02, 0x85, 0x31, 0x39, 0x93, 0x3A, 0x53, 0x47, 0xA5 } } } }, // floppy + { UNK_LANG, kPlatformPC, { 0x00000267, 0x00002100, { { 0xD9, 0x5E, 0x59, 0xF0, 0x7B, 0xC8, 0xF1, 0x40, 0x4F, 0x68, 0x6F, 0xEC, 0xB5, 0xE8, 0x88, 0xE2 } } } }, // floppy { UNK_LANG, kPlatformUnknown, { 0x0000027B, 0x0000220A, { { 0xB7, 0xC1, 0x57, 0x04, 0x9B, 0x67, 0x82, 0x7B, 0x6E, 0xFD, 0x59, 0xF2, 0x10, 0x93, 0x89, 0x12 } } } }, // CD + Amiga { UNK_LANG, kPlatformUnknown, { 0x000002B8, 0x0000280B, { { 0x98, 0xC8, 0x36, 0x8C, 0xF8, 0x92, 0xC2, 0xB9, 0x1B, 0x71, 0x6B, 0x4C, 0xA4, 0x6C, 0xF6, 0x30 } } } }, // Amiga + CD demo @@ -134,8 +135,9 @@ const ExtractEntrySearchData k1AmuleteAnimSeqProvider[] = { const ExtractEntrySearchData k1OutroReunionSeqProvider[] = { { UNK_LANG, kPlatformPC, { 0x00000547, 0x0000781C, { { 0xCF, 0xD6, 0x1D, 0x3D, 0x14, 0x40, 0x88, 0x35, 0x36, 0x4F, 0x0B, 0x1F, 0x9A, 0x1C, 0x3D, 0xAC } } } }, // floppy + { UNK_LANG, kPlatformPC, { 0x00000547, 0x000077E0, { { 0x80, 0xC4, 0xFC, 0xD5, 0xEB, 0xAA, 0xA5, 0x87, 0x58, 0x5E, 0xAA, 0xE7, 0x01, 0x8F, 0x59, 0x3F } } } }, // floppy { UNK_LANG, kPlatformPC, { 0x000005E5, 0x00008918, { { 0x6A, 0x33, 0x8C, 0xB0, 0x16, 0x57, 0x2D, 0xEB, 0xB2, 0xE1, 0x64, 0x80, 0x98, 0x99, 0x98, 0x19 } } } }, // CD - + { UNK_LANG, kPlatformAmiga, { 0x0000054A, 0x0000785F, { { 0x55, 0xEA, 0xB8, 0x7F, 0x3A, 0x86, 0xCD, 0xA6, 0xBC, 0xA7, 0x9A, 0x39, 0xED, 0xF5, 0x30, 0x0A } } } }, { UNK_LANG, kPlatformUnknown, { 0x00000547, 0x00007876, { { 0x7A, 0xC7, 0x80, 0x34, 0x7A, 0x1B, 0xAB, 0xF8, 0xA7, 0x2F, 0x63, 0x3C, 0xDA, 0x89, 0x3F, 0x82 } } } }, // some floppy DOS + FM-TOWNS @@ -150,6 +152,7 @@ const ExtractEntrySearchData k1IntroCPSStringsProvider[] = { { UNK_LANG, kPlatformUnknown, { 0x00000014, 0x0000071D, { { 0xBA, 0xB6, 0x58, 0xB3, 0x28, 0x5E, 0x9F, 0x77, 0x69, 0x9D, 0x77, 0x53, 0x9D, 0x0D, 0xB0, 0x29 } } } }, // floppy + PC98 { UNK_LANG, kPlatformPC, { 0x00000015, 0x00000786, { { 0xCF, 0x09, 0xE1, 0xD9, 0x8E, 0x34, 0x5D, 0xEA, 0xBC, 0xAC, 0xC4, 0xF4, 0x4A, 0xEC, 0xFF, 0xC1 } } } }, // CD + { UNK_LANG, kPlatformPC, { 0x00000019, 0x000008DB, { { 0x3A, 0xDC, 0x1D, 0xAD, 0xF4, 0x5E, 0xC9, 0x19, 0xE9, 0x84, 0xD1, 0x31, 0x89, 0x6B, 0x6C, 0xF7 } } } }, // Old floppy { UNK_LANG, kPlatformPC, { 0x0000000C, 0x00000413, { { 0xA1, 0xE3, 0x06, 0x53, 0x23, 0x9A, 0xE0, 0xF1, 0xE4, 0xFD, 0xD9, 0x05, 0x22, 0xA6, 0x28, 0x46 } } } }, // demo { UNK_LANG, kPlatformAmiga, { 0x00000016, 0x0000070A, { { 0xD9, 0xDB, 0x91, 0xCD, 0x93, 0x81, 0xC4, 0x3F, 0x14, 0xF1, 0xC5, 0x02, 0xE7, 0x3F, 0x3A, 0x6C } } } }, @@ -194,6 +197,8 @@ const ExtractEntrySearchData k1IntroStringsProvider[] = { { ES_ESP, kPlatformPC, { 0x000005CF, 0x00020415, { { 0xCC, 0xE5, 0x9F, 0xB8, 0xCA, 0xFA, 0x2D, 0x05, 0xB8, 0xAF, 0x9F, 0x1F, 0x8A, 0xA8, 0x56, 0xDE } } } }, + { RU_RUS, kPlatformPC, { 0x000004F6, 0x000131C6, { { 0x77, 0x76, 0x12, 0xB1, 0xDA, 0x9C, 0xA9, 0xB5, 0x21, 0x1E, 0x49, 0x08, 0x46, 0xB3, 0xE4, 0x61 } } } }, + { EN_ANY, kPlatformAmiga, { 0x0000050A, 0x0001A7B1, { { 0x1B, 0x74, 0x71, 0x4C, 0xAB, 0x81, 0x10, 0x59, 0x8A, 0x21, 0x50, 0xBB, 0xFE, 0x6F, 0xD0, 0xE8 } } } }, { DE_DEU, kPlatformAmiga, { 0x00000626, 0x00021319, { { 0x80, 0x55, 0x54, 0x14, 0x5D, 0x6F, 0x49, 0x04, 0x4A, 0xEF, 0x92, 0xB8, 0x5B, 0x01, 0x0F, 0x97 } } } }, @@ -219,6 +224,8 @@ const ExtractEntrySearchData k1OutroHomeStringProvider[] = { { IT_ITA, kPlatformPC, { 0x00000007, 0x000001B8, { { 0x17, 0x95, 0x5B, 0x4F, 0xE2, 0x07, 0x5A, 0x49, 0xFA, 0xCE, 0x53, 0x8B, 0xE7, 0x46, 0x69, 0xC7 } } } }, // (fan) CD + { RU_RUS, kPlatformPC, { 0x00000005, 0x000000EF, { { 0xA0, 0xB4, 0xF2, 0x11, 0x16, 0x92, 0xC8, 0xEB, 0xF2, 0x0C, 0xFE, 0x43, 0xFE, 0x18, 0xF6, 0xBB } } } }, + EXTRACT_END_ENTRY }; @@ -235,6 +242,7 @@ const ExtractEntrySearchData k1RoomListProvider[] = { { UNK_LANG, kPlatformFMTowns, { 0x000064E8, 0x0010312B, { { 0x94, 0x5C, 0x87, 0x35, 0x35, 0x6B, 0x3E, 0xBF, 0x55, 0x3D, 0xDB, 0xD9, 0xFB, 0x97, 0x27, 0x5D } } } }, { UNK_LANG, kPlatformUnknown, { 0x00004DD6, 0x0010312B, { { 0xC6, 0xF0, 0xC4, 0x2C, 0x5A, 0xD7, 0x48, 0xE4, 0x41, 0x23, 0x65, 0x6D, 0xC8, 0xC7, 0xCE, 0xF5 } } } }, // DOS + PC98 + { UNK_LANG, kPlatformUnknown, { 0x00004DD6, 0x0010315D, { { 0x4A, 0x1B, 0xA2, 0x35, 0xE1, 0x22, 0xD3, 0x7A, 0xE9, 0x69, 0x12, 0x3A, 0x9C, 0x92, 0x6F, 0x5C } } } }, // Old DOS floppy { UNK_LANG, kPlatformAmiga, { 0x00004ECC, 0x0010312B, { { 0x9A, 0x91, 0xF1, 0x9C, 0x8A, 0x96, 0x1C, 0x7B, 0xB7, 0xE4, 0xF1, 0xE9, 0x7D, 0xEF, 0x40, 0xBF } } } }, @@ -252,13 +260,19 @@ const ExtractEntrySearchData k1CharacterImageFilenamesProvider[] = { }; const ExtractEntrySearchData k1AudioTracksProvider[] = { - { UNK_LANG, kPlatformPC, { 0x00000041, 0x00000FBF, { { 0xB5, 0xA2, 0x90, 0xE9, 0x73, 0x83, 0x47, 0x5A, 0xB3, 0x3E, 0x04, 0xBB, 0xAA, 0xC8, 0x84, 0x53 } } } }, + { UNK_LANG, kPlatformPC, { 0x00000038, 0x00000D5C, { { 0x65, 0x35, 0x2F, 0xA3, 0x93, 0x22, 0x15, 0xA0, 0xC6, 0x2B, 0x73, 0x7C, 0x3E, 0xB8, 0x7A, 0xB5 } } } }, { UNK_LANG, kPlatformFMTowns, { 0x0000005D, 0x0000154E, { { 0xA7, 0x7E, 0x03, 0x0A, 0x81, 0x54, 0xD2, 0x5D, 0x7B, 0x33, 0x07, 0xBF, 0x70, 0x01, 0x4B, 0x79 } } } }, EXTRACT_END_ENTRY }; +const ExtractEntrySearchData k1AudioTracks2Provider[] = { + { UNK_LANG, kPlatformPC, { 0x00000009, 0x00000363, { { 0x16, 0xA2, 0x68, 0x21, 0x04, 0xA8, 0x39, 0x7E, 0xA1, 0x7D, 0x70, 0xFD, 0x86, 0xC7, 0x69, 0x28 } } } }, + + EXTRACT_END_ENTRY +}; + const ExtractEntrySearchData k1AudioTracksIntroProvider[] = { { UNK_LANG, kPlatformUnknown, { 0x00000006, 0x0000022C, { { 0x5F, 0xC9, 0xE1, 0x4B, 0x34, 0x52, 0xB9, 0xF8, 0xFF, 0x37, 0x8B, 0xF4, 0xEF, 0x5E, 0xC5, 0xDA } } } }, // floppy + demo { UNK_LANG, kPlatformUnknown, { 0x0000000C, 0x00000458, { { 0xEB, 0xB3, 0x96, 0xA5, 0x07, 0xE6, 0x11, 0x58, 0xDB, 0x3F, 0x34, 0x30, 0xFB, 0x7B, 0x92, 0xC8 } } } }, // CD @@ -278,6 +292,8 @@ const ExtractEntrySearchData k1ItemNamesProvider[] = { { ES_ESP, kPlatformPC, { 0x00000530, 0x0001D90A, { { 0x52, 0xFB, 0xA8, 0x3F, 0xA3, 0x6F, 0xC2, 0x67, 0x55, 0x9F, 0x66, 0x9F, 0xFD, 0x79, 0x44, 0xDF } } } }, + { RU_RUS, kPlatformPC, { 0x000004AE, 0x00011888, { { 0x6F, 0x4D, 0xBE, 0xC8, 0xAE, 0x7C, 0x12, 0x3E, 0x69, 0x0B, 0x39, 0xCB, 0x4D, 0x4B, 0xA8, 0x3A } } } }, // floppy + { EN_ANY, kPlatformAmiga, { 0x00000380, 0x00012960, { { 0x2D, 0x81, 0xCF, 0x7A, 0x9D, 0x71, 0x83, 0xB7, 0xE5, 0x00, 0xB0, 0x6E, 0x25, 0x94, 0xCB, 0xA4 } } } }, { DE_DEU, kPlatformAmiga, { 0x000003E5, 0x0001607D, { { 0x6D, 0xBE, 0xAD, 0xE5, 0xD1, 0x41, 0x6C, 0x42, 0x71, 0x79, 0x9C, 0x78, 0x93, 0x84, 0xC8, 0x11 } } } }, @@ -302,6 +318,8 @@ const ExtractEntrySearchData k1TakenStringsProvider[] = { { ES_ESP, kPlatformPC, { 0x00000014, 0x000005D8, { { 0xD6, 0x00, 0x90, 0x6A, 0x75, 0x3B, 0xF1, 0xFE, 0xF4, 0x3E, 0x0E, 0x1D, 0x39, 0xEB, 0x2D, 0xC8 } } } }, + { RU_RUS, kPlatformPC, { 0x00000010, 0x00000262, { { 0x1E, 0x90, 0x20, 0xC8, 0xD3, 0x08, 0x53, 0x4F, 0x28, 0x95, 0x6A, 0xA4, 0x14, 0x37, 0x05, 0xF0 } } } }, + { EN_ANY, kPlatformAmiga, { 0x00000008, 0x00000261, { { 0x93, 0x5B, 0x79, 0xE8, 0x89, 0x8E, 0xB5, 0x37, 0x39, 0x2A, 0xB0, 0x04, 0x98, 0x80, 0x5A, 0x4E } } } }, { DE_DEU, kPlatformAmiga, { 0x0000000E, 0x000004E0, { { 0x52, 0x4D, 0x74, 0x91, 0x70, 0x0D, 0x4C, 0x40, 0x5C, 0x7E, 0xBA, 0xDA, 0x24, 0x49, 0xF3, 0x1A } } } }, @@ -324,8 +342,10 @@ const ExtractEntrySearchData k1PlacedStringsProvider[] = { { IT_ITA, kPlatformPC, { 0x0000000D, 0x0000040D, { { 0x9C, 0x71, 0x53, 0x35, 0xC3, 0xE8, 0x46, 0xB9, 0xD2, 0xFA, 0x1C, 0x8C, 0xC3, 0xFF, 0xBC, 0x1F } } } }, // floppy { IT_ITA, kPlatformPC, { 0x00000011, 0x000003B8, { { 0xC8, 0xA6, 0xE4, 0x8A, 0xF7, 0x4C, 0x3F, 0xA6, 0x24, 0x7F, 0xEF, 0xE4, 0x63, 0x8B, 0x72, 0xF3 } } } }, // (fan) CD - + { ES_ESP, kPlatformPC, { 0x0000000D, 0x00000439, { { 0x57, 0xAE, 0x1C, 0xC1, 0xF5, 0xE8, 0x5B, 0x9E, 0x90, 0x02, 0xB9, 0x8D, 0x86, 0x38, 0xFB, 0xA8 } } } }, + + { RU_RUS, kPlatformPC, { 0x00000009, 0x00000203, { { 0x7D, 0xAE, 0x67, 0x94, 0x8E, 0x73, 0x35, 0xC1, 0x11, 0xB4, 0x55, 0x6E, 0x92, 0x25, 0x39, 0xE4 } } } }, EXTRACT_END_ENTRY }; @@ -344,6 +364,8 @@ const ExtractEntrySearchData k1DroppedStringsProvider[] = { { ES_ESP, kPlatformPC, { 0x00000008, 0x00000261, { { 0x1D, 0xB5, 0xFB, 0x23, 0x94, 0xA7, 0x86, 0x7A, 0xAC, 0x53, 0xDA, 0x6F, 0xCC, 0x41, 0x0F, 0xD7 } } } }, + { RU_RUS, kPlatformPC, { 0x0000000A, 0x000001F5, { { 0xAA, 0x21, 0x88, 0x6D, 0xD0, 0xAB, 0x5C, 0x15, 0x7F, 0xAD, 0x0E, 0x3B, 0x2F, 0x17, 0xBF, 0xAD } } } }, + EXTRACT_END_ENTRY }; @@ -384,6 +406,8 @@ const ExtractEntrySearchData k1PutDownStringProvider[] = { { ES_ESP, kPlatformPC, { 0x0000002D, 0x00001052, { { 0x12, 0x0A, 0x23, 0x11, 0xDF, 0x8A, 0x59, 0xD4, 0xF2, 0xCA, 0xA5, 0xA7, 0x76, 0x1B, 0x54, 0xB6 } } } }, + { RU_RUS, kPlatformPC, { 0x00000024, 0x0000099F, { { 0x05, 0xD7, 0xB8, 0x32, 0x95, 0x93, 0x29, 0x5F, 0xF3, 0x1A, 0xF0, 0x2E, 0xBA, 0x3A, 0x0D, 0x27 } } } }, + EXTRACT_END_ENTRY }; @@ -401,6 +425,8 @@ const ExtractEntrySearchData k1WaitAmuletStringProvider[] = { { ES_ESP, kPlatformPC, { 0x00000042, 0x000017FD, { { 0x0A, 0x8A, 0x7E, 0x9A, 0x5F, 0x4A, 0x35, 0x06, 0x4D, 0x6B, 0xBF, 0x29, 0x1B, 0xAD, 0xD8, 0x37 } } } }, + { RU_RUS, kPlatformPC, { 0x0000003C, 0x00000EF1, { { 0xC1, 0x0A, 0xFA, 0xBB, 0x65, 0xC3, 0x31, 0xC9, 0x80, 0x9B, 0x0C, 0x16, 0xED, 0xBF, 0x47, 0xFA } } } }, + { EN_ANY, kPlatformUnknown, { 0x0000003E, 0x0000150D, { { 0xA8, 0xBF, 0x99, 0x9B, 0xC1, 0x36, 0x21, 0x47, 0x6D, 0x99, 0x4F, 0x34, 0xE6, 0x61, 0x47, 0xFD } } } }, // Amiga + FM-TOWNS EXTRACT_END_ENTRY @@ -420,6 +446,8 @@ const ExtractEntrySearchData k1BlackJewelStringProvider[] = { { ES_ESP, kPlatformPC, { 0x00000025, 0x00000CF6, { { 0x4B, 0x13, 0x39, 0xCB, 0x3F, 0x44, 0x18, 0x46, 0x43, 0xDB, 0x94, 0xC5, 0x3E, 0x6B, 0xC4, 0x74 } } } }, + { RU_RUS, kPlatformPC, { 0x00000021, 0x000007FF, { { 0x3F, 0x26, 0xB4, 0xB4, 0x11, 0x0C, 0xEF, 0xC0, 0x6A, 0xD1, 0xCC, 0x0E, 0x68, 0x7D, 0xA5, 0x1A } } } }, + { EN_ANY, kPlatformUnknown, { 0x00000024, 0x00000B73, { { 0x8D, 0x57, 0x5F, 0x93, 0x85, 0x75, 0xF2, 0xD8, 0x36, 0xC2, 0x7C, 0x0E, 0x3B, 0xEA, 0xE0, 0x0A } } } }, // Amiga + FM-TOWNS EXTRACT_END_ENTRY @@ -438,6 +466,8 @@ const ExtractEntrySearchData k1PoisonGoneStringProvider[] = { { ES_ESP, kPlatformPC, { 0x00000033, 0x0000127E, { { 0x67, 0xEB, 0xD3, 0x00, 0xF8, 0x4F, 0xF1, 0x79, 0x48, 0xE6, 0x9C, 0xB2, 0xA7, 0xCF, 0x76, 0x07 } } } }, + { RU_RUS, kPlatformPC, { 0x00000027, 0x00000952, { { 0x36, 0x64, 0x30, 0x1C, 0x5A, 0xC0, 0x0D, 0x73, 0xE5, 0xA6, 0x2F, 0xD8, 0x64, 0x98, 0x81, 0x56 } } } }, + { EN_ANY, kPlatformAmiga, { 0x0000002E, 0x00000F59, { { 0xAD, 0x95, 0xF3, 0xA7, 0xBB, 0x04, 0x08, 0x77, 0xD0, 0x71, 0xFC, 0x8B, 0x33, 0x2A, 0x6D, 0xD3 } } } }, { DE_DEU, kPlatformAmiga, { 0x00000037, 0x00001324, { { 0xB3, 0xE6, 0x0A, 0x49, 0x37, 0x73, 0x3C, 0xAF, 0x78, 0x9E, 0x7D, 0x13, 0x75, 0xAE, 0xA8, 0x89 } } } }, @@ -463,6 +493,8 @@ const ExtractEntrySearchData k1HealingTipStringProvider[] = { { ES_ESP, kPlatformPC, { 0x00000028, 0x00000E0F, { { 0x3E, 0x40, 0xCA, 0x2A, 0x5F, 0xFE, 0x74, 0x30, 0x8C, 0x31, 0x41, 0x09, 0xBD, 0xFD, 0xA3, 0x7E } } } }, + { RU_RUS, kPlatformPC, { 0x00000026, 0x000008EE, { { 0x7C, 0xC0, 0x62, 0x39, 0x66, 0x9E, 0x63, 0xCD, 0x21, 0x3D, 0x72, 0x91, 0xB8, 0xB9, 0xB6, 0x92 } } } }, + { EN_ANY, kPlatformUnknown, { 0x0000002E, 0x00000F04, { { 0x95, 0x39, 0x36, 0x89, 0xC4, 0x60, 0x7C, 0x0C, 0xDC, 0x06, 0xF7, 0x86, 0x1A, 0xF7, 0x93, 0x2B } } } }, // Amiga + FM-TOWNS EXTRACT_END_ENTRY @@ -483,6 +515,9 @@ const ExtractEntrySearchData k1WispJewelStringsProvider[] = { { ES_ESP, kPlatformPC, { 0x0000005F, 0x0000211E, { { 0xE7, 0x0A, 0x85, 0x25, 0x44, 0x41, 0x47, 0x3B, 0x7A, 0xA6, 0x62, 0xAE, 0xAE, 0xD5, 0x92, 0x45 } } } }, + // only one of two strings translated in the fan translation + { RU_RUS, kPlatformPC, { 0x00000053, 0x0000191F, { { 0x14, 0xEB, 0x38, 0x54, 0x40, 0x40, 0x04, 0xA6, 0xA0, 0xFE, 0xDB, 0xD0, 0x8C, 0xA6, 0x1F, 0x55 } } } }, + { EN_ANY, kPlatformAmiga, { 0x00000056, 0x00001C62, { { 0x43, 0x28, 0x3C, 0x0F, 0x78, 0x52, 0xE7, 0x2A, 0x77, 0xF3, 0x21, 0x5A, 0xF0, 0xFC, 0x9E, 0xF8 } } } }, { DE_DEU, kPlatformAmiga, { 0x00000063, 0x00002184, { { 0x6B, 0xDC, 0x6B, 0xCF, 0xD4, 0xC7, 0x2A, 0x9A, 0x2E, 0x34, 0x71, 0x4E, 0xB7, 0xF6, 0xAF, 0xDA } } } }, @@ -508,6 +543,8 @@ const ExtractEntrySearchData k1MagicJewelStringsProvider[] = { { ES_ESP, kPlatformPC, { 0x00000011, 0x000005CD, { { 0x32, 0x2A, 0xFF, 0x9F, 0x10, 0x75, 0x6B, 0xD6, 0x46, 0xAE, 0x55, 0xD3, 0x68, 0x4F, 0xBB, 0x5A } } } }, + { RU_RUS, kPlatformPC, { 0x00000012, 0x0000047D, { { 0xB1, 0xC3, 0x66, 0xBC, 0x42, 0xAD, 0x5B, 0xD8, 0xF5, 0x3D, 0xB9, 0x50, 0x77, 0x32, 0xA7, 0x15 } } } }, + { EN_ANY, kPlatformUnknown, { 0x00000014, 0x0000069E, { { 0x6A, 0x1C, 0x9B, 0x85, 0x61, 0xC7, 0x28, 0xA9, 0xA3, 0xF4, 0xFA, 0x47, 0x90, 0x8F, 0x06, 0xB4 } } } }, // Amiga + FM-TOWNS EXTRACT_END_ENTRY @@ -525,6 +562,8 @@ const ExtractEntrySearchData k1ThePoisonStringsProvider[] = { { ES_ESP, kPlatformPC, { 0x00000059, 0x00001DF7, { { 0x16, 0x7B, 0x5F, 0x91, 0x06, 0x5B, 0xFC, 0x9C, 0x88, 0x61, 0xCC, 0x1B, 0x52, 0x4F, 0x91, 0xC5 } } } }, + { RU_RUS, kPlatformPC, { 0x00000052, 0x0000136F, { { 0xEF, 0xD2, 0xA0, 0x5F, 0xD5, 0xE6, 0x77, 0x96, 0xFA, 0xC5, 0x60, 0x7C, 0xB7, 0xA8, 0x7C, 0x7A } } } }, + { EN_ANY, kPlatformAmiga, { 0x00000058, 0x00001C24, { { 0xBA, 0x1F, 0xBD, 0x5C, 0x85, 0x3D, 0x3C, 0x92, 0xD1, 0x13, 0xF3, 0x40, 0x2E, 0xBB, 0x1C, 0xE2 } } } }, { DE_DEU, kPlatformAmiga, { 0x00000073, 0x00002690, { { 0x44, 0xAE, 0xC9, 0xFD, 0x9F, 0x8E, 0x1B, 0xDD, 0x3F, 0xE4, 0x4D, 0x4B, 0x5A, 0x13, 0xE5, 0x99 } } } }, @@ -549,6 +588,9 @@ const ExtractEntrySearchData k1FluteStringsProvider[] = { { ES_ESP, kPlatformPC, { 0x00000052, 0x00001D8E, { { 0x9D, 0xA5, 0xF1, 0x42, 0xD1, 0x48, 0xEB, 0x8F, 0x4B, 0xDC, 0xD9, 0x10, 0x55, 0xBD, 0x12, 0xBB } } } }, + // not translated in the fan translation + { RU_RUS, kPlatformPC, { 0x0000003C, 0x00001599, { { 0x96, 0x72, 0x5A, 0x8A, 0xA0, 0xEE, 0xA2, 0xCE, 0x4D, 0x21, 0x01, 0x6C, 0xC5, 0x1A, 0xEB, 0x21 } } } }, + { EN_ANY, kPlatformFMTowns, { 0x0000005A, 0x000024F9, { { 0xCA, 0x1F, 0x62, 0x23, 0x22, 0x25, 0x4A, 0x94, 0x8A, 0x50, 0x59, 0xD5, 0xB4, 0x4E, 0xF1, 0xA6 } } } }, { JA_JPN, kPlatformFMTowns, { 0x00000053, 0x00002745, { { 0x7A, 0xBB, 0xFC, 0x30, 0xB6, 0xCE, 0x61, 0xD4, 0xDB, 0xB0, 0xE6, 0xB2, 0xF4, 0x4D, 0x81, 0x35 } } } }, @@ -571,6 +613,8 @@ const ExtractEntrySearchData k1FlaskFullStringProvider[] = { { ES_ESP, kPlatformPC, { 0x0000001B, 0x0000099D, { { 0x13, 0x23, 0x5D, 0x38, 0x9B, 0xFB, 0x00, 0x5C, 0xA1, 0x3A, 0x22, 0xD6, 0xCD, 0x5C, 0x09, 0xAE } } } }, + { RU_RUS, kPlatformPC, { 0x0000001A, 0x0000066E, { { 0x36, 0x43, 0xB6, 0xB2, 0xED, 0xBA, 0x21, 0x0C, 0x16, 0x54, 0x99, 0xF9, 0x2E, 0x6E, 0x0A, 0x28 } } } }, + EXTRACT_END_ENTRY }; @@ -586,6 +630,8 @@ const ExtractEntrySearchData k1FullFlaskStringProvider[] = { { ES_ESP, kPlatformPC, { 0x0000009A, 0x0000363B, { { 0x38, 0x25, 0xE6, 0xB5, 0xCB, 0x78, 0x5E, 0xAD, 0x2D, 0xD4, 0x2E, 0x8B, 0x89, 0x20, 0xB1, 0x95 } } } }, + { RU_RUS, kPlatformPC, { 0x00000094, 0x0000232B, { { 0xBF, 0x68, 0xF9, 0x8F, 0x82, 0xE9, 0xE7, 0x69, 0x33, 0xD6, 0x41, 0x15, 0x2C, 0xFE, 0x72, 0xAB } } } }, + { EN_ANY, kPlatformAmiga, { 0x0000009A, 0x00003521, { { 0x26, 0xE5, 0xC8, 0x6D, 0x14, 0x81, 0x9F, 0x90, 0x38, 0x3C, 0x00, 0x9D, 0x8E, 0x72, 0xB1, 0x83 } } } }, { DE_DEU, kPlatformAmiga, { 0x000000B0, 0x00003E38, { { 0x8A, 0x6D, 0x42, 0x36, 0x29, 0x06, 0xB2, 0xCE, 0xA3, 0x41, 0x14, 0xE8, 0xB1, 0xEF, 0x6E, 0x3B } } } }, @@ -611,6 +657,9 @@ const ExtractEntrySearchData k1VeryCleverStringProvider[] = { { ES_ESP, kPlatformPC, { 0x00000036, 0x000013F8, { { 0x2D, 0x9B, 0x7D, 0x58, 0xD1, 0x94, 0x04, 0x45, 0x6E, 0x81, 0xCC, 0x1E, 0x2F, 0xC5, 0xC9, 0xEA } } } }, + // not translated in the fan translation + { RU_RUS, kPlatformPC, { 0x00000032, 0x0000118D, { { 0x4B, 0x6D, 0xD4, 0xDC, 0x3E, 0xA2, 0x2D, 0x6D, 0x2C, 0x5A, 0xF7, 0x67, 0x4B, 0x6D, 0x40, 0xEF } } } }, + EXTRACT_END_ENTRY }; @@ -628,6 +677,8 @@ const ExtractEntrySearchData k1NewGameStringProvider[] = { { ES_ESP, kPlatformPC, { 0x0000001B, 0x00000701, { { 0x2B, 0x87, 0xC3, 0x82, 0x68, 0xA5, 0xFC, 0xC5, 0x64, 0x9E, 0xAB, 0xD2, 0x8A, 0x07, 0x9C, 0x1E } } } }, + { RU_RUS, kPlatformPC, { 0x00000015, 0x0000035F, { { 0x7E, 0x49, 0xC1, 0xCB, 0x2D, 0x61, 0xA7, 0x4C, 0x20, 0xAC, 0xEC, 0x54, 0x80, 0x14, 0x6A, 0xCA } } } }, + EXTRACT_END_ENTRY }; @@ -654,7 +705,7 @@ const ExtractEntrySearchData k1Healing2ShapesProvider[] = { const ExtractEntrySearchData k1PoisonDeathShapesProvider[] = { { UNK_LANG, kPlatformUnknown, { 0x0000008C, 0x00002E90, { { 0xBC, 0x44, 0xFB, 0x98, 0xE7, 0x42, 0xF6, 0xC8, 0x87, 0xDD, 0x00, 0x42, 0x85, 0xD8, 0x1E, 0x81 } } } }, - + { UNK_LANG, kPlatformUnknown, { 0x0000008C, 0x00002E7C, { { 0xA5, 0xD7, 0x13, 0xFC, 0x43, 0x22, 0x13, 0xBC, 0x5F, 0x3F, 0xC8, 0x28, 0xDA, 0x04, 0xB0, 0xDD } } } }, // Old Dos Floppy EXTRACT_END_ENTRY }; @@ -931,6 +982,8 @@ const ExtractEntrySearchData k1GUIStringsProvider[] = { { ES_ESP, kPlatformPC, { 0x0000023A, 0x0000C3BD, { { 0xED, 0x0D, 0xE7, 0x5B, 0xDC, 0x21, 0x41, 0x54, 0x68, 0x7D, 0x8E, 0x97, 0x1A, 0xB1, 0xA1, 0x4A } } } }, // floppy + { RU_RUS, kPlatformPC, { 0x000001B1, 0x000065E8, { { 0x91, 0x22, 0x61, 0x8B, 0xCD, 0x7C, 0x0E, 0xD4, 0x32, 0x00, 0xC3, 0x6E, 0x50, 0x7F, 0x3C, 0x82 } } } }, // floppy + { EN_ANY, kPlatformAmiga, { 0x000001DF, 0x00009042, { { 0x0D, 0xD3, 0x1A, 0x92, 0x8D, 0x9C, 0x72, 0x55, 0xEF, 0xFB, 0x81, 0x21, 0x3B, 0x43, 0xA7, 0xE8 } } } }, { DE_DEU, kPlatformAmiga, { 0x00000237, 0x0000BAF7, { { 0xD7, 0x1A, 0x8E, 0xCC, 0x6D, 0x3E, 0xA9, 0xDD, 0x9A, 0x6B, 0x71, 0xFE, 0xD4, 0x50, 0x30, 0x6E } } } }, @@ -957,6 +1010,9 @@ const ExtractEntrySearchData k1ConfigStringsProvider[] = { { ES_ESP, kPlatformPC, { 0x0000004A, 0x00001B7B, { { 0x6B, 0x69, 0x50, 0x92, 0x9B, 0x35, 0x58, 0xE1, 0xEA, 0xBF, 0x42, 0x0B, 0xEB, 0x88, 0x41, 0x8D } } } }, // floppy + // not translated in the fan translation + { RU_RUS, kPlatformPC, { 0x0000003F, 0x00000B0D, { { 0x0E, 0x60, 0x0F, 0x4A, 0xA9, 0xF0, 0x1B, 0x76, 0xBB, 0x33, 0xB2, 0x4B, 0x5C, 0xB5, 0x4A, 0x97 } } } }, // floppy + { EN_ANY, kPlatformAmiga, { 0x0000002E, 0x00000FA1, { { 0x5E, 0xFF, 0xFF, 0x3D, 0xF8, 0x11, 0x6F, 0x3B, 0xC5, 0x39, 0x8F, 0x25, 0x8F, 0x0F, 0xE9, 0x2B } } } }, { DE_DEU, kPlatformAmiga, { 0x00000043, 0x00001783, { { 0xB2, 0x2B, 0xAB, 0x27, 0x06, 0x9A, 0x1E, 0x4B, 0xA7, 0xD3, 0xFF, 0xEB, 0xFD, 0x12, 0xDC, 0x94 } } } }, @@ -1773,6 +1829,7 @@ const ExtractEntry extractProviders[] = { { k1RoomList, k1RoomListProvider }, { k1CharacterImageFilenames, k1CharacterImageFilenamesProvider }, { k1AudioTracks, k1AudioTracksProvider }, + { k1AudioTracks2, k1AudioTracks2Provider }, { k1AudioTracksIntro, k1AudioTracksIntroProvider }, { k1ItemNames, k1ItemNamesProvider }, { k1TakenStrings, k1TakenStringsProvider }, diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat index d3f8f39180d7f5e60d31227b2fdac436b0ffdf02..902d55c457c409bc756d0543f063f638a56f63b0 100644 GIT binary patch delta 23030 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 delta 17784 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 L`*z27>%0FK1!dbw diff --git a/engines/kyra/detection_tables.h b/engines/kyra/detection_tables.h index 2f2c21bc3686..c224c8f46dea 100644 --- a/engines/kyra/detection_tables.h +++ b/engines/kyra/detection_tables.h @@ -21,40 +21,41 @@ namespace { -#define FLAGS(x, y, z, a, b, c, d, id) { Common::UNK_LANG, Common::UNK_LANG, Common::UNK_LANG, Common::kPlatformUnknown, x, y, z, a, b, c, d, id } -#define FLAGS_FAN(fanLang, repLang, x, y, z, a, b, c, d, id) { Common::UNK_LANG, fanLang, repLang, Common::kPlatformUnknown, x, y, z, a, b, c, d, id } - -#define KYRA1_FLOPPY_FLAGS FLAGS(false, false, false, false, false, false, false, Kyra::GI_KYRA1) -#define KYRA1_FLOPPY_CMP_FLAGS FLAGS(false, false, false, false, false, false, true, Kyra::GI_KYRA1) -#define KYRA1_AMIGA_FLAGS FLAGS(false, false, false, false, false, false, false, Kyra::GI_KYRA1) -#define KYRA1_TOWNS_FLAGS FLAGS(false, true, false, false, false, false, false, Kyra::GI_KYRA1) -#define KYRA1_TOWNS_SJIS_FLAGS FLAGS(false, true, false, true, false, false, false, Kyra::GI_KYRA1) -#define KYRA1_CD_FLAGS FLAGS(false, true, true, false, false, false, false, Kyra::GI_KYRA1) -#define KYRA1_DEMO_FLAGS FLAGS(true, false, false, false, false, false, false, Kyra::GI_KYRA1) -#define KYRA1_DEMO_CD_FLAGS FLAGS(true, true, true, false, false, false, false, Kyra::GI_KYRA1) - -#define KYRA2_FLOPPY_FLAGS FLAGS(false, false, false, false, false, false, false, Kyra::GI_KYRA2) -#define KYRA2_FLOPPY_CMP_FLAGS FLAGS(false, false, false, false, false, false, true, Kyra::GI_KYRA2) -#define KYRA2_FLOPPY_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, false, false, false, false, false, false, Kyra::GI_KYRA2) -#define KYRA2_CD_FLAGS FLAGS(false, false, true, false, false, false, false, Kyra::GI_KYRA2) -#define KYRA2_CD_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, false, true, false, false, false, false, Kyra::GI_KYRA2) -#define KYRA2_CD_DEMO_FLAGS FLAGS(true, false, true, false, false, false, false, Kyra::GI_KYRA2) -#define KYRA2_DEMO_FLAGS FLAGS(true, false, false, false, false, false, false, Kyra::GI_KYRA2) -#define KYRA2_TOWNS_FLAGS FLAGS(false, false, false, false, false, false, false, Kyra::GI_KYRA2) -#define KYRA2_TOWNS_SJIS_FLAGS FLAGS(false, false, false, true, false, false, false, Kyra::GI_KYRA2) - -#define KYRA3_CD_FLAGS FLAGS(false, false, true, false, false, true, true, Kyra::GI_KYRA3) -#define KYRA3_CD_INS_FLAGS FLAGS(false, false, true, false, false, true, false, Kyra::GI_KYRA3) -#define KYRA3_CD_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, false, true, false, false, true, false, Kyra::GI_KYRA3) - -#define LOL_CD_FLAGS FLAGS(false, false, true, false, false, false, false, Kyra::GI_LOL) -#define LOL_CD_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, false, true, false, false, false, false, Kyra::GI_LOL) -#define LOL_FLOPPY_FLAGS FLAGS(false, false, false, false, false, false, false, Kyra::GI_LOL) -#define LOL_FLOPPY_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, false, false, false, false, false, false, Kyra::GI_LOL) -#define LOL_FLOPPY_CMP_FLAGS FLAGS(false, false, false, false, false, false, true, Kyra::GI_LOL) -#define LOL_PC98_SJIS_FLAGS FLAGS(false, false, false, true, true, false, false, Kyra::GI_LOL) -#define LOL_DEMO_FLAGS FLAGS(true, true, false, false, false, false, false, Kyra::GI_LOL) -#define LOL_KYRA2_DEMO_FLAGS FLAGS(true, false, false, false, false, false, false, Kyra::GI_KYRA2) +#define FLAGS(x, y, z, a, b, c, d, e, id) { Common::UNK_LANG, Common::UNK_LANG, Common::UNK_LANG, Common::kPlatformUnknown, x, y, z, a, b, c, d, e, id } +#define FLAGS_FAN(fanLang, repLang, x, y, z, a, b, c, d, e, id) { Common::UNK_LANG, fanLang, repLang, Common::kPlatformUnknown, x, y, z, a, b, c, d, e, id } + +#define KYRA1_FLOPPY_FLAGS FLAGS(false, false, false, false, false, false, false, false, Kyra::GI_KYRA1) +#define KYRA1_FLOPPY_CMP_FLAGS FLAGS(false, false, false, false, false, false, false, true, Kyra::GI_KYRA1) +#define KYRA1_OLDFLOPPY_FLAGS FLAGS(false, false, false, true, false, false, false, false, Kyra::GI_KYRA1) +#define KYRA1_AMIGA_FLAGS FLAGS(false, false, false, false, false, false, false, false, Kyra::GI_KYRA1) +#define KYRA1_TOWNS_FLAGS FLAGS(false, true, false, false, false, false, false, false, Kyra::GI_KYRA1) +#define KYRA1_TOWNS_SJIS_FLAGS FLAGS(false, true, false, false, true, false, false, false, Kyra::GI_KYRA1) +#define KYRA1_CD_FLAGS FLAGS(false, true, true, false, false, false, false, false, Kyra::GI_KYRA1) +#define KYRA1_DEMO_FLAGS FLAGS(true, false, false, false, false, false, false, false, Kyra::GI_KYRA1) +#define KYRA1_DEMO_CD_FLAGS FLAGS(true, true, true, false, false, false, false, false, Kyra::GI_KYRA1) + +#define KYRA2_FLOPPY_FLAGS FLAGS(false, false, false, false, false, false, false, false, Kyra::GI_KYRA2) +#define KYRA2_FLOPPY_CMP_FLAGS FLAGS(false, false, false, false, false, false, false, true, Kyra::GI_KYRA2) +#define KYRA2_FLOPPY_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, false, false, false, false, false, false, false, Kyra::GI_KYRA2) +#define KYRA2_CD_FLAGS FLAGS(false, false, true, false, false, false, false, false, Kyra::GI_KYRA2) +#define KYRA2_CD_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, false, true, false, false, false, false, false, Kyra::GI_KYRA2) +#define KYRA2_CD_DEMO_FLAGS FLAGS(true, false, true, false, false, false, false, false, Kyra::GI_KYRA2) +#define KYRA2_DEMO_FLAGS FLAGS(true, false, false, false, false, false, false, false, Kyra::GI_KYRA2) +#define KYRA2_TOWNS_FLAGS FLAGS(false, false, false, false, false, false, false, false, Kyra::GI_KYRA2) +#define KYRA2_TOWNS_SJIS_FLAGS FLAGS(false, false, false, false, true, false, false, false, Kyra::GI_KYRA2) + +#define KYRA3_CD_FLAGS FLAGS(false, false, true, false, false, false, true, true, Kyra::GI_KYRA3) +#define KYRA3_CD_INS_FLAGS FLAGS(false, false, true, false, false, false, true, false, Kyra::GI_KYRA3) +#define KYRA3_CD_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, false, true, false, false, false, true, false, Kyra::GI_KYRA3) + +#define LOL_CD_FLAGS FLAGS(false, false, true, false, false, false, false, false, Kyra::GI_LOL) +#define LOL_CD_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, false, true, false, false, false, false, false, Kyra::GI_LOL) +#define LOL_FLOPPY_FLAGS FLAGS(false, false, false, false, false, false, false, false, Kyra::GI_LOL) +#define LOL_FLOPPY_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, false, false, false, false, false, false, false, Kyra::GI_LOL) +#define LOL_FLOPPY_CMP_FLAGS FLAGS(false, false, false, false, false, false, false, true, Kyra::GI_LOL) +#define LOL_PC98_SJIS_FLAGS FLAGS(false, false, false, false, true, true, false, false, Kyra::GI_LOL) +#define LOL_DEMO_FLAGS FLAGS(true, true, false, false, false, false, false, false, Kyra::GI_LOL) +#define LOL_KYRA2_DEMO_FLAGS FLAGS(true, false, false, false, false, false, false, false, Kyra::GI_KYRA2) const KYRAGameDescription adGameDescs[] = { /* disable these targets until they get supported @@ -156,7 +157,7 @@ const KYRAGameDescription adGameDescs[] = { ADGF_NO_FLAGS, Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIPCSPK }, - KYRA1_FLOPPY_FLAGS + KYRA1_OLDFLOPPY_FLAGS }, { // from VooD { @@ -1438,7 +1439,7 @@ const KYRAGameDescription adGameDescs[] = { LOL_KYRA2_DEMO_FLAGS }, #endif // ENABLE_LOL - { AD_TABLE_END_MARKER, FLAGS(0, 0, 0, 0, 0, 0, 0, 0) } + { AD_TABLE_END_MARKER, FLAGS(0, 0, 0, 0, 0, 0, 0, 0, 0) } }; const PlainGameDescriptor gameList[] = { diff --git a/engines/kyra/items_lok.cpp b/engines/kyra/items_lok.cpp index d66eb553f2e5..105a8efa0d27 100644 --- a/engines/kyra/items_lok.cpp +++ b/engines/kyra/items_lok.cpp @@ -575,7 +575,14 @@ void KyraEngine_LoK::dropItem(int unk1, int item, int x, int y, int unk2) { if (processItemDrop(_currentCharacter->sceneId, item, x, y, unk1, unk2)) return; snd_playSoundEffect(54); + + // Old floppy versions don't print warning messages and don't have the necessary string resources. + // These versions will only play the warning sound effect. + if (_flags.isOldFloppy && !_noDropList) + return; + assert(_noDropList); + if (12 == countItemsInScene(_currentCharacter->sceneId)) drawSentenceCommand(_noDropList[0], 6); else diff --git a/engines/kyra/kyra_lok.cpp b/engines/kyra/kyra_lok.cpp index 7f356f34c104..27d0849e5f91 100644 --- a/engines/kyra/kyra_lok.cpp +++ b/engines/kyra/kyra_lok.cpp @@ -98,6 +98,8 @@ KyraEngine_LoK::KyraEngine_LoK(OSystem *system, const GameFlags &flags) _malcolmFrame = 0; _malcolmTimer1 = _malcolmTimer2 = 0; + + _soundFiles = 0; } KyraEngine_LoK::~KyraEngine_LoK() { @@ -121,6 +123,8 @@ KyraEngine_LoK::~KyraEngine_LoK() { delete _animator; delete _seq; + delete[] _soundFiles; + delete[] _characterList; delete[] _roomTable; diff --git a/engines/kyra/kyra_v1.h b/engines/kyra/kyra_v1.h index 83455f39224d..43a709456db6 100644 --- a/engines/kyra/kyra_v1.h +++ b/engines/kyra/kyra_v1.h @@ -109,6 +109,7 @@ struct GameFlags { bool isDemo : 1; bool useAltShapeHeader : 1; // alternative shape header (uses 2 bytes more, those are unused though) bool isTalkie : 1; + bool isOldFloppy : 1; bool useHiResOverlay : 1; bool use16ColorMode : 1; bool useDigSound : 1; diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h index 1c69362bfd8c..3f64442858c1 100644 --- a/engines/kyra/resource.h +++ b/engines/kyra/resource.h @@ -202,6 +202,7 @@ enum KyraResources { k1ConfigStrings, k1AudioTracks, + k1AudioTracks2, k1AudioTracksIntro, k1CreditsStrings, diff --git a/engines/kyra/script_lok.cpp b/engines/kyra/script_lok.cpp index 2b90d001ca26..ea46958b502c 100644 --- a/engines/kyra/script_lok.cpp +++ b/engines/kyra/script_lok.cpp @@ -558,7 +558,10 @@ int KyraEngine_LoK::o1_setCustomPaletteRange(EMCState *script) { _screen->copyPalette(0, 12); } } else { - _screen->getPalette(1).copy(_specialPalettes[stackPos(0)], 0, stackPos(2), stackPos(1)); + if (!_specialPalettes[stackPos(0)]) + warning("KyraEngine_LoK::o1_setCustomPaletteRange(): Trying to use missing special palette %d", stackPos(0)); + else + _screen->getPalette(1).copy(_specialPalettes[stackPos(0)], 0, stackPos(2), stackPos(1)); } return 0; } diff --git a/engines/kyra/sequences_lok.cpp b/engines/kyra/sequences_lok.cpp index 5f9bd867247e..c26d2e352b07 100644 --- a/engines/kyra/sequences_lok.cpp +++ b/engines/kyra/sequences_lok.cpp @@ -250,7 +250,7 @@ bool KyraEngine_LoK::seq_introStory() { if (!textEnabled() && speechEnabled() && _flags.lang != Common::IT_ITA) return false; - if ((_flags.lang == Common::EN_ANY && !_flags.isTalkie && _flags.platform == Common::kPlatformPC) || _flags.platform == Common::kPlatformAmiga) + if (((_flags.lang == Common::EN_ANY || _flags.lang == Common::RU_RUS) && !_flags.isTalkie && _flags.platform == Common::kPlatformPC) || _flags.platform == Common::kPlatformAmiga) _screen->loadBitmap("TEXT.CPS", 3, 3, &_screen->getPalette(0)); else if (_flags.lang == Common::EN_ANY || _flags.lang == Common::JA_JPN) _screen->loadBitmap("TEXT_ENG.CPS", 3, 3, &_screen->getPalette(0)); diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index c9e994f71e3c..ecb32e68d9a2 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -38,7 +38,7 @@ namespace Kyra { -#define RESFILE_VERSION 77 +#define RESFILE_VERSION 78 namespace { bool checkKyraDat(Common::SeekableReadStream *file) { @@ -90,6 +90,7 @@ const IndexTable iLanguageTable[] = { { Common::ES_ESP, 4 }, { Common::IT_ITA, 5 }, { Common::JA_JPN, 6 }, + { Common::RU_RUS, 7 }, { -1, -1 } }; @@ -111,7 +112,9 @@ byte getPlatformID(const GameFlags &flags) { } byte getSpecialID(const GameFlags &flags) { - if (flags.isDemo && flags.isTalkie) + if (flags.isOldFloppy) + return 4; + else if (flags.isDemo && flags.isTalkie) return 3; else if (flags.isDemo) return 2; @@ -748,7 +751,17 @@ void KyraEngine_LoK::initStaticResource() { _storyStrings = _staticres->loadStrings(k1PC98StoryStrings, _storyStringsSize); - _soundFiles = _staticres->loadStrings(k1AudioTracks, _soundFilesSize); + int size1, size2; + const char *const *soundfiles1 = _staticres->loadStrings(k1AudioTracks, size1); + const char *const *soundfiles2 = _staticres->loadStrings(k1AudioTracks2, size2); + _soundFilesSize = size1 + size2; + if (_soundFilesSize) { + delete[] _soundFiles; + const char **soundfiles = new const char*[_soundFilesSize]; + for (int i = 0; i < _soundFilesSize; i++) + soundfiles[i] = (i < size1) ? soundfiles1[i] : soundfiles2[i - size1]; + _soundFiles = soundfiles; + } _soundFilesIntro = _staticres->loadStrings(k1AudioTracksIntro, _soundFilesIntroSize); _cdaTrackTable = (const int32 *)_staticres->loadRawData(k1TownsCDATable, _cdaTrackTableSize); @@ -926,7 +939,7 @@ void KyraEngine_LoK::loadButtonShapes() { void KyraEngine_LoK::loadMainScreen(int page) { _screen->clearPage(page); - if ((_flags.lang == Common::EN_ANY && !_flags.isTalkie && _flags.platform == Common::kPlatformPC) || _flags.platform == Common::kPlatformAmiga) + if (((_flags.lang == Common::EN_ANY || _flags.lang == Common::RU_RUS) && !_flags.isTalkie && _flags.platform == Common::kPlatformPC) || _flags.platform == Common::kPlatformAmiga) _screen->loadBitmap("MAIN15.CPS", page, page, &_screen->getPalette(0)); else if (_flags.lang == Common::EN_ANY || _flags.lang == Common::JA_JPN || (_flags.isTalkie && _flags.lang == Common::IT_ITA)) _screen->loadBitmap("MAIN_ENG.CPS", page, page, 0);