Skip to content

Commit

Permalink
KYRA: add support for Kyra 2 Russian floppy
Browse files Browse the repository at this point in the history
  • Loading branch information
athrxx committed Jul 25, 2011
1 parent 77908a9 commit f2f6ddc
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 16 deletions.
2 changes: 1 addition & 1 deletion devtools/create_kyradat/create_kyradat.cpp
Expand Up @@ -45,7 +45,7 @@
#include <map>

enum {
kKyraDatVersion = 76
kKyraDatVersion = 77
};

const ExtractFilename extractFilenames[] = {
Expand Down
92 changes: 78 additions & 14 deletions devtools/create_kyradat/extract.cpp
Expand Up @@ -142,25 +142,32 @@ 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) {
int fmtPatch = 0;
int patch = 0;
// FM Towns files that need addional patches
if (info->platform == kPlatformFMTowns) {
if (id == k1TakenStrings || id == k1NoDropStrings || id == k1PoisonGoneString ||
id == k1ThePoisonStrings || id == k1FluteStrings || id == k1WispJewelStrings)
fmtPatch = 1;
patch = 1;
else if (id == k1IntroStrings)
fmtPatch = 2;
patch = 2;
else if (id == k2SeqplayStrings)
fmtPatch = 3;
patch = 3;
} else if (info->platform == kPlatformPC) {
if (id == k2IngamePakFiles)
fmtPatch = 4;
patch = 4;

if (id == k2SeqplayStrings && info->lang == Common::RU_RUS)
patch = 5;

// 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) {
Expand All @@ -183,7 +190,7 @@ bool extractStrings(PAKFile &out, const ExtractInformation *info, const byte *da
break;
targetsize--;
}
if (fmtPatch == 1) {
if (patch == 1) {
// Here is the first step of the extra treatment for all FM-TOWNS string arrays that
// contain more than one string and which the original code
// addresses via stringname[boolJapanese].
Expand All @@ -201,11 +208,38 @@ bool extractStrings(PAKFile &out, const ExtractInformation *info, const byte *da
targetsize--;
}
}
} else if (patch == 5) {
++skipCount;
while (!data[++i]) {
if (skipCount == 81) {
++skipCount;
++entries;
break;
}
if (i == size)
break;
targetsize--;
}

for (uint32 ii = 0; ii < ARRAYSIZE(rusFanSkipId); ++ii) {
// Skip English string left-overs in the hacky Russian fan translation
if (skipCount == rusFanSkipId[ii]) {
++skipCount;
uint32 len = strlen((const char*) data + i);
i += len;
targetsize = targetsize - 1 - len;
while (!data[++i]) {
if (i == len)
break;
targetsize--;
}
}
}
}
}
}

