From 3a7f85971fd00e598eca357010b18314d890e28b Mon Sep 17 00:00:00 2001 From: Bastien Bouclet Date: Fri, 6 Jul 2018 07:06:05 +0200 Subject: MOHAWK: MYST: Add support for the localized 25th games --- engines/mohawk/detection.cpp | 35 ++++++----- engines/mohawk/detection_tables.h | 121 ++++++++++++++++++++++++------------ engines/mohawk/mohawk.h | 12 ++-- engines/mohawk/myst.cpp | 121 ++++++++++++++++++++++++++---------- engines/mohawk/myst.h | 4 ++ engines/mohawk/myst_areas.cpp | 1 + engines/mohawk/myst_graphics.cpp | 15 +++-- engines/mohawk/myst_graphics.h | 4 +- engines/mohawk/myst_stacks/menu.cpp | 36 +++++++++-- engines/mohawk/myst_stacks/menu.h | 4 +- engines/mohawk/riven.cpp | 60 +++++++++--------- engines/mohawk/riven.h | 3 +- 12 files changed, 274 insertions(+), 142 deletions(-) (limited to 'engines') diff --git a/engines/mohawk/detection.cpp b/engines/mohawk/detection.cpp index 98783d703e..e81fc56199 100644 --- a/engines/mohawk/detection.cpp +++ b/engines/mohawk/detection.cpp @@ -87,6 +87,24 @@ bool MohawkEngine::hasFeature(EngineFeature f) const { (f == kSupportsRTL); } +Common::String MohawkEngine::getDatafileLanguageName(const char *prefix) const { + const ADGameFileDescription *fileDesc; + for (fileDesc = _gameDescription->desc.filesDescriptions; fileDesc->fileName; fileDesc++) { + if (Common::String(fileDesc->fileName).hasPrefix(prefix)) { + break; + } + } + + if (!fileDesc->fileName) { + warning("Malformed detection entry"); + + return ""; + } + + size_t prefixLength = strlen(prefix); + return Common::String(&fileDesc->fileName[prefixLength], strlen(fileDesc->fileName) - prefixLength - 4); +} + #ifdef ENABLE_MYST bool MohawkEngine_Myst::hasFeature(EngineFeature f) const { @@ -107,23 +125,6 @@ bool MohawkEngine_Riven::hasFeature(EngineFeature f) const { || (f == kSupportsSavingDuringRuntime); } -Common::String MohawkEngine_Riven::getDatafileLanguageName() const { - const ADGameFileDescription *fileDesc; - for (fileDesc = _gameDescription->desc.filesDescriptions; fileDesc->fileName; fileDesc++) { - if (Common::String(fileDesc->fileName).hasPrefix("a_data_")) { - break; - } - } - - if (!fileDesc->fileName) { - warning("Malformed 25th Anniversary Riven entry"); - - return ""; - } - - return Common::String(&fileDesc->fileName[7], strlen(fileDesc->fileName) - 7 - 4); -} - #endif } // End of Namespace Mohawk diff --git a/engines/mohawk/detection_tables.h b/engines/mohawk/detection_tables.h index bd0a127c30..04fec52dea 100644 --- a/engines/mohawk/detection_tables.h +++ b/engines/mohawk/detection_tables.h @@ -40,7 +40,7 @@ static const MohawkGameDescription gameDescriptions[] = { { "myst", "", - AD_ENTRY1("MYST.DAT", "ae3258c9c90128d274aa6a790b3ad181"), + AD_ENTRY1("myst.dat", "ae3258c9c90128d274aa6a790b3ad181"), Common::EN_ANY, Common::kPlatformWindows, ADGF_NO_FLAGS, @@ -58,7 +58,7 @@ static const MohawkGameDescription gameDescriptions[] = { { "myst", "", - AD_ENTRY1("MYST.DAT", "4beb3366ed3f3b9bfb6e81a14a43bdcc"), + AD_ENTRY1("myst.dat", "4beb3366ed3f3b9bfb6e81a14a43bdcc"), Common::EN_ANY, Common::kPlatformWindows, ADGF_NO_FLAGS, @@ -76,7 +76,7 @@ static const MohawkGameDescription gameDescriptions[] = { { "myst", "", - AD_ENTRY1("MYST.DAT", "0e4b6fcbd2419d4371365314fb7443f8"), + AD_ENTRY1("myst.dat", "0e4b6fcbd2419d4371365314fb7443f8"), Common::EN_ANY, Common::kPlatformWindows, ADGF_NO_FLAGS, @@ -112,7 +112,7 @@ static const MohawkGameDescription gameDescriptions[] = { { "myst", "", - AD_ENTRY1("MYST.DAT", "4beb3366ed3f3b9bfb6e81a14a43bdcc"), + AD_ENTRY1("myst.dat", "4beb3366ed3f3b9bfb6e81a14a43bdcc"), Common::DE_DEU, Common::kPlatformWindows, ADGF_NO_FLAGS, @@ -130,7 +130,7 @@ static const MohawkGameDescription gameDescriptions[] = { { "myst", "", - AD_ENTRY1("MYST.DAT", "e0937cca1ab125e48e30dc3cd5046ddf"), + AD_ENTRY1("myst.dat", "e0937cca1ab125e48e30dc3cd5046ddf"), Common::DE_DEU, Common::kPlatformWindows, ADGF_NO_FLAGS, @@ -148,7 +148,7 @@ static const MohawkGameDescription gameDescriptions[] = { { "myst", "", - AD_ENTRY1("MYST.DAT", "f7e7d7ca69934f1351b5acd4fe4d44c2"), + AD_ENTRY1("myst.dat", "f7e7d7ca69934f1351b5acd4fe4d44c2"), Common::ES_ESP, Common::kPlatformWindows, ADGF_NO_FLAGS, @@ -166,7 +166,7 @@ static const MohawkGameDescription gameDescriptions[] = { { "myst", "", - AD_ENTRY1("MYST.DAT", "a5795ce1751fc42525e4f9a1859181d5"), + AD_ENTRY1("myst.dat", "a5795ce1751fc42525e4f9a1859181d5"), Common::IT_ITA, Common::kPlatformWindows, ADGF_NO_FLAGS, @@ -184,7 +184,7 @@ static const MohawkGameDescription gameDescriptions[] = { { "myst", "", - AD_ENTRY1("MYST.DAT", "032c88e3b7e8db4ca475e7b7db9a66bb"), + AD_ENTRY1("myst.dat", "032c88e3b7e8db4ca475e7b7db9a66bb"), Common::JA_JPN, Common::kPlatformWindows, ADGF_NO_FLAGS, @@ -202,7 +202,7 @@ static const MohawkGameDescription gameDescriptions[] = { { "myst", "", - AD_ENTRY1("MYST.DAT", "d631d42567a941c67c78f2e491f4ea58"), + AD_ENTRY1("myst.dat", "d631d42567a941c67c78f2e491f4ea58"), Common::FR_FRA, Common::kPlatformWindows, ADGF_NO_FLAGS, @@ -219,7 +219,7 @@ static const MohawkGameDescription gameDescriptions[] = { { "myst", "", - AD_ENTRY1("MYST.DAT", "196384f87e8bcb51731bce8416ab6a07"), + AD_ENTRY1("myst.dat", "196384f87e8bcb51731bce8416ab6a07"), Common::RU_RUS, Common::kPlatformWindows, ADGF_NO_FLAGS, @@ -237,7 +237,7 @@ static const MohawkGameDescription gameDescriptions[] = { { "makingofmyst", "", - AD_ENTRY1("MAKING.DAT", "f6387e8f0f7b8a3e42c95294315d6a0e"), + AD_ENTRY1("making.dat", "f6387e8f0f7b8a3e42c95294315d6a0e"), Common::EN_ANY, Common::kPlatformWindows, ADGF_NO_FLAGS, @@ -255,7 +255,7 @@ static const MohawkGameDescription gameDescriptions[] = { { "makingofmyst", "", - AD_ENTRY1("MAKING.DAT", "03ff62607e64419ab2b6ebf7b7bcdf63"), + AD_ENTRY1("making.dat", "03ff62607e64419ab2b6ebf7b7bcdf63"), Common::JA_JPN, Common::kPlatformWindows, ADGF_NO_FLAGS, @@ -273,7 +273,7 @@ static const MohawkGameDescription gameDescriptions[] = { { "myst", "Masterpiece Edition", - AD_ENTRY1("MYST.DAT", "c4cae9f143b5947262e6cb2397e1617e"), + AD_ENTRY1("myst.dat", "c4cae9f143b5947262e6cb2397e1617e"), Common::EN_ANY, Common::kPlatformWindows, ADGF_NO_FLAGS, @@ -291,7 +291,7 @@ static const MohawkGameDescription gameDescriptions[] = { { "myst", "Masterpiece Edition", - AD_ENTRY1("MYST.DAT", "f88e0ace66dbca78eebdaaa1d3314ceb"), + AD_ENTRY1("myst.dat", "f88e0ace66dbca78eebdaaa1d3314ceb"), Common::DE_DEU, Common::kPlatformWindows, ADGF_NO_FLAGS, @@ -309,7 +309,7 @@ static const MohawkGameDescription gameDescriptions[] = { { "myst", "Masterpiece Edition", - AD_ENTRY1("MYST.DAT", "aea81633b2d2ae498f09072fb87263b6"), + AD_ENTRY1("myst.dat", "aea81633b2d2ae498f09072fb87263b6"), Common::FR_FRA, Common::kPlatformWindows, ADGF_NO_FLAGS, @@ -327,7 +327,7 @@ static const MohawkGameDescription gameDescriptions[] = { { "myst", "Masterpiece Edition", - AD_ENTRY1("MYST.DAT", "4a05771b60f4a69869838d01e85c9e80"), + AD_ENTRY1("myst.dat", "4a05771b60f4a69869838d01e85c9e80"), Common::PL_POL, Common::kPlatformWindows, ADGF_NO_FLAGS, @@ -339,15 +339,14 @@ static const MohawkGameDescription gameDescriptions[] = { }, // Myst Masterpiece Edition - 25th Anniversary - // English Windows - // Created by the ScummVM team + // English Windows - Created by the ScummVM team { { "myst", "Masterpiece Edition - 25th Anniversary", { - {"MYST.DAT", 0, "c4cae9f143b5947262e6cb2397e1617e", -1}, - {"MENU.DAT", 0, "7dc23051084f79b1c2bccc84cdec0503", -1}, + {"myst.dat", 0, "c4cae9f143b5947262e6cb2397e1617e", -1}, + {"menu.dat", 0, "7dc23051084f79b1c2bccc84cdec0503", -1}, AD_LISTEND }, Common::EN_ANY, @@ -361,15 +360,14 @@ static const MohawkGameDescription gameDescriptions[] = { }, // Myst Masterpiece Edition - 25th Anniversary - // French Windows - // Created by the ScummVM team + // French Windows - Repacked by the ScummVM team { { "myst", "Masterpiece Edition - 25th Anniversary", { - {"MYST.DAT", 0, "aea81633b2d2ae498f09072fb87263b6", -1}, - {"MENU.DAT", 0, "7dc23051084f79b1c2bccc84cdec0503", -1}, + {"myst_french.dat", 0, "7c8230be50ffcac588e7db8788ad7614", -1}, + {"menu.dat", 0, "7dc23051084f79b1c2bccc84cdec0503", -1}, AD_LISTEND }, Common::FR_FRA, @@ -378,20 +376,19 @@ static const MohawkGameDescription gameDescriptions[] = { GUI_OPTIONS_MYST_ME }, GType_MYST, - GF_ME | GF_25TH, + GF_ME | GF_25TH | GF_LANGUAGE_FILES, 0, }, // Myst Masterpiece Edition - 25th Anniversary - // German Windows - // Created by the ScummVM team + // German Windows - Repacked by the ScummVM team { { "myst", - "Masterpiece Edition", + "Masterpiece Edition - 25th Anniversary", { - {"MYST.DAT", 0, "f88e0ace66dbca78eebdaaa1d3314ceb", -1}, - {"MENU.DAT", 0, "7dc23051084f79b1c2bccc84cdec0503", -1}, + {"myst_german.dat", 0, "3952554439960b22a360e8e006dfed58", -1}, + {"menu.dat", 0, "7dc23051084f79b1c2bccc84cdec0503", -1}, AD_LISTEND }, Common::DE_DEU, @@ -400,7 +397,49 @@ static const MohawkGameDescription gameDescriptions[] = { GUI_OPTIONS_MYST_ME }, GType_MYST, - GF_ME, + GF_ME | GF_25TH | GF_LANGUAGE_FILES, + 0, + }, + + // Myst Masterpiece Edition - 25th Anniversary + // Polish Windows - Repacked by the ScummVM team + { + { + "myst", + "Masterpiece Edition - 25th Anniversary", + { + {"myst_polish.dat", 0, "9ca82ff26fcbfacf40e4164523a50854", -1}, + {"menu.dat", 0, "7dc23051084f79b1c2bccc84cdec0503", -1}, + AD_LISTEND + }, + Common::PL_POL, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUI_OPTIONS_MYST_ME + }, + GType_MYST, + GF_ME | GF_25TH | GF_LANGUAGE_FILES, + 0, + }, + + // Myst Masterpiece Edition - 25th Anniversary + // Spanish Windows - Repacked by the ScummVM team + { + { + "myst", + "Masterpiece Edition - 25th Anniversary", + { + {"myst_spanish.dat", 0, "822ed3c0de912c10b877dcd2cc078493", -1}, + {"menu.dat", 0, "7dc23051084f79b1c2bccc84cdec0503", -1}, + AD_LISTEND + }, + Common::ES_ESP, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUI_OPTIONS_MYST_ME + }, + GType_MYST, + GF_ME | GF_25TH | GF_LANGUAGE_FILES, 0, }, @@ -678,7 +717,7 @@ static const MohawkGameDescription gameDescriptions[] = { GUI_OPTIONS_RIVEN }, GType_RIVEN, - GF_DVD | GF_25TH, + GF_DVD | GF_25TH | GF_LANGUAGE_FILES, 0, }, @@ -699,7 +738,7 @@ static const MohawkGameDescription gameDescriptions[] = { GUI_OPTIONS_RIVEN }, GType_RIVEN, - GF_DVD | GF_25TH, + GF_DVD | GF_25TH | GF_LANGUAGE_FILES, 0, }, @@ -720,7 +759,7 @@ static const MohawkGameDescription gameDescriptions[] = { GUI_OPTIONS_RIVEN }, GType_RIVEN, - GF_DVD | GF_25TH, + GF_DVD | GF_25TH | GF_LANGUAGE_FILES, 0, }, @@ -741,7 +780,7 @@ static const MohawkGameDescription gameDescriptions[] = { GUI_OPTIONS_RIVEN }, GType_RIVEN, - GF_DVD | GF_25TH, + GF_DVD | GF_25TH | GF_LANGUAGE_FILES, 0, }, @@ -762,7 +801,7 @@ static const MohawkGameDescription gameDescriptions[] = { GUI_OPTIONS_RIVEN }, GType_RIVEN, - GF_DVD | GF_25TH, + GF_DVD | GF_25TH | GF_LANGUAGE_FILES, 0, }, @@ -783,7 +822,7 @@ static const MohawkGameDescription gameDescriptions[] = { GUI_OPTIONS_RIVEN }, GType_RIVEN, - GF_DVD | GF_25TH, + GF_DVD | GF_25TH | GF_LANGUAGE_FILES, 0, }, @@ -804,7 +843,7 @@ static const MohawkGameDescription gameDescriptions[] = { GUI_OPTIONS_RIVEN }, GType_RIVEN, - GF_DVD | GF_25TH, + GF_DVD | GF_25TH | GF_LANGUAGE_FILES, 0, }, @@ -2940,9 +2979,9 @@ static const MohawkGameDescription fallbackDescs[] = { }; static const ADFileBasedFallback fileBased[] = { - { &fallbackDescs[0].desc, { "MYST.DAT", 0 } }, - { &fallbackDescs[1].desc, { "MAKING.DAT", 0 } }, - { &fallbackDescs[2].desc, { "MYST.DAT", "Help.dat", 0 } }, // Help system doesn't exist in original + { &fallbackDescs[0].desc, { "myst.dat", 0 } }, + { &fallbackDescs[1].desc, { "making.dat", 0 } }, + { &fallbackDescs[2].desc, { "myst.dat", "help.dat", 0 } }, // Help system doesn't exist in original { &fallbackDescs[3].desc, { "a_Data.MHK", 0 } }, { &fallbackDescs[4].desc, { "a_Data.MHK", "t_Data1.MHK" , 0 } }, { 0, { 0 } } diff --git a/engines/mohawk/mohawk.h b/engines/mohawk/mohawk.h index ad4ff7b3f0..2a2d25b771 100644 --- a/engines/mohawk/mohawk.h +++ b/engines/mohawk/mohawk.h @@ -58,11 +58,12 @@ enum MohawkGameType { }; enum MohawkGameFeatures { - GF_ME = (1 << 0), // Myst Masterpiece Edition - GF_25TH = (1 << 1), // Myst and Riven 25th Anniversary - GF_DVD = (1 << 2), - GF_DEMO = (1 << 3), - GF_LB_10 = (1 << 4) // very early Living Books 1.0 games + GF_ME = (1 << 0), // Myst Masterpiece Edition + GF_25TH = (1 << 1), // Myst and Riven 25th Anniversary + GF_DVD = (1 << 2), + GF_DEMO = (1 << 3), + GF_LB_10 = (1 << 4), // very early Living Books 1.0 games + GF_LANGUAGE_FILES = (1 << 5) // Myst and Riven versions using language override files }; struct MohawkGameDescription; @@ -87,6 +88,7 @@ public: Common::Platform getPlatform() const; uint8 getGameType() const; Common::Language getLanguage() const; + Common::String getDatafileLanguageName(const char *prefix) const; bool hasFeature(EngineFeature f) const override; diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp index d4e15e6d85..ed3d40d2b2 100644 --- a/engines/mohawk/myst.cpp +++ b/engines/mohawk/myst.cpp @@ -120,7 +120,13 @@ Common::SeekableReadStream *MohawkEngine_Myst::getResource(uint32 tag, uint16 id } Common::Array MohawkEngine_Myst::getResourceIDList(uint32 type) const { - return _mhk[0]->getResourceIDList(type); + Common::Array ids; + + for (uint i = 0; i < _mhk.size(); i++) { + ids.push_back(_mhk[i]->getResourceIDList(type)); + } + + return ids; } void MohawkEngine_Myst::cachePreload(uint32 tag, uint16 id) { @@ -153,19 +159,19 @@ void MohawkEngine_Myst::cachePreload(uint32 tag, uint16 id) { } static const char *mystFiles[] = { - "channel.dat", - "credits.dat", - "demo.dat", - "dunny.dat", - "intro.dat", - "making.dat", - "mechan.dat", - "myst.dat", - "selen.dat", - "slides.dat", - "sneak.dat", - "stone.dat", - "menu.dat" + "channel", + "credits", + "demo", + "dunny", + "intro", + "making", + "mechan", + "myst", + "selen", + "slides", + "sneak", + "stone", + "menu" }; // Myst Hardcoded Movie Paths @@ -219,8 +225,23 @@ Common::String MohawkEngine_Myst::wrapMovieFilename(const Common::String &movieN return Common::String("qtw/") + prefix + movieName + ".mov"; } +Common::String MohawkEngine_Myst::selectLocalizedMovieFilename(const Common::String &movieName) { + Common::String language; + if (getFeatures() & GF_LANGUAGE_FILES) { + language = getDatafileLanguageName("myst_"); + } + + Common::String localizedMovieName = Common::String::format("%s/%s", language.c_str(), movieName.c_str()); + if (!language.empty() && SearchMan.hasFile(localizedMovieName)) { + return localizedMovieName; + } else { + return movieName; + } +} + VideoEntryPtr MohawkEngine_Myst::playMovie(const Common::String &name, MystStack stack) { Common::String filename = wrapMovieFilename(name, stack); + filename = selectLocalizedMovieFilename(filename); VideoEntryPtr video = _video->playMovie(filename, Audio::Mixer::kSFXSoundType); if (!video) { @@ -241,11 +262,13 @@ VideoEntryPtr MohawkEngine_Myst::playMovieFullscreen(const Common::String &name, VideoEntryPtr MohawkEngine_Myst::findVideo(const Common::String &name, MystStack stack) { Common::String filename = wrapMovieFilename(name, stack); + filename = selectLocalizedMovieFilename(filename); return _video->findVideo(filename); } void MohawkEngine_Myst::playMovieBlocking(const Common::String &name, MystStack stack, uint16 x, uint16 y) { Common::String filename = wrapMovieFilename(name, stack); + filename = selectLocalizedMovieFilename(filename); VideoEntryPtr video = _video->playMovie(filename, Audio::Mixer::kSFXSoundType); if (!video) { error("Failed to open the '%s' movie", filename.c_str()); @@ -355,11 +378,6 @@ Common::Error MohawkEngine_Myst::run() { // Cursor is visible by default _cursor->showCursor(); - _mhk.resize(3); - _mhk[0] = new MohawkArchive(); - _mhk[1] = new MohawkArchive(); - _mhk[2] = new MohawkArchive(); - // Load game from launcher/command line if requested if (ConfMan.hasKey("save_slot") && hasGameSaveSupport()) { int saveSlot = ConfMan.getInt("save_slot"); @@ -377,21 +395,62 @@ Common::Error MohawkEngine_Myst::run() { changeToStack(kIntroStack, 1, 0, 0); } - // Load Help System (Masterpiece Edition Only) + while (!shouldQuit()) { + doFrame(); + } + + return Common::kNoError; +} + +void MohawkEngine_Myst::loadStackArchives(MystStack stackId) { + for (uint i = 0; i < _mhk.size(); i++) { + delete _mhk[i]; + } + _mhk.clear(); + + Common::String language; + if (getFeatures() & GF_LANGUAGE_FILES) { + language = getDatafileLanguageName("myst_"); + } + + if (!language.empty()) { + loadArchive(mystFiles[stackId], language.c_str(), false); + } + + loadArchive(mystFiles[stackId], nullptr, true); + if (getFeatures() & GF_ME) { - if (!_mhk[1]->openFile("help.dat")) - error("Could not load help.dat"); + if (!language.empty()) { + loadArchive("help", language.c_str(), false); + } + + loadArchive("help", nullptr, true); } + if (getFeatures() & GF_25TH) { - if (!_mhk[2]->openFile("menu.dat")) - error("Could not load menu.dat"); + loadArchive("menu", nullptr, true); } +} - while (!shouldQuit()) { - doFrame(); +void MohawkEngine_Myst::loadArchive(const char *archiveName, const char *language, bool mandatory) { + Common::String filename; + if (language) { + filename = Common::String::format("%s_%s.dat", archiveName, language); + } else { + filename = Common::String::format("%s.dat", archiveName); } - return Common::kNoError; + Archive *archive = new MohawkArchive(); + if (!archive->openFile(filename)) { + delete archive; + if (mandatory) { + error("Could not open %s", filename.c_str()); + } else { + return; + } + } + + _mhk.push_back(archive); } void MohawkEngine_Myst::doFrame() { @@ -676,13 +735,7 @@ void MohawkEngine_Myst::changeToStack(MystStack stackId, uint16 card, uint16 lin error("Unknown Myst stack %d", stackId); } - // If the array is empty, add a new one. Otherwise, delete the first - // entry which is the stack file (the second, if there, is the help file). - delete _mhk[0]; - _mhk[0] = new MohawkArchive(); - - if (!_mhk[0]->openFile(mystFiles[stackId])) - error("Could not open %s", mystFiles[stackId]); + loadStackArchives(stackId); // Clear the resource cache and the image cache _cache.clear(); diff --git a/engines/mohawk/myst.h b/engines/mohawk/myst.h index 007a0c59ef..b850bbd613 100644 --- a/engines/mohawk/myst.h +++ b/engines/mohawk/myst.h @@ -173,6 +173,7 @@ public: void playMovieBlocking(const Common::String &name, MystStack stack, uint16 x, uint16 y); void playFlybyMovie(MystStack stack); void waitUntilMovieEnds(const VideoEntryPtr &video); + Common::String selectLocalizedMovieFilename(const Common::String &movieName); void playSoundBlocking(uint16 id); @@ -218,6 +219,9 @@ private: Common::String wrapMovieFilename(const Common::String &movieName, uint16 stack); + void loadStackArchives(MystStack stackId); + void loadArchive(const char *archiveName, const char *language, bool mandatory); + // Input bool _mouseClicked; bool _mouseMoved; diff --git a/engines/mohawk/myst_areas.cpp b/engines/mohawk/myst_areas.cpp index d03c78a497..a572b14958 100644 --- a/engines/mohawk/myst_areas.cpp +++ b/engines/mohawk/myst_areas.cpp @@ -196,6 +196,7 @@ MystAreaVideo::MystAreaVideo(MohawkEngine_Myst *vm, ResourceType type, Common::S _videoFile.deleteLastChar(); _videoFile = convertMystVideoName(_videoFile); + _videoFile = _vm->selectLocalizedMovieFilename(_videoFile); // Position values require modulus 10000 to keep in sane range. _left = rlstStream->readSint16LE() % 10000; diff --git a/engines/mohawk/myst_graphics.cpp b/engines/mohawk/myst_graphics.cpp index 8e557abaef..55a92b2b08 100644 --- a/engines/mohawk/myst_graphics.cpp +++ b/engines/mohawk/myst_graphics.cpp @@ -69,9 +69,16 @@ MystGraphics::MystGraphics(MohawkEngine_Myst* vm) : if (_vm->getFeatures() & GF_25TH) { const char *menuFontName = "NotoSans-ExtraBold.ttf"; #ifdef USE_FREETYPE2 + int fontSize; + if (_vm->getLanguage() == Common::PL_POL) { + fontSize = 11; // The Polish diacritics need significantly more space, so we use a smaller font + } else { + fontSize = 16; + } + Common::SeekableReadStream *fontStream = SearchMan.createReadStreamForMember(menuFontName); if (fontStream) { - _menuFont = Graphics::loadTTFFont(*fontStream, 16); + _menuFont = Graphics::loadTTFFont(*fontStream, fontSize); delete fontStream; } else #endif @@ -850,15 +857,15 @@ Graphics::Surface *MystGraphics::getThumbnailForMainMenu() const { return _mainMenuBackupScreenThumbnail.get(); } -void MystGraphics::drawText(uint16 image, const char *text, const Common::Rect &dest, uint8 r, uint8 g, uint8 b, Graphics::TextAlign align, int16 deltaY) { +void MystGraphics::drawText(uint16 image, const Common::U32String &text, const Common::Rect &dest, uint8 r, uint8 g, uint8 b, Graphics::TextAlign align, int16 deltaY) { MohawkSurface *mhkSurface = findImage(image); Graphics::Surface *surface = mhkSurface->getSurface(); const Graphics::Font *font = getMenuFont(); - font->drawString(surface, text, dest.left, dest.top + deltaY, dest.width(), surface->format.RGBToColor(r, g, b), align, 0, false); + font->drawString(surface, text, dest.left, dest.top + deltaY, dest.width(), surface->format.RGBToColor(r, g, b), align); } -Common::Rect MystGraphics::getTextBoundingBox(const char *text, const Common::Rect &dest, Graphics::TextAlign align) { +Common::Rect MystGraphics::getTextBoundingBox(const Common::U32String &text, const Common::Rect &dest, Graphics::TextAlign align) { const Graphics::Font *font = getMenuFont(); return font->getBoundingBox(text, dest.left, dest.top, dest.width(), align); } diff --git a/engines/mohawk/myst_graphics.h b/engines/mohawk/myst_graphics.h index 03f5b76ce2..63c559f7b3 100644 --- a/engines/mohawk/myst_graphics.h +++ b/engines/mohawk/myst_graphics.h @@ -64,8 +64,8 @@ public: void restoreStateForMainMenu(); Graphics::Surface *getThumbnailForMainMenu() const; - Common::Rect getTextBoundingBox(const char *text, const Common::Rect &dest, Graphics::TextAlign align); - void drawText(uint16 image, const char *text, const Common::Rect &dest, uint8 r, uint8 g, uint8 b, Graphics::TextAlign align, int16 deltaY); + Common::Rect getTextBoundingBox(const Common::U32String &text, const Common::Rect &dest, Graphics::TextAlign align); + void drawText(uint16 image, const Common::U32String &text, const Common::Rect &dest, uint8 r, uint8 g, uint8 b, Graphics::TextAlign align, int16 deltaY); void replaceImageWithRect(uint16 destImage, uint16 sourceImage, const Common::Rect &sourceRect); diff --git a/engines/mohawk/myst_stacks/menu.cpp b/engines/mohawk/myst_stacks/menu.cpp index e3e9feaa26..e83a05e0cd 100644 --- a/engines/mohawk/myst_stacks/menu.cpp +++ b/engines/mohawk/myst_stacks/menu.cpp @@ -139,7 +139,8 @@ void Menu::o_menuInit(uint16 var, const ArgumentsArray &args) { MystAreaImageSwitch *image = _vm->getCard()->getResource(2 * i + 0); MystAreaHover *hover = _vm->getCard()->getResource (2 * i + 1); - drawButtonImages(buttonCaptions[i], image, buttons[i].align, buttons[i].highlightedIndex, buttons[i].disabledIndex); + Common::U32String str = Common::convertUtf8ToUtf32(buttonCaptions[i]); + drawButtonImages(str, image, buttons[i].align, buttons[i].highlightedIndex, buttons[i].disabledIndex); hover->setRect(image->getRect()); } } @@ -172,18 +173,40 @@ const char **Menu::getButtonCaptions() const { "OPTIONEN" }; + static const char *buttonCaptionsSpanish[] = { + "JUEGO NUEVO", + "CARGAR JUEGO", + "GUARDAR JUEGO", + "CONTINUAR", + "SALIR", + "OPCIONES" + }; + + static const char *buttonCaptionsPolish[] = { + "NOWA GRA", + "ZAŁADUJ GRĘ", + "ZAPISZ GRĘ", + "POWRÓT", + "WYJŚCIE", + "OPCJE" + }; + switch (_vm->getLanguage()) { case Common::FR_FRA: return buttonCaptionsFrench; case Common::DE_DEU: return buttonCaptionsGerman; + case Common::ES_ESP: + return buttonCaptionsSpanish; + case Common::PL_POL: + return buttonCaptionsPolish; case Common::EN_ANY: default: return buttonCaptionsEnglish; } } -void Menu::drawButtonImages(const char *text, MystAreaImageSwitch *area, Graphics::TextAlign align, uint16 highlightedIndex, uint16 disabledIndex) const { +void Menu::drawButtonImages(const Common::U32String &text, MystAreaImageSwitch *area, Graphics::TextAlign align, uint16 highlightedIndex, uint16 disabledIndex) const { Common::Rect backgroundRect = area->getRect(); Common::Rect textBoundingBox = _vm->_gfx->getTextBoundingBox(text, backgroundRect, align); @@ -203,7 +226,12 @@ void Menu::drawButtonImages(const char *text, MystAreaImageSwitch *area, Graphic area->setSubImageRect(0, Common::Rect(backgroundRect.left, idle.rect.top, backgroundRect.right, idle.rect.bottom)); // Align the text to the top of the destination rectangles - int16 deltaY = backgroundRect.top - textBoundingBox.top; + int16 deltaY; + if (_vm->getLanguage() == Common::PL_POL) { + deltaY = -2; + } else { + deltaY = backgroundRect.top - textBoundingBox.top; + } if (highlightedIndex) { replaceButtonSubImageWithText(text, align, area, highlightedIndex, backgroundRect, deltaY, 215, 216, 219); @@ -217,7 +245,7 @@ void Menu::drawButtonImages(const char *text, MystAreaImageSwitch *area, Graphic _vm->_gfx->drawText(cardBackground, text, backgroundRect, 181, 184, 189, align, deltaY); } -void Menu::replaceButtonSubImageWithText(const char *text, const Graphics::TextAlign &align, MystAreaImageSwitch *area, +void Menu::replaceButtonSubImageWithText(const Common::U32String &text, const Graphics::TextAlign &align, MystAreaImageSwitch *area, uint16 subimageIndex, const Common::Rect &backgroundRect, int16 deltaY, uint8 r, uint8 g, uint8 b) const { uint16 cardBackground = _vm->getCard()->getBackgroundImageId(); diff --git a/engines/mohawk/myst_stacks/menu.h b/engines/mohawk/myst_stacks/menu.h index 01dd597485..449a8bd97b 100644 --- a/engines/mohawk/myst_stacks/menu.h +++ b/engines/mohawk/myst_stacks/menu.h @@ -82,8 +82,8 @@ private: bool showConfirmationDialog(const char *message, const char *confirmButton, const char *cancelButton); - void drawButtonImages(const char *text, MystAreaImageSwitch *area, Graphics::TextAlign align, uint16 highlightedIndex, uint16 disabledIndex) const; - void replaceButtonSubImageWithText(const char *text, const Graphics::TextAlign &align, MystAreaImageSwitch *area, + void drawButtonImages(const Common::U32String &text, MystAreaImageSwitch *area, Graphics::TextAlign align, uint16 highlightedIndex, uint16 disabledIndex) const; + void replaceButtonSubImageWithText(const Common::U32String &text, const Graphics::TextAlign &align, MystAreaImageSwitch *area, uint16 subimageIndex, const Common::Rect &backgroundRect, int16 deltaY, uint8 r, uint8 g, uint8 b) const; const char **getButtonCaptions() const; diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp index 2f17d5ee16..a668052503 100644 --- a/engines/mohawk/riven.cpp +++ b/engines/mohawk/riven.cpp @@ -406,30 +406,8 @@ void MohawkEngine_Riven::changeToStack(uint16 stackId) { char prefix = RivenStacks::getName(stackId)[0]; // Load the localization override file if any - Common::String languageDatafile = getLanguageDatafile(prefix); - if (!languageDatafile.empty()) { - MohawkArchive *mhk = new MohawkArchive(); - if (mhk->openFile(languageDatafile)) { - - if (stackId == kStackOspit && getLanguage() != Common::EN_ANY && getLanguage() != Common::RU_RUS) { - // WORKAROUND: The international CD versions were repacked for the 25th anniversary release - // so they share the same resources as the English DVD version. The resource IDs for the DVD - // version resources have a delta of 1 in their numbering when compared the the CD version - // resources for Gehn's office. Unfortunately this delta was not compensated when repacking - // the archives. We need to do it here at run time... - mhk->offsetResourceIDs(ID_TBMP, 196, 1); - } else if (stackId == kStackJspit && getLanguage() != Common::EN_ANY && getLanguage() != Common::RU_RUS) { - // WORKAROUND: Same thing with Gehn's imager in the School in Jungle Island. - mhk->offsetResourceIDs(ID_TMOV, 342, -2); - } else if (stackId == kStackGspit && getLanguage() == Common::PL_POL) { - // WORKAROUND: Same thing for the advertisement easter egg on Garden Island. - mhk->offsetResourceIDs(ID_TMOV, 148, 2); - } - - _mhk.push_back(mhk); - } - else - delete mhk; + if (getFeatures() & GF_LANGUAGE_FILES) { + loadLanguageDatafile(prefix, stackId); } // Load files that start with the prefix @@ -532,16 +510,36 @@ bool MohawkEngine_Riven::checkDatafiles() { return false; } -Common::String MohawkEngine_Riven::getLanguageDatafile(char prefix) const { - if (!(getFeatures() & GF_25TH) || getLanguage() == Common::EN_ANY) - return ""; - - Common::String language = getDatafileLanguageName(); +void MohawkEngine_Riven::loadLanguageDatafile(char prefix, uint16 stackId) { + Common::String language = getDatafileLanguageName("a_data_"); if (language.empty()) { - return ""; + return; } - return Common::String::format("%c_data_%s.mhk", prefix, language.c_str()); + Common::String languageDatafile = Common::String::format("%c_data_%s.mhk", prefix, language.c_str()); + + MohawkArchive *mhk = new MohawkArchive(); + if (mhk->openFile(languageDatafile)) { + + if (stackId == kStackOspit && getLanguage() != Common::EN_ANY && getLanguage() != Common::RU_RUS) { + // WORKAROUND: The international CD versions were repacked for the 25th anniversary release + // so they share the same resources as the English DVD version. The resource IDs for the DVD + // version resources have a delta of 1 in their numbering when compared the the CD version + // resources for Gehn's office. Unfortunately this delta was not compensated when repacking + // the archives. We need to do it here at run time... + mhk->offsetResourceIDs(ID_TBMP, 196, 1); + } else if (stackId == kStackJspit && getLanguage() != Common::EN_ANY && getLanguage() != Common::RU_RUS) { + // WORKAROUND: Same thing with Gehn's imager in the School in Jungle Island. + mhk->offsetResourceIDs(ID_TMOV, 342, -2); + } else if (stackId == kStackGspit && getLanguage() == Common::PL_POL) { + // WORKAROUND: Same thing for the advertisement easter egg on Garden Island. + mhk->offsetResourceIDs(ID_TMOV, 148, 2); + } + + _mhk.push_back(mhk); + } else { + delete mhk; + } } RivenStack *MohawkEngine_Riven::constructStackById(uint16 id) { diff --git a/engines/mohawk/riven.h b/engines/mohawk/riven.h index 30c6eb39fe..b887fc1184 100644 --- a/engines/mohawk/riven.h +++ b/engines/mohawk/riven.h @@ -111,8 +111,7 @@ private: // Datafiles MohawkArchive *_extrasFile; // We need a separate handle for the extra data const char **listExpectedDatafiles() const; - Common::String getDatafileLanguageName() const; - Common::String getLanguageDatafile(char prefix) const; + void loadLanguageDatafile(char prefix, uint16 stackId); bool checkDatafiles(); RivenConsole *_console; -- cgit v1.2.3