diff options
Diffstat (limited to 'engines/sword25')
-rw-r--r-- | engines/sword25/POTFILES | 1 | ||||
-rw-r--r-- | engines/sword25/configure.engine | 2 | ||||
-rw-r--r-- | engines/sword25/detection.cpp | 17 | ||||
-rw-r--r-- | engines/sword25/detection_tables.h | 29 | ||||
-rw-r--r-- | engines/sword25/fmv/movieplayer.cpp | 2 | ||||
-rw-r--r-- | engines/sword25/fmv/movieplayer.h | 2 | ||||
-rw-r--r-- | engines/sword25/gfx/animationresource.cpp | 5 | ||||
-rw-r--r-- | engines/sword25/gfx/fontresource.cpp | 5 | ||||
-rw-r--r-- | engines/sword25/gfx/text.cpp | 3 | ||||
-rw-r--r-- | engines/sword25/kernel/kernel_script.cpp | 1 | ||||
-rw-r--r-- | engines/sword25/package/packagemanager.cpp | 45 | ||||
-rw-r--r-- | engines/sword25/package/packagemanager.h | 3 | ||||
-rw-r--r-- | engines/sword25/script/luacallback.cpp | 2 | ||||
-rw-r--r-- | engines/sword25/script/luascript.cpp | 2 | ||||
-rw-r--r-- | engines/sword25/sword25.cpp | 2 | ||||
-rw-r--r-- | engines/sword25/util/lua/lbaselib.cpp | 2 | ||||
-rw-r--r-- | engines/sword25/util/lua/ldo.cpp | 7 | ||||
-rw-r--r-- | engines/sword25/util/lua/luaconf.h | 2 |
18 files changed, 93 insertions, 39 deletions
diff --git a/engines/sword25/POTFILES b/engines/sword25/POTFILES new file mode 100644 index 0000000000..f4b0e6fc27 --- /dev/null +++ b/engines/sword25/POTFILES @@ -0,0 +1 @@ +engines/sword25/detection.cpp diff --git a/engines/sword25/configure.engine b/engines/sword25/configure.engine index 6a9428c758..f805483f54 100644 --- a/engines/sword25/configure.engine +++ b/engines/sword25/configure.engine @@ -1,3 +1,3 @@ # This file is included from the main "configure" script # add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps] -add_engine sword25 "Broken Sword 2.5" yes "" "" "png zlib 16bit" +add_engine sword25 "Broken Sword 2.5" yes "" "" "png zlib 16bit highres" diff --git a/engines/sword25/detection.cpp b/engines/sword25/detection.cpp index df68d11609..4ca565c972 100644 --- a/engines/sword25/detection.cpp +++ b/engines/sword25/detection.cpp @@ -21,6 +21,7 @@ */ #include "base/plugins.h" +#include "common/translation.h" #include "engines/advancedDetector.h" #include "sword25/sword25.h" @@ -41,10 +42,17 @@ static const char *directoryGlobs[] = { 0 }; +static const ExtraGuiOption sword25ExtraGuiOption = { + _s("Use English speech"), + _s("Use English speech instead of German for every language other than German"), + "english_speech", + false +}; + class Sword25MetaEngine : public AdvancedMetaEngine { public: Sword25MetaEngine() : AdvancedMetaEngine(Sword25::gameDescriptions, sizeof(ADGameDescription), sword25Game) { - _guioptions = GUIO1(GUIO_NOMIDI); + _guiOptions = GUIO1(GUIO_NOMIDI); _maxScanDepth = 2; _directoryGlobs = directoryGlobs; } @@ -58,6 +66,7 @@ public: virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; virtual bool hasFeature(MetaEngineFeature f) const; + virtual const ExtraGuiOptions getExtraGuiOptions(const Common::String &target) const; virtual int getMaximumSaveSlot() const { return Sword25::PersistenceService::getSlotCount(); } virtual SaveStateList listSaves(const char *target) const; }; @@ -74,6 +83,12 @@ bool Sword25MetaEngine::hasFeature(MetaEngineFeature f) const { (f == kSupportsListSaves); } +const ExtraGuiOptions Sword25MetaEngine::getExtraGuiOptions(const Common::String &target) const { + ExtraGuiOptions options; + options.push_back(sword25ExtraGuiOption); + return options; +} + SaveStateList Sword25MetaEngine::listSaves(const char *target) const { Common::String pattern = target; pattern = pattern + ".???"; diff --git a/engines/sword25/detection_tables.h b/engines/sword25/detection_tables.h index b58f430fcf..927060bf18 100644 --- a/engines/sword25/detection_tables.h +++ b/engines/sword25/detection_tables.h @@ -29,7 +29,7 @@ static const ADGameDescription gameDescriptions[] = { AD_ENTRY1s("data.b25c", "f8b6e03ada2d2f6cf27fbc11ad1572e9", 654310588), Common::EN_ANY, Common::kPlatformUnknown, - ADGF_TESTING, + ADGF_NO_FLAGS, GUIO1(GUIO_NOASPECT) }, { @@ -38,7 +38,7 @@ static const ADGameDescription gameDescriptions[] = { AD_ENTRY1s("lang_fr.b25c", "690caf157387e06d2c3d1ca53c43f428", 1006043), Common::FR_FRA, Common::kPlatformUnknown, - ADGF_TESTING, + ADGF_NO_FLAGS, GUIO1(GUIO_NOASPECT) }, { @@ -47,7 +47,7 @@ static const ADGameDescription gameDescriptions[] = { AD_ENTRY1s("data.b25c", "f8b6e03ada2d2f6cf27fbc11ad1572e9", 654310588), Common::DE_DEU, Common::kPlatformUnknown, - ADGF_TESTING, + ADGF_NO_FLAGS, GUIO1(GUIO_NOASPECT) }, { @@ -56,7 +56,7 @@ static const ADGameDescription gameDescriptions[] = { AD_ENTRY1s("lang_hr.b25c", "e881054d1f8ec1e527422fc521c25405", 1273217), Common::HR_HRV, Common::kPlatformUnknown, - ADGF_TESTING, + ADGF_NO_FLAGS, GUIO1(GUIO_NOASPECT) }, { @@ -65,7 +65,7 @@ static const ADGameDescription gameDescriptions[] = { AD_ENTRY1s("lang_it.b25c", "f3325666da0515cc2b42062e953c0889", 996197), Common::IT_ITA, Common::kPlatformUnknown, - ADGF_TESTING, + ADGF_NO_FLAGS, GUIO1(GUIO_NOASPECT) }, { @@ -74,7 +74,7 @@ static const ADGameDescription gameDescriptions[] = { AD_ENTRY1s("lang_pl.b25c", "49dc1a20f95391a808e475c49be2bac0", 1281799), Common::PL_POL, Common::kPlatformUnknown, - ADGF_TESTING, + ADGF_NO_FLAGS, GUIO1(GUIO_NOASPECT) }, { @@ -83,7 +83,7 @@ static const ADGameDescription gameDescriptions[] = { AD_ENTRY1s("lang_pt.b25c", "1df701432f9e13dcefe1adeb890b9c69", 993812), Common::PT_BRA, Common::kPlatformUnknown, - ADGF_TESTING, + ADGF_NO_FLAGS, GUIO1(GUIO_NOASPECT) }, { @@ -92,7 +92,7 @@ static const ADGameDescription gameDescriptions[] = { AD_ENTRY1s("lang_ru.b25c", "deb33dd2f90a71ff60181918a8ce5063", 1235378), Common::RU_RUS, Common::kPlatformUnknown, - ADGF_TESTING, + ADGF_NO_FLAGS, GUIO1(GUIO_NOASPECT) }, { @@ -101,7 +101,7 @@ static const ADGameDescription gameDescriptions[] = { AD_ENTRY1s("lang_es.b25c", "384c19072d83725f351bb9ecb4d3f02b", 987965), Common::ES_ESP, Common::kPlatformUnknown, - ADGF_TESTING, + ADGF_NO_FLAGS, GUIO1(GUIO_NOASPECT) }, // Hungarian "psylog" version. @@ -112,7 +112,7 @@ static const ADGameDescription gameDescriptions[] = { AD_ENTRY1s("lang_hu.b25c", "7de51a3b4926a192549e75b1a7d81667", 1864915), Common::HU_HUN, Common::kPlatformUnknown, - ADGF_TESTING, + ADGF_NO_FLAGS, GUIO1(GUIO_NOASPECT) }, @@ -126,19 +126,22 @@ static const ADGameDescription gameDescriptions[] = { AD_LISTEND}, Common::EN_ANY, Common::kPlatformUnknown, - GF_EXTRACTED | ADGF_TESTING, + GF_EXTRACTED | ADGF_NO_FLAGS, GUIO1(GUIO_NOASPECT) }, // Distributed by ScummVM // Contains all language packs, English voice-overs and Hungarian version + // Mark it as Unknown Language since it contains multiple languages. If we + // mark it as English, then changing the language in-game causes the detection + // to fail the next time we try to start the engine. { "sword25", "Latest version", AD_ENTRY1s("data.b25c", "880a8a67faf4a4e7ab62cf114b771428", 827397764), - Common::EN_ANY, + Common::UNK_LANG, Common::kPlatformUnknown, - ADGF_TESTING, + ADGF_NO_FLAGS, GUIO1(GUIO_NOASPECT) }, diff --git a/engines/sword25/fmv/movieplayer.cpp b/engines/sword25/fmv/movieplayer.cpp index eb0f0390dc..62a897a332 100644 --- a/engines/sword25/fmv/movieplayer.cpp +++ b/engines/sword25/fmv/movieplayer.cpp @@ -58,6 +58,8 @@ MoviePlayer::~MoviePlayer() { } bool MoviePlayer::loadMovie(const Common::String &filename, uint z) { + if (isMovieLoaded()) + unloadMovie(); // Get the file and load it into the decoder Common::SeekableReadStream *in = Kernel::getInstance()->getPackage()->getStream(filename); _decoder.loadStream(in); diff --git a/engines/sword25/fmv/movieplayer.h b/engines/sword25/fmv/movieplayer.h index 95fb05ee60..b59b223b4c 100644 --- a/engines/sword25/fmv/movieplayer.h +++ b/engines/sword25/fmv/movieplayer.h @@ -67,7 +67,7 @@ public: * movie file, it will be unloaded and, if necessary, stopped playing. * @param Filename The filename of the movie file to be loaded * @param Z Z indicates the position of the film on the main graphics layer - * @return Returns false if an error occured while loading, otherwise true. + * @return Returns false if an error occurred while loading, otherwise true. */ bool loadMovie(const Common::String &filename, uint z); diff --git a/engines/sword25/gfx/animationresource.cpp b/engines/sword25/gfx/animationresource.cpp index 431d466658..423a2b86b4 100644 --- a/engines/sword25/gfx/animationresource.cpp +++ b/engines/sword25/gfx/animationresource.cpp @@ -211,8 +211,9 @@ bool AnimationResource::precacheAllFrames() const { error("Could not precache \"%s\".", (*iter).fileName.c_str()); return false; } -#else - Kernel::getInstance()->getResourceManager()->requestResource((*iter).fileName); +#else + Resource *pResource = Kernel::getInstance()->getResourceManager()->requestResource((*iter).fileName); + pResource->release(); //unlock precached resource #endif } diff --git a/engines/sword25/gfx/fontresource.cpp b/engines/sword25/gfx/fontresource.cpp index c4d4c3c52e..1d7aedcb6e 100644 --- a/engines/sword25/gfx/fontresource.cpp +++ b/engines/sword25/gfx/fontresource.cpp @@ -103,8 +103,9 @@ bool FontResource::parserCallback_font(ParserNode *node) { if (!_pKernel->getResourceManager()->precacheResource(_bitmapFileName)) { error("Could not precache \"%s\".", _bitmapFileName.c_str()); } -#else - _pKernel->getResourceManager()->requestResource(_bitmapFileName); +#else + Resource *pResource = _pKernel->getResourceManager()->requestResource(_bitmapFileName); + pResource->release(); //unlock precached resource #endif return true; diff --git a/engines/sword25/gfx/text.cpp b/engines/sword25/gfx/text.cpp index d409c538c0..769c9b1162 100644 --- a/engines/sword25/gfx/text.cpp +++ b/engines/sword25/gfx/text.cpp @@ -77,7 +77,8 @@ bool Text::setFont(const Common::String &font) { return false; } #else - getResourceManager()->requestResource(font); + Resource *pResource = getResourceManager()->requestResource(font); + pResource->release(); //unlock precached resource _font = font; updateFormat(); forceRefresh(); diff --git a/engines/sword25/kernel/kernel_script.cpp b/engines/sword25/kernel/kernel_script.cpp index 1b7c6a6f14..40dcbd5b98 100644 --- a/engines/sword25/kernel/kernel_script.cpp +++ b/engines/sword25/kernel/kernel_script.cpp @@ -257,6 +257,7 @@ static int processMessages(lua_State *L) { // to the closeWanted() opcode; see also the TODO comment in there. lua_pushbooleancpp(L, !Engine::shouldQuit()); + g_system->delayMillis(10); return 1; } diff --git a/engines/sword25/package/packagemanager.cpp b/engines/sword25/package/packagemanager.cpp index 2db4f2da74..457dda6268 100644 --- a/engines/sword25/package/packagemanager.cpp +++ b/engines/sword25/package/packagemanager.cpp @@ -56,7 +56,8 @@ static Common::String normalizePath(const Common::String &path, const Common::St PackageManager::PackageManager(Kernel *pKernel) : Service(pKernel), _currentDirectory(PATH_SEPARATOR), - _rootFolder(ConfMan.get("path")) { + _rootFolder(ConfMan.get("path")), + _useEnglishSpeech(ConfMan.getBool("english_speech")) { if (!registerScriptBindings()) error("Script bindings could not be registered."); else @@ -71,14 +72,34 @@ PackageManager::~PackageManager() { } +Common::String PackageManager::ensureSpeechLang(const Common::String &fileName) { + if (!_useEnglishSpeech || fileName.size() < 9 || !fileName.hasPrefix("/speech/")) + return fileName; + + // Always keep German speech as a fallback in case the English speech pack is not present. + // However this means we cannot play with German text and English voice. + if (fileName.hasPrefix("/speech/de")) + return fileName; + + Common::String newFileName = "/speech/en"; + int fileIdx = 9; + while (fileIdx < fileName.size() && fileName[fileIdx] != '/') + ++fileIdx; + if (fileIdx < fileName.size()) + newFileName += fileName.c_str() + fileIdx; + + return newFileName; +} + /** * Scans through the archive list for a specified file */ Common::ArchiveMemberPtr PackageManager::getArchiveMember(const Common::String &fileName) { + Common::String fileName2 = ensureSpeechLang(fileName); // Loop through checking each archive Common::List<ArchiveEntry *>::iterator i; for (i = _archiveList.begin(); i != _archiveList.end(); ++i) { - if (!fileName.hasPrefix((*i)->_mountPath)) { + if (!fileName2.hasPrefix((*i)->_mountPath)) { // The mount path is in different subtree. Skipping continue; } @@ -87,7 +108,7 @@ Common::ArchiveMemberPtr PackageManager::getArchiveMember(const Common::String & Common::Archive *archiveFolder = (*i)->archive; // Construct relative path - Common::String resPath(&fileName.c_str()[(*i)->_mountPath.size()]); + Common::String resPath(&fileName2.c_str()[(*i)->_mountPath.size()]); if (archiveFolder->hasFile(resPath)) { return archiveFolder->getMember(resPath); @@ -203,23 +224,29 @@ bool PackageManager::changeDirectory(const Common::String &directory) { } Common::String PackageManager::getAbsolutePath(const Common::String &fileName) { - return normalizePath(fileName, _currentDirectory); + return normalizePath(ensureSpeechLang(fileName), _currentDirectory); } bool PackageManager::fileExists(const Common::String &fileName) { // FIXME: The current Zip implementation doesn't support getting a folder entry, which is needed for detecting - // the English voick pack - if (fileName == "/speech/en") { + // the English voice pack + Common::String fileName2 = ensureSpeechLang(fileName); + if (fileName2 == "/speech/en") { // To get around this, change to detecting one of the files in the folder - return getArchiveMember(normalizePath(fileName + "/APO0001.ogg", _currentDirectory)); + bool exists = getArchiveMember(normalizePath(fileName2 + "/APO0001.ogg", _currentDirectory)); + if (!exists && _useEnglishSpeech) { + _useEnglishSpeech = false; + warning("English speech not found"); + } + return exists; } - Common::ArchiveMemberPtr fileNode = getArchiveMember(normalizePath(fileName, _currentDirectory)); + Common::ArchiveMemberPtr fileNode = getArchiveMember(normalizePath(fileName2, _currentDirectory)); return fileNode; } int PackageManager::doSearch(Common::ArchiveMemberList &list, const Common::String &filter, const Common::String &path, uint typeFilter) { - Common::String normalizedFilter = normalizePath(filter, _currentDirectory); + Common::String normalizedFilter = normalizePath(ensureSpeechLang(filter), _currentDirectory); int num = 0; if (path.size() > 0) diff --git a/engines/sword25/package/packagemanager.h b/engines/sword25/package/packagemanager.h index a1806a4046..5475cb02fc 100644 --- a/engines/sword25/package/packagemanager.h +++ b/engines/sword25/package/packagemanager.h @@ -87,6 +87,9 @@ private: Common::String _currentDirectory; Common::FSNode _rootFolder; Common::List<ArchiveEntry *> _archiveList; + + bool _useEnglishSpeech; + Common::String ensureSpeechLang(const Common::String &fileName); Common::ArchiveMemberPtr getArchiveMember(const Common::String &fileName); diff --git a/engines/sword25/script/luacallback.cpp b/engines/sword25/script/luacallback.cpp index 72f7e01612..acfda498c6 100644 --- a/engines/sword25/script/luacallback.cpp +++ b/engines/sword25/script/luacallback.cpp @@ -119,7 +119,7 @@ void LuaCallback::invokeCallbackFunctions(lua_State *L, uint objectHandle) { // Lua_pcall the function and the parameters pop themselves from the stack if (lua_pcall(L, argumentCount, 0, 0) != 0) { // An error has occurred - error("An error occured executing a callback function: %s", lua_tostring(L, -1)); + error("An error occurred executing a callback function: %s", lua_tostring(L, -1)); // Pop error message from the stack lua_pop(L, 1); diff --git a/engines/sword25/script/luascript.cpp b/engines/sword25/script/luascript.cpp index e93289596b..3aca6676ac 100644 --- a/engines/sword25/script/luascript.cpp +++ b/engines/sword25/script/luascript.cpp @@ -214,7 +214,7 @@ bool LuaScriptEngine::executeBuffer(const byte *data, uint size, const Common::S // Run buffer contents if (lua_pcall(_state, 0, 0, -2) != 0) { - error("An error occured while executing \"%s\":\n%s.", + error("An error occurred while executing \"%s\":\n%s.", name.c_str(), lua_tostring(_state, -1)); lua_pop(_state, 2); diff --git a/engines/sword25/sword25.cpp b/engines/sword25/sword25.cpp index 5223481d50..b6f2641714 100644 --- a/engines/sword25/sword25.cpp +++ b/engines/sword25/sword25.cpp @@ -120,7 +120,7 @@ Common::Error Sword25Engine::appStart() { // Pass the command line to the script engine. ScriptEngine *scriptPtr = Kernel::getInstance()->getScript(); if (!scriptPtr) { - error("Script intialization failed."); + error("Script initialization failed."); return Common::kUnknownError; } diff --git a/engines/sword25/util/lua/lbaselib.cpp b/engines/sword25/util/lua/lbaselib.cpp index 659c61d956..ec044970ad 100644 --- a/engines/sword25/util/lua/lbaselib.cpp +++ b/engines/sword25/util/lua/lbaselib.cpp @@ -492,7 +492,7 @@ static int costatus (lua_State *L, lua_State *co) { else return CO_SUS; /* initial state */ } - default: /* some error occured */ + default: /* some error occurred */ return CO_DEAD; } } diff --git a/engines/sword25/util/lua/ldo.cpp b/engines/sword25/util/lua/ldo.cpp index a230097f2a..f4139cb9fc 100644 --- a/engines/sword25/util/lua/ldo.cpp +++ b/engines/sword25/util/lua/ldo.cpp @@ -111,10 +111,9 @@ static const char* luaErrorDescription[] = { void luaD_throw (lua_State *L, int errcode) { if (L->errorJmp) { L->errorJmp->status = errcode; - // LUAI_THROW has been replaced with an error message in ScummVM, together - // with the LUA error code and description - //LUAI_THROW(L, L->errorJmp); - error("LUA error occured, error code is %d (%s)", errcode, luaErrorDescription[errcode]); + // LUAI_THROW is sometimes used to ignore the error and restore LUA state + LUAI_THROW(L, L->errorJmp); + error("LUA error occurred, error code is %d (%s)", errcode, luaErrorDescription[errcode]); } else { L->status = cast_byte(errcode); diff --git a/engines/sword25/util/lua/luaconf.h b/engines/sword25/util/lua/luaconf.h index fb85983998..53d0f55290 100644 --- a/engines/sword25/util/lua/luaconf.h +++ b/engines/sword25/util/lua/luaconf.h @@ -621,7 +621,7 @@ union luai_Cast { double l_d; long l_l; }; #else /* default handling with long jumps */ -//#define LUAI_THROW(L,c) longjmp((c)->b, 1) // replaced with error() in ScummVM +#define LUAI_THROW(L,c) longjmp((c)->b, 1) #define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } #define luai_jmpbuf jmp_buf |