if (fmtPatch == 2) {
if (patch == 2) {
if (info->lang == EN_ANY) {
targetsize--;
entries += 1;
Expand All @@ -215,12 +249,12 @@ bool extractStrings(PAKFile &out, const ExtractInformation *info, const byte *da
}
}

if (fmtPatch == 3) {
if (patch == 3) {
entries++;
targetsize++;
}

if (fmtPatch == 4) {
if (patch == 4) {
targetsize -= 9;
}

Expand All @@ -229,12 +263,13 @@ bool extractStrings(PAKFile &out, const ExtractInformation *info, const byte *da
memset(buffer, 0, targetsize);
uint8 *output = buffer;
const uint8 *input = (const uint8*) data;
skipCount = 0;

WRITE_BE_UINT32(output, entries); output += 4;
if (info->platform == kPlatformFMTowns) {
const byte *c = data + size;
do {
if (fmtPatch == 2 && input - data == 0x3C0 && input[0x10] == 0x32) {
if (patch == 2 && input - data == 0x3C0 && input[0x10] == 0x32) {
memcpy(output, input, 0x0F);
input += 0x11; output += 0x0F;
}
Expand All @@ -245,14 +280,14 @@ bool extractStrings(PAKFile &out, const ExtractInformation *info, const byte *da
// skip empty entries
while (!*input) {
// Write one empty string into intro strings file
if (fmtPatch == 2) {
if (patch == 2) {
if ((info->lang == EN_ANY && input - data == 0x260) ||
(info->lang == JA_JPN && (input - data == 0x2BD || input - data == 0x2BE)))
*output++ = *input;
}

// insert one dummy string at hof sequence strings position 59
if (fmtPatch == 3) {
if (patch == 3) {
if ((info->lang == EN_ANY && input - data == 0x695) ||
(info->lang == JA_JPN && input - data == 0x598))
*output++ = *input;
Expand All @@ -262,7 +297,7 @@ bool extractStrings(PAKFile &out, const ExtractInformation *info, const byte *da
break;
}

if (fmtPatch == 1) {
if (patch == 1) {
// Here is the extra treatment for all FM-TOWNS string arrays that
// contain more than one string and which the original code
// addresses via stringname[boolJapanese].
Expand Down Expand Up @@ -292,9 +327,38 @@ bool extractStrings(PAKFile &out, const ExtractInformation *info, const byte *da
++dstPos;
}
targetsize = dstPos + 4;
} else if (patch == 5) {
const byte *c = data + size;
do {
strcpy((char*) output, (const char*) input);
uint32 stringsize = strlen((const char*)output) + 1;
input += stringsize; output += stringsize;

++skipCount;
while (!*input) {
if (skipCount == 81) {
*output++ = *input;
++skipCount;
}
if (++input == c)
break;
}
// Skip English string left-overs in the hacky Russian fan translation
for (uint32 ii = 0; ii < ARRAYSIZE(rusFanSkipId); ++ii) {
if (skipCount == rusFanSkipId[ii]) {
++skipCount;
input += strlen((const char*)input);
while (!*input) {
if (++input == c)
break;
}
}
}

} while (input < c);
} else {
uint32 copySize = size;
if (fmtPatch == 4) {
if (patch == 4) {
memcpy(output, data, 44);
output += 44;
data += 44;
Expand Down
1 change: 1 addition & 0 deletions devtools/create_kyradat/games.cpp
Expand Up @@ -71,6 +71,7 @@ const Game kyra2Games[] = {
{ kKyra2, { FR_FRA, -1, -1 }, kPlatformPC, kNoSpecial, { "df31cc9e37e1cf68df2fdc75ddf2d87b", "fc2c6782778e6c6d5a553d1cb73c98ad" } },
{ kKyra2, { DE_DEU, -1, -1 }, kPlatformPC, kNoSpecial, { "0ca4f9a1438264a4c63c3218e064ed3b", "0d9b0eb7b0ad889ec942d74d80dde1bf" } },
{ kKyra2, { IT_ITA, -1, -1 }, kPlatformPC, kNoSpecial, { "178d3ab913f61bfba21d2fb196405e8c", "3a61ed6b7c00ddae383a0361799e2ba6" } },
{ kKyra2, { RU_RUS, -1, -1 }, kPlatformPC, kNoSpecial, { "fd6a388c01de9a578e24e3bbeacd8012", "3a61ed6b7c00ddae383a0361799e2ba6" } },

// talkie games
{ kKyra2, { EN_ANY, FR_FRA, DE_DEU }, kPlatformPC, kTalkieVersion, { "85bbc1cc6c4cef6ad31fc6ee79518efb", "e20d0d2e500f01e399ec588247a7e213" } },
Expand Down
2 changes: 2 additions & 0 deletions devtools/create_kyradat/tables.cpp
Expand Up @@ -1057,6 +1057,8 @@ const ExtractEntrySearchData k2SeqplayStringsProvider[] = {
{ IT_ITA, kPlatformPC, { 0x00000916, 0x0003188F, { { 0xDC, 0x46, 0x06, 0xE1, 0xB0, 0x66, 0xBC, 0x18, 0x2E, 0x6E, 0x9E, 0xC9, 0xA4, 0x14, 0x8D, 0x08 } } } }, // floppy
{ IT_ITA, kPlatformPC, { 0x000008C8, 0x00030947, { { 0x7F, 0x75, 0x5F, 0x99, 0x94, 0xFE, 0xA1, 0xE6, 0xEF, 0xB8, 0x93, 0x71, 0x83, 0x1B, 0xAC, 0x4A } } } }, // (fan) CD

{ RU_RUS, kPlatformPC, { 0x000008C8, 0x00028639, { { 0xF9, 0x1D, 0x6A, 0x85, 0x23, 0x5E, 0x2A, 0x64, 0xBC, 0x45, 0xB2, 0x48, 0x13, 0x49, 0xD4, 0xF7 } } } }, // (fan) floppy

{ EN_ANY, kPlatformFMTowns, { 0x00000990, 0x00030C61, { { 0x60, 0x51, 0x11, 0x83, 0x3F, 0x06, 0xC3, 0xA3, 0xE0, 0xC0, 0x2F, 0x41, 0x29, 0xDE, 0x65, 0xB1 } } } },
{ JA_JPN, kPlatformFMTowns, { 0x000008A8, 0x00036831, { { 0x56, 0x5B, 0x23, 0x61, 0xE8, 0x3B, 0xE1, 0x36, 0xD6, 0x62, 0xD0, 0x84, 0x00, 0x04, 0x05, 0xAD } } } },

Expand Down
Binary file modified dists/engine-data/kyra.dat
Binary file not shown.
27 changes: 27 additions & 0 deletions engines/kyra/detection_tables.h
Expand Up @@ -35,6 +35,7 @@ namespace {

#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)
Expand Down Expand Up @@ -500,6 +501,32 @@ const KYRAGameDescription adGameDescs[] = {
KYRA2_FLOPPY_FLAGS
},

{ // Floppy version extracted
{
"kyra2",
"Extracted",
AD_ENTRY1("CH01-S00.DLG", "54b7a5a94f6e1ec91f0fb1311eec09ab"),
Common::RU_RUS,
Common::kPlatformPC,
ADGF_NO_FLAGS,
Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK
},
KYRA2_FLOPPY_FAN_FLAGS(Common::RU_RUS, Common::EN_ANY)
},

{ // Floppy version extracted
{
"kyra2",
"Extracted",
AD_ENTRY1("CH01-S00.DLG", "7c36c0e63ab8c81cbb3ea58681331366"),
Common::RU_RUS,
Common::kPlatformPC,
ADGF_NO_FLAGS,
Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK
},
KYRA2_FLOPPY_FAN_FLAGS(Common::RU_RUS, Common::EN_ANY)
},

{ // CD version
{
"kyra2",
Expand Down
2 changes: 1 addition & 1 deletion engines/kyra/staticres.cpp
Expand Up @@ -38,7 +38,7 @@

namespace Kyra {

#define RESFILE_VERSION 76
#define RESFILE_VERSION 77

namespace {
bool checkKyraDat(Common::SeekableReadStream *file) {
Expand Down

0 comments on commit f2f6ddc

Please sign in to comment.