aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/advancedDetector.cpp175
-rw-r--r--engines/advancedDetector.h57
-rw-r--r--engines/agi/agi.cpp37
-rw-r--r--engines/agi/detection.cpp30
-rw-r--r--engines/agi/predictive.cpp6
-rw-r--r--engines/agi/sound_2gs.cpp2
-rw-r--r--engines/agi/sound_pcjr.cpp5
-rw-r--r--engines/agos/detection.cpp34
-rw-r--r--engines/cine/detection.cpp31
-rw-r--r--engines/cruise/detection.cpp30
-rw-r--r--engines/draci/detection.cpp29
-rw-r--r--engines/drascula/detection.cpp30
-rw-r--r--engines/gob/detection.cpp32
-rw-r--r--engines/groovie/detection.cpp32
-rw-r--r--engines/groovie/groovie.cpp5
-rw-r--r--engines/groovie/groovie.h1
-rw-r--r--engines/groovie/music.cpp3
-rw-r--r--engines/groovie/resource.cpp13
-rw-r--r--engines/hugo/detection.cpp28
-rw-r--r--engines/kyra/animator_mr.cpp7
-rw-r--r--engines/kyra/detection.cpp32
-rw-r--r--engines/kyra/detection_tables.h105
-rw-r--r--engines/kyra/gui_lol.cpp15
-rw-r--r--engines/kyra/gui_mr.cpp20
-rw-r--r--engines/kyra/items_lol.cpp26
-rw-r--r--engines/kyra/kyra_mr.cpp33
-rw-r--r--engines/kyra/kyra_mr.h2
-rw-r--r--engines/kyra/kyra_v1.cpp77
-rw-r--r--engines/kyra/kyra_v1.h4
-rw-r--r--engines/kyra/lol.cpp74
-rw-r--r--engines/kyra/lol.h3
-rw-r--r--engines/kyra/scene_lol.cpp42
-rw-r--r--engines/kyra/script_lol.cpp41
-rw-r--r--engines/kyra/script_tim.cpp26
-rw-r--r--engines/kyra/sequences_lol.cpp72
-rw-r--r--engines/kyra/sound_lok.cpp5
-rw-r--r--engines/kyra/sound_lol.cpp40
-rw-r--r--engines/kyra/staticres.cpp2
-rw-r--r--engines/kyra/text_hof.cpp9
-rw-r--r--engines/kyra/text_mr.cpp12
-rw-r--r--engines/lastexpress/data/animation.cpp13
-rw-r--r--engines/lastexpress/debug.cpp2
-rw-r--r--engines/lastexpress/detection.cpp35
-rw-r--r--engines/lastexpress/game/sound.cpp2
-rw-r--r--engines/lastexpress/lastexpress.cpp2
-rw-r--r--engines/lastexpress/lastexpress.h5
-rw-r--r--engines/lure/detection.cpp32
-rw-r--r--engines/m4/detection.cpp32
-rw-r--r--engines/made/detection.cpp29
-rw-r--r--engines/mohawk/detection.cpp33
-rw-r--r--engines/mohawk/detection_tables.h434
-rw-r--r--engines/parallaction/detection.cpp29
-rw-r--r--engines/saga/detection.cpp30
-rw-r--r--engines/sci/console.cpp176
-rw-r--r--engines/sci/console.h2
-rw-r--r--engines/sci/detection.cpp30
-rw-r--r--engines/sci/detection_tables.h8
-rw-r--r--engines/sci/engine/kfile.cpp28
-rw-r--r--engines/sci/engine/scriptdebug.cpp10
-rw-r--r--engines/sci/engine/state.cpp8
-rw-r--r--engines/sci/engine/vm.cpp24
-rw-r--r--engines/sci/engine/vm_types.cpp4
-rw-r--r--engines/sci/engine/workarounds.cpp5
-rw-r--r--engines/sci/graphics/compare.cpp9
-rw-r--r--engines/sci/graphics/controls.cpp1
-rw-r--r--engines/sci/graphics/menu.cpp4
-rw-r--r--engines/sci/graphics/picture.cpp2
-rw-r--r--engines/sci/graphics/screen.cpp3
-rw-r--r--engines/sci/graphics/transitions.cpp8
-rw-r--r--engines/sci/graphics/view.cpp4
-rw-r--r--engines/sci/sci.h2
-rw-r--r--engines/sci/sound/drivers/amigamac.cpp62
-rw-r--r--engines/scumm/gfx_towns.cpp19
-rw-r--r--engines/scumm/he/resource_he.cpp2
-rw-r--r--engines/scumm/scumm.cpp14
-rw-r--r--engines/sword25/detection.cpp34
-rw-r--r--engines/sword25/fmv/theora_decoder.cpp6
-rw-r--r--engines/sword25/gfx/animationresource.cpp14
-rw-r--r--engines/sword25/gfx/animationresource.h21
-rw-r--r--engines/sword25/gfx/fontresource.cpp12
-rw-r--r--engines/sword25/sfx/soundengine.cpp63
-rw-r--r--engines/sword25/util/lua/ldblib.cpp4
-rw-r--r--engines/teenagent/detection.cpp31
-rw-r--r--engines/testbed/config.cpp16
-rw-r--r--engines/testbed/config.h6
-rw-r--r--engines/testbed/detection.cpp31
-rw-r--r--engines/testbed/fs.cpp4
-rw-r--r--engines/testbed/graphics.cpp28
-rw-r--r--engines/testbed/graphics.h4
-rw-r--r--engines/testbed/midi.cpp4
-rw-r--r--engines/testbed/misc.cpp7
-rw-r--r--engines/testbed/misc.h2
-rw-r--r--engines/testbed/savegame.cpp14
-rw-r--r--engines/testbed/sound.h4
-rw-r--r--engines/testbed/testbed.cpp8
-rw-r--r--engines/testbed/testsuite.cpp5
-rw-r--r--engines/testbed/testsuite.h6
-rw-r--r--engines/tinsel/detection.cpp35
-rw-r--r--engines/toon/audio.cpp67
-rw-r--r--engines/toon/audio.h4
-rw-r--r--engines/toon/detection.cpp35
-rw-r--r--engines/toon/toon.cpp1
-rw-r--r--engines/toon/toon.h3
-rw-r--r--engines/touche/detection.cpp35
-rw-r--r--engines/tsage/core.cpp217
-rw-r--r--engines/tsage/core.h6
-rw-r--r--engines/tsage/detection.cpp21
-rw-r--r--engines/tsage/detection_tables.h39
-rw-r--r--engines/tsage/dialogs.cpp16
-rw-r--r--engines/tsage/events.cpp10
-rw-r--r--engines/tsage/events.h6
-rw-r--r--engines/tsage/globals.cpp29
-rw-r--r--engines/tsage/globals.h2
-rw-r--r--engines/tsage/graphics.cpp71
-rw-r--r--engines/tsage/graphics.h2
-rw-r--r--engines/tsage/ringworld_demo.cpp12
-rw-r--r--engines/tsage/ringworld_scenes1.cpp60
-rw-r--r--engines/tsage/ringworld_scenes1.h4
-rw-r--r--engines/tsage/saveload.cpp1
-rw-r--r--engines/tsage/saveload.h2
-rw-r--r--engines/tsage/tsage.h1
-rw-r--r--engines/tucker/detection.cpp29
122 files changed, 1844 insertions, 1518 deletions
diff --git a/engines/advancedDetector.cpp b/engines/advancedDetector.cpp
index d093c958e7..b0a304aad9 100644
--- a/engines/advancedDetector.cpp
+++ b/engines/advancedDetector.cpp
@@ -20,9 +20,6 @@
*
*/
-// FIXME: Avoid using printf
-#define FORBIDDEN_SYMBOL_EXCEPTION_printf
-
#include "common/debug.h"
#include "common/util.h"
#include "common/hash-str.h"
@@ -30,55 +27,13 @@
#include "common/macresman.h"
#include "common/md5.h"
#include "common/config-manager.h"
+#include "common/system.h"
#include "common/textconsole.h"
+#include "common/translation.h"
#include "engines/advancedDetector.h"
-/**
- * A list of pointers to ADGameDescription structs (or subclasses thereof).
- */
-typedef Common::Array<const ADGameDescription*> ADGameDescList;
-
-
-/**
- * Detect games in specified directory.
- * Parameters language and platform are used to pass on values
- * specified by the user. I.e. this is used to restrict search scope.
- *
- * @param fslist FSList to scan or NULL for scanning all specified
- * default directories.
- * @param params a ADParams struct containing various parameters
- * @param language restrict results to specified language only
- * @param platform restrict results to specified platform only
- * @return list of ADGameDescription (or subclass) pointers corresponding to matched games
- */
-static ADGameDescList detectGame(const Common::FSList &fslist, const ADParams &params, Common::Language language, Common::Platform platform, const Common::String &extra);
-
-
-/**
- * Returns list of targets supported by the engine.
- * Distinguishes engines with single ID
- */
-static GameList gameIDList(const ADParams &params) {
- if (params.singleid != NULL) {
- GameList gl;
-
- const PlainGameDescriptor *g = params.list;
- while (g->gameid) {
- if (0 == scumm_stricmp(params.singleid, g->gameid)) {
- gl.push_back(GameDescriptor(g->gameid, g->description));
-
- return gl;
- }
- g++;
- }
- error("Engine %s doesn't have its singleid specified in ids list", params.singleid);
- }
-
- return GameList(params.list);
-}
-
-static void upgradeTargetIfNecessary(const ADParams &params) {
+void AdvancedMetaEngine::upgradeTargetIfNecessary() const {
if (params.obsoleteList == 0)
return;
@@ -110,11 +65,11 @@ namespace AdvancedDetector {
GameDescriptor findGameID(
const char *gameid,
- const PlainGameDescriptor *list,
+ const PlainGameDescriptor *gameDescriptors,
const ADObsoleteGameID *obsoleteList
) {
- // First search the list of supported game IDs for a match.
- const PlainGameDescriptor *g = findPlainGameDescriptor(gameid, list);
+ // First search the list of supported gameids for a match.
+ const PlainGameDescriptor *g = findPlainGameDescriptor(gameid, gameDescriptors);
if (g)
return GameDescriptor(*g);
@@ -124,7 +79,7 @@ GameDescriptor findGameID(
const ADObsoleteGameID *o = obsoleteList;
while (o->from) {
if (0 == scumm_stricmp(gameid, o->from)) {
- g = findPlainGameDescriptor(o->to, list);
+ g = findPlainGameDescriptor(o->to, gameDescriptors);
if (g && g->description)
return GameDescriptor(gameid, "Obsolete game ID (" + Common::String(g->description) + ")");
else
@@ -190,7 +145,7 @@ static Common::String generatePreferredTarget(const Common::String &id, const AD
return res;
}
-static void updateGameDescriptor(GameDescriptor &desc, const ADGameDescription *realDesc, const ADParams &params) {
+void AdvancedMetaEngine::updateGameDescriptor(GameDescriptor &desc, const ADGameDescription *realDesc) const {
if (params.singleid != NULL) {
desc["preferredtarget"] = desc["gameid"];
desc["gameid"] = params.singleid;
@@ -235,7 +190,7 @@ bool cleanupPirated(ADGameDescList &matched) {
GameList AdvancedMetaEngine::detectGames(const Common::FSList &fslist) const {
- ADGameDescList matches = detectGame(fslist, params, Common::UNK_LANG, Common::kPlatformUnknown, "");
+ ADGameDescList matches = detectGame(fslist, Common::UNK_LANG, Common::kPlatformUnknown, "");
GameList detectedGames;
if (cleanupPirated(matches))
@@ -245,15 +200,15 @@ GameList AdvancedMetaEngine::detectGames(const Common::FSList &fslist) const {
// Use fallback detector if there were no matches by other means
const ADGameDescription *fallbackDesc = fallbackDetect(fslist);
if (fallbackDesc != 0) {
- GameDescriptor desc(toGameDescriptor(*fallbackDesc, params.list));
- updateGameDescriptor(desc, fallbackDesc, params);
+ GameDescriptor desc(toGameDescriptor(*fallbackDesc, params.gameDescriptors));
+ updateGameDescriptor(desc, fallbackDesc);
detectedGames.push_back(desc);
}
} else {
// Otherwise use the found matches
for (uint i = 0; i < matches.size(); i++) {
- GameDescriptor desc(toGameDescriptor(*matches[i], params.list));
- updateGameDescriptor(desc, matches[i], params);
+ GameDescriptor desc(toGameDescriptor(*matches[i], params.gameDescriptors));
+ updateGameDescriptor(desc, matches[i]);
detectedGames.push_back(desc);
}
}
@@ -263,7 +218,7 @@ GameList AdvancedMetaEngine::detectGames(const Common::FSList &fslist) const {
Common::Error AdvancedMetaEngine::createInstance(OSystem *syst, Engine **engine) const {
assert(engine);
- upgradeTargetIfNecessary(params);
+ upgradeTargetIfNecessary();
const ADGameDescription *agdDesc = 0;
Common::Language language = Common::UNK_LANG;
@@ -306,7 +261,7 @@ Common::Error AdvancedMetaEngine::createInstance(OSystem *syst, Engine **engine)
return Common::kNoGameDataFoundError;
}
- ADGameDescList matches = detectGame(files, params, language, platform, extra);
+ ADGameDescList matches = detectGame(files, language, platform, extra);
if (cleanupPirated(matches))
return Common::kNoGameDataFoundError;
@@ -345,7 +300,7 @@ Common::Error AdvancedMetaEngine::createInstance(OSystem *syst, Engine **engine)
Common::updateGameGUIOptions(agdDesc->guioptions | params.guioptions, lang);
- debug(2, "Running %s", toGameDescriptor(*agdDesc, params.list).description().c_str());
+ debug(2, "Running %s", toGameDescriptor(*agdDesc, params.gameDescriptors).description().c_str());
if (!createInstance(syst, engine, agdDesc))
return Common::kNoGameDataFoundError;
else
@@ -358,7 +313,6 @@ struct SizeMD5 {
};
typedef Common::HashMap<Common::String, SizeMD5, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> SizeMD5Map;
-typedef Common::HashMap<Common::String, Common::FSNode, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> FileMap;
static void reportUnknown(const Common::FSNode &path, const SizeMD5Map &filesSizeMD5) {
// TODO: This message should be cleaned up / made more specific.
@@ -366,36 +320,36 @@ static void reportUnknown(const Common::FSNode &path, const SizeMD5Map &filesSiz
//
// Might also be helpful to display the full path (for when this is used
// from the mass detector).
- printf("The game in '%s' seems to be unknown.\n", path.getPath().c_str());
- printf("Please, report the following data to the ScummVM team along with name\n");
- printf("of the game you tried to add and its version/language/etc.:\n");
+ Common::String report = Common::String::format(_("The game in '%s' seems to be unknown."), path.getPath().c_str()) + "\n";
+ report += _("Please, report the following data to the ScummVM team along with name");
+ report += "\n";
+ report += _("of the game you tried to add and its version/language/etc.:");
+ report += "\n";
for (SizeMD5Map::const_iterator file = filesSizeMD5.begin(); file != filesSizeMD5.end(); ++file)
- printf(" {\"%s\", 0, \"%s\", %d},\n", file->_key.c_str(), file->_value.md5.c_str(), file->_value.size);
+ report += Common::String::format(" {\"%s\", 0, \"%s\", %d},\n", file->_key.c_str(), file->_value.md5.c_str(), file->_value.size);
- printf("\n");
-}
+ report += "\n";
-static ADGameDescList detectGameFilebased(const FileMap &allFiles, const ADParams &params);
+ g_system->logMessage(LogMessageType::kInfo, report.c_str());
+}
-static void composeFileHashMap(const Common::FSList &fslist, FileMap &allFiles, int depth, const char * const *directoryGlobs) {
+void AdvancedMetaEngine::composeFileHashMap(const Common::FSList &fslist, FileMap &allFiles, int depth) const {
if (depth <= 0)
return;
if (fslist.empty())
return;
- // First we compose a hashmap of all files in fslist.
- // Includes nifty stuff like removing trailing dots and ignoring case.
for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
if (file->isDirectory()) {
Common::FSList files;
- if (!directoryGlobs)
+ if (!params.directoryGlobs)
continue;
bool matched = false;
- for (const char * const *glob = directoryGlobs; *glob; glob++)
+ for (const char * const *glob = params.directoryGlobs; *glob; glob++)
if (file->getName().matchString(*glob, true)) {
matched = true;
break;
@@ -407,7 +361,7 @@ static void composeFileHashMap(const Common::FSList &fslist, FileMap &allFiles,
if (!file->getChildren(files, Common::FSNode::kListAll))
continue;
- composeFileHashMap(files, allFiles, depth - 1, directoryGlobs);
+ composeFileHashMap(files, allFiles, depth - 1);
}
Common::String tstr = file->getName();
@@ -420,7 +374,7 @@ static void composeFileHashMap(const Common::FSList &fslist, FileMap &allFiles,
}
}
-static ADGameDescList detectGame(const Common::FSList &fslist, const ADParams &params, Common::Language language, Common::Platform platform, const Common::String &extra) {
+ADGameDescList AdvancedMetaEngine::detectGame(const Common::FSList &fslist, Common::Language language, Common::Platform platform, const Common::String &extra) const {
FileMap allFiles;
SizeMD5Map filesSizeMD5;
@@ -434,8 +388,7 @@ static ADGameDescList detectGame(const Common::FSList &fslist, const ADParams &p
debug(3, "Starting detection in dir '%s'", parent.getPath().c_str());
// First we compose a hashmap of all files in fslist.
- // Includes nifty stuff like removing trailing dots and ignoring case.
- composeFileHashMap(fslist, allFiles, (params.depth == 0 ? 1 : params.depth), params.directoryGlobs);
+ composeFileHashMap(fslist, allFiles, (params.depth == 0 ? 1 : params.depth));
// Check which files are included in some ADGameDescription *and* present
// in fslist. Compute MD5s and file sizes for these files.
@@ -453,16 +406,14 @@ static ADGameDescList detectGame(const Common::FSList &fslist, const ADParams &p
// file and as one with resource fork.
if (g->flags & ADGF_MACRESFORK) {
- Common::MacResManager *macResMan = new Common::MacResManager();
+ Common::MacResManager macResMan;
- if (macResMan->open(parent, fname)) {
- tmp.md5 = macResMan->computeResForkMD5AsString(params.md5Bytes);
- tmp.size = macResMan->getResForkDataSize();
+ if (macResMan.open(parent, fname)) {
+ tmp.md5 = macResMan.computeResForkMD5AsString(params.md5Bytes);
+ tmp.size = macResMan.getResForkDataSize();
debug(3, "> '%s': '%s'", fname.c_str(), tmp.md5.c_str());
filesSizeMD5[fname] = tmp;
}
-
- delete macResMan;
} else {
if (allFiles.contains(fname)) {
debug(3, "+ %s", fname.c_str());
@@ -575,19 +526,13 @@ static ADGameDescList detectGame(const Common::FSList &fslist, const ADParams &p
// Filename based fallback
if (params.fileBasedFallback != 0)
- matched = detectGameFilebased(allFiles, params);
+ matched = detectGameFilebased(allFiles);
}
return matched;
}
-/**
- * Check for each ADFileBasedFallback record whether all files listed
- * in it are present. If multiple pass this test, we pick the one with
- * the maximal number of matching files. In case of a tie, the entry
- * coming first in the list is chosen.
- */
-static ADGameDescList detectGameFilebased(const FileMap &allFiles, const ADParams &params) {
+ADGameDescList AdvancedMetaEngine::detectGameFilebased(const FileMap &allFiles) const {
const ADFileBasedFallback *ptr;
const char* const* filenames;
@@ -626,10 +571,14 @@ static ADGameDescList detectGameFilebased(const FileMap &allFiles, const ADParam
if (matchedDesc) { // We got a match
matched.push_back(matchedDesc);
if (params.flags & kADFlagPrintWarningOnFileBasedFallback) {
- printf("Your game version has been detected using filename matching as a\n");
- printf("variant of %s.\n", matchedDesc->gameid);
- printf("If this is an original and unmodified version, please report any\n");
- printf("information previously printed by ScummVM to the team.\n");
+ Common::String report = Common::String::format(_("Your game version has been detected using "
+ "filename matching as a variant of %s."), matchedDesc->gameid);
+ report += "\n";
+ report += _("If this is an original and unmodified version, please report any");
+ report += "\n";
+ report += _("information previously printed by ScummVM to the team.");
+ report += "\n";
+ g_system->logMessage(LogMessageType::kInfo, report.c_str());
}
}
@@ -637,8 +586,38 @@ static ADGameDescList detectGameFilebased(const FileMap &allFiles, const ADParam
}
GameList AdvancedMetaEngine::getSupportedGames() const {
- return gameIDList(params);
+ if (params.singleid != NULL) {
+ GameList gl;
+
+ const PlainGameDescriptor *g = params.gameDescriptors;
+ while (g->gameid) {
+ if (0 == scumm_stricmp(params.singleid, g->gameid)) {
+ gl.push_back(GameDescriptor(g->gameid, g->description));
+
+ return gl;
+ }
+ g++;
+ }
+ error("Engine %s doesn't have its singleid specified in ids list", params.singleid);
+ }
+
+ return GameList(params.gameDescriptors);
}
+
GameDescriptor AdvancedMetaEngine::findGame(const char *gameid) const {
- return AdvancedDetector::findGameID(gameid, params.list, params.obsoleteList);
+ return AdvancedDetector::findGameID(gameid, params.gameDescriptors, params.obsoleteList);
+}
+
+AdvancedMetaEngine::AdvancedMetaEngine(const void *descs, uint descItemSize, const PlainGameDescriptor *gameDescriptors) {
+ params.descs = (const byte *)descs;
+ params.descItemSize = descItemSize;
+ params.md5Bytes = 5000;
+ params.gameDescriptors = gameDescriptors;
+ params.obsoleteList = NULL;
+ params.singleid = NULL;
+ params.fileBasedFallback = NULL;
+ params.flags = 0;
+ params.guioptions = Common::GUIO_NONE;
+ params.depth = 1;
+ params.directoryGlobs = NULL;
}
diff --git a/engines/advancedDetector.h b/engines/advancedDetector.h
index 408c46556d..e5922bea4a 100644
--- a/engines/advancedDetector.h
+++ b/engines/advancedDetector.h
@@ -71,6 +71,11 @@ struct ADGameDescription {
};
/**
+ * A list of pointers to ADGameDescription structs (or subclasses thereof).
+ */
+typedef Common::Array<const ADGameDescription*> ADGameDescList;
+
+/**
* End marker for a table of ADGameDescription structs. Use this to
* terminate a list to be passed to the AdvancedDetector API.
*/
@@ -148,7 +153,7 @@ struct ADParams {
* A list of all gameids (and their corresponding descriptions) supported
* by this engine.
*/
- const PlainGameDescriptor *list;
+ const PlainGameDescriptor *gameDescriptors;
/**
* Structure for autoupgrading obsolete targets (optional).
@@ -214,7 +219,7 @@ namespace AdvancedDetector {
*/
GameDescriptor findGameID(
const char *gameid,
- const PlainGameDescriptor *list,
+ const PlainGameDescriptor *gameDescriptors,
const ADObsoleteGameID *obsoleteList = 0
);
@@ -224,16 +229,26 @@ GameDescriptor findGameID(
* A MetaEngine implementation based around the advanced detector code.
*/
class AdvancedMetaEngine : public MetaEngine {
- const ADParams &params;
+protected:
+ ADParams params;
public:
AdvancedMetaEngine(const ADParams &dp) : params(dp) {}
+ AdvancedMetaEngine(const void *descs, uint descItemSize, const PlainGameDescriptor *gameDescriptors);
+ /**
+ * Returns list of targets supported by the engine.
+ * Distinguishes engines with single ID
+ */
virtual GameList getSupportedGames() const;
+
virtual GameDescriptor findGame(const char *gameid) const;
+
virtual GameList detectGames(const Common::FSList &fslist) const;
+
virtual Common::Error createInstance(OSystem *syst, Engine **engine) const;
- // To be provided by subclasses
+protected:
+ // To be implemented by subclasses
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const = 0;
/**
@@ -244,6 +259,40 @@ public:
virtual const ADGameDescription *fallbackDetect(const Common::FSList &fslist) const {
return 0;
}
+
+protected:
+ typedef Common::HashMap<Common::String, Common::FSNode, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> FileMap;
+
+ /**
+ * Detect games in specified directory.
+ * Parameters language and platform are used to pass on values
+ * specified by the user. I.e. this is used to restrict search scope.
+ *
+ * @param fslist FSList to scan or NULL for scanning all specified
+ * default directories.
+ * @param language restrict results to specified language only
+ * @param platform restrict results to specified platform only
+ * @return list of ADGameDescription (or subclass) pointers corresponding to matched games
+ */
+ ADGameDescList detectGame(const Common::FSList &fslist, Common::Language language, Common::Platform platform, const Common::String &extra) const;
+
+ /**
+ * Check for each ADFileBasedFallback record whether all files listed
+ * in it are present. If multiple pass this test, we pick the one with
+ * the maximal number of matching files. In case of a tie, the entry
+ * coming first in the list is chosen.
+ */
+ ADGameDescList detectGameFilebased(const FileMap &allFiles) const;
+
+ void upgradeTargetIfNecessary() const;
+
+ void updateGameDescriptor(GameDescriptor &desc, const ADGameDescription *realDesc) const;
+
+ /**
+ * Compose a hashmap of all files in fslist.
+ * Includes nifty stuff like removing trailing dots and ignoring case.
+ */
+ void composeFileHashMap(const Common::FSList &fslist, FileMap &allFiles, int depth) const;
};
#endif
diff --git a/engines/agi/agi.cpp b/engines/agi/agi.cpp
index 78316588b0..811a58f45d 100644
--- a/engines/agi/agi.cpp
+++ b/engines/agi/agi.cpp
@@ -131,46 +131,65 @@ void AgiEngine::processEvents() {
switch (key = event.kbd.keycode) {
case Common::KEYCODE_LEFT:
case Common::KEYCODE_KP4:
- if (_allowSynthetic || !event.synthetic)
+ if (_predictiveDialogRunning && key == Common::KEYCODE_KP4)
+ key = event.kbd.ascii;
+ else if (_allowSynthetic || !event.synthetic)
key = KEY_LEFT;
break;
case Common::KEYCODE_RIGHT:
case Common::KEYCODE_KP6:
- if (_allowSynthetic || !event.synthetic)
+ if (_predictiveDialogRunning && key == Common::KEYCODE_KP6)
+ key = event.kbd.ascii;
+ else if (_allowSynthetic || !event.synthetic)
key = KEY_RIGHT;
break;
case Common::KEYCODE_UP:
case Common::KEYCODE_KP8:
- if (_allowSynthetic || !event.synthetic)
+ if (_predictiveDialogRunning && key == Common::KEYCODE_KP8)
+ key = event.kbd.ascii;
+ else if (_allowSynthetic || !event.synthetic)
key = KEY_UP;
break;
case Common::KEYCODE_DOWN:
case Common::KEYCODE_KP2:
- if (_allowSynthetic || !event.synthetic)
+ if (_predictiveDialogRunning && key == Common::KEYCODE_KP2)
+ key = event.kbd.ascii;
+ else if (_allowSynthetic || !event.synthetic)
key = KEY_DOWN;
break;
case Common::KEYCODE_PAGEUP:
case Common::KEYCODE_KP9:
- if (_allowSynthetic || !event.synthetic)
+ if (_predictiveDialogRunning && key == Common::KEYCODE_KP9)
+ key = event.kbd.ascii;
+ else if (_allowSynthetic || !event.synthetic)
key = KEY_UP_RIGHT;
break;
case Common::KEYCODE_PAGEDOWN:
case Common::KEYCODE_KP3:
- if (_allowSynthetic || !event.synthetic)
+ if (_predictiveDialogRunning && key == Common::KEYCODE_KP3)
+ key = event.kbd.ascii;
+ else if (_allowSynthetic || !event.synthetic)
key = KEY_DOWN_RIGHT;
break;
case Common::KEYCODE_HOME:
case Common::KEYCODE_KP7:
- if (_allowSynthetic || !event.synthetic)
+ if (_predictiveDialogRunning && key == Common::KEYCODE_KP7)
+ key = event.kbd.ascii;
+ else if (_allowSynthetic || !event.synthetic)
key = KEY_UP_LEFT;
break;
case Common::KEYCODE_END:
case Common::KEYCODE_KP1:
- if (_allowSynthetic || !event.synthetic)
+ if (_predictiveDialogRunning && key == Common::KEYCODE_KP1)
+ key = event.kbd.ascii;
+ else if (_allowSynthetic || !event.synthetic)
key = KEY_DOWN_LEFT;
break;
case Common::KEYCODE_KP5:
- key = KEY_STATIONARY;
+ if (_predictiveDialogRunning)
+ key = event.kbd.ascii;
+ else
+ key = KEY_STATIONARY;
break;
case Common::KEYCODE_PLUS:
key = '+';
diff --git a/engines/agi/detection.cpp b/engines/agi/detection.cpp
index 22d8adf92d..b0e055edcc 100644
--- a/engines/agi/detection.cpp
+++ b/engines/agi/detection.cpp
@@ -129,31 +129,6 @@ static const PlainGameDescriptor agiGames[] = {
#include "agi/detection_tables.h"
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Agi::gameDescriptions,
- // Size of that superset structure
- sizeof(Agi::AGIGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- agiGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "agi",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NOSPEECH,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
using namespace Agi;
class AgiMetaEngine : public AdvancedMetaEngine {
@@ -161,7 +136,10 @@ class AgiMetaEngine : public AdvancedMetaEngine {
mutable Common::String _extra;
public:
- AgiMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ AgiMetaEngine() : AdvancedMetaEngine(Agi::gameDescriptions, sizeof(Agi::AGIGameDescription), agiGames) {
+ params.singleid = "agi";
+ params.guioptions = Common::GUIO_NOSPEECH;
+ }
virtual const char *getName() const {
return "AGI preAGI + v2 + v3";
diff --git a/engines/agi/predictive.cpp b/engines/agi/predictive.cpp
index 80e89f410b..edfe83b1cb 100644
--- a/engines/agi/predictive.cpp
+++ b/engines/agi/predictive.cpp
@@ -190,7 +190,7 @@ bool AgiEngine::predictiveDialog() {
bool needRefresh = true;
- for (;;) {
+ while (!shouldQuit()) {
if (needRefresh) {
for (int i = 0; buttons[i]; i++) {
int color1 = colors[i * 2];
@@ -573,8 +573,10 @@ bool AgiEngine::matchWord() {
hi = line - 1;
else if (cmpVal < 0)
lo = line + 1;
- else
+ else {
hi = line;
+ break;
+ }
}
_currentWord.clear();
diff --git a/engines/agi/sound_2gs.cpp b/engines/agi/sound_2gs.cpp
index 6d64c29de9..3c8a3dfc8d 100644
--- a/engines/agi/sound_2gs.cpp
+++ b/engines/agi/sound_2gs.cpp
@@ -135,7 +135,7 @@ void SoundGen2GS::stop() {
* Fill output buffer by advancing the generators for a 1/60th of a second.
* @return Number of generated samples
*/
-uint32 SoundGen2GS::generateOutput() {
+uint SoundGen2GS::generateOutput() {
memset(_out, 0, _outSize * 2 * 2);
if (!_playing || _playingSound == -1)
diff --git a/engines/agi/sound_pcjr.cpp b/engines/agi/sound_pcjr.cpp
index 319b7049ed..fdebf16b1a 100644
--- a/engines/agi/sound_pcjr.cpp
+++ b/engines/agi/sound_pcjr.cpp
@@ -219,6 +219,7 @@ int SoundGenPCJr::volumeCalc(SndGenChan *chan) {
// return 0 if it's passing more data
// return -1 if it's passing nothing (end of data)
int SoundGenPCJr::getNextNote(int ch, Tone *tone) {
+ ToneChan *tpcm;
SndGenChan *chan;
const byte *data;
@@ -228,6 +229,7 @@ int SoundGenPCJr::getNextNote(int ch, Tone *tone) {
if (!_vm->getflag(fSoundOn))
return -1;
+ tpcm = &_tchannel[ch];
chan = &_channel[ch];
if (!chan->avail)
return -1;
@@ -241,6 +243,9 @@ int SoundGenPCJr::getNextNote(int ch, Tone *tone) {
// if it's 0 then it's not going to be played
// if it's 0xFFFF then the channel data has finished.
if ((chan->duration != 0) && (chan->duration != 0xFFFF)) {
+ tpcm->genTypePrev = -1;
+ tpcm->freqCountPrev = -1;
+
// only tone channels dissolve
if ((ch != 3) && (_dissolveMethod != 0)) // != noise??
chan->dissolveCount = 0;
diff --git a/engines/agos/detection.cpp b/engines/agos/detection.cpp
index 629a5d63fc..dbd1743304 100644
--- a/engines/agos/detection.cpp
+++ b/engines/agos/detection.cpp
@@ -63,7 +63,7 @@ static const ADObsoleteGameID obsoleteGameIDsTable[] = {
{0, 0, Common::kPlatformUnknown}
};
-static const PlainGameDescriptor simonGames[] = {
+static const PlainGameDescriptor agosGames[] = {
{"pn", "Personal Nightmare"},
{"elvira1", "Elvira - Mistress of the Dark"},
{"elvira2", "Elvira II - The Jaws of Cerberus"},
@@ -87,36 +87,16 @@ static const char *directoryGlobs[] = {
0
};
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)AGOS::gameDescriptions,
- // Size of that superset structure
- sizeof(AGOS::AGOSGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- simonGames,
- // Structure for autoupgrading obsolete targets
- obsoleteGameIDsTable,
- // Name of single gameid (optional)
- 0,
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NOLAUNCHLOAD,
- // Maximum directory depth
- 2,
- // List of directory globs
- directoryGlobs
-};
-
using namespace AGOS;
class AgosMetaEngine : public AdvancedMetaEngine {
public:
- AgosMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ AgosMetaEngine() : AdvancedMetaEngine(AGOS::gameDescriptions, sizeof(AGOS::AGOSGameDescription), agosGames) {
+ params.obsoleteList = obsoleteGameIDsTable;
+ params.guioptions = Common::GUIO_NOLAUNCHLOAD;
+ params.depth = 2;
+ params.directoryGlobs = directoryGlobs;
+ }
virtual const char *getName() const {
return "AGOS";
diff --git a/engines/cine/detection.cpp b/engines/cine/detection.cpp
index 738366124c..89c81c2599 100644
--- a/engines/cine/detection.cpp
+++ b/engines/cine/detection.cpp
@@ -60,34 +60,13 @@ static const ADObsoleteGameID obsoleteGameIDsTable[] = {
#include "cine/detection_tables.h"
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Cine::gameDescriptions,
- // Size of that superset structure
- sizeof(Cine::CINEGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- cineGames,
- // Structure for autoupgrading obsolete targets
- obsoleteGameIDsTable,
- // Name of single gameid (optional)
- "cine",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NOSPEECH | Common::GUIO_NOMIDI,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
class CineMetaEngine : public AdvancedMetaEngine {
public:
- CineMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ CineMetaEngine() : AdvancedMetaEngine(Cine::gameDescriptions, sizeof(Cine::CINEGameDescription), cineGames) {
+ params.obsoleteList = obsoleteGameIDsTable;
+ params.singleid = "cine";
+ params.guioptions = Common::GUIO_NOSPEECH | Common::GUIO_NOMIDI;
+ }
virtual const char *getName() const {
return "Cine";
diff --git a/engines/cruise/detection.cpp b/engines/cruise/detection.cpp
index 3bd0c1f76f..f6f8db4f3a 100644
--- a/engines/cruise/detection.cpp
+++ b/engines/cruise/detection.cpp
@@ -217,34 +217,12 @@ static const CRUISEGameDescription gameDescriptions[] = {
}
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Cruise::gameDescriptions,
- // Size of that superset structure
- sizeof(Cruise::CRUISEGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- cruiseGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "cruise",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NOSPEECH | Common::GUIO_NOMIDI,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
class CruiseMetaEngine : public AdvancedMetaEngine {
public:
- CruiseMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ CruiseMetaEngine() : AdvancedMetaEngine(Cruise::gameDescriptions, sizeof(Cruise::CRUISEGameDescription), cruiseGames) {
+ params.singleid = "cruise";
+ params.guioptions = Common::GUIO_NOSPEECH | Common::GUIO_NOMIDI;
+ }
virtual const char *getName() const {
return "CruisE";
diff --git a/engines/draci/detection.cpp b/engines/draci/detection.cpp
index d3483eb5a4..cf0413ffa9 100644
--- a/engines/draci/detection.cpp
+++ b/engines/draci/detection.cpp
@@ -83,34 +83,11 @@ const ADGameDescription gameDescriptions[] = {
} // End of namespace Draci
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Draci::gameDescriptions,
- // Size of that superset structure
- sizeof(ADGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- draciGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "draci",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NONE,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
class DraciMetaEngine : public AdvancedMetaEngine {
public:
- DraciMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ DraciMetaEngine() : AdvancedMetaEngine(Draci::gameDescriptions, sizeof(ADGameDescription), draciGames) {
+ params.singleid = "draci";
+ }
virtual const char *getName() const {
return "Draci";
diff --git a/engines/drascula/detection.cpp b/engines/drascula/detection.cpp
index 5a8903db9d..9494bfa66b 100644
--- a/engines/drascula/detection.cpp
+++ b/engines/drascula/detection.cpp
@@ -266,34 +266,12 @@ static const DrasculaGameDescription gameDescriptions[] = {
} // End of namespace Drascula
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Drascula::gameDescriptions,
- // Size of that superset structure
- sizeof(Drascula::DrasculaGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- drasculaGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "drascula",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NOMIDI | Common::GUIO_NOLAUNCHLOAD,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
class DrasculaMetaEngine : public AdvancedMetaEngine {
public:
- DrasculaMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ DrasculaMetaEngine() : AdvancedMetaEngine(Drascula::gameDescriptions, sizeof(Drascula::DrasculaGameDescription), drasculaGames) {
+ params.singleid = "drascula";
+ params.guioptions = Common::GUIO_NOMIDI | Common::GUIO_NOLAUNCHLOAD;
+ }
virtual const char *getName() const {
return "Drascula";
diff --git a/engines/gob/detection.cpp b/engines/gob/detection.cpp
index be44c05bfb..2ecd6b741e 100644
--- a/engines/gob/detection.cpp
+++ b/engines/gob/detection.cpp
@@ -86,34 +86,14 @@ static const ADObsoleteGameID obsoleteGameIDsTable[] = {
#include "gob/detection_tables.h"
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Gob::gameDescriptions,
- // Size of that superset structure
- sizeof(Gob::GOBGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- gobGames,
- // Structure for autoupgrading obsolete targets
- obsoleteGameIDsTable,
- // Name of single gameid (optional)
- "gob",
- // List of files for file-based fallback detection (optional)
- Gob::fileBased,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NOLAUNCHLOAD,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
class GobMetaEngine : public AdvancedMetaEngine {
public:
- GobMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ GobMetaEngine() : AdvancedMetaEngine(Gob::gameDescriptions, sizeof(Gob::GOBGameDescription), gobGames) {
+ params.obsoleteList = obsoleteGameIDsTable;
+ params.singleid = "gob";
+ params.fileBasedFallback = Gob::fileBased;
+ params.guioptions = Common::GUIO_NOLAUNCHLOAD;
+ }
virtual const char *getName() const {
return "Gob";
diff --git a/engines/groovie/detection.cpp b/engines/groovie/detection.cpp
index 0dd510abca..62ee65d74a 100644
--- a/engines/groovie/detection.cpp
+++ b/engines/groovie/detection.cpp
@@ -202,35 +202,13 @@ static const GroovieGameDescription gameDescriptions[] = {
{AD_TABLE_END_MARKER, kGroovieT7G, 0}
};
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)gameDescriptions,
- // Size of that superset structure
- sizeof(GroovieGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- groovieGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "groovie",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- kADFlagUseExtraAsHint,
- // Additional GUI options (for every game}
- Common::GUIO_NOSUBTITLES | Common::GUIO_NOSFX,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
-
class GroovieMetaEngine : public AdvancedMetaEngine {
public:
- GroovieMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ GroovieMetaEngine() : AdvancedMetaEngine(gameDescriptions, sizeof(GroovieGameDescription), groovieGames) {
+ params.singleid = "groovie";
+ params.flags = kADFlagUseExtraAsHint;
+ params.guioptions = Common::GUIO_NOSUBTITLES | Common::GUIO_NOSFX;
+ }
const char *getName() const {
return "Groovie";
diff --git a/engines/groovie/groovie.cpp b/engines/groovie/groovie.cpp
index 8b6ee2ca42..5f95de649a 100644
--- a/engines/groovie/groovie.cpp
+++ b/engines/groovie/groovie.cpp
@@ -336,11 +336,6 @@ bool GroovieEngine::hasFeature(EngineFeature f) const {
(f == kSupportsLoadingDuringRuntime);
}
-void GroovieEngine::errorString(const char *buf_input, char *buf_output, int buf_output_size) {
- //snprintf(buf_output, buf_output_size, "%s%s\n", _script.getContext().c_str(), buf_input);
- snprintf(buf_output, buf_output_size, "%s", buf_input);
-}
-
void GroovieEngine::syncSoundSettings() {
Engine::syncSoundSettings();
diff --git a/engines/groovie/groovie.h b/engines/groovie/groovie.h
index eb64cfc60a..df2f062757 100644
--- a/engines/groovie/groovie.h
+++ b/engines/groovie/groovie.h
@@ -91,7 +91,6 @@ protected:
// Engine APIs
Common::Error run();
- virtual void errorString(const char *buf_input, char *buf_output, int buf_output_size);
virtual bool hasFeature(EngineFeature f) const;
diff --git a/engines/groovie/music.cpp b/engines/groovie/music.cpp
index 9a3903e9dc..33fc986193 100644
--- a/engines/groovie/music.cpp
+++ b/engines/groovie/music.cpp
@@ -845,6 +845,9 @@ bool MusicPlayerIOS::load(uint32 fileref, bool loop) {
if (loop)
audStream = Audio::makeLoopingAudioStream((Audio::RewindableAudioStream *)audStream, 0);
+ // MIDI player handles volume reset on load, IOS player doesn't - force update here
+ updateVolume();
+
// Play!
_vm->_system->getMixer()->playStream(Audio::Mixer::kMusicSoundType, &_handle, audStream);
return true;
diff --git a/engines/groovie/resource.cpp b/engines/groovie/resource.cpp
index 05b43b7d3c..c26f04d6ee 100644
--- a/engines/groovie/resource.cpp
+++ b/engines/groovie/resource.cpp
@@ -169,7 +169,7 @@ bool ResMan_t7g::getResInfo(uint32 fileRef, ResInfo &resInfo) {
error("Groovie::Resource: Invalid resource number: 0x%04X (%s)", resNum, rlFileName.c_str());
}
- // Read the resource name (just for debugging purposes)
+ // Read the resource name
char resname[13];
rlFile->read(resname, 12);
resname[12] = 0;
@@ -240,7 +240,7 @@ uint32 ResMan_v2::getRef(Common::String name, Common::String scriptname) {
// Test whether it's the resource we're searching
Common::String resname(readname, 18);
if (resname.hasPrefix(name.c_str())) {
- debugC(2, kGroovieDebugResource | kGroovieDebugAll, "Groovie::Resource: Resource %12s matches %s", readname, name.c_str());
+ debugC(2, kGroovieDebugResource | kGroovieDebugAll, "Groovie::Resource: Resource %18s matches %s", readname, name.c_str());
found = true;
}
}
@@ -279,10 +279,11 @@ bool ResMan_v2::getResInfo(uint32 fileRef, ResInfo &resInfo) {
resInfo.size = rlFile.readUint32LE();
resInfo.gjd = rlFile.readUint16LE();
- // Read the resource name (just for debugging purposes)
- char resname[12];
- rlFile.read(resname, 12);
- debugC(2, kGroovieDebugResource | kGroovieDebugAll, "Groovie::Resource: Resource name: %12s", resname);
+ // Read the resource name
+ char resname[19];
+ resname[18] = 0;
+ rlFile.read(resname, 18);
+ debugC(2, kGroovieDebugResource | kGroovieDebugAll, "Groovie::Resource: Resource name: %18s", resname);
resInfo.filename = resname;
// 6 padding bytes? (it looks like they're always 0)
diff --git a/engines/hugo/detection.cpp b/engines/hugo/detection.cpp
index 25b8b16084..f70a21aa8f 100644
--- a/engines/hugo/detection.cpp
+++ b/engines/hugo/detection.cpp
@@ -131,34 +131,10 @@ static const HugoGameDescription gameDescriptions[] = {
{AD_TABLE_END_MARKER, kGameTypeNone}
};
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)gameDescriptions,
- // Size of that superset structure
- sizeof(HugoGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- hugoGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- 0,
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NONE,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
class HugoMetaEngine : public AdvancedMetaEngine {
public:
- HugoMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ HugoMetaEngine() : AdvancedMetaEngine(gameDescriptions, sizeof(HugoGameDescription), hugoGames) {
+ }
const char *getName() const {
return "Hugo";
diff --git a/engines/kyra/animator_mr.cpp b/engines/kyra/animator_mr.cpp
index 6db2e45b0e..84bda3f3fd 100644
--- a/engines/kyra/animator_mr.cpp
+++ b/engines/kyra/animator_mr.cpp
@@ -449,11 +449,10 @@ void KyraEngine_MR::showIdleAnim() {
"A", "R", "R", "FR", "FX", "FL", "L", "L"
};
- char filename[14];
- snprintf(filename, 14, "MI0%s%.02d.EMC", facingTable[_mainCharacter.facing], _characterShapeFile);
+ Common::String filename = Common::String::format( "MI0%s%.02d.EMC", facingTable[_mainCharacter.facing], _characterShapeFile);
- if (_res->exists(filename))
- runAnimationScript(filename, 1, 1, 1, 1);
+ if (_res->exists(filename.c_str()))
+ runAnimationScript(filename.c_str(), 1, 1, 1, 1);
}
_nextIdleType = !_nextIdleType;
diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp
index 47a086e08c..6589c2b45b 100644
--- a/engines/kyra/detection.cpp
+++ b/engines/kyra/detection.cpp
@@ -47,37 +47,15 @@ const char * const directoryGlobs[] = {
0
};
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)adGameDescs,
- // Size of that superset structure
- sizeof(KYRAGameDescription),
- // Number of bytes to compute MD5 sum for
- 1024 * 1024,
- // List of all engine targets
- gameList,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- 0,
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NONE,
- // Maximum directory depth
- 2,
- // List of directory globs
- directoryGlobs
-};
-
} // End of anonymous namespace
class KyraMetaEngine : public AdvancedMetaEngine {
public:
- KyraMetaEngine() : AdvancedMetaEngine(detectionParams) {}
-
+ KyraMetaEngine() : AdvancedMetaEngine(adGameDescs, sizeof(KYRAGameDescription), gameList) {
+ params.md5Bytes = 1024 * 1024;
+ params.depth = 2;
+ params.directoryGlobs = directoryGlobs;
+ }
const char *getName() const {
return "Kyra";
}
diff --git a/engines/kyra/detection_tables.h b/engines/kyra/detection_tables.h
index 8a948eff00..47a3c4362a 100644
--- a/engines/kyra/detection_tables.h
+++ b/engines/kyra/detection_tables.h
@@ -47,6 +47,7 @@ namespace {
#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_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)
@@ -1056,6 +1057,109 @@ const KYRAGameDescription adGameDescs[] = {
LOL_CD_FLAGS
},
+ // Italian fan translation
+ {
+ {
+ "lol",
+ "CD",
+ {
+ { "GENERAL.PAK", 0, "05a4f588fb81dc9c0ef1f2ec20d89e24", -1 },
+ { "L01.PAK", 0, "898485c0eb7bb4403fdd63bf5191f37e", -1 },
+ { 0, 0, 0, 0 }
+ },
+ Common::IT_ITA,
+ Common::kPlatformPC,
+ ADGF_DROPLANGUAGE | ADGF_CD,
+ Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK
+ },
+ LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
+ },
+
+ {
+ {
+ "lol",
+ "CD",
+ {
+ { "GENERAL.PAK", 0, "05a4f588fb81dc9c0ef1f2ec20d89e24", -1 },
+ { "L01.PAK", 0, "898485c0eb7bb4403fdd63bf5191f37e", -1 },
+ { 0, 0, 0, 0 }
+ },
+ Common::DE_DEU,
+ Common::kPlatformPC,
+ ADGF_DROPLANGUAGE | ADGF_CD,
+ Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK
+ },
+ LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
+ },
+
+ {
+ {
+ "lol",
+ "CD",
+ {
+ { "GENERAL.PAK", 0, "05a4f588fb81dc9c0ef1f2ec20d89e24", -1 },
+ { "L01.PAK", 0, "898485c0eb7bb4403fdd63bf5191f37e", -1 },
+ { 0, 0, 0, 0 }
+ },
+ Common::FR_FRA,
+ Common::kPlatformPC,
+ ADGF_DROPLANGUAGE | ADGF_CD,
+ Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK
+ },
+ LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
+ },
+
+ {
+ {
+ "lol",
+ "CD",
+ {
+ { "GENERAL.PAK", 0, "9e4bab499b7ea9337b91ac29fcba6d13", -1 },
+ { "L01.PAK", 0, "898485c0eb7bb4403fdd63bf5191f37e", -1 },
+ { 0, 0, 0, 0 }
+ },
+ Common::IT_ITA,
+ Common::kPlatformPC,
+ ADGF_DROPLANGUAGE | ADGF_CD,
+ Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK
+ },
+ LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
+ },
+
+ {
+ {
+ "lol",
+ "CD",
+ {
+ { "GENERAL.PAK", 0, "9e4bab499b7ea9337b91ac29fcba6d13", -1 },
+ { "L01.PAK", 0, "898485c0eb7bb4403fdd63bf5191f37e", -1 },
+ { 0, 0, 0, 0 }
+ },
+ Common::DE_DEU,
+ Common::kPlatformPC,
+ ADGF_DROPLANGUAGE | ADGF_CD,
+ Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK
+ },
+ LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
+ },
+
+ {
+ {
+ "lol",
+ "CD",
+ {
+ { "GENERAL.PAK", 0, "9e4bab499b7ea9337b91ac29fcba6d13", -1 },
+ { "L01.PAK", 0, "898485c0eb7bb4403fdd63bf5191f37e", -1 },
+ { 0, 0, 0, 0 }
+ },
+ Common::FR_FRA,
+ Common::kPlatformPC,
+ ADGF_DROPLANGUAGE | ADGF_CD,
+ Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK
+ },
+ LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
+ },
+
{
{
"lol",
@@ -1222,7 +1326,6 @@ const KYRAGameDescription adGameDescs[] = {
LOL_KYRA2_DEMO_FLAGS
},
#endif // ENABLE_LOL
-
{ AD_TABLE_END_MARKER, FLAGS(0, 0, 0, 0, 0, 0, 0, 0) }
};
diff --git a/engines/kyra/gui_lol.cpp b/engines/kyra/gui_lol.cpp
index 4c4dc50503..fb11040168 100644
--- a/engines/kyra/gui_lol.cpp
+++ b/engines/kyra/gui_lol.cpp
@@ -2806,15 +2806,18 @@ int GUI_LoL::clickedOptionsMenu(Button *button) {
case 0xfff3:
_vm->_configVoice ^= 3;
break;
- case 0x4072:
- char filename[13];
- snprintf(filename, sizeof(filename), "LEVEL%02d.%s", _vm->_currentLevel, _vm->_languageExt[_vm->_lang]);
+ case 0x4072: {
+ Common::String filename;
+ filename = Common::String::format("LEVEL%02d.%s", _vm->_currentLevel, _vm->_languageExt[_vm->_lang]);
delete[] _vm->_levelLangFile;
- _vm->_levelLangFile = _vm->resource()->fileData(filename, 0);
- snprintf(filename, sizeof(filename), "LANDS.%s", _vm->_languageExt[_vm->_lang]);
+ _vm->_levelLangFile = _vm->resource()->fileData(filename.c_str(), 0);
+ filename = Common::String::format("LANDS.%s", _vm->_languageExt[_vm->_lang]);
delete[] _vm->_landsFile;
- _vm->_landsFile = _vm->resource()->fileData(filename, 0);
+ _vm->_landsFile = _vm->resource()->fileData(filename.c_str(), 0);
_newMenu = _lastMenu;
+ } break;
+ default:
+ // TODO: Is there anything we should do if we hit this case?
break;
}
diff --git a/engines/kyra/gui_mr.cpp b/engines/kyra/gui_mr.cpp
index 25a77c6cc8..32eb02e06d 100644
--- a/engines/kyra/gui_mr.cpp
+++ b/engines/kyra/gui_mr.cpp
@@ -717,25 +717,25 @@ void KyraEngine_MR::showAlbum() {
}
void KyraEngine_MR::loadAlbumPage() {
- char filename[16];
+ Common::String filename;
int num = _album.curPage / 2;
if (num == 0) {
- strcpy(filename, "ALBUM0.CPS");
+ filename = "ALBUM0.CPS";
} else if (num >= 1 && num <= 6) {
--num;
num %= 2;
- snprintf(filename, 16, "ALBUM%d.CPS", num+1);
+ filename = Common::String::format("ALBUM%d.CPS", num+1);
} else {
- strcpy(filename, "ALBUM3.CPS");
+ filename = "ALBUM3.CPS";
}
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 4, Screen::CR_NO_P_CHECK);
- _screen->loadBitmap(filename, 3, 3, 0);
+ _screen->loadBitmap(filename.c_str(), 3, 3, 0);
}
void KyraEngine_MR::loadAlbumPageWSA() {
- char filename[16];
+ Common::String filename;
_album.leftPage.curFrame = 0;
_album.leftPage.maxFrame = 0;
@@ -746,14 +746,14 @@ void KyraEngine_MR::loadAlbumPageWSA() {
_album.rightPage.wsa->close();
if (_album.curPage) {
- snprintf(filename, 16, "PAGE%x.WSA", _album.curPage);
- _album.leftPage.wsa->open(filename, 1, 0);
+ filename = Common::String::format("PAGE%x.WSA", _album.curPage);
+ _album.leftPage.wsa->open(filename.c_str(), 1, 0);
_album.leftPage.maxFrame = _album.leftPage.wsa->frames()-1;
}
if (_album.curPage != 14) {
- snprintf(filename, 16, "PAGE%x.WSA", _album.curPage+1);
- _album.rightPage.wsa->open(filename, 1, 0);
+ filename = Common::String::format("PAGE%x.WSA", _album.curPage+1);
+ _album.rightPage.wsa->open(filename.c_str(), 1, 0);
_album.rightPage.maxFrame = _album.leftPage.wsa->frames()-1;
}
}
diff --git a/engines/kyra/items_lol.cpp b/engines/kyra/items_lol.cpp
index b6388604f5..2cf2cb2c70 100644
--- a/engines/kyra/items_lol.cpp
+++ b/engines/kyra/items_lol.cpp
@@ -396,20 +396,20 @@ bool LoLEngine::launchObject(int objectType, Item item, int startX, int startY,
return true;
}
-void LoLEngine::endObjectFlight(FlyingObject *t, int x, int y, int objectOnNextBlock) {
+void LoLEngine::endObjectFlight(FlyingObject *t, int x, int y, int collisionObject) {
int cx = x;
int cy = y;
uint16 block = calcBlockIndex(t->x, t->y);
removeAssignedObjectFromBlock(&_levelBlockProperties[block], t->item);
removeDrawObjectFromBlock(&_levelBlockProperties[block], t->item);
- if (objectOnNextBlock == 1) {
+ if (collisionObject == 1) {
cx = t->x;
cy = t->y;
}
if (t->objectType == 0 || t->objectType == 1) {
- objectFlightProcessHits(t, cx, cy, objectOnNextBlock);
+ objectFlightProcessHits(t, cx, cy, collisionObject);
t->x = (cx & 0xffc0) | 0x40;
t->y = (cy & 0xffc0) | 0x40;
t->flyingHeight = 0;
@@ -481,8 +481,24 @@ void LoLEngine::updateFlyingObject(FlyingObject *t) {
int x = 0;
int y = 0;
getNextStepCoords(t->x, t->y, x, y, t->direction);
- // WORKAROUND: The next line seems to be bugged in the original code. I have fixed it in a way that at least seems to work fine.
- int objectOnNextBlock = checkBlockBeforeObjectPlacement(x, y, _itemProperties[_itemsInPlay[t->item].itemPropertyIndex].flags & 0x4000 ? 127 : 63, t->flags, t->wallFlags);
+ /* WORKAROUND:
+ Large fireballs cast by the "birds" in white tower level 2 and by the "wraith knights" in castle cimmeria
+ level 1 (or possible other objects with flag 0x4000) could not fly through corridors in ScummVM and would
+ be terminated prematurely. The original code (all versions) involuntarily circumvents this via a bug in the
+ next line of code.
+ The original checks for _itemProperties[t->item].flags instead of _itemProperties[_itemsInPlay[t->item].itemPropertyIndex].flags.
+ This leads to more or less unpredictable object widths. The large fireballs will usually get a width of 63
+ instead of 256 making them work just fine in the original.
+
+ I have fixed this by setting an object width of 63 of here. This produces results faithful to the original
+ at least.
+
+ Other methods of working around this issue don't make too much sense. An object with a width of 256
+ could never fly through corridors, since 256 is also the width of a block. Aligning the fireballs to the
+ middle of a block (or making the monsters align to the middle before casting them) wouldn't help here
+ (and wouldn't be faithful to the original either).
+ */
+ int objectOnNextBlock = checkBlockBeforeObjectPlacement(x, y, /*_itemProperties[_itemsInPlay[t->item].itemPropertyIndex].flags & 0x4000 ? 256 :*/ 63, t->flags, t->wallFlags);
if (objectOnNextBlock) {
endObjectFlight(t, x, y, objectOnNextBlock);
} else {
diff --git a/engines/kyra/kyra_mr.cpp b/engines/kyra/kyra_mr.cpp
index 4ce5c5b2cf..973ab25088 100644
--- a/engines/kyra/kyra_mr.cpp
+++ b/engines/kyra/kyra_mr.cpp
@@ -366,10 +366,9 @@ void KyraEngine_MR::uninitMainMenu() {
void KyraEngine_MR::playVQA(const char *name) {
VQAMovie vqa(this, _system);
- char filename[20];
- snprintf(filename, sizeof(filename), "%s%d.VQA", name, _configVQAQuality);
+ Common::String filename = Common::String::format("%s%d.VQA", name, _configVQAQuality);
- if (vqa.open(filename)) {
+ if (vqa.open(filename.c_str())) {
for (int i = 0; i < 4; ++i) {
if (i != _musicSoundChannel)
_soundDigital->stopSound(i);
@@ -444,12 +443,11 @@ void KyraEngine_MR::fadeOutMusic(int ticks) {
void KyraEngine_MR::snd_playSoundEffect(int item, int volume) {
if (_sfxFileMap[item*2+0] != 0xFF) {
- char filename[16];
assert(_sfxFileMap[item*2+0] < _sfxFileListSize);
- snprintf(filename, 16, "%s", _sfxFileList[_sfxFileMap[item*2+0]]);
+ Common::String filename = Common::String::format("%s", _sfxFileList[_sfxFileMap[item*2+0]]);
uint8 priority = _sfxFileMap[item*2+1];
- _soundDigital->playSound(filename, priority, Audio::Mixer::kSFXSoundType, volume);
+ _soundDigital->playSound(filename.c_str(), priority, Audio::Mixer::kSFXSoundType, volume);
}
}
@@ -458,11 +456,10 @@ void KyraEngine_MR::playVoice(int high, int low) {
}
void KyraEngine_MR::snd_playVoiceFile(int file) {
- char filename[16];
- snprintf(filename, 16, "%.08u", (uint)file);
+ Common::String filename = Common::String::format("%.08u", (uint)file);
if (speechEnabled())
- _voiceSoundChannel = _soundDigital->playSound(filename, 0xFE, Audio::Mixer::kSpeechSoundType, 255);
+ _voiceSoundChannel = _soundDigital->playSound(filename.c_str(), 0xFE, Audio::Mixer::kSpeechSoundType, 255);
}
bool KyraEngine_MR::snd_voiceIsPlaying() {
@@ -1242,26 +1239,14 @@ void KyraEngine_MR::restoreGfxRect32x32(int x, int y) {
#pragma mark -
-char *KyraEngine_MR::appendLanguage(char *buf, int lang, int bufSize) {
- assert(lang < _languageExtensionSize);
-
- const int size = Common::strlcat(buf, _languageExtension[lang], bufSize);
- if (size >= bufSize) {
- warning("buffer too small to append language extension");
- return 0;
- }
-
- return buf;
-}
-
int KyraEngine_MR::loadLanguageFile(const char *file, uint8 *&buffer) {
delete[] buffer;
buffer = 0;
uint32 size = 0;
- char nBuf[32];
- Common::strlcpy(nBuf, file, sizeof(nBuf));
- buffer = _res->fileData(appendLanguage(nBuf, _lang, sizeof(nBuf)), &size);
+ Common::String nBuf = file;
+ nBuf += _languageExtension[_lang];
+ buffer = _res->fileData(nBuf.c_str(), &size);
return buffer ? size : 0;
}
diff --git a/engines/kyra/kyra_mr.h b/engines/kyra/kyra_mr.h
index 0d9d66ce95..b762648d29 100644
--- a/engines/kyra/kyra_mr.h
+++ b/engines/kyra/kyra_mr.h
@@ -662,8 +662,6 @@ private:
static const char *_languageExtension[];
static const int _languageExtensionSize;
- char *appendLanguage(char *buf, int lang, int bufSize);
-
int loadLanguageFile(const char *file, uint8 *&buffer);
};
diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp
index f108082e13..f79fabf9eb 100644
--- a/engines/kyra/kyra_v1.cpp
+++ b/engines/kyra/kyra_v1.cpp
@@ -93,15 +93,6 @@ Common::Error KyraEngine_v1::init() {
syncSoundSettings();
if (!_flags.useDigSound) {
- // In Kyra 1 users who have specified a default MT-32 device in the launcher settings
- // will get MT-32 music, otherwise AdLib. In Kyra 2 and LoL users who have specified a
- // default GM device in the launcher will get GM music, otherwise AdLib. Users who want
- // MT-32 music in Kyra2 or LoL have to select this individually (since we assume that
- // most users rather have a GM device than a MT-32 device).
- // Users who want PC speaker sound always have to select this individually for all
- // Kyra games.
- MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_PCSPK | MDT_MIDI | MDT_ADLIB | ((_flags.gameID == GI_KYRA2 || _flags.gameID == GI_LOL) ? MDT_PREFER_GM : MDT_PREFER_MT32));
-
if (_flags.platform == Common::kPlatformFMTowns) {
if (_flags.gameID == GI_KYRA1)
_sound = new SoundTowns(this, _mixer);
@@ -114,43 +105,53 @@ Common::Error KyraEngine_v1::init() {
_sound = new SoundTownsPC98_v2(this, _mixer);
} else if (_flags.platform == Common::kPlatformAmiga) {
_sound = new SoundAmiga(this, _mixer);
- } else if (MidiDriver::getMusicType(dev) == MT_ADLIB) {
- _sound = new SoundAdLibPC(this, _mixer);
} else {
- Sound::kType type;
- const MusicType midiType = MidiDriver::getMusicType(dev);
+ // In Kyra 1 users who have specified a default MT-32 device in the launcher settings
+ // will get MT-32 music, otherwise AdLib. In Kyra 2 and LoL users who have specified a
+ // default GM device in the launcher will get GM music, otherwise AdLib. Users who want
+ // MT-32 music in Kyra2 or LoL have to select this individually (since we assume that
+ // most users rather have a GM device than a MT-32 device).
+ // Users who want PC speaker sound always have to select this individually for all
+ // Kyra games.
+ MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_PCSPK | MDT_MIDI | MDT_ADLIB | ((_flags.gameID == GI_KYRA2 || _flags.gameID == GI_LOL) ? MDT_PREFER_GM : MDT_PREFER_MT32));
+ if (MidiDriver::getMusicType(dev) == MT_ADLIB) {
+ _sound = new SoundAdLibPC(this, _mixer);
+ } else {
+ Sound::kType type;
+ const MusicType midiType = MidiDriver::getMusicType(dev);
- if (midiType == MT_PCSPK || midiType == MT_NULL)
- type = Sound::kPCSpkr;
- else if (midiType == MT_MT32 || ConfMan.getBool("native_mt32"))
- type = Sound::kMidiMT32;
- else
- type = Sound::kMidiGM;
+ if (midiType == MT_PCSPK || midiType == MT_NULL)
+ type = Sound::kPCSpkr;
+ else if (midiType == MT_MT32 || ConfMan.getBool("native_mt32"))
+ type = Sound::kMidiMT32;
+ else
+ type = Sound::kMidiGM;
- MidiDriver *driver = 0;
+ MidiDriver *driver = 0;
- if (MidiDriver::getMusicType(dev) == MT_PCSPK) {
- driver = new MidiDriver_PCSpeaker(_mixer);
- } else {
- driver = MidiDriver::createMidi(dev);
- if (type == Sound::kMidiMT32)
- driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
- }
+ if (MidiDriver::getMusicType(dev) == MT_PCSPK) {
+ driver = new MidiDriver_PCSpeaker(_mixer);
+ } else {
+ driver = MidiDriver::createMidi(dev);
+ if (type == Sound::kMidiMT32)
+ driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
+ }
- assert(driver);
+ assert(driver);
- SoundMidiPC *soundMidiPc = new SoundMidiPC(this, _mixer, driver, type);
- _sound = soundMidiPc;
- assert(_sound);
+ SoundMidiPC *soundMidiPc = new SoundMidiPC(this, _mixer, driver, type);
+ _sound = soundMidiPc;
+ assert(_sound);
- // Unlike some SCUMM games, it's not that the MIDI sounds are
- // missing. It's just that at least at the time of writing they
- // are decidedly inferior to the AdLib ones.
- if (ConfMan.getBool("multi_midi")) {
- SoundAdLibPC *adlib = new SoundAdLibPC(this, _mixer);
- assert(adlib);
+ // Unlike some SCUMM games, it's not that the MIDI sounds are
+ // missing. It's just that at least at the time of writing they
+ // are decidedly inferior to the AdLib ones.
+ if (ConfMan.getBool("multi_midi")) {
+ SoundAdLibPC *adlib = new SoundAdLibPC(this, _mixer);
+ assert(adlib);
- _sound = new MixedSoundDriver(this, _mixer, soundMidiPc, adlib);
+ _sound = new MixedSoundDriver(this, _mixer, soundMidiPc, adlib);
+ }
}
}
diff --git a/engines/kyra/kyra_v1.h b/engines/kyra/kyra_v1.h
index bb533b14a5..5b4f3385a4 100644
--- a/engines/kyra/kyra_v1.h
+++ b/engines/kyra/kyra_v1.h
@@ -99,7 +99,7 @@ class KyraMetaEngine;
* - The Legend of Kyrandia (fully supported, except for Macintosh port, which lacks sound)
* - (The) Hand of Fate (fully supported)
* - Malcolm's Revenge (fully supported)
- * - Lands of Lore: The Throne of Chaos (completable, still work in progress)
+ * - Lands of Lore: The Throne of Chaos (fully supported)
*/
namespace Kyra {
@@ -418,7 +418,7 @@ protected:
void loadGameStateCheck(int slot);
virtual Common::Error loadGameState(int slot) = 0;
- Common::Error saveGameState(int slot, const char *saveName) { return saveGameStateIntern(slot, saveName, 0); }
+ Common::Error saveGameState(int slot, const Common::String &desc) { return saveGameStateIntern(slot, desc.c_str(), 0); }
virtual Common::Error saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumbnail) = 0;
Common::SeekableReadStream *openSaveForReading(const char *filename, SaveHeader &header);
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index 9b0ae173d5..c567cbb037 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -42,9 +42,13 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
_gui = 0;
_txt = 0;
_tim = 0;
- _animator = 0;
- switch (_flags.lang) {
+ _lang = 0;
+ Common::Language lang = Common::parseLanguage(ConfMan.get("language"));
+ if (lang == _flags.fanLang && _flags.replacedLang != Common::UNK_LANG)
+ lang = _flags.replacedLang;
+
+ switch (lang) {
case Common::EN_ANY:
case Common::EN_USA:
case Common::EN_GRB:
@@ -576,7 +580,6 @@ Common::Error LoLEngine::go() {
_tim = new TIMInterpreter_LoL(this, _screen, _system);
assert(_tim);
- _animator = _tim->animator();
if (shouldQuit())
return Common::kNoError;
@@ -613,11 +616,11 @@ void LoLEngine::preInit() {
loadTalkFile(0);
- char filename[32];
- snprintf(filename, sizeof(filename), "LANDS.%s", _languageExt[_lang]);
- _res->exists(filename, true);
+ Common::String filename;
+ filename = Common::String::format("LANDS.%s", _languageExt[_lang]);
+ _res->exists(filename.c_str(), true);
delete[] _landsFile;
- _landsFile = _res->fileData(filename, 0);
+ _landsFile = _res->fileData(filename.c_str(), 0);
loadItemIconShapes();
}
@@ -1163,9 +1166,8 @@ void LoLEngine::loadCharFaceShapes(int charNum, int id) {
if (id < 0)
id = -id;
- char file[13];
- snprintf(file, sizeof(file), "FACE%02d.SHP", id);
- _screen->loadBitmap(file, 3, 3, 0);
+ Common::String file = Common::String::format("FACE%02d.SHP", id);
+ _screen->loadBitmap(file.c_str(), 3, 3, 0);
const uint8 *p = _screen->getCPagePtr(3);
for (int i = 0; i < 40; i++) {
@@ -1811,29 +1813,26 @@ void LoLEngine::createTransparencyTables() {
}
void LoLEngine::updateSequenceBackgroundAnimations() {
- if (_updateFlags & 8 || !_animator)
+ if (_updateFlags & 8 || !_tim)
+ return;
+ if (!_tim->animator())
return;
for (int i = 0; i < 6; i++)
- _animator->update(i);
+ _tim->animator()->update(i);
}
void LoLEngine::loadTalkFile(int index) {
- char file[8];
-
if (index == _curTlkFile)
return;
- if (_curTlkFile > 0 && index > 0) {
- snprintf(file, sizeof(file), "%02d.TLK", _curTlkFile);
- _res->unloadPakFile(file);
- }
+ if (_curTlkFile > 0 && index > 0)
+ _res->unloadPakFile(Common::String::format("%02d.TLK", _curTlkFile));
if (index > 0)
_curTlkFile = index;
- snprintf(file, sizeof(file), "%02d.TLK", index);
- _res->loadPakFile(file);
+ _res->loadPakFile(Common::String::format("%02d.TLK", index));
}
int LoLEngine::characterSays(int track, int charId, bool redraw) {
@@ -2702,12 +2701,11 @@ int LoLEngine::processMagicMistOfDoom(int charNum, int spellLevel) {
snd_playSoundEffect(155, -1);
- char wsafile[13];
- snprintf(wsafile, 13, "mists%0d.wsa", spellLevel + 1);
+ Common::String wsafile = Common::String::format("mists%0d.wsa", spellLevel + 1);
WSAMovie_v2 *mov = new WSAMovie_v2(this);
- mov->open(wsafile, 1, 0);
+ mov->open(wsafile.c_str(), 1, 0);
if (!mov->opened())
- error("Mist: Unable to load mists.wsa");
+ error("Mist: Unable to load %s", wsafile.c_str());
snd_playSoundEffect(_mistAnimData[spellLevel].sound, -1);
playSpellAnimation(mov, _mistAnimData[spellLevel].part1First, _mistAnimData[spellLevel].part1Last, 7, 112, 0, 0, 0, 0, 0, false);
@@ -2720,7 +2718,7 @@ int LoLEngine::processMagicMistOfDoom(int charNum, int spellLevel) {
_screen->copyPage(12, 0);
updateDrawPage2();
- this->snd_playQueuedEffects();
+ snd_playQueuedEffects();
return 1;
}
@@ -2734,12 +2732,11 @@ int LoLEngine::processMagicLightning(int charNum, int spellLevel) {
_lightningDiv = _lightningProps[spellLevel].frameDiv;
_lightningFirstSfx = 0;
- char wsafile[13];
- snprintf(wsafile, 13, "litning%d.wsa", spellLevel + 1);
+ Common::String wsafile = Common::String::format("litning%d.wsa", spellLevel + 1);
WSAMovie_v2 *mov = new WSAMovie_v2(this);
- mov->open(wsafile, 1, 0);
+ mov->open(wsafile.c_str(), 1, 0);
if (!mov->opened())
- error("Litning: Unable to load litning.wsa");
+ error("Litning: Unable to load %s", wsafile.c_str());
for (int i = 0; i < 4; i++)
playSpellAnimation(mov, 0, _lightningProps[spellLevel].lastFrame, 3, 93, 0, &LoLEngine::callbackProcessMagicLightning, 0, 0, 0, false);
@@ -3139,11 +3136,10 @@ void LoLEngine::transferSpellToScollAnimation(int charNum, int spell, int slot)
int vX = _updateSpellBookCoords[slot << 1] + 32;
int vY = _updateSpellBookCoords[(slot << 1) + 1] + 5;
- char wsaFile[13];
+ Common::String wsaFile = Common::String::format("write%0d", spell);
if (_flags.isTalkie)
- snprintf(wsaFile, 13, "write%0d%c.wsa", spell, (_lang == 1) ? 'f' : (_lang == 0 ? 'e' : 'g'));
- else
- snprintf(wsaFile, 13, "write%0d.wsa", spell);
+ wsaFile += (_lang == 1) ? 'f' : (_lang == 0 ? 'e' : 'g');
+ wsaFile += ".wsa";
snd_playSoundEffect(_updateSpellBookAnimData[(spell << 2) + 3], -1);
snd_playSoundEffect(95, -1);
@@ -3187,7 +3183,7 @@ void LoLEngine::transferSpellToScollAnimation(int charNum, int spell, int slot)
playSpellAnimation(mov, 0, 6, 5, _updateSpellBookCoords[slot << 1], _updateSpellBookCoords[(slot << 1) + 1], 0, 0, 0, 0, false);
mov->close();
- mov->open(wsaFile, 0, 0);
+ mov->open(wsaFile.c_str(), 0, 0);
if (!mov->opened())
error("SpellBook: Unable to load spellbook anim");
snd_playSoundEffect(_updateSpellBookAnimData[(spell << 2) + 3], -1);
@@ -4160,10 +4156,9 @@ void LoLEngine::loadMapLegendData(int level) {
legendData[i * 6 + 5] = 0xffff;
}
- char file[13];
+ Common::String file = Common::String::format("level%d.xxx", level);
uint32 size = 0;
- snprintf(file, 12, "level%d.xxx", level);
- uint8 *data = _res->fileData(file, &size);
+ uint8 *data = _res->fileData(file.c_str(), &size);
uint8 *pos = data;
size = MIN<uint32>(size / 12, 32);
@@ -4531,10 +4526,9 @@ void LoLEngine::generateTempData() {
_lvlTempData[l]->monsters = new MonsterInPlay[30];
_lvlTempData[l]->flyingObjects = new FlyingObject[8];
- char filename[13];
- snprintf(filename, sizeof(filename), "LEVEL%d.CMZ", _currentLevel);
+ Common::String filename = Common::String::format("LEVEL%d.CMZ", _currentLevel);
- _screen->loadBitmap(filename, 15, 15, 0);
+ _screen->loadBitmap(filename.c_str(), 15, 15, 0);
const uint8 *p = _screen->getCPagePtr(14);
uint16 len = READ_LE_UINT16(p + 4);
p += 6;
diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h
index a815fa1a37..943bb7f8d5 100644
--- a/engines/kyra/lol.h
+++ b/engines/kyra/lol.h
@@ -315,7 +315,6 @@ private:
GUI_LoL *_gui;
TIMInterpreter *_tim;
- TimAnimator *_animator;
Common::Error init();
Common::Error go();
@@ -1215,7 +1214,7 @@ private:
void setItemPosition(Item item, uint16 x, uint16 y, int flyingHeight, int b);
void removeLevelItem(Item item, int block);
bool launchObject(int objectType, Item item, int startX, int startY, int flyingHeight, int direction, int, int attackerId, int c);
- void endObjectFlight(FlyingObject *t, int x, int y, int objectOnNextBlock);
+ void endObjectFlight(FlyingObject *t, int x, int y, int collisionObject);
void processObjectFlight(FlyingObject *t, int x, int y);
void updateObjectFlightPosition(FlyingObject *t);
void objectFlightProcessHits(FlyingObject *t, int x, int y, int objectOnNextBlock);
diff --git a/engines/kyra/scene_lol.cpp b/engines/kyra/scene_lol.cpp
index 305036fc51..165919dff2 100644
--- a/engines/kyra/scene_lol.cpp
+++ b/engines/kyra/scene_lol.cpp
@@ -67,18 +67,17 @@ void LoLEngine::loadLevel(int index) {
loadLevelWallData(index, true);
_loadLevelFlag = 1;
- char filename[13];
- snprintf(filename, sizeof(filename), "LEVEL%d.INI", index);
+ Common::String filename = Common::String::format("LEVEL%d.INI", index);
int f = _hasTempDataFlags & (1 << (index - 1));
- runInitScript(filename, f ? 0 : 1);
+ runInitScript(filename.c_str(), f ? 0 : 1);
if (f)
restoreBlockTempData(index);
- snprintf(filename, sizeof(filename), "LEVEL%d.INF", index);
- runInfScript(filename);
+ filename = Common::String::format("LEVEL%d.INF", index);
+ runInfScript(filename.c_str());
addLevelItems();
deleteMonstersFromBlock(_currentBlock);
@@ -142,11 +141,10 @@ void LoLEngine::assignBlockObject(LevelBlockProperty *l, uint16 item) {
}
void LoLEngine::loadLevelWallData(int index, bool mapShapes) {
- char filename[13];
- snprintf(filename, sizeof(filename), "LEVEL%d.WLL", index);
+ Common::String filename = Common::String::format("LEVEL%d.WLL", index);
uint32 size;
- uint8 *file = _res->fileData(filename, &size);
+ uint8 *file = _res->fileData(filename.c_str(), &size);
uint16 c = READ_LE_UINT16(file);
loadLevelShpDat(_levelShpList[c], _levelDatList[c], false);
@@ -241,10 +239,9 @@ void LoLEngine::restoreBlockTempData(int index) {
memcpy(_monsters, _lvlTempData[l]->monsters, sizeof(MonsterInPlay) * 30);
memcpy(_flyingObjects, _lvlTempData[l]->flyingObjects, sizeof(FlyingObject) * 8);
- char filename[13];
- snprintf(filename, sizeof(filename), "LEVEL%d.CMZ", index);
+ Common::String filename = Common::String::format("LEVEL%d.CMZ", index);
- _screen->loadBitmap(filename, 3, 3, 0);
+ _screen->loadBitmap(filename.c_str(), 3, 3, 0);
const uint8 *p = _screen->getCPagePtr(2);
uint16 len = READ_LE_UINT16(p + 4);
p += 6;
@@ -366,13 +363,13 @@ void LoLEngine::loadLevelGraphics(const char *file, int specialColor, int weight
_lastSpecialColor = 0x44;
}
- char fname[13];
+ Common::String fname;
const uint8 *v = 0;
int tlen = 0;
if (_flags.use16ColorMode) {
- snprintf(fname, sizeof(fname), "%s.VCF", _lastBlockDataFile);
- _screen->loadBitmap(fname, 3, 3, 0);
+ fname = Common::String::format("%s.VCF", _lastBlockDataFile);
+ _screen->loadBitmap(fname.c_str(), 3, 3, 0);
v = _screen->getCPagePtr(2);
tlen = READ_LE_UINT16(v) << 5;
v += 2;
@@ -383,8 +380,8 @@ void LoLEngine::loadLevelGraphics(const char *file, int specialColor, int weight
memcpy(_vcfBlocks, v, tlen);
}
- snprintf(fname, sizeof(fname), "%s.VCN", _lastBlockDataFile);
- _screen->loadBitmap(fname, 3, 3, 0);
+ fname = Common::String::format("%s.VCN", _lastBlockDataFile);
+ _screen->loadBitmap(fname.c_str(), 3, 3, 0);
v = _screen->getCPagePtr(2);
tlen = READ_LE_UINT16(v);
v += 2;
@@ -434,8 +431,8 @@ void LoLEngine::loadLevelGraphics(const char *file, int specialColor, int weight
memcpy(_vcnBlocks, v, vcnLen);
v += vcnLen;
- snprintf(fname, sizeof(fname), "%s.VMP", _lastBlockDataFile);
- _screen->loadBitmap(fname, 3, 3, 0);
+ fname = Common::String::format("%s.VMP", _lastBlockDataFile);
+ _screen->loadBitmap(fname.c_str(), 3, 3, 0);
v = _screen->getCPagePtr(2);
if (vmpLen == -1)
@@ -503,9 +500,7 @@ void LoLEngine::loadLevelGraphics(const char *file, int specialColor, int weight
generateBrightnessPalette(_screen->getPalette(0), _screen->getPalette(1), _brightness, _lampEffect);
if (_flags.isTalkie) {
- char tname[13];
- snprintf(tname, sizeof(tname), "LEVEL%.02d.TLC", _currentLevel);
- Common::SeekableReadStream *s = _res->createReadStream(tname);
+ Common::SeekableReadStream *s = _res->createReadStream(Common::String::format("LEVEL%.02d.TLC", _currentLevel));
s->read(_transparencyTable1, 256);
s->read(_transparencyTable2, 5120);
delete s;
@@ -1375,9 +1370,8 @@ void LoLEngine::processGasExplosion(int soundId) {
if (dist) {
WSAMovie_v2 *mov = new WSAMovie_v2(this);
- char file[13];
- snprintf(file, 13, "gasexp%0d.wsa", dist);
- mov->open(file, 1, 0);
+ Common::String file = Common::String::format("gasexp%0d.wsa", dist);
+ mov->open(file.c_str(), 1, 0);
if (!mov->opened())
error("Gas: Unable to load gasexp.wsa");
diff --git a/engines/kyra/script_lol.cpp b/engines/kyra/script_lol.cpp
index 2261ef8389..695528b8d1 100644
--- a/engines/kyra/script_lol.cpp
+++ b/engines/kyra/script_lol.cpp
@@ -524,7 +524,7 @@ int LoLEngine::olol_initAnimStruct(EMCState *script) {
int LoLEngine::olol_playAnimationPart(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_playAnimationPart(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
- _animator->playPart(stackPos(0), stackPos(1), stackPos(2), stackPos(3));
+ _tim->animator()->playPart(stackPos(0), stackPos(1), stackPos(2), stackPos(3));
return 1;
}
@@ -593,13 +593,13 @@ int LoLEngine::olol_clearDialogueField(EMCState *script) {
int LoLEngine::olol_setupBackgroundAnimationPart(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setupBackgroundAnimationPart(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9));
- _animator->setupPart(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9));
+ _tim->animator()->setupPart(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9));
return 0;
}
int LoLEngine::olol_startBackgroundAnimation(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_startBackgroundAnimation(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
- _animator->start(stackPos(0), stackPos(1));
+ _tim->animator()->start(stackPos(0), stackPos(1));
return 1;
}
@@ -629,7 +629,7 @@ int LoLEngine::olol_loadBitmap(EMCState *script) {
int LoLEngine::olol_stopBackgroundAnimation(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_stopBackgroundAnimation(%p) (%d)", (const void *)script, stackPos(0));
- _animator->stop(stackPos(0));
+ _tim->animator()->stop(stackPos(0));
return 1;
}
@@ -1136,9 +1136,8 @@ int LoLEngine::olol_loadTimScript(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_loadTimScript(%p) (%d, %s)", (const void *)script, stackPos(0), stackPosString(1));
if (_activeTim[stackPos(0)])
return 1;
- char file[13];
- snprintf(file, sizeof(file), "%s.TIM", stackPosString(1));
- _activeTim[stackPos(0)] = _tim->load(file, &_timIngameOpcodes);
+ Common::String file = Common::String::format("%s.TIM", stackPosString(1));
+ _activeTim[stackPos(0)] = _tim->load(file.c_str(), &_timIngameOpcodes);
return 1;
}
@@ -1185,10 +1184,9 @@ int LoLEngine::olol_giveItemToMonster(EMCState *script) {
int LoLEngine::olol_loadLangFile(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_loadLangFile(%p) (%s)", (const void *)script, stackPosString(0));
- char filename[13];
- snprintf(filename, sizeof(filename), "%s.%s", stackPosString(0), _languageExt[_lang]);
+ Common::String filename = Common::String::format("%s.%s", stackPosString(0), _languageExt[_lang]);
delete[] _levelLangFile;
- _levelLangFile = _res->fileData(filename, 0);
+ _levelLangFile = _res->fileData(filename.c_str(), 0);
return 1;
}
@@ -1440,7 +1438,10 @@ int LoLEngine::olol_playEndSequence(EMCState *script){
_screen->getPalette(1).clear();
showOutro(c, (_monsterDifficulty == 2));
- quitGame();
+ // Don't call quitGame() on a RTL request (because this would
+ // make the next game launched from the launcher quit instantly.
+ if (!shouldQuit())
+ quitGame();
return 0;
}
@@ -1983,7 +1984,7 @@ int LoLEngine::olol_removeInventoryItem(EMCState *script) {
int LoLEngine::olol_getAnimationLastPart(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getAnimationLastPart(%p) (%d)", (const void *)script, stackPos(0));
- return _animator->resetLastPart(stackPos(0));
+ return _tim->animator()->resetLastPart(stackPos(0));
}
int LoLEngine::olol_assignSpecialGuiShape(EMCState *script) {
@@ -2406,16 +2407,16 @@ int LoLEngine::tlol_processWsaFrame(const TIM *tim, const uint16 *param) {
const int y2 = param[3];
const int factor = MAX<int>(0, (int16)param[4]);
- const int x1 = _animator->getAnimX(animIndex);
- const int y1 = _animator->getAnimY(animIndex);
- const Movie *wsa = _animator->getWsaCPtr(animIndex);
+ const int x1 = _tim->animator()->getAnimX(animIndex);
+ const int y1 = _tim->animator()->getAnimY(animIndex);
+ const Movie *wsa = _tim->animator()->getWsaCPtr(animIndex);
int w1 = wsa->width();
int h1 = wsa->height();
int w2 = (w1 * factor) / 100;
int h2 = (h1 * factor) / 100;
- _animator->displayFrame(animIndex, 2, frame);
+ _tim->animator()->displayFrame(animIndex, 2, frame);
_screen->wsaFrameAnimationStep(x1, y1, x2, y2, w1, h1, w2, h2, 2, _flags.isDemo && _flags.platform != Common::kPlatformPC98 ? 0 : 8, 0);
if (!_flags.isDemo && _flags.platform != Common::kPlatformPC98)
_screen->checkedPageUpdate(8, 4);
@@ -2584,13 +2585,13 @@ int LoLEngine::tlol_playSoundEffect(const TIM *tim, const uint16 *param) {
int LoLEngine::tlol_startBackgroundAnimation(const TIM *tim, const uint16 *param) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_startBackgroundAnimation(%p, %p) (%d, %d)", (const void *)tim, (const void *)param, param[0], param[1]);
- _animator->start(param[0], param[1]);
+ _tim->animator()->start(param[0], param[1]);
return 1;
}
int LoLEngine::tlol_stopBackgroundAnimation(const TIM *tim, const uint16 *param) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_stopBackgroundAnimation(%p, %p) (%d)", (const void *)tim, (const void *)param, param[0]);
- _animator->stop(param[0]);
+ _tim->animator()->stop(param[0]);
return 1;
}
@@ -2674,12 +2675,12 @@ int LoLEngine::tlol_displayAnimFrame(const TIM *tim, const uint16 *param) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_displayAnimFrame(%p, %p) (%d, %d)", (const void *)tim, (const void *)param, param[0], param[1]);
const int animIndex = tim->wsa[param[0]].anim - 1;
- const Movie *wsa = _animator->getWsaCPtr(animIndex);
+ const Movie *wsa = _tim->animator()->getWsaCPtr(animIndex);
if (param[1] == 0xFFFF) {
_screen->copyRegion(0, 0, 0, 0, 320, 200, 0, 2, Screen::CR_NO_P_CHECK);
} else {
- _animator->displayFrame(animIndex, 2, param[1], 0);
+ _tim->animator()->displayFrame(animIndex, 2, param[1], 0);
_screen->copyRegion(wsa->xAdd(), wsa->yAdd(), wsa->xAdd(), wsa->yAdd(), wsa->width(), wsa->height(), 2, 0);
}
diff --git a/engines/kyra/script_tim.cpp b/engines/kyra/script_tim.cpp
index 501ae2defd..6f0f0ab083 100644
--- a/engines/kyra/script_tim.cpp
+++ b/engines/kyra/script_tim.cpp
@@ -482,17 +482,16 @@ int TIMInterpreter::initAnimStruct(int index, const char *filename, int x, int y
wsaOpenFlags = 1;
}
- char file[32];
- snprintf(file, 32, "%s.WSA", filename);
+ Common::String file = Common::String::format("%s.WSA", filename);
- if (_vm->resource()->exists(file)) {
+ if (_vm->resource()->exists(file.c_str())) {
if (isLoLDemo)
wsa = new WSAMovie_v1(_vm);
else
wsa = new WSAMovie_v2(_vm);
assert(wsa);
- wsa->open(file, wsaOpenFlags, (index == 1) ? &_screen->getPalette(0) : 0);
+ wsa->open(file.c_str(), wsaOpenFlags, (index == 1) ? &_screen->getPalette(0) : 0);
}
if (wsa && wsa->opened()) {
@@ -526,10 +525,10 @@ int TIMInterpreter::initAnimStruct(int index, const char *filename, int x, int y
}
if (wsaFlags & 4) {
- snprintf(file, 32, "%s.CPS", filename);
+ file = Common::String::format("%s.CPS", filename);
- if (_vm->resource()->exists(file)) {
- _screen->loadBitmap(file, 3, 3, &_screen->getPalette(0));
+ if (_vm->resource()->exists(file.c_str())) {
+ _screen->loadBitmap(file.c_str(), 3, 3, &_screen->getPalette(0));
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, _drawPage2, Screen::CR_NO_P_CHECK);
if (_drawPage2)
_screen->checkedPageUpdate(8, 4);
@@ -550,10 +549,10 @@ int TIMInterpreter::initAnimStruct(int index, const char *filename, int x, int y
_screen->updateScreen();
}
- snprintf(file, 32, "%s.CPS", filename);
+ file = Common::String::format("%s.CPS", filename);
- if (_vm->resource()->exists(file)) {
- _screen->loadBitmap(file, 3, 3, &_screen->getPalette(0));
+ if (_vm->resource()->exists(file.c_str())) {
+ _screen->loadBitmap(file.c_str(), 3, 3, &_screen->getPalette(0));
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, _drawPage2, Screen::CR_NO_P_CHECK);
if (_drawPage2)
_screen->checkedPageUpdate(8, 4);
@@ -922,13 +921,12 @@ int TIMInterpreter_LoL::initAnimStruct(int index, const char *filename, int x, i
if (wsaFlags & 8)
wsaOpenFlags |= 1;
- char file[32];
- snprintf(file, 32, "%s.WSA", filename);
+ Common::String file = Common::String::format("%s.WSA", filename);
- if (_vm->resource()->exists(file)) {
+ if (_vm->resource()->exists(file.c_str())) {
wsa = new WSAMovie_v2(_vm);
assert(wsa);
- wsa->open(file, wsaOpenFlags, &_screen->getPalette(3));
+ wsa->open(file.c_str(), wsaOpenFlags, &_screen->getPalette(3));
}
if (!_vm->_flags.use16ColorMode) {
diff --git a/engines/kyra/sequences_lol.cpp b/engines/kyra/sequences_lol.cpp
index d11403ad9f..01bf3c5e26 100644
--- a/engines/kyra/sequences_lol.cpp
+++ b/engines/kyra/sequences_lol.cpp
@@ -202,8 +202,7 @@ void LoLEngine::setupPrologueData(bool load) {
void LoLEngine::showIntro() {
_tim = new TIMInterpreter(this, _screen, _system);
assert(_tim);
- _animator = _tim->animator();
-
+
if (_flags.platform == Common::kPlatformPC98)
showStarcraftLogo();
@@ -262,7 +261,6 @@ void LoLEngine::showIntro() {
delete _tim;
_tim = 0;
- _animator = 0;
_screen->fadePalette(_screen->getPalette(1), 30, 0);
}
@@ -270,7 +268,6 @@ void LoLEngine::showIntro() {
int LoLEngine::chooseCharacter() {
_tim = new TIMInterpreter(this, _screen, _system);
assert(_tim);
- _animator = _tim->animator();
_tim->setLangData("LOLINTRO.DIP");
@@ -309,9 +306,8 @@ int LoLEngine::chooseCharacter() {
Screen::FontId old = _screen->setFont(Screen::FID_SJIS_FNT);
for (int j = 0; j < 3; ++j) {
- char buffer[3];
- snprintf(buffer, sizeof(buffer), "%2d", _charPreviews[i].attrib[j]);
- _screen->printText(buffer, _charPosXPC98[i] + 16, 176 + j * 8, 0x81, 0x00);
+ Common::String attribString = Common::String::format("%2d", _charPreviews[i].attrib[j]);
+ _screen->printText(attribString.c_str(), _charPosXPC98[i] + 16, 176 + j * 8, 0x81, 0x00);
}
_screen->setFont(old);
}
@@ -387,7 +383,6 @@ int LoLEngine::chooseCharacter() {
delete _tim;
_tim = 0;
- _animator = 0;
return _charSelection;
}
@@ -1061,7 +1056,6 @@ void LoLEngine::showOutro(int character, bool maxDifficulty) {
setupEpilogueData(true);
TIMInterpreter *timBackUp = _tim;
_tim = new TIMInterpreter(this, _screen, _system);
- _animator = _tim->animator();
_screen->getPalette(0).clear();
_screen->setScreenPalette(_screen->getPalette(0));
@@ -1117,47 +1111,49 @@ void LoLEngine::showOutro(int character, bool maxDifficulty) {
_screen->fadeToBlack(30);
- showCredits();
+ if (!shouldQuit())
+ showCredits();
_eventList.clear();
+
+ if (!shouldQuit()) {
+ switch (character) {
+ case 0:
+ _screen->loadBitmap("KIERAN.CPS", 3, 3, &_screen->getPalette(0));
+ break;
- switch (character) {
- case 0:
- _screen->loadBitmap("KIERAN.CPS", 3, 3, &_screen->getPalette(0));
- break;
-
- case 1:
- _screen->loadBitmap("AK'SHEL.CPS", 3, 3, &_screen->getPalette(0));
- break;
+ case 1:
+ _screen->loadBitmap("AK'SHEL.CPS", 3, 3, &_screen->getPalette(0));
+ break;
- case 2:
- _screen->loadBitmap("MICHAEL.CPS", 3, 3, &_screen->getPalette(0));
- break;
+ case 2:
+ _screen->loadBitmap("MICHAEL.CPS", 3, 3, &_screen->getPalette(0));
+ break;
- case 3:
- _screen->loadBitmap("CONRAD.CPS", 3, 3, &_screen->getPalette(0));
- break;
+ case 3:
+ _screen->loadBitmap("CONRAD.CPS", 3, 3, &_screen->getPalette(0));
+ break;
- default:
- _screen->clearPage(3);
- _screen->getPalette(0).clear();
- }
+ default:
+ _screen->clearPage(3);
+ _screen->getPalette(0).clear();
+ }
- _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
- if (maxDifficulty && !_flags.use16ColorMode)
- _tim->displayText(0x8000, 0, 0xDC);
- _screen->updateScreen();
- _screen->fadePalette(_screen->getPalette(0), 30, 0);
+ _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
+ if (maxDifficulty && !_flags.use16ColorMode)
+ _tim->displayText(0x8000, 0, 0xDC);
+ _screen->updateScreen();
+ _screen->fadePalette(_screen->getPalette(0), 30, 0);
- while (!checkInput(0) && !shouldQuit())
- delay(_tickLength);
+ while (!checkInput(0) && !shouldQuit())
+ delay(_tickLength);
- _screen->fadeToBlack(30);
+ _screen->fadeToBlack(30);
+ }
_tim->clearLangData();
delete _tim;
_tim = timBackUp;
- _animator = 0;
setupEpilogueData(false);
}
@@ -1245,7 +1241,7 @@ void LoLEngine::processCredits(char *t, int dimState, int page, int delayTime) {
int curShapeFile = 0;
uint8 *shapes[12];
- memset(&shapes, 0, sizeof(shapes));
+ memset(shapes, 0, sizeof(shapes));
loadOutroShapes(curShapeFile++, shapes);
uint8 *monsterPal = 0;
diff --git a/engines/kyra/sound_lok.cpp b/engines/kyra/sound_lok.cpp
index 95a632c08c..b2a9c2fd93 100644
--- a/engines/kyra/sound_lok.cpp
+++ b/engines/kyra/sound_lok.cpp
@@ -74,9 +74,8 @@ void KyraEngine_LoK::snd_playWanderScoreViaMap(int command, int restart) {
}
void KyraEngine_LoK::snd_playVoiceFile(int id) {
- char vocFile[9];
- snprintf(vocFile, sizeof(vocFile), "%03d", id);
- _speechPlayTime = _sound->voicePlay(vocFile, &_speechHandle);
+ Common::String vocFile = Common::String::format("%03d", id);
+ _speechPlayTime = _sound->voicePlay(vocFile.c_str(), &_speechHandle);
}
void KyraEngine_LoK::snd_voiceWaitForFinish(bool ingame) {
diff --git a/engines/kyra/sound_lol.cpp b/engines/kyra/sound_lol.cpp
index a7776f0ab6..7262635728 100644
--- a/engines/kyra/sound_lol.cpp
+++ b/engines/kyra/sound_lol.cpp
@@ -50,36 +50,34 @@ bool LoLEngine::snd_playCharacterSpeech(int id, int8 speaker, int) {
_lastSpeaker = speaker;
_nextSpeechId = _nextSpeaker = -1;
- char pattern1[8];
- char pattern2[5];
- char file1[13];
- char file2[13];
- char file3[13];
- file3[0] = 0;
+ Common::String pattern1;
+ Common::String file1;
+ Common::String file2;
+ Common::String file3;
SpeechList newSpeechList;
- snprintf(pattern2, sizeof(pattern2), "%02d", id & 0x4000 ? 0 : _curTlkFile);
+ Common::String pattern2 = Common::String::format("%02d", id & 0x4000 ? 0 : _curTlkFile);
if (id & 0x4000) {
- snprintf(pattern1, sizeof(pattern1), "%03X", id & 0x3fff);
+ pattern1 = Common::String::format("%03X", id & 0x3fff);
} else if (id < 1000) {
- snprintf(pattern1, sizeof(pattern1), "%03d", id);
+ pattern1 = Common::String::format("%03d", id);
} else {
- snprintf(file3, sizeof(file3), "@%04d%c.%s", id - 1000, (char)speaker, pattern2);
- if (_sound->isVoicePresent(file3))
- newSpeechList.push_back(_sound->getVoiceStream(file3));
+ file3 = Common::String::format("@%04d%c.%s", id - 1000, (char)speaker, pattern2.c_str());
+ if (_sound->isVoicePresent(file3.c_str()))
+ newSpeechList.push_back(_sound->getVoiceStream(file3.c_str()));
}
- if (!file3[0]) {
+ if (file3.empty()) {
for (char i = 0; ; i++) {
char symbol = '0' + i;
- snprintf(file1, sizeof(file1), "%s%c%c.%s", pattern1, (char)speaker, symbol, pattern2);
- snprintf(file2, sizeof(file2), "%s%c%c.%s", pattern1, '_', symbol, pattern2);
- if (_sound->isVoicePresent(file1))
- newSpeechList.push_back(_sound->getVoiceStream(file1));
- else if (_sound->isVoicePresent(file2))
- newSpeechList.push_back(_sound->getVoiceStream(file2));
+ file1 = Common::String::format("%s%c%c.%s", pattern1.c_str(), (char)speaker, symbol, pattern2.c_str());
+ file2 = Common::String::format("%s%c%c.%s", pattern1.c_str(), '_', symbol, pattern2.c_str());
+ if (_sound->isVoicePresent(file1.c_str()))
+ newSpeechList.push_back(_sound->getVoiceStream(file1.c_str()));
+ else if (_sound->isVoicePresent(file2.c_str()))
+ newSpeechList.push_back(_sound->getVoiceStream(file2.c_str()));
else
break;
}
@@ -260,9 +258,7 @@ void LoLEngine::snd_loadSoundFile(int track) {
int t = (track - 250) * 3;
if (_curMusicFileIndex != _musicTrackMap[t] || _curMusicFileExt != (char)_musicTrackMap[t + 1]) {
snd_stopMusic();
- char filename[13];
- snprintf(filename, sizeof(filename), "LORE%02d%c", _musicTrackMap[t], (char)_musicTrackMap[t + 1]);
- _sound->loadSoundFile(filename);
+ _sound->loadSoundFile(Common::String::format("LORE%02d%c", _musicTrackMap[t], (char)_musicTrackMap[t + 1]));
_curMusicFileIndex = _musicTrackMap[t];
_curMusicFileExt = (char)_musicTrackMap[t + 1];
} else {
diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp
index 499cc6f301..d56abc5d47 100644
--- a/engines/kyra/staticres.cpp
+++ b/engines/kyra/staticres.cpp
@@ -38,7 +38,7 @@
namespace Kyra {
-#define RESFILE_VERSION 73
+#define RESFILE_VERSION 74
namespace {
bool checkKyraDat(Common::SeekableReadStream *file) {
diff --git a/engines/kyra/text_hof.cpp b/engines/kyra/text_hof.cpp
index 393fa8d11f..4406f3ec41 100644
--- a/engines/kyra/text_hof.cpp
+++ b/engines/kyra/text_hof.cpp
@@ -436,15 +436,16 @@ void KyraEngine_HoF::updateDlgBuffer() {
_npcTalkChpIndex = _currentChapter;
_npcTalkDlgIndex = _mainCharacter.dlgIndex;
- char filename[13];
- snprintf(filename, 13, "CH%.02d-S%.02d.DLG", _currentChapter, _npcTalkDlgIndex);
+ Common::String filename = Common::String::format("CH%.02d-S%.02d.DL", _currentChapter, _npcTalkDlgIndex);
const char *suffix = _flags.isTalkie ? suffixTalkie : suffixTowns;
if (_flags.platform != Common::kPlatformPC || _flags.isTalkie)
- filename[11] = suffix[_lang];
+ filename += suffix[_lang];
+ else
+ filename += 'G';
delete[] _dlgBuffer;
- _dlgBuffer = _res->fileData(filename, 0);
+ _dlgBuffer = _res->fileData(filename.c_str(), 0);
}
void KyraEngine_HoF::loadDlgHeader(int &csEntry, int &vocH, int &scIndex1, int &scIndex2) {
diff --git a/engines/kyra/text_mr.cpp b/engines/kyra/text_mr.cpp
index 2cb752fdb3..d690b70266 100644
--- a/engines/kyra/text_mr.cpp
+++ b/engines/kyra/text_mr.cpp
@@ -625,24 +625,20 @@ void KyraEngine_MR::malcolmSceneStartupChat() {
}
void KyraEngine_MR::updateDlgBuffer() {
- char dlgFile[16];
- char cnvFile[16];
-
if (_cnvFile)
_cnvFile->seek(0, SEEK_SET);
if (_curDlgIndex == _mainCharacter.dlgIndex && _curDlgChapter == _currentChapter && _curDlgLang == _lang)
return;
- snprintf(dlgFile, 16, "CH%.02d-S%.02d.", _currentChapter, _mainCharacter.dlgIndex);
- appendLanguage(dlgFile, _lang, 16);
- snprintf(cnvFile, 16, "CH%.02d-S%.02d.CNV", _currentChapter, _mainCharacter.dlgIndex);
+ Common::String dlgFile = Common::String::format("CH%.02d-S%.02d.%s", _currentChapter, _mainCharacter.dlgIndex, _languageExtension[_lang]);
+ Common::String cnvFile = Common::String::format("CH%.02d-S%.02d.CNV", _currentChapter, _mainCharacter.dlgIndex);
delete _cnvFile;
delete _dlgBuffer;
- _res->exists(cnvFile, true);
- _res->exists(dlgFile, true);
+ _res->exists(cnvFile.c_str(), true);
+ _res->exists(dlgFile.c_str(), true);
_cnvFile = _res->createReadStream(cnvFile);
_dlgBuffer = _res->createReadStream(dlgFile);
assert(_cnvFile);
diff --git a/engines/lastexpress/data/animation.cpp b/engines/lastexpress/data/animation.cpp
index 8ce73993c3..1cbf7672d1 100644
--- a/engines/lastexpress/data/animation.cpp
+++ b/engines/lastexpress/data/animation.cpp
@@ -94,7 +94,7 @@ bool Animation::load(Common::SeekableReadStream *stream, int flag) {
}
_currentChunk = _chunks.begin();
_changed = false;
- _startTime = g_engine->_system->getMillis();
+ _startTime = g_system->getMillis();
return true;
}
@@ -110,7 +110,7 @@ bool Animation::process() {
// - Re-implement to be closer to the original engine
// - Add support for subtitles
// - Use engine sound queue instead of our own appendable sound instance
- int32 currentFrame = (g_engine->_system->getMillis() - _startTime) * 3 / 100;
+ int32 currentFrame = (g_system->getMillis() - _startTime) * 3 / 100;
// Process all chunks until the current frame
while (!_changed && _currentChunk != NULL && currentFrame > _currentChunk->frame && !hasEnded()) {
@@ -180,7 +180,7 @@ bool Animation::process() {
// Synchronize the audio by resetting the start time
if (_currentChunk->frame == 0)
- _startTime = g_engine->_system->getMillis();
+ _startTime = g_system->getMillis();
break;
case kChunkTypeAudioEnd:
@@ -260,7 +260,8 @@ void Animation::processChunkAudio(Common::SeekableReadStream *in, const Chunk &c
// TODO: this method will probably go away and be integrated in the main loop
void Animation::play() {
- while (!hasEnded() && !g_engine->getEventManager()->shouldQuit() && !g_engine->getEventManager()->shouldRTL()) {
+ Common::EventManager *eventMan = g_system->getEventManager();
+ while (!hasEnded() && !Engine::shouldQuit()) {
process();
if (_changed) {
@@ -283,11 +284,11 @@ void Animation::play() {
g_system->updateScreen();
//FIXME: implement subtitles
- g_engine->_system->delayMillis(20);
+ g_system->delayMillis(20);
// Handle right-click to interrupt animations
Common::Event ev = Common::Event();
- while (g_engine->getEventManager()->pollEvent(ev)) {
+ while (eventMan->pollEvent(ev)) {
if (ev.type == Common::EVENT_RBUTTONUP) {
// Stop audio
if (_audio)
diff --git a/engines/lastexpress/debug.cpp b/engines/lastexpress/debug.cpp
index e1bd9494a9..4b7c5f6a9a 100644
--- a/engines/lastexpress/debug.cpp
+++ b/engines/lastexpress/debug.cpp
@@ -865,7 +865,7 @@ bool Debugger::cmdBeetle(int argc, const char **argv) {
askForRedraw();
redrawScreen();
- while (g_engine->getEventManager()->pollEvent(ev)) {
+ while (g_system->getEventManager()->pollEvent(ev)) {
switch (ev.type) {
default:
diff --git a/engines/lastexpress/detection.cpp b/engines/lastexpress/detection.cpp
index 7c7c6b0a36..bf575b63f8 100644
--- a/engines/lastexpress/detection.cpp
+++ b/engines/lastexpress/detection.cpp
@@ -21,6 +21,7 @@
*/
#include "lastexpress/lastexpress.h"
+#include "engines/advancedDetector.h"
namespace LastExpress {
@@ -176,35 +177,13 @@ static const ADGameDescription gameDescriptions[] = {
AD_TABLE_END_MARKER
};
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)gameDescriptions,
- // Size of that superset structure
- sizeof(ADGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- lastExpressGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "lastexpress",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NOSUBTITLES | Common::GUIO_NOSFX,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
class LastExpressMetaEngine : public AdvancedMetaEngine {
public:
- LastExpressMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ LastExpressMetaEngine() : AdvancedMetaEngine(gameDescriptions, sizeof(ADGameDescription), lastExpressGames) {
+ params.singleid = "lastexpress";
+ params.guioptions = Common::GUIO_NOSUBTITLES | Common::GUIO_NOSFX;
+ }
const char *getName() const {
return "Lastexpress";
@@ -224,6 +203,10 @@ bool LastExpressMetaEngine::createInstance(OSystem *syst, Engine **engine, const
return gd != 0;
}
+bool LastExpressEngine::isDemo() const {
+ return (bool)(_gameDescription->flags & ADGF_DEMO);
+}
+
} // End of namespace LastExpress
#if PLUGIN_ENABLED_DYNAMIC(LASTEXPRESS)
diff --git a/engines/lastexpress/game/sound.cpp b/engines/lastexpress/game/sound.cpp
index 63efd182a8..3f98ac79ea 100644
--- a/engines/lastexpress/game/sound.cpp
+++ b/engines/lastexpress/game/sound.cpp
@@ -699,7 +699,6 @@ bool SoundManager::playSoundWithSubtitles(Common::String filename, FlagType flag
}
void SoundManager::playSoundEvent(EntityIndex entity, byte action, byte a3) {
- char filename[12];
int values[5];
if (getEntityData(entity)->car != getEntityData(kEntityPlayer)->car)
@@ -842,7 +841,6 @@ void SoundManager::playSteam(CityIndex index) {
void SoundManager::playFightSound(byte action, byte a4) {
int _action = (int)action;
- char filename[12];
int values[5];
switch (action) {
diff --git a/engines/lastexpress/lastexpress.cpp b/engines/lastexpress/lastexpress.cpp
index 6fdd18413b..e162998719 100644
--- a/engines/lastexpress/lastexpress.cpp
+++ b/engines/lastexpress/lastexpress.cpp
@@ -37,6 +37,8 @@
#include "common/config-manager.h"
#include "common/debug-channels.h"
+#include "common/error.h"
+#include "common/fs.h"
#include "engines/util.h"
diff --git a/engines/lastexpress/lastexpress.h b/engines/lastexpress/lastexpress.h
index d78bba36f0..f8f38788a0 100644
--- a/engines/lastexpress/lastexpress.h
+++ b/engines/lastexpress/lastexpress.h
@@ -29,11 +29,12 @@
#include "common/random.h"
#include "common/timer.h"
-#include "engines/advancedDetector.h"
#include "engines/engine.h"
#include "graphics/pixelformat.h"
+struct ADGameDescription;
+
/**
* This is the namespace of the LastExpress engine.
*
@@ -101,7 +102,7 @@ public:
void restoreEventHandlers();
void setEventHandlers(EventHandler::EventFunction *eventMouse, EventHandler::EventFunction *eventTick);
- bool isDemo() const { return (bool)(_gameDescription->flags & ADGF_DEMO); }
+ bool isDemo() const;
// Frame Counter
uint32 getFrameCounter() { return _frameCounter; }
diff --git a/engines/lure/detection.cpp b/engines/lure/detection.cpp
index ced0be0cfb..83ede92569 100644
--- a/engines/lure/detection.cpp
+++ b/engines/lure/detection.cpp
@@ -175,34 +175,14 @@ static const LureGameDescription gameDescriptions[] = {
} // End of namespace Lure
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Lure::gameDescriptions,
- // Size of that superset structure
- sizeof(Lure::LureGameDescription),
- // Number of bytes to compute MD5 sum for
- 1024,
- // List of all engine targets
- lureGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "lure",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- kADFlagUseExtraAsHint,
- // Additional GUI options (for every game}
- Common::GUIO_NOSPEECH,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
class LureMetaEngine : public AdvancedMetaEngine {
public:
- LureMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ LureMetaEngine() : AdvancedMetaEngine(Lure::gameDescriptions, sizeof(Lure::LureGameDescription), lureGames) {
+ params.md5Bytes = 1024;
+ params.singleid = "lure";
+ params.flags = kADFlagUseExtraAsHint;
+ params.guioptions = Common::GUIO_NOSPEECH;
+ }
virtual const char *getName() const {
return "Lure";
diff --git a/engines/m4/detection.cpp b/engines/m4/detection.cpp
index 1aefe3d02d..bab17d9e1d 100644
--- a/engines/m4/detection.cpp
+++ b/engines/m4/detection.cpp
@@ -384,34 +384,14 @@ static const char *directoryGlobs[] = {
0
};
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)M4::gameDescriptions,
- // Size of that superset structure
- sizeof(M4::M4GameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- m4Games,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "m4",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NOMIDI,
- // Maximum directory depth
- 2,
- // List of directory globs
- directoryGlobs
-};
-
class M4MetaEngine : public AdvancedMetaEngine {
public:
- M4MetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ M4MetaEngine() : AdvancedMetaEngine(M4::gameDescriptions, sizeof(M4::M4GameDescription), m4Games) {
+ params.singleid = "m4";
+ params.guioptions = Common::GUIO_NOMIDI;
+ params.depth = 2;
+ params.directoryGlobs = directoryGlobs;
+ }
virtual const char *getName() const {
return "MADS/M4";
diff --git a/engines/made/detection.cpp b/engines/made/detection.cpp
index 4576e2b5ce..a0576a458e 100644
--- a/engines/made/detection.cpp
+++ b/engines/made/detection.cpp
@@ -525,34 +525,11 @@ static MadeGameDescription g_fallbackDesc = {
} // End of namespace Made
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Made::gameDescriptions,
- // Size of that superset structure
- sizeof(Made::MadeGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- madeGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "made",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NONE,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
class MadeMetaEngine : public AdvancedMetaEngine {
public:
- MadeMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ MadeMetaEngine() : AdvancedMetaEngine(Made::gameDescriptions, sizeof(Made::MadeGameDescription), madeGames) {
+ params.singleid = "made";
+ }
virtual const char *getName() const {
return "MADE";
diff --git a/engines/mohawk/detection.cpp b/engines/mohawk/detection.cpp
index 6a73b28246..a7442729d2 100644
--- a/engines/mohawk/detection.cpp
+++ b/engines/mohawk/detection.cpp
@@ -158,35 +158,14 @@ static const char *directoryGlobs[] = {
0
};
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Mohawk::gameDescriptions,
- // Size of that superset structure
- sizeof(Mohawk::MohawkGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- mohawkGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "mohawk",
- // List of files for file-based fallback detection (optional)
- Mohawk::fileBased,
- // Flags
- 0,
- // Additional GUI options (for every game)
- Common::GUIO_NONE,
- // Maximum directory depth
- 2,
- // List of directory globs
- directoryGlobs
-};
-
class MohawkMetaEngine : public AdvancedMetaEngine {
public:
- MohawkMetaEngine() : AdvancedMetaEngine(detectionParams) {}
-
+ MohawkMetaEngine() : AdvancedMetaEngine(Mohawk::gameDescriptions, sizeof(Mohawk::MohawkGameDescription), mohawkGames) {
+ params.singleid = "mohawk";
+ params.fileBasedFallback = Mohawk::fileBased;
+ params.depth = 2;
+ params.directoryGlobs = directoryGlobs;
+ }
virtual const char *getName() const {
return "Mohawk";
}
diff --git a/engines/mohawk/detection_tables.h b/engines/mohawk/detection_tables.h
index 5510643d04..df66c3dc1c 100644
--- a/engines/mohawk/detection_tables.h
+++ b/engines/mohawk/detection_tables.h
@@ -527,7 +527,7 @@ static const MohawkGameDescription gameDescriptions[] = {
"harryhh",
"",
AD_ENTRY1("HHHB.LB", "267bb6e3c8f237ca98b02c07b9c4013f"),
- Common::EN_ANY,
+ Common::EN_GRB,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
Common::GUIO_NONE
@@ -573,6 +573,54 @@ static const MohawkGameDescription gameDescriptions[] = {
0
},
+ // From afholman in bug#3309308
+ {
+ {
+ "harryhh",
+ "",
+ AD_ENTRY1("EnglishBO", "b63a7b67834de0cd4cdbf02cf40d8547"),
+ Common::EN_GRB,
+ Common::kPlatformMacintosh,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV2,
+ 0,
+ 0
+ },
+
+ // From afholman in bug#3309308
+ {
+ {
+ "harryhh",
+ "",
+ AD_ENTRY1("GermanBO", "eb740102c1c8379c2c610cba14484ccb"),
+ Common::DE_DEU,
+ Common::kPlatformMacintosh,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV2,
+ 0,
+ 0
+ },
+
+ // From afholman in bug#3309308
+ {
+ {
+ "harryhh",
+ "",
+ AD_ENTRY1("FrenchBO", "2118de914ab9eaec482c245c06145071"),
+ Common::FR_FRA,
+ Common::kPlatformMacintosh,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV2,
+ 0,
+ 0
+ },
+
// Harry and the Haunted House 1.1
// From pacifist
{
@@ -866,6 +914,54 @@ static const MohawkGameDescription gameDescriptions[] = {
"TORTOISE.EXE"
},
+ // From afholman in bug#3309308
+ {
+ {
+ "tortoise",
+ "",
+ AD_ENTRY1("TORTB.LB", "83f6bfcf30c445d13e81e0faed9aa27b"),
+ Common::EN_GRB,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV2,
+ 0,
+ 0,
+ },
+
+ // From afholman in bug#3309308
+ {
+ {
+ "tortoise",
+ "",
+ AD_ENTRY1("TORTD.LB", "21761e7de4e5f12298f43fa17c00f3e1"),
+ Common::DE_DEU,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV2,
+ 0,
+ 0,
+ },
+
+ // From afholman in bug#3309308
+ {
+ {
+ "tortoise",
+ "",
+ AD_ENTRY1("TORTF.LB", "9693043df217ffc0667a1f45f2849aa7"),
+ Common::FR_FRA,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV2,
+ 0,
+ 0,
+ },
+
{
{
"tortoise",
@@ -942,6 +1038,38 @@ static const MohawkGameDescription gameDescriptions[] = {
"ARTHUR.EXE"
},
+ // From afholman in bug#3309308
+ {
+ {
+ "arthur",
+ "",
+ AD_ENTRY1("BookOutline", "133750de1ceb9e7351599d79f99fee4d"),
+ Common::EN_ANY,
+ Common::kPlatformMacintosh,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV1,
+ GF_LB_10,
+ "Arthur's Teacher Trouble"
+ },
+
+ // From darthbo in bug#3301791
+ {
+ {
+ "arthur",
+ "",
+ AD_ENTRY1("PAGES.512", "cd995d20d0d7b4642476fd76044b4e5b"),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV1,
+ GF_LB_10,
+ "ARTHUR.EXE"
+ },
+
{
{
"arthur",
@@ -1145,6 +1273,22 @@ static const MohawkGameDescription gameDescriptions[] = {
"RUFF.EXE"
},
+ // From aluff in bug#3307785
+ {
+ {
+ "ruff",
+ "",
+ AD_ENTRY1("BookOutline", "f625d4056c750b9aad6f94dd854f5abe"),
+ Common::EN_ANY,
+ Common::kPlatformMacintosh,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV1,
+ 0,
+ "Living Books Player"
+ },
+
{
{
"ruff",
@@ -1191,6 +1335,38 @@ static const MohawkGameDescription gameDescriptions[] = {
"Living Books Player"
},
+ // From aluff in bug#3309981
+ {
+ {
+ "newkid",
+ "",
+ AD_ENTRY1("NEWKID.512", "5135f24afa138ecdf5b52d955e9a9189"),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV1,
+ 0,
+ "NEWKID.EXE"
+ },
+
+ // From aluff in bug#3309981
+ {
+ {
+ "newkid",
+ "",
+ AD_ENTRY1("BookOutline", "6aa7c4720b922f4164584956be5ba9e5"),
+ Common::EN_ANY,
+ Common::kPlatformMacintosh,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV1,
+ 0,
+ "Living Books Player"
+ },
+
{
{
"newkid",
@@ -1299,6 +1475,22 @@ static const MohawkGameDescription gameDescriptions[] = {
"BIRTHDAY.EXE"
},
+ // From aluff in bug#3309936
+ {
+ {
+ "arthurbday",
+ "",
+ AD_ENTRY1("BookOutline", "d631242b004720ecc615e4f855825860"),
+ Common::EN_ANY,
+ Common::kPlatformMacintosh,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV1,
+ 0,
+ "Living Books Player"
+ },
+
{
{
"arthurbday",
@@ -1375,6 +1567,102 @@ static const MohawkGameDescription gameDescriptions[] = {
"Little Monster at School"
},
+ // From afholman in bug#3309308
+ {
+ {
+ "lilmonster",
+ "",
+ AD_ENTRY1("lmasb.lb", "18a4e82f2c5cc30f7a2f9bd95e8c1364"),
+ Common::EN_GRB,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV2,
+ 0,
+ 0
+ },
+
+ // From afholman in bug#3309308
+ {
+ {
+ "lilmonster",
+ "",
+ AD_ENTRY1("lmasd.lb", "422b94c0e663305869cb2d2f1109a0bc"),
+ Common::DE_DEU,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV2,
+ 0,
+ 0
+ },
+
+ // From afholman in bug#3309308
+ {
+ {
+ "lilmonster",
+ "",
+ AD_ENTRY1("lmasf.lb", "8c22e79c97a86827d56b4c596066dcea"),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV2,
+ 0,
+ 0
+ },
+
+ // From afholman in bug#3309308
+ {
+ {
+ "lilmonster",
+ "",
+ AD_ENTRY1("EnglishBO", "7aa2a1694255000b72ff0cc179f8059f"),
+ Common::EN_GRB,
+ Common::kPlatformMacintosh,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV2,
+ 0,
+ 0
+ },
+
+ // From afholman in bug#3309308
+ {
+ {
+ "lilmonster",
+ "",
+ AD_ENTRY1("GermanBO", "ff7ac4b1b4f2ded71ff3650f383fea48"),
+ Common::DE_DEU,
+ Common::kPlatformMacintosh,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV2,
+ 0,
+ 0
+ },
+
+ // From afholman in bug#3309308
+ {
+ {
+ "lilmonster",
+ "",
+ AD_ENTRY1("FrenchBO", "d13e5eae0f68cecc91a0dcfcceec7061"),
+ Common::FR_FRA,
+ Common::kPlatformMacintosh,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV2,
+ 0,
+ 0
+ },
+
// From Scarlatti in bug #3275626
{
{
@@ -1686,6 +1974,38 @@ static const MohawkGameDescription gameDescriptions[] = {
0
},
+ // From aluff in bug#3306722
+ {
+ {
+ "stellaluna",
+ "",
+ AD_ENTRY1("STELLA.LB", "ca8562a79f63485680e21191f5865fd7"),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV2,
+ 0,
+ 0
+ },
+
+ // From aluff in bug#3306722
+ {
+ {
+ "stellaluna",
+ "",
+ AD_ENTRY1("BookOutline", "7e931a455ac88557e04ca682579cd5a5"),
+ Common::EN_ANY,
+ Common::kPlatformMacintosh,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV2,
+ 0,
+ 0
+ },
+
// Sheila Rae the Brave 1.0
// From pacifist
{
@@ -1703,6 +2023,118 @@ static const MohawkGameDescription gameDescriptions[] = {
0
},
+ // From aluff in bug#3309934
+ {
+ {
+ "sheila",
+ "",
+ AD_ENTRY1("BookOutline", "961f0cf4de2fbaa1da8ce0011822cd38"),
+ Common::EN_ANY,
+ Common::kPlatformMacintosh,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV2,
+ 0,
+ 0
+ },
+
+ // From afholman in bug#3309308
+ {
+ {
+ "sheila",
+ "",
+ AD_ENTRY1("SRAEB.LB", "4835612022c2ae1944bde453d3202803"),
+ Common::EN_GRB,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV2,
+ 0,
+ 0
+ },
+
+ // From afholman in bug#3309308
+ {
+ {
+ "sheila",
+ "",
+ AD_ENTRY1("SRAED.LB", "3f21183534d324cf3bb8464f9217712c"),
+ Common::DE_DEU,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV2,
+ 0,
+ 0
+ },
+
+ // From afholman in bug#3309308
+ {
+ {
+ "sheila",
+ "",
+ AD_ENTRY1("SRAEF.LB", "96b00fc4b44c0e881c674d4bae5aa79a"),
+ Common::FR_FRA,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV2,
+ 0,
+ 0
+ },
+
+ // From afholman in bug#3309308
+ {
+ {
+ "sheila",
+ "",
+ AD_ENTRY1("EnglishBO", "6d3ad5724f1729a1d96d812668770c2e"),
+ Common::EN_GRB,
+ Common::kPlatformMacintosh,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV2,
+ 0,
+ 0
+ },
+
+ // From afholman in bug#3309308
+ {
+ {
+ "sheila",
+ "",
+ AD_ENTRY1("GermanBO", "af1dc5a8bc8da58310d17b72b657fc1f"),
+ Common::DE_DEU,
+ Common::kPlatformMacintosh,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV2,
+ 0,
+ 0
+ },
+
+ // From afholman in bug#3309308
+ {
+ {
+ "sheila",
+ "",
+ AD_ENTRY1("FrenchBO", "62eefcb8424a5f9ba7db5af6f0421e58"),
+ Common::FR_FRA,
+ Common::kPlatformMacintosh,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV2,
+ 0,
+ 0
+ },
+
{ AD_TABLE_END_MARKER, 0, 0, 0 }
};
diff --git a/engines/parallaction/detection.cpp b/engines/parallaction/detection.cpp
index c3719bcd51..09f6fa5e2e 100644
--- a/engines/parallaction/detection.cpp
+++ b/engines/parallaction/detection.cpp
@@ -220,34 +220,11 @@ static const PARALLACTIONGameDescription gameDescriptions[] = {
}
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Parallaction::gameDescriptions,
- // Size of that superset structure
- sizeof(Parallaction::PARALLACTIONGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- parallactionGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- 0,
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NOLAUNCHLOAD,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
class ParallactionMetaEngine : public AdvancedMetaEngine {
public:
- ParallactionMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ ParallactionMetaEngine() : AdvancedMetaEngine(Parallaction::gameDescriptions, sizeof(Parallaction::PARALLACTIONGameDescription), parallactionGames) {
+ params.guioptions = Common::GUIO_NOLAUNCHLOAD;
+ }
virtual const char *getName() const {
return "Parallaction";
diff --git a/engines/saga/detection.cpp b/engines/saga/detection.cpp
index 23bdc73666..ece90855b7 100644
--- a/engines/saga/detection.cpp
+++ b/engines/saga/detection.cpp
@@ -101,34 +101,12 @@ static const ADObsoleteGameID obsoleteGameIDsTable[] = {
#include "saga/detection_tables.h"
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Saga::gameDescriptions,
- // Size of that superset structure
- sizeof(Saga::SAGAGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- sagaGames,
- // Structure for autoupgrading obsolete targets
- obsoleteGameIDsTable,
- // Name of single gameid (optional)
- "saga",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NONE,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
class SagaMetaEngine : public AdvancedMetaEngine {
public:
- SagaMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ SagaMetaEngine() : AdvancedMetaEngine(Saga::gameDescriptions, sizeof(Saga::SAGAGameDescription), sagaGames) {
+ params.obsoleteList = obsoleteGameIDsTable;
+ params.singleid = "saga";
+ }
virtual const char *getName() const {
return "SAGA ["
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index af945247ba..b1b5f81995 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -131,6 +131,8 @@ Console::Console(SciEngine *engine) : GUI::Debugger(),
DCmd_Register("al", WRAP_METHOD(Console, cmdAnimateList)); // alias
DCmd_Register("window_list", WRAP_METHOD(Console, cmdWindowList));
DCmd_Register("wl", WRAP_METHOD(Console, cmdWindowList)); // alias
+ DCmd_Register("saved_bits", WRAP_METHOD(Console, cmdSavedBits));
+ DCmd_Register("show_saved_bits", WRAP_METHOD(Console, cmdShowSavedBits));
// Segments
DCmd_Register("segment_table", WRAP_METHOD(Console, cmdPrintSegmentTable));
DCmd_Register("segtable", WRAP_METHOD(Console, cmdPrintSegmentTable)); // alias
@@ -364,6 +366,8 @@ bool Console::cmdHelp(int argc, const char **argv) {
DebugPrintf(" undither - Enable/disable undithering\n");
DebugPrintf(" play_video - Plays a SEQ, AVI, VMD, RBT or DUK video\n");
DebugPrintf(" animate_object_list / al - Shows the current list of objects in kAnimate's draw list\n");
+ DebugPrintf(" saved_bits - List saved bits on the hunk\n");
+ DebugPrintf(" show_saved_bits - Display saved bits\n");
DebugPrintf("\n");
DebugPrintf("Segments:\n");
DebugPrintf(" segment_table / segtable - Lists all segments\n");
@@ -1600,6 +1604,174 @@ bool Console::cmdWindowList(int argc, const char **argv) {
return true;
}
+
+bool Console::cmdSavedBits(int argc, const char **argv) {
+ SegManager *segman = _engine->_gamestate->_segMan;
+ SegmentId id = segman->findSegmentByType(SEG_TYPE_HUNK);
+ HunkTable* hunks = (HunkTable*)segman->getSegmentObj(id);
+ if (!hunks) {
+ DebugPrintf("No hunk segment found.\n");
+ return true;
+ }
+
+ Common::Array<reg_t> entries = hunks->listAllDeallocatable(id);
+
+ for (uint i = 0; i < entries.size(); ++i) {
+ uint16 offset = entries[i].offset;
+ const Hunk& h = hunks->_table[offset];
+ if (strcmp(h.type, "SaveBits()") == 0) {
+ byte* memoryPtr = (byte*)h.mem;
+
+ if (memoryPtr) {
+ DebugPrintf("%04x:%04x:", PRINT_REG(entries[i]));
+
+ Common::Rect rect;
+ byte mask;
+ assert(h.size >= sizeof(rect) + sizeof(mask));
+
+ memcpy((void *)&rect, memoryPtr, sizeof(rect));
+ memcpy((void *)&mask, memoryPtr + sizeof(rect), sizeof(mask));
+
+ DebugPrintf(" %d,%d - %d,%d", rect.top, rect.left,
+ rect.bottom, rect.right);
+ if (mask & GFX_SCREEN_MASK_VISUAL)
+ DebugPrintf(" visual");
+ if (mask & GFX_SCREEN_MASK_PRIORITY)
+ DebugPrintf(" priority");
+ if (mask & GFX_SCREEN_MASK_CONTROL)
+ DebugPrintf(" control");
+ if (mask & GFX_SCREEN_MASK_DISPLAY)
+ DebugPrintf(" display");
+ DebugPrintf("\n");
+ }
+ }
+ }
+
+
+ return true;
+}
+
+bool Console::cmdShowSavedBits(int argc, const char **argv) {
+ if (argc < 2) {
+ DebugPrintf("Display saved bits.\n");
+ DebugPrintf("Usage: %s <address>\n", argv[0]);
+ DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ return true;
+ }
+
+ reg_t memoryHandle = NULL_REG;
+
+ if (parse_reg_t(_engine->_gamestate, argv[1], &memoryHandle, false)) {
+ DebugPrintf("Invalid address passed.\n");
+ DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ return true;
+ }
+
+ if (memoryHandle.isNull()) {
+ DebugPrintf("Invalid address.\n");
+ return true;
+ }
+
+ SegManager *segman = _engine->_gamestate->_segMan;
+ SegmentId id = segman->findSegmentByType(SEG_TYPE_HUNK);
+ HunkTable* hunks = (HunkTable*)segman->getSegmentObj(id);
+ if (!hunks) {
+ DebugPrintf("No hunk segment found.\n");
+ return true;
+ }
+
+ if (memoryHandle.segment != id || !hunks->isValidOffset(memoryHandle.offset)) {
+ DebugPrintf("Invalid address.\n");
+ return true;
+ }
+
+ const Hunk& h = hunks->_table[memoryHandle.offset];
+
+ if (strcmp(h.type, "SaveBits()") != 0) {
+ DebugPrintf("Invalid address.\n");
+ return true;
+ }
+
+ byte *memoryPtr = segman->getHunkPointer(memoryHandle);
+
+ if (!memoryPtr) {
+ DebugPrintf("Invalid or freed bits.\n");
+ return true;
+ }
+
+ // Now we _finally_ know these are valid saved bits
+
+ Common::Rect rect;
+ byte mask;
+ assert(h.size >= sizeof(rect) + sizeof(mask));
+
+ memcpy((void *)&rect, memoryPtr, sizeof(rect));
+ memcpy((void *)&mask, memoryPtr + sizeof(rect), sizeof(mask));
+
+ Common::Point tl(rect.left, rect.top);
+ Common::Point tr(rect.right-1, rect.top);
+ Common::Point bl(rect.left, rect.bottom-1);
+ Common::Point br(rect.right-1, rect.bottom-1);
+
+ DebugPrintf(" %d,%d - %d,%d", rect.top, rect.left,
+ rect.bottom, rect.right);
+ if (mask & GFX_SCREEN_MASK_VISUAL)
+ DebugPrintf(" visual");
+ if (mask & GFX_SCREEN_MASK_PRIORITY)
+ DebugPrintf(" priority");
+ if (mask & GFX_SCREEN_MASK_CONTROL)
+ DebugPrintf(" control");
+ if (mask & GFX_SCREEN_MASK_DISPLAY)
+ DebugPrintf(" display");
+ DebugPrintf("\n");
+
+ if (!_engine->_gfxPaint16 || !_engine->_gfxScreen)
+ return true;
+
+ // We backup all planes, and then flash the saved bits
+ // FIXME: This probably won't work well with hi-res games
+
+ byte bakMask = GFX_SCREEN_MASK_VISUAL | GFX_SCREEN_MASK_PRIORITY | GFX_SCREEN_MASK_CONTROL;
+ int bakSize = _engine->_gfxScreen->bitsGetDataSize(rect, bakMask);
+ reg_t bakScreen = segman->allocateHunkEntry("show_saved_bits backup", bakSize);
+ byte* bakMemory = segman->getHunkPointer(bakScreen);
+ assert(bakMemory);
+ _engine->_gfxScreen->bitsSave(rect, bakMask, bakMemory);
+
+#ifndef USE_TEXT_CONSOLE_FOR_DEBUGGER
+ // If a graphical debugger overlay is used, hide it here, so that the
+ // results can be drawn.
+ g_system->hideOverlay();
+#endif
+
+ const int paintCount = 3;
+ for (int i = 0; i < paintCount; ++i) {
+ _engine->_gfxScreen->bitsRestore(memoryPtr);
+ _engine->_gfxScreen->drawLine(tl, tr, 0, 255, 255);
+ _engine->_gfxScreen->drawLine(tr, br, 0, 255, 255);
+ _engine->_gfxScreen->drawLine(br, bl, 0, 255, 255);
+ _engine->_gfxScreen->drawLine(bl, tl, 0, 255, 255);
+ _engine->_gfxScreen->copyRectToScreen(rect);
+ g_system->updateScreen();
+ g_sci->sleep(500);
+ _engine->_gfxScreen->bitsRestore(bakMemory);
+ _engine->_gfxScreen->copyRectToScreen(rect);
+ g_system->updateScreen();
+ if (i < paintCount - 1)
+ g_sci->sleep(500);
+ }
+
+ _engine->_gfxPaint16->bitsFree(bakScreen);
+
+#ifndef USE_TEXT_CONSOLE_FOR_DEBUGGER
+ // Show the graphical debugger overlay
+ g_system->showOverlay();
+#endif
+
+ return true;
+}
+
+
bool Console::cmdParseGrammar(int argc, const char **argv) {
DebugPrintf("Parse grammar, in strict GNF:\n");
@@ -2782,7 +2954,7 @@ void Console::printKernelCallsFound(int kernelFuncNum, bool showFoundScripts) {
uint16 argc2 = opparams[1];
if (kFuncNum == kernelFuncNum) {
- DebugPrintf("Called from script %d, object %s, method %s(%d) with %d parameters\n",
+ DebugPrintf("Called from script %d, object %s, method %s(%d) with %d bytes for arguments\n",
itr->getNumber(), objName,
_engine->getKernel()->getSelectorName(obj->getFuncSelector(i)).c_str(), i, argc2);
}
@@ -2799,7 +2971,7 @@ void Console::printKernelCallsFound(int kernelFuncNum, bool showFoundScripts) {
// Check for end of function/script
if (offset >= script->getBufSize())
break;
- if (opcode == op_ret)// && offset >= maxJmpOffset)
+ if (opcode == op_ret && offset >= maxJmpOffset)
break;
} // while (true)
} // for (uint16 i = 0; i < obj->getMethodCount(); i++)
diff --git a/engines/sci/console.h b/engines/sci/console.h
index 1e2ebe4ba2..d943923ba1 100644
--- a/engines/sci/console.h
+++ b/engines/sci/console.h
@@ -94,6 +94,8 @@ private:
bool cmdPlayVideo(int argc, const char **argv);
bool cmdAnimateList(int argc, const char **argv);
bool cmdWindowList(int argc, const char **argv);
+ bool cmdSavedBits(int argc, const char **argv);
+ bool cmdShowSavedBits(int argc, const char **argv);
// Segments
bool cmdPrintSegmentTable(int argc, const char **argv);
bool cmdSegmentInfo(int argc, const char **argv);
diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp
index 100b71efa7..302ba13247 100644
--- a/engines/sci/detection.cpp
+++ b/engines/sci/detection.cpp
@@ -371,35 +371,11 @@ static ADGameDescription s_fallbackDesc = {
static char s_fallbackGameIdBuf[256];
-
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Sci::SciGameDescriptions,
- // Size of that superset structure
- sizeof(ADGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- s_sciGameTitles,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "sci",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NONE,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
class SciMetaEngine : public AdvancedMetaEngine {
public:
- SciMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ SciMetaEngine() : AdvancedMetaEngine(Sci::SciGameDescriptions, sizeof(ADGameDescription), s_sciGameTitles) {
+ params.singleid = "sci";
+ }
virtual const char *getName() const {
return "SCI [SCI0, SCI01, SCI10, SCI11"
diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h
index d56d8f03cd..def3879945 100644
--- a/engines/sci/detection_tables.h
+++ b/engines/sci/detection_tables.h
@@ -503,6 +503,14 @@ static const struct ADGameDescription SciGameDescriptions[] = {
AD_LISTEND},
Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH },
+ // Eco Quest 2 - Spanish DOS Floppy (supplied by umbrio in bug report #3313962)
+ {"ecoquest2", "Floppy", {
+ {"resource.map", 0, "a6b271b934afa7e84d03816a4fefa67b", 5593},
+ {"resource.000", 0, "1c4093f7248240329121fdf8c0d59152", 4209150},
+ {"resource.msg", 0, "eff8be1925d42288de55e405983e9314", 117810},
+ AD_LISTEND},
+ Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH },
+
// Freddy Pharkas - English DOS demo (from FRG)
// SCI interpreter version 1.001.069
{"freddypharkas", "Demo", {
diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp
index ee88d8af15..e1e52215d2 100644
--- a/engines/sci/engine/kfile.cpp
+++ b/engines/sci/engine/kfile.cpp
@@ -100,12 +100,12 @@ enum {
-reg_t file_open(EngineState *s, const char *filename, int mode, bool unwrapFilename) {
+reg_t file_open(EngineState *s, const Common::String &filename, int mode, bool unwrapFilename) {
Common::String englishName = g_sci->getSciLanguageString(filename, K_LANG_ENGLISH);
Common::String wrappedName = unwrapFilename ? g_sci->wrapFilename(englishName) : englishName;
Common::SeekableReadStream *inFile = 0;
Common::WriteStream *outFile = 0;
- Common::SaveFileManager *saveFileMan = g_engine->getSaveFileManager();
+ Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager();
if (mode == _K_FILE_MODE_OPEN_OR_FAIL) {
// Try to open file, abort if not possible
@@ -178,7 +178,7 @@ reg_t kFOpen(EngineState *s, int argc, reg_t *argv) {
int mode = argv[1].toUint16();
debugC(kDebugLevelFile, "kFOpen(%s,0x%x)", name.c_str(), mode);
- return file_open(s, name.c_str(), mode, true);
+ return file_open(s, name, mode, true);
}
static FileHandle *getFileFromHandle(EngineState *s, uint handle) {
@@ -349,7 +349,7 @@ reg_t kDeviceInfo(EngineState *s, int argc, reg_t *argv) {
if (findSavegame(saves, savegameId) != -1) {
// Confirmed that this id still lives...
Common::String filename = g_sci->getSavegameName(savegameId);
- Common::SaveFileManager *saveFileMan = g_engine->getSaveFileManager();
+ Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager();
saveFileMan->removeSavefile(filename);
}
break;
@@ -410,7 +410,7 @@ static bool _savegame_sort_byDate(const SavegameDesc &l, const SavegameDesc &r)
// Create a sorted array containing all found savedgames
static void listSavegames(Common::Array<SavegameDesc> &saves) {
- Common::SaveFileManager *saveFileMan = g_engine->getSaveFileManager();
+ Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager();
// Load all saves
Common::StringArray saveNames = saveFileMan->listSavefiles(g_sci->getSavegamePattern());
@@ -637,14 +637,14 @@ reg_t kSaveGame(EngineState *s, int argc, reg_t *argv) {
s->r_acc = NULL_REG;
Common::String filename = g_sci->getSavegameName(savegameId);
- Common::SaveFileManager *saveFileMan = g_engine->getSaveFileManager();
+ Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager();
Common::OutSaveFile *out;
out = saveFileMan->openForSaving(filename);
if (!out) {
warning("Error opening savegame \"%s\" for writing", filename.c_str());
} else {
- if (!gamestate_save(s, out, game_description.c_str(), version.c_str())) {
+ if (!gamestate_save(s, out, game_description, version)) {
warning("Saving the game failed");
} else {
s->r_acc = TRUE_REG; // save successful
@@ -705,7 +705,7 @@ reg_t kRestoreGame(EngineState *s, int argc, reg_t *argv) {
s->r_acc = TRUE_REG;
warning("Savegame ID %d not found", savegameId);
} else {
- Common::SaveFileManager *saveFileMan = g_engine->getSaveFileManager();
+ Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager();
Common::String filename = g_sci->getSavegameName(savegameId);
Common::SeekableReadStream *in;
@@ -792,7 +792,7 @@ reg_t kFileIOOpen(EngineState *s, int argc, reg_t *argv) {
unwrapFilename = false;
}
- return file_open(s, name.c_str(), mode, unwrapFilename);
+ return file_open(s, name, mode, unwrapFilename);
}
reg_t kFileIOClose(EngineState *s, int argc, reg_t *argv) {
@@ -845,7 +845,7 @@ reg_t kFileIOWriteRaw(EngineState *s, int argc, reg_t *argv) {
reg_t kFileIOUnlink(EngineState *s, int argc, reg_t *argv) {
Common::String name = s->_segMan->getString(argv[0]);
- Common::SaveFileManager *saveFileMan = g_engine->getSaveFileManager();
+ Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager();
bool result;
// SQ4 floppy prepends /\ to the filenames
@@ -920,7 +920,7 @@ reg_t kFileIOSeek(EngineState *s, int argc, reg_t *argv) {
}
void DirSeeker::addAsVirtualFiles(Common::String title, Common::String fileMask) {
- Common::SaveFileManager *saveFileMan = g_engine->getSaveFileManager();
+ Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager();
Common::StringArray foundFiles = saveFileMan->listSavefiles(fileMask);
if (!foundFiles.empty()) {
_files.push_back(title);
@@ -984,7 +984,7 @@ reg_t DirSeeker::firstFile(const Common::String &mask, reg_t buffer, SegManager
const Common::String wrappedMask = g_sci->wrapFilename(mask);
// Obtain a list of all files matching the given mask
- Common::SaveFileManager *saveFileMan = g_engine->getSaveFileManager();
+ Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager();
_files = saveFileMan->listSavefiles(wrappedMask);
}
@@ -1043,7 +1043,7 @@ reg_t kFileIOExists(EngineState *s, int argc, reg_t *argv) {
exists = Common::File::exists(name);
// Check for a savegame with the name
- Common::SaveFileManager *saveFileMan = g_engine->getSaveFileManager();
+ Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager();
if (!exists)
exists = !saveFileMan->listSavefiles(name).empty();
@@ -1083,7 +1083,7 @@ reg_t kFileIORename(EngineState *s, int argc, reg_t *argv) {
// SCI1.1 returns 0 on success and a DOS error code on fail. SCI32
// returns -1 on fail. We just return -1 for all versions.
- if (g_engine->getSaveFileManager()->renameSavefile(oldName, newName))
+ if (g_sci->getSaveFileManager()->renameSavefile(oldName, newName))
return NULL_REG;
else
return SIGNAL_REG;
diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp
index 16098ab275..957930784b 100644
--- a/engines/sci/engine/scriptdebug.cpp
+++ b/engines/sci/engine/scriptdebug.cpp
@@ -174,13 +174,15 @@ reg_t disassemble(EngineState *s, reg_t pos, bool printBWTag, bool printBytecode
break;
case Script_SRelative:
- if (opsize)
- param_value = scr[retval.offset++];
+ if (opsize) {
+ int8 offset = (int8)scr[retval.offset++];
+ debugN(" %02x [%04x]", 0xff & offset, 0xffff & (retval.offset + offset));
+ }
else {
- param_value = READ_SCI11ENDIAN_UINT16(&scr[retval.offset]);
+ int16 offset = (int16)READ_SCI11ENDIAN_UINT16(&scr[retval.offset]);
retval.offset += 2;
+ debugN(" %04x [%04x]", 0xffff & offset, 0xffff & (retval.offset + offset));
}
- debugN(opsize ? " %02x [%04x]" : " %04x [%04x]", param_value, (0xffff) & (retval.offset + param_value));
break;
case Script_End:
diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp
index e094ed3bd7..3328f80de1 100644
--- a/engines/sci/engine/state.cpp
+++ b/engines/sci/engine/state.cpp
@@ -192,10 +192,10 @@ static kLanguage charToLanguage(const char c) {
}
}
-Common::String SciEngine::getSciLanguageString(const char *str, kLanguage lang, kLanguage *lang2) const {
+Common::String SciEngine::getSciLanguageString(const Common::String &str, kLanguage lang, kLanguage *lang2) const {
kLanguage secondLang = K_LANG_NONE;
- const char *seeker = str;
+ const char *seeker = str.c_str();
while (*seeker) {
if ((*seeker == '%') || (*seeker == '#')) {
secondLang = charToLanguage(*(seeker + 1));
@@ -242,9 +242,9 @@ Common::String SciEngine::getSciLanguageString(const char *str, kLanguage lang,
}
if (seeker)
- return Common::String(str, seeker - str);
+ return Common::String(str.c_str(), seeker - str.c_str());
else
- return Common::String(str);
+ return str;
}
kLanguage SciEngine::getSciLanguage() {
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index 499574957e..1517355365 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -130,16 +130,16 @@ static reg_t read_var(EngineState *s, int type, int index) {
if (solution.type == WORKAROUND_NONE) {
#ifdef RELEASE_BUILD
// If we are running an official ScummVM release -> fake 0 in unknown cases
- warning("Uninitialized read for temp %d from method %s::%s (script %d, room %d, localCall %x)",
- index, originReply.objectName.c_str(), originReply.methodName.c_str(), originReply.scriptNr,
- g_sci->getEngineState()->currentRoomNumber(), originReply.localCallOffset);
+ warning("Uninitialized read for temp %d from method %s::%s (room %d, script %d, localCall %x)",
+ index, originReply.objectName.c_str(), originReply.methodName.c_str(), s->currentRoomNumber(),
+ originReply.scriptNr, originReply.localCallOffset);
s->variables[type][index] = NULL_REG;
break;
#else
- error("Uninitialized read for temp %d from method %s::%s (script %d, room %d, localCall %x)",
- index, originReply.objectName.c_str(), originReply.methodName.c_str(), originReply.scriptNr,
- g_sci->getEngineState()->currentRoomNumber(), originReply.localCallOffset);
+ error("Uninitialized read for temp %d from method %s::%s (room %d, script %d, localCall %x)",
+ index, originReply.objectName.c_str(), originReply.methodName.c_str(), s->currentRoomNumber(),
+ originReply.scriptNr, originReply.localCallOffset);
#endif
}
assert(solution.type == WORKAROUND_FAKE);
@@ -366,9 +366,9 @@ static void callKernelFunc(EngineState *s, int kernelCallNr, int argc) {
switch (solution.type) {
case WORKAROUND_NONE:
kernel->signatureDebug(kernelCall.signature, argc, argv);
- error("[VM] k%s[%x]: signature mismatch via method %s::%s (script %d, room %d, localCall 0x%x)",
+ error("[VM] k%s[%x]: signature mismatch via method %s::%s (room %d, script %d, localCall 0x%x)",
kernelCall.name, kernelCallNr, originReply.objectName.c_str(), originReply.methodName.c_str(),
- originReply.scriptNr, s->currentRoomNumber(), originReply.localCallOffset);
+ s->currentRoomNumber(), originReply.scriptNr, originReply.localCallOffset);
break;
case WORKAROUND_IGNORE: // don't do kernel call, leave acc alone
return;
@@ -418,13 +418,13 @@ static void callKernelFunc(EngineState *s, int kernelCallNr, int argc) {
int callNameLen = strlen(kernelCall.name);
if (strncmp(kernelCall.name, kernelSubCall.name, callNameLen) == 0) {
const char *subCallName = kernelSubCall.name + callNameLen;
- error("[VM] k%s(%s): signature mismatch via method %s::%s (script %d, room %d, localCall %x)",
+ error("[VM] k%s(%s): signature mismatch via method %s::%s (room %d, script %d, localCall %x)",
kernelCall.name, subCallName, originReply.objectName.c_str(), originReply.methodName.c_str(),
- originReply.scriptNr, s->currentRoomNumber(), originReply.localCallOffset);
+ s->currentRoomNumber(), originReply.scriptNr, originReply.localCallOffset);
}
- error("[VM] k%s: signature mismatch via method %s::%s (script %d, room %d, localCall %x)",
+ error("[VM] k%s: signature mismatch via method %s::%s (room %d, script %d, localCall %x)",
kernelSubCall.name, originReply.objectName.c_str(), originReply.methodName.c_str(),
- originReply.scriptNr, s->currentRoomNumber(), originReply.localCallOffset);
+ s->currentRoomNumber(), originReply.scriptNr, originReply.localCallOffset);
break;
}
case WORKAROUND_IGNORE: // don't do kernel call, leave acc alone
diff --git a/engines/sci/engine/vm_types.cpp b/engines/sci/engine/vm_types.cpp
index 71a28a9761..e39c7708ad 100644
--- a/engines/sci/engine/vm_types.cpp
+++ b/engines/sci/engine/vm_types.cpp
@@ -32,9 +32,9 @@ reg_t reg_t::lookForWorkaround(const reg_t right) const {
SciTrackOriginReply originReply;
SciWorkaroundSolution solution = trackOriginAndFindWorkaround(0, arithmeticWorkarounds, &originReply);
if (solution.type == WORKAROUND_NONE)
- error("Invalid arithmetic operation (params: %04x:%04x and %04x:%04x) from method %s::%s (script %d, room %d, localCall %x)",
+ error("Invalid arithmetic operation (params: %04x:%04x and %04x:%04x) from method %s::%s (room %d, script %d, localCall %x)",
PRINT_REG(*this), PRINT_REG(right), originReply.objectName.c_str(),
- originReply.methodName.c_str(), originReply.scriptNr, g_sci->getEngineState()->currentRoomNumber(),
+ originReply.methodName.c_str(), g_sci->getEngineState()->currentRoomNumber(), originReply.scriptNr,
originReply.localCallOffset);
assert(solution.type == WORKAROUND_FAKE);
return make_reg(0, solution.value);
diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp
index fa25b02a8f..464b4d8d5b 100644
--- a/engines/sci/engine/workarounds.cpp
+++ b/engines/sci/engine/workarounds.cpp
@@ -34,6 +34,7 @@ namespace Sci {
const SciWorkaroundEntry arithmeticWorkarounds[] = {
{ GID_CAMELOT, 92, 92, 0, "endingCartoon2", "changeState", 0x20d, 0, { WORKAROUND_FAKE, 0 } }, // op_lai: during the ending, sub gets called with no parameters, uses parameter 1 which is theGrail in this case - bug #3044734
{ GID_ECOQUEST2, 100, 0, 0, "Rain", "points", 0xcc6, 0, { WORKAROUND_FAKE, 0 } }, // op_or: when giving the papers to the customs officer, gets called against a pointer instead of a number - bug #3034464
+ { GID_ECOQUEST2, 100, 0, 0, "Rain", "points", 0xce0, 0, { WORKAROUND_FAKE, 0 } }, // Same as above, for the Spanish version - bug #3313962
{ GID_FANMADE, 516, 983, 0, "Wander", "setTarget", -1, 0, { WORKAROUND_FAKE, 0 } }, // op_mul: The Legend of the Lost Jewel Demo (fan made): called with object as second parameter when attacked by insects - bug #3038913
{ GID_ICEMAN, 199, 977, 0, "Grooper", "doit", -1, 0, { WORKAROUND_FAKE, 0 } }, // op_add: While dancing with the girl
{ GID_MOTHERGOOSE256, -1, 999, 0, "Event", "new", -1, 0, { WORKAROUND_FAKE, 0 } }, // op_and: constantly during the game (SCI1 version)
@@ -447,7 +448,7 @@ SciWorkaroundSolution trackOriginAndFindWorkaround(int index, const SciWorkaroun
workaround = workaroundList;
while (workaround->methodName) {
bool objectNameMatches = (workaround->objectName == NULL) ||
- (workaround->objectName == g_sci->getSciLanguageString(searchObjectName.c_str(), K_LANG_ENGLISH));
+ (workaround->objectName == g_sci->getSciLanguageString(searchObjectName, K_LANG_ENGLISH));
// Special case: in the fanmade Russian translation of SQ4, all
// of the object names have been deleted or renamed to Russian,
@@ -460,7 +461,7 @@ SciWorkaroundSolution trackOriginAndFindWorkaround(int index, const SciWorkaroun
&& ((workaround->roomNr == -1) || (workaround->roomNr == curRoomNumber))
&& ((workaround->inheritanceLevel == -1) || (workaround->inheritanceLevel == inheritanceLevel))
&& objectNameMatches
- && workaround->methodName == g_sci->getSciLanguageString(curMethodName.c_str(), K_LANG_ENGLISH)
+ && workaround->methodName == g_sci->getSciLanguageString(curMethodName, K_LANG_ENGLISH)
&& workaround->localCallOffset == lastCall->debugLocalCallOffset
&& ((workaround->index == -1) || (workaround->index == index))) {
// Workaround found
diff --git a/engines/sci/graphics/compare.cpp b/engines/sci/graphics/compare.cpp
index 1dbe279f8a..3183ffa2b9 100644
--- a/engines/sci/graphics/compare.cpp
+++ b/engines/sci/graphics/compare.cpp
@@ -84,7 +84,14 @@ reg_t GfxCompare::canBeHereCheckRectList(reg_t checkObject, const Common::Rect &
curRect.right = readSelectorValue(_segMan, curObject, SELECTOR(brRight));
curRect.bottom = readSelectorValue(_segMan, curObject, SELECTOR(brBottom));
// Check if curRect is within checkRect
- if (checkRect.contains(curRect))
+ // This behavior is slightly odd, but it's how the original SCI
+ // engine did it: a rect cannot be contained within itself
+ // (there is no equality). Do NOT change this to contains(), as
+ // it breaks KQ4 early (bug #3315639).
+ if (curRect.right > checkRect.left &&
+ curRect.left < checkRect.right &&
+ curRect.bottom > checkRect.top &&
+ curRect.top < checkRect.bottom)
return curObject;
}
}
diff --git a/engines/sci/graphics/controls.cpp b/engines/sci/graphics/controls.cpp
index 0289735c0a..8d4712a969 100644
--- a/engines/sci/graphics/controls.cpp
+++ b/engines/sci/graphics/controls.cpp
@@ -329,7 +329,6 @@ void GfxControls::kernelDrawText(Common::Rect rect, reg_t obj, const char *text,
if (style & SCI_CONTROLS_STYLE_SELECTED) {
_paint16->frameRect(rect);
}
- rect.grow(1);
if (!getPicNotValid())
_paint16->bitsShow(rect);
} else {
diff --git a/engines/sci/graphics/menu.cpp b/engines/sci/graphics/menu.cpp
index 9d4ab3f589..913f680e99 100644
--- a/engines/sci/graphics/menu.cpp
+++ b/engines/sci/graphics/menu.cpp
@@ -423,7 +423,9 @@ reg_t GfxMenu::kernelSelect(reg_t eventObject, bool pauseSound) {
default:
while (itemIterator != itemEnd) {
itemEntry = *itemIterator;
- if ((itemEntry->keyPress == keyPress) && (itemEntry->keyModifier == keyModifier))
+ if (itemEntry->keyPress == keyPress &&
+ itemEntry->keyModifier == keyModifier &&
+ itemEntry->enabled)
break;
itemIterator++;
}
diff --git a/engines/sci/graphics/picture.cpp b/engines/sci/graphics/picture.cpp
index 6529a6ae64..ce69ba8922 100644
--- a/engines/sci/graphics/picture.cpp
+++ b/engines/sci/graphics/picture.cpp
@@ -330,7 +330,7 @@ void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos
if (!_addToFlag && _resourceType != SCI_PICTURE_TYPE_SCI32)
clearColor = _screen->getColorWhite();
- byte drawMask = priority == 255 ? GFX_SCREEN_MASK_VISUAL : GFX_SCREEN_MASK_VISUAL | GFX_SCREEN_MASK_PRIORITY;
+ byte drawMask = priority > 15 ? GFX_SCREEN_MASK_VISUAL : GFX_SCREEN_MASK_VISUAL | GFX_SCREEN_MASK_PRIORITY;
ptr = celBitmap;
ptr += skipCelBitmapPixels;
diff --git a/engines/sci/graphics/screen.cpp b/engines/sci/graphics/screen.cpp
index 2446ea545e..4ab0b9719f 100644
--- a/engines/sci/graphics/screen.cpp
+++ b/engines/sci/graphics/screen.cpp
@@ -763,11 +763,14 @@ int16 GfxScreen::kernelPicNotValid(int16 newPicNotValid) {
uint16 GfxScreen::getLowResScreenHeight() {
// Some Mac SCI1/1.1 games only take up 190 rows and do not
// have the menu bar.
+ // TODO: Verify that LSL1 and LSL5 use height 190
if (g_sci->getPlatform() == Common::kPlatformMacintosh) {
switch (g_sci->getGameId()) {
case GID_FREDDYPHARKAS:
case GID_KQ5:
case GID_KQ6:
+ case GID_LSL1:
+ case GID_LSL5:
case GID_SQ1:
return 190;
default:
diff --git a/engines/sci/graphics/transitions.cpp b/engines/sci/graphics/transitions.cpp
index 1256db8969..d047eb10a1 100644
--- a/engines/sci/graphics/transitions.cpp
+++ b/engines/sci/graphics/transitions.cpp
@@ -189,14 +189,6 @@ void GfxTransitions::doit(Common::Rect picRect) {
// Now we do the actual transition to the new screen
doTransition(_number, false);
- if (picRect.bottom != _screen->getHeight()) {
- // TODO: this is a workaround for lsl6 not showing menubar when playing
- // There is some new code in the sierra sci in ShowPic that seems to do
- // something similar to this
- _screen->copyToScreen();
- g_system->updateScreen();
- }
-
_screen->_picNotValid = 0;
}
diff --git a/engines/sci/graphics/view.cpp b/engines/sci/graphics/view.cpp
index 5c8e9c3d2e..afb4c184e8 100644
--- a/engines/sci/graphics/view.cpp
+++ b/engines/sci/graphics/view.cpp
@@ -692,7 +692,7 @@ void GfxView::draw(const Common::Rect &rect, const Common::Rect &clipRect, const
const int16 celHeight = celInfo->height;
const int16 celWidth = celInfo->width;
const byte clearKey = celInfo->clearKey;
- const byte drawMask = (priority == 255) ? GFX_SCREEN_MASK_VISUAL : GFX_SCREEN_MASK_VISUAL|GFX_SCREEN_MASK_PRIORITY;
+ const byte drawMask = priority > 15 ? GFX_SCREEN_MASK_VISUAL : GFX_SCREEN_MASK_VISUAL|GFX_SCREEN_MASK_PRIORITY;
int x, y;
if (_embeddedPal)
@@ -753,7 +753,7 @@ void GfxView::drawScaled(const Common::Rect &rect, const Common::Rect &clipRect,
const int16 celHeight = celInfo->height;
const int16 celWidth = celInfo->width;
const byte clearKey = celInfo->clearKey;
- const byte drawMask = (priority == 255) ? GFX_SCREEN_MASK_VISUAL : GFX_SCREEN_MASK_VISUAL|GFX_SCREEN_MASK_PRIORITY;
+ const byte drawMask = priority > 15 ? GFX_SCREEN_MASK_VISUAL : GFX_SCREEN_MASK_VISUAL|GFX_SCREEN_MASK_PRIORITY;
uint16 scalingX[640];
uint16 scalingY[480];
int16 scaledWidth, scaledHeight;
diff --git a/engines/sci/sci.h b/engines/sci/sci.h
index 77718e4b37..04ccbd97d2 100644
--- a/engines/sci/sci.h
+++ b/engines/sci/sci.h
@@ -290,7 +290,7 @@ public:
void setSciLanguage(kLanguage lang);
void setSciLanguage();
- Common::String getSciLanguageString(const char *str, kLanguage lang, kLanguage *lang2 = NULL) const;
+ Common::String getSciLanguageString(const Common::String &str, kLanguage lang, kLanguage *lang2 = NULL) const;
// Check if vocabulary needs to get switched (in multilingual parser games)
void checkVocabularySwitch();
diff --git a/engines/sci/sound/drivers/amigamac.cpp b/engines/sci/sound/drivers/amigamac.cpp
index 158b4b08fb..1436ca45a7 100644
--- a/engines/sci/sound/drivers/amigamac.cpp
+++ b/engines/sci/sound/drivers/amigamac.cpp
@@ -24,6 +24,7 @@
#include "sci/sound/drivers/mididriver.h"
#include "sci/resource.h"
+#include "common/debug-channels.h"
#include "common/file.h"
#include "common/frac.h"
#include "common/memstream.h"
@@ -33,8 +34,6 @@
namespace Sci {
-//#define DEBUG
-
class MidiDriver_AmigaMac : public MidiDriver_Emulated {
public:
enum {
@@ -287,12 +286,10 @@ void MidiDriver_AmigaMac::playInstrument(int16 *dest, Voice *channel, int count)
}
void MidiDriver_AmigaMac::changeInstrument(int channel, int instrument) {
-#ifdef DEBUG
- if (_bank.instruments[instrument][0])
- debugN("Amiga/Mac driver: Setting channel %i to \"%s\" (%i)\n", channel, _bank.instruments[instrument].name, instrument);
+ if (((uint)instrument < _bank.instruments.size()) && (_bank.instruments[instrument].size() > 0))
+ debugC(1, kDebugLevelSound, "Amiga/Mac driver: Setting channel %i to \"%s\" (%i)", channel, _bank.instruments[instrument].name, instrument);
else
- warning("Amiga/Mac driver: instrument %i does not exist (channel %i)", instrument, channel);
-#endif
+ debugC(kDebugLevelSound, "Amiga/Mac driver: instrument %i does not exist (channel %i)", instrument, channel);
_channels[channel].instrument = instrument;
}
@@ -325,9 +322,7 @@ void MidiDriver_AmigaMac::stopNote(int ch, int note) {
break;
if (channel == kChannels) {
-#ifdef DEBUG
- warning("Amiga/Mac driver: cannot stop note %i on channel %i", note, ch);
-#endif
+ debugC(1, kDebugLevelSound, "Amiga/Mac driver: cannot stop note %i on channel %i", note, ch);
return;
}
@@ -466,9 +461,9 @@ MidiDriver_AmigaMac::InstrumentSample *MidiDriver_AmigaMac::readInstrumentSCI0(C
instrument->fixedNote = 101;
instrument->mode = header[33];
- instrument->transpose = (int8) header[34];
+ instrument->transpose = (int8)header[34];
for (int i = 0; i < 4; i++) {
- int length = (int8) header[49 + i];
+ int length = (int8)header[49 + i];
if (length == 0 && i > 0)
length = 256;
@@ -488,15 +483,18 @@ MidiDriver_AmigaMac::InstrumentSample *MidiDriver_AmigaMac::readInstrumentSCI0(C
strncpy(instrument->name, (char *) header + 2, 29);
instrument->name[29] = 0;
-#ifdef DEBUG
- debugN("Amiga/Mac driver: Reading instrument %i: \"%s\" (%i bytes)\n",
- *id, instrument->name, size);
- debugN(" Mode: %02x\n", instrument->mode);
- debugN(" Looping: %s\n", instrument->mode & kModeLoop ? "on" : "off");
- debugN(" Pitch changes: %s\n", instrument->mode & kModePitch ? "on" : "off");
- debugN(" Segment sizes: %i %i %i\n", seg_size[0], seg_size[1], seg_size[2]);
- debugN(" Segment offsets: 0 %i %i\n", loop_offset, (int32)READ_BE_UINT32(header + 43));
-#endif
+ if (DebugMan.isDebugChannelEnabled(kDebugLevelSound)) {
+ debug("Amiga/Mac driver: Reading instrument %i: \"%s\" (%i bytes)",
+ *id, instrument->name, size);
+ debugN(" Mode: %02x (", header[33]);
+ debugN("looping: %s, ", header[33] & kModeLoop ? "on" : "off");
+ debug("pitch changes: %s)", header[33] & kModePitch ? "on" : "off");
+ debug(" Transpose: %i", (int8)header[34]);
+ for (uint i = 0; i < 3; i++)
+ debug(" Segment %i: %i words @ offset %i", i, (int16)READ_BE_UINT16(header + 35 + 6 * i), (i == 0 ? 0 : (int32)READ_BE_UINT32(header + 31 + 6 * i)));
+ for (uint i = 0; i < 4; i++)
+ debug(" Envelope %i: period %i / delta %i / target %i", i, header[49 + i], (int8)header[53 + i], header[57 + i]);
+ }
instrument->samples = (int8 *) malloc(size + 1);
if (file.read(instrument->samples, size) < (unsigned int)size) {
@@ -511,10 +509,8 @@ MidiDriver_AmigaMac::InstrumentSample *MidiDriver_AmigaMac::readInstrumentSCI0(C
if (instrument->mode & kModeLoop) {
if (loop_offset + seg_size[1] > size) {
-#ifdef DEBUG
- warning("Amiga/Mac driver: looping samples extend %i bytes past end of sample block",
- loop_offset + seg_size[1] - size);
-#endif
+ debugC(kDebugLevelSound, "Amiga/Mac driver: looping samples extend %i bytes past end of sample block",
+ loop_offset + seg_size[1] - size);
seg_size[1] = size - loop_offset;
}
@@ -675,15 +671,11 @@ void MidiDriver_AmigaMac::send(uint32 b) {
break;
case 0x0a: // pan
// TODO
-#ifdef DEBUG
- warning("Amiga/Mac driver: ignoring pan 0x%02x event for channel %i", op2, channel);
-#endif
+ debugC(1, kDebugLevelSound, "Amiga/Mac driver: ignoring pan 0x%02x event for channel %i", op2, channel);
break;
case 0x40: // hold
// TODO
-#ifdef DEBUG
- warning("Amiga/Mac driver: ignoring hold 0x%02x event for channel %i", op2, channel);
-#endif
+ debugC(1, kDebugLevelSound, "Amiga/Mac driver: ignoring hold 0x%02x event for channel %i", op2, channel);
break;
case 0x4b: // voice mapping
break;
@@ -768,9 +760,7 @@ bool MidiDriver_AmigaMac::loadInstrumentsSCI0(Common::File &file) {
_bank.size = READ_BE_UINT16(header + 38);
strncpy(_bank.name, (char *) header + 8, 29);
_bank.name[29] = 0;
-#ifdef DEBUG
- debugN("Amiga/Mac driver: Reading %i instruments from bank \"%s\"\n", _bank.size, _bank.name);
-#endif
+ debugC(kDebugLevelSound, "Amiga/Mac driver: Reading %i instruments from bank \"%s\"", _bank.size, _bank.name);
for (uint i = 0; i < _bank.size; i++) {
int id;
@@ -807,9 +797,7 @@ bool MidiDriver_AmigaMac::loadInstrumentsSCI0Mac(Common::SeekableReadStream &fil
_bank.size = 128;
strncpy(_bank.name, (char *) header + 8, 29);
_bank.name[29] = 0;
-#ifdef DEBUG
- debugN("Amiga/Mac driver: Reading %i instruments from bank \"%s\"\n", _bank.size, _bank.name);
-#endif
+ debugC(kDebugLevelSound, "Amiga/Mac driver: Reading %i instruments from bank \"%s\"", _bank.size, _bank.name);
Common::Array<uint32> instrumentOffsets;
instrumentOffsets.resize(_bank.size);
diff --git a/engines/scumm/gfx_towns.cpp b/engines/scumm/gfx_towns.cpp
index 82bb32cdfb..10d6ee0082 100644
--- a/engines/scumm/gfx_towns.cpp
+++ b/engines/scumm/gfx_towns.cpp
@@ -248,7 +248,7 @@ void TownsScreen::setupLayer(int layer, int width, int height, int numCol, void
l->palette = (uint8*)pal;
if (l->palette && _bpp == 1)
- warning("TownsScreen::setupLayer(): Layer palette usage requires 15 bit graphics setting.\nLayer palette will be ignored.");
+ warning("TownsScreen::setupLayer(): Layer palette usage requires 16 bit graphics setting.\nLayer palette will be ignored.");
delete[] l->pixels;
l->pixels = new uint8[l->pitch * l->height];
@@ -270,7 +270,8 @@ void TownsScreen::setupLayer(int layer, int width, int height, int numCol, void
l->bltTmpPal = (l->bpp == 1 && _bpp == 2) ? new uint16[l->numCol] : 0;
l->enabled = true;
- l->onBottom = (!layer || !_layers[0].enabled);
+ _layers[0].onBottom = true;
+ _layers[1].onBottom = _layers[0].enabled ? false : true;
l->ready = true;
}
@@ -420,10 +421,10 @@ void TownsScreen::toggleLayers(int flag) {
if (flag < 0 || flag > 3)
return;
- for (int i = 0; i < 2; ++i) {
- _layers[i].enabled = (flag & (i + 1)) ? true : false;
- _layers[i].onBottom = (!i || !_layers[0].enabled);
- }
+ _layers[0].enabled = (flag & 1) ? true : false;
+ _layers[0].onBottom = true;
+ _layers[1].enabled = (flag & 2) ? true : false;
+ _layers[1].onBottom = _layers[0].enabled ? false : true;
_dirtyRects.clear();
_dirtyRects.push_back(Common::Rect(_width - 1, _height - 1));
@@ -458,12 +459,12 @@ void TownsScreen::updateOutputBuffer() {
for (int y = r->top; y <= r->bottom; ++y) {
if (l->bpp == _bpp && l->scaleW == 1 && l->onBottom) {
- memcpy(dst, l->bltInternY[y] + l->bltInternX[r->left], (r->right + 1 - r->left) * _bpp);
+ memcpy(dst, &l->bltInternY[y][l->bltInternX[r->left]], (r->right + 1 - r->left) * _bpp);
dst += _pitch;
} else if (_bpp == 2) {
for (int x = r->left; x <= r->right; ++x) {
- uint8 *src = l->bltInternY[y] + l->bltInternX[x];
+ uint8 *src = &l->bltInternY[y][l->bltInternX[x]];
if (l->bpp == 1) {
uint8 col = *src;
if (col || l->onBottom) {
@@ -480,7 +481,7 @@ void TownsScreen::updateOutputBuffer() {
} else {
for (int x = r->left; x <= r->right; ++x) {
- uint8 col = *(l->bltInternY[y] + l->bltInternX[x]);
+ uint8 col = l->bltInternY[y][l->bltInternX[x]];
if (col || l->onBottom) {
if (l->numCol == 16)
col = (col >> 4) & (col & 0x0f);
diff --git a/engines/scumm/he/resource_he.cpp b/engines/scumm/he/resource_he.cpp
index 6b195bec84..4565bb9f26 100644
--- a/engines/scumm/he/resource_he.cpp
+++ b/engines/scumm/he/resource_he.cpp
@@ -171,7 +171,7 @@ bool MacResExtractor::extractResource(int id, CachedCursor *cc) {
return false;
// If we don't have a cursor palette, force monochrome cursors
- bool forceMonochrome = !_vm->_system->hasFeature(OSystem::kFeatureCursorHasPalette);
+ bool forceMonochrome = !_vm->_system->hasFeature(OSystem::kFeatureCursorPalette);
Graphics::MacCursor *macCursor = new Graphics::MacCursor();
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index c0c477a597..dd26e23b4d 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -162,7 +162,7 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_pauseDialog = NULL;
_versionDialog = NULL;
_fastMode = 0;
- _actors = NULL;
+ _actors = _sortedActors = NULL;
_arraySlot = NULL;
_inventory = NULL;
_newNames = NULL;
@@ -584,9 +584,12 @@ ScummEngine::~ScummEngine() {
_mixer->stopAll();
- for (int i = 0; i < _numActors; ++i)
- delete _actors[i];
- delete[] _actors;
+ if (_actors) {
+ for (int i = 0; i < _numActors; ++i)
+ delete _actors[i];
+ delete[] _actors;
+ }
+
delete[] _sortedActors;
delete[] _2byteFontPtr;
@@ -1361,6 +1364,7 @@ void ScummEngine::resetScumm() {
#ifdef USE_RGB_COLOR
if (_game.features & GF_16BIT_COLOR
#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
+
|| _game.platform == Common::kPlatformFMTowns
#endif
)
@@ -1832,7 +1836,7 @@ void ScummEngine::setupMusic(int midi) {
if (nativeMidiDriver != NULL && _native_mt32)
nativeMidiDriver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
bool multi_midi = ConfMan.getBool("multi_midi") && _musicType != MDT_NONE && (midi & MDT_ADLIB);
- if (_musicType == MDT_ADLIB || MDT_TOWNS || multi_midi) {
+ if (_musicType == MDT_ADLIB || _musicType == MDT_TOWNS || multi_midi) {
adlibMidiDriver = MidiDriver::createMidi(MidiDriver::detectDevice(_musicType == MDT_TOWNS ? MDT_TOWNS : MDT_ADLIB));
adlibMidiDriver->property(MidiDriver::PROP_OLD_ADLIB, (_game.features & GF_SMALL_HEADER) ? 1 : 0);
}
diff --git a/engines/sword25/detection.cpp b/engines/sword25/detection.cpp
index edb8c30545..c704b3e833 100644
--- a/engines/sword25/detection.cpp
+++ b/engines/sword25/detection.cpp
@@ -31,7 +31,7 @@ namespace Sword25 {
uint32 Sword25Engine::getGameFlags() const { return _gameDescription->flags; }
}
-static const PlainGameDescriptor Sword25Game[] = {
+static const PlainGameDescriptor sword25Game[] = {
{"sword25", "Broken Sword 2.5"},
{0, 0}
};
@@ -41,35 +41,13 @@ static const char *directoryGlobs[] = {
0
};
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Sword25::gameDescriptions,
- // Size of that superset structure
- sizeof(ADGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- Sword25Game,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- NULL,
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NOMIDI,
- // Maximum directory depth
- 2,
- // List of directory globs
- directoryGlobs
-};
-
class Sword25MetaEngine : public AdvancedMetaEngine {
public:
- Sword25MetaEngine() : AdvancedMetaEngine(detectionParams) {}
-
+ Sword25MetaEngine() : AdvancedMetaEngine(Sword25::gameDescriptions, sizeof(ADGameDescription), sword25Game) {
+ params.guioptions = Common::GUIO_NOMIDI;
+ params.depth = 2;
+ params.directoryGlobs = directoryGlobs;
+ }
virtual const char *getName() const {
return "Sword25";
}
diff --git a/engines/sword25/fmv/theora_decoder.cpp b/engines/sword25/fmv/theora_decoder.cpp
index be6d940d23..098bd2c6b9 100644
--- a/engines/sword25/fmv/theora_decoder.cpp
+++ b/engines/sword25/fmv/theora_decoder.cpp
@@ -479,12 +479,6 @@ void TheoraDecoder::reset() {
if (_fileStream)
_fileStream->seek(0);
-#if ENABLE_THEORA_SEEKING
- _videobufGranulePos = -1;
- _audiobufGranulePos = 0;
- _videobufTime = 0;
-#endif
-
_audiobufFill = 0;
_audiobufReady = false;
diff --git a/engines/sword25/gfx/animationresource.cpp b/engines/sword25/gfx/animationresource.cpp
index a9c9cf9c29..b9d70cf87b 100644
--- a/engines/sword25/gfx/animationresource.cpp
+++ b/engines/sword25/gfx/animationresource.cpp
@@ -38,11 +38,11 @@
namespace Sword25 {
-namespace {
-const int DEFAULT_FPS = 10;
-const int MIN_FPS = 1;
-const int MAX_FPS = 200;
-}
+enum {
+ DEFAULT_FPS = 10,
+ MIN_FPS = 1,
+ MAX_FPS = 200
+};
AnimationResource::AnimationResource(const Common::String &filename) :
Resource(filename, Resource::TYPE_ANIMATION),
@@ -112,8 +112,8 @@ bool AnimationResource::parseBooleanKey(Common::String s, bool &result) {
bool AnimationResource::parserCallback_animation(ParserNode *node) {
if (!parseIntegerKey(node->values["fps"], 1, &_FPS) || (_FPS < MIN_FPS) || (_FPS > MAX_FPS)) {
- return parserError("Illegal or missing fps attribute in <animation> tag in \"%s\". Assuming default (\"%d\").",
- getFileName().c_str(), DEFAULT_FPS);
+ return parserError(Common::String::format("Illegal or missing fps attribute in <animation> tag in \"%s\". Assuming default (\"%d\").",
+ getFileName().c_str(), DEFAULT_FPS));
}
// Loop type value
diff --git a/engines/sword25/gfx/animationresource.h b/engines/sword25/gfx/animationresource.h
index 2a1e3ce882..70291f220e 100644
--- a/engines/sword25/gfx/animationresource.h
+++ b/engines/sword25/gfx/animationresource.h
@@ -48,36 +48,35 @@ public:
AnimationResource(const Common::String &filename);
virtual ~AnimationResource();
- virtual const Frame &getFrame(uint index) const {
- assert(index < _frames.size());
+ virtual const Frame &getFrame(uint index) const {
return _frames[index];
}
- virtual uint getFrameCount() const {
+ virtual uint getFrameCount() const {
return _frames.size();
}
- virtual void unlock() {
+ virtual void unlock() {
release();
}
- Animation::ANIMATION_TYPES getAnimationType() const {
+ Animation::ANIMATION_TYPES getAnimationType() const {
return _animationType;
}
- int getFPS() const {
+ int getFPS() const {
return _FPS;
}
- int getMillisPerFrame() const {
+ int getMillisPerFrame() const {
return _millisPerFrame;
}
- bool isScalingAllowed() const {
+ bool isScalingAllowed() const {
return _scalingAllowed;
}
- bool isAlphaAllowed() const {
+ bool isAlphaAllowed() const {
return _alphaAllowed;
}
- bool isColorModulationAllowed() const {
+ bool isColorModulationAllowed() const {
return _colorModulationAllowed;
}
- bool isValid() const {
+ bool isValid() const {
return _valid;
}
diff --git a/engines/sword25/gfx/fontresource.cpp b/engines/sword25/gfx/fontresource.cpp
index f99987fc91..7657abb5f2 100644
--- a/engines/sword25/gfx/fontresource.cpp
+++ b/engines/sword25/gfx/fontresource.cpp
@@ -115,23 +115,23 @@ bool FontResource::parserCallback_character(ParserNode *node) {
int charCode, top, left, right, bottom;
if (!parseIntegerKey(node->values["code"], 1, &charCode) || (charCode < 0) || (charCode >= 256)) {
- return parserError("Illegal or missing code attribute in <character> tag in \"%s\".", getFileName().c_str());
+ return parserError("Illegal or missing code attribute in <character> tag in '" + getFileName() + "'.");
}
if (!parseIntegerKey(node->values["top"], 1, &top) || (top < 0)) {
- return parserError("Illegal or missing top attribute in <character> tag in \"%s\".", getFileName().c_str());
+ return parserError("Illegal or missing top attribute in <character> tag in '" + getFileName() + "'.");
}
if (!parseIntegerKey(node->values["left"], 1, &left) || (left < 0)) {
- return parserError("Illegal or missing left attribute in <character> tag in \"%s\".", getFileName().c_str());
+ return parserError("Illegal or missing left attribute in <character> tag in '" + getFileName() + "'.");
}
if (!parseIntegerKey(node->values["right"], 1, &right) || (right < 0)) {
- return parserError("Illegal or missing right attribute in <character> tag in \"%s\".", getFileName().c_str());
+ return parserError("Illegal or missing right attribute in <character> tag in '" + getFileName() + "'.");
}
if (!parseIntegerKey(node->values["bottom"], 1, &bottom) || (bottom < 0)) {
- return parserError("Illegal or missing bottom attribute in <character> tag in \"%s\".", getFileName().c_str());
+ return parserError("Illegal or missing bottom attribute in <character> tag in '" + getFileName() + "'.");
}
- this->_characterRects[charCode] = Common::Rect(left, top, right, bottom);
+ _characterRects[charCode] = Common::Rect(left, top, right, bottom);
return true;
}
diff --git a/engines/sword25/sfx/soundengine.cpp b/engines/sword25/sfx/soundengine.cpp
index 20622b2098..9244137c25 100644
--- a/engines/sword25/sfx/soundengine.cpp
+++ b/engines/sword25/sfx/soundengine.cpp
@@ -37,6 +37,7 @@
#include "audio/decoders/vorbis.h"
#include "common/system.h"
+#include "common/config-manager.h"
namespace Sword25 {
@@ -65,8 +66,6 @@ SoundEngine::SoundEngine(Kernel *pKernel) : ResourceService(pKernel) {
}
bool SoundEngine::init(uint sampleRate, uint channels) {
- warning("STUB: SoundEngine::init(%d, %d)", sampleRate, channels);
-
return true;
}
@@ -74,12 +73,44 @@ void SoundEngine::update() {
}
void SoundEngine::setVolume(float volume, SOUND_TYPES type) {
- warning("STUB: SoundEngine::setVolume(%f, %d)", volume, type);
+ int val = (int)(255 * volume);
+
+ switch (type) {
+ case SoundEngine::MUSIC:
+ ConfMan.setInt("music_volume", val);
+ _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, val);
+ break;
+ case SoundEngine::SPEECH:
+ ConfMan.setInt("speech_volume", val);
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, val);
+ break;
+ case SoundEngine::SFX:
+ ConfMan.setInt("sfx_volume", val);
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, val);
+ break;
+ default:
+ error("Unknown SOUND_TYPE");
+ }
}
float SoundEngine::getVolume(SOUND_TYPES type) {
- warning("STUB: SoundEngine::getVolume(%d)", type);
- return 0;
+ int val = 0;
+
+ switch (type) {
+ case SoundEngine::MUSIC:
+ val = ConfMan.getInt("music_volume");
+ break;
+ case SoundEngine::SPEECH:
+ val = ConfMan.getInt("speech_volume");
+ break;
+ case SoundEngine::SFX:
+ val = ConfMan.getInt("sfx_volume");
+ break;
+ default:
+ error("Unknown SOUND_TYPE");
+ }
+
+ return (float)val / 255.0;
}
void SoundEngine::pauseAll() {
@@ -95,11 +126,15 @@ void SoundEngine::resumeAll() {
}
void SoundEngine::pauseLayer(uint layer) {
- warning("STUB: SoundEngine::pauseLayer(%d)", layer);
+ // Not used in the game
+
+ warning("SoundEngine::pauseLayer(%d)", layer);
}
void SoundEngine::resumeLayer(uint layer) {
- warning("STUB: SoundEngine::resumeLayer(%d)", layer);
+ // Not used in the game
+
+ warning("SoundEngine::resumeLayer(%d)", layer);
}
SndHandle *SoundEngine::getHandle(uint *id) {
@@ -207,7 +242,9 @@ void SoundEngine::stopSound(uint handle) {
}
bool SoundEngine::isSoundPaused(uint handle) {
- warning("STUB: SoundEngine::isSoundPaused(%d)", handle);
+ // Not used in the game
+
+ warning("SoundEngine::isSoundPaused(%d)", handle);
return false;
}
@@ -221,20 +258,18 @@ bool SoundEngine::isSoundPlaying(uint handle) {
}
float SoundEngine::getSoundVolume(uint handle) {
- warning("STUB: SoundEngine::getSoundVolume(%d)", handle);
+ debugC(1, kDebugSound, "SoundEngine::getSoundVolume(%d)", handle);
- return 0;
+ return (float)_mixer->getChannelVolume(_handles[handle].handle) / 255.0;
}
float SoundEngine::getSoundPanning(uint handle) {
- warning("STUB: SoundEngine::getSoundPanning(%d)", handle);
+ debugC(1, kDebugSound, "SoundEngine::getSoundPanning(%d)", handle);
- return 0;
+ return (float)_mixer->getChannelBalance(_handles[handle].handle) / 127.0;
}
Resource *SoundEngine::loadResource(const Common::String &fileName) {
- warning("STUB: SoundEngine::loadResource(%s)", fileName.c_str());
-
return new SoundResource(fileName);
}
diff --git a/engines/sword25/util/lua/ldblib.cpp b/engines/sword25/util/lua/ldblib.cpp
index b2e249e9b7..4d0333b46e 100644
--- a/engines/sword25/util/lua/ldblib.cpp
+++ b/engines/sword25/util/lua/ldblib.cpp
@@ -4,6 +4,10 @@
** See Copyright Notice in lua.h
*/
+#define FORBIDDEN_SYMBOL_EXCEPTION_stdin
+#define FORBIDDEN_SYMBOL_EXCEPTION_stderr
+#define FORBIDDEN_SYMBOL_EXCEPTION_fputs
+#define FORBIDDEN_SYMBOL_EXCEPTION_fgets
#include <stdio.h>
#include <stdlib.h>
diff --git a/engines/teenagent/detection.cpp b/engines/teenagent/detection.cpp
index 5012e6af65..b684560bc7 100644
--- a/engines/teenagent/detection.cpp
+++ b/engines/teenagent/detection.cpp
@@ -79,37 +79,14 @@ static const ADGameDescription teenAgentGameDescriptions[] = {
AD_TABLE_END_MARKER,
};
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)teenAgentGameDescriptions,
- // Size of that superset structure
- sizeof(ADGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- teenAgentGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "teenagent",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NONE,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
+enum {
+ MAX_SAVES = 20
};
-#define MAX_SAVES 20
-
-
class TeenAgentMetaEngine : public AdvancedMetaEngine {
public:
- TeenAgentMetaEngine() : AdvancedMetaEngine(detectionParams) {
+ TeenAgentMetaEngine() : AdvancedMetaEngine(teenAgentGameDescriptions, sizeof(ADGameDescription), teenAgentGames) {
+ params.singleid = "teenagent";
}
virtual const char *getName() const {
diff --git a/engines/testbed/config.cpp b/engines/testbed/config.cpp
index 6adf82952f..6bd4c82b41 100644
--- a/engines/testbed/config.cpp
+++ b/engines/testbed/config.cpp
@@ -126,10 +126,13 @@ void TestbedOptionsDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd,
ws = _testbedConfMan->getConfigWriteStream();
_testbedConfMan->writeTestbedConfigToStream(ws);
delete ws;
- default:
- GUI::Dialog::handleCommand(sender, cmd, data);
+ break;
+ default:
+ break;
}
+
+ GUI::Dialog::handleCommand(sender, cmd, data);
}
void TestbedInteractionDialog::addText(uint w, uint h, const Common::String text, Graphics::TextAlign textAlign, uint xOffset, uint yPadding) {
@@ -150,7 +153,7 @@ void TestbedInteractionDialog::addButton(uint w, uint h, const Common::String na
_yOffset += h;
}
-void TestbedInteractionDialog::addList(uint x, uint y, uint w, uint h, Common::Array<Common::String> &strArray, GUI::ListWidget::ColorList *colors, uint yPadding) {
+void TestbedInteractionDialog::addList(uint x, uint y, uint w, uint h, const Common::Array<Common::String> &strArray, GUI::ListWidget::ColorList *colors, uint yPadding) {
_yOffset += yPadding;
GUI::ListWidget *list = new GUI::ListWidget(this, x, y, w, h);
list->setEditable(false);
@@ -159,7 +162,7 @@ void TestbedInteractionDialog::addList(uint x, uint y, uint w, uint h, Common::A
_yOffset += h;
}
-void TestbedInteractionDialog::addButtonXY(uint x, uint y, uint w, uint h, const Common::String name, uint32 cmd) {
+void TestbedInteractionDialog::addButtonXY(uint x, uint /* y */, uint w, uint h, const Common::String name, uint32 cmd) {
_buttonArray.push_back(new GUI::ButtonWidget(this, x, _yOffset, w, h, name, 0, cmd));
}
@@ -174,7 +177,6 @@ void TestbedConfigManager::initDefaultConfiguration() {
}
void TestbedConfigManager::writeTestbedConfigToStream(Common::WriteStream *ws) {
- Common::String wStr;
for (Common::Array<Testsuite *>::const_iterator i = _testsuiteList.begin(); i < _testsuiteList.end(); i++) {
_configFileInterface.setKey("this", (*i)->getName(), boolToString((*i)->isEnabled()));
const Common::Array<Test *> &testList = (*i)->getTestList();
@@ -186,13 +188,13 @@ void TestbedConfigManager::writeTestbedConfigToStream(Common::WriteStream *ws) {
ws->flush();
}
-Common::SeekableReadStream *TestbedConfigManager::getConfigReadStream() {
+Common::SeekableReadStream *TestbedConfigManager::getConfigReadStream() const {
// Look for config file using SearchMan
Common::SeekableReadStream *rs = SearchMan.createReadStreamForMember(_configFileName);
return rs;
}
-Common::WriteStream *TestbedConfigManager::getConfigWriteStream() {
+Common::WriteStream *TestbedConfigManager::getConfigWriteStream() const {
// Look for config file in game-path
const Common::String &path = ConfMan.get("path");
Common::WriteStream *ws;
diff --git a/engines/testbed/config.h b/engines/testbed/config.h
index c0df65ad32..fd5588aa31 100644
--- a/engines/testbed/config.h
+++ b/engines/testbed/config.h
@@ -50,8 +50,8 @@ public:
~TestbedConfigManager() {}
void selectTestsuites();
void setConfigFile(const Common::String fName) { _configFileName = fName; }
- Common::SeekableReadStream *getConfigReadStream();
- Common::WriteStream *getConfigWriteStream();
+ Common::SeekableReadStream *getConfigReadStream() const;
+ Common::WriteStream *getConfigWriteStream() const;
void writeTestbedConfigToStream(Common::WriteStream *ws);
Testsuite *getTestsuiteByName(const Common::String &name);
bool stringToBool(const Common::String str) { return str.equalsIgnoreCase("true") ? true : false; }
@@ -119,7 +119,7 @@ public:
void addButton(uint w, uint h, const Common::String name, uint32 cmd, uint xOffset = 0, uint yPadding = 8);
void addButtonXY(uint x, uint y, uint w, uint h, const Common::String name, uint32 cmd);
void addText(uint w, uint h, const Common::String text, Graphics::TextAlign textAlign, uint xOffset, uint yPadding = 8);
- void addList(uint x, uint y, uint w, uint h, Common::Array<Common::String> &strArray, GUI::ListWidget::ColorList *colors = 0, uint yPadding = 8);
+ void addList(uint x, uint y, uint w, uint h, const Common::Array<Common::String> &strArray, GUI::ListWidget::ColorList *colors = 0, uint yPadding = 8);
protected:
Common::Array<GUI::ButtonWidget *> _buttonArray;
uint _xOffset;
diff --git a/engines/testbed/detection.cpp b/engines/testbed/detection.cpp
index 91518b2b8e..2c3d5b43c5 100644
--- a/engines/testbed/detection.cpp
+++ b/engines/testbed/detection.cpp
@@ -45,34 +45,11 @@ static const ADGameDescription testbedDescriptions[] = {
AD_TABLE_END_MARKER
};
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)testbedDescriptions,
- // Size of that superset structure
- sizeof(ADGameDescription),
- // Number of bytes to compute MD5 sum for
- 512,
- // List of all engine targets
- testbed_setting,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "testbed",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- ADGF_NO_FLAGS,
- // Additional GUI options (for every game}
- Common::GUIO_NONE,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
class TestbedMetaEngine : public AdvancedMetaEngine {
public:
- TestbedMetaEngine() : AdvancedMetaEngine(detectionParams) {
+ TestbedMetaEngine() : AdvancedMetaEngine(testbedDescriptions, sizeof(ADGameDescription), testbed_setting) {
+ params.md5Bytes = 512;
+ params.singleid = "testbed";
}
virtual const char *getName() const {
@@ -83,7 +60,7 @@ public:
return "Copyright (C) ScummVM";
}
- virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
+ virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription * /* desc */) const {
// Instantiate Engine even if the game data is not found.
*engine = new Testbed::TestbedEngine(syst);
return true;
diff --git a/engines/testbed/fs.cpp b/engines/testbed/fs.cpp
index e2bedb1898..62ac616192 100644
--- a/engines/testbed/fs.cpp
+++ b/engines/testbed/fs.cpp
@@ -167,7 +167,7 @@ TestExitStatus FStests::testWriteFile() {
return kTestPassed;
}
- return kTestFailed;
+ return kTestFailed;
}
@@ -189,7 +189,7 @@ FSTestSuite::FSTestSuite() {
}
void FSTestSuite::enable(bool flag) {
- Testsuite::enable(ConfParams.isGameDataFound() & flag);
+ Testsuite::enable(ConfParams.isGameDataFound() ? flag : false);
}
} // End of namespace Testbed
diff --git a/engines/testbed/graphics.cpp b/engines/testbed/graphics.cpp
index b38b83f222..36ec726fc7 100644
--- a/engines/testbed/graphics.cpp
+++ b/engines/testbed/graphics.cpp
@@ -102,7 +102,7 @@ void GFXtests::initMousePalette() {
CursorMan.replaceCursorPalette(palette, 0, 3);
}
-Common::Rect GFXtests::computeSize(Common::Rect &cursorRect, int scalingFactor, int cursorTargetScale) {
+Common::Rect GFXtests::computeSize(const Common::Rect &cursorRect, int scalingFactor, int cursorTargetScale) {
if (cursorTargetScale == 1 || scalingFactor == 1) {
// Game data and cursor would be scaled equally.
// so dimensions would be same.
@@ -137,7 +137,7 @@ void GFXtests::HSVtoRGB(int &rComp, int &gComp, int &bComp, int hue, int sat, in
float f, p, q, t;
if (s == 0) {
- r = g = b = v * 255;
+ rComp = gComp = bComp = (int)(v * 255);
return;
}
@@ -186,7 +186,7 @@ void GFXtests::HSVtoRGB(int &rComp, int &gComp, int &bComp, int hue, int sat, in
bComp = (int)(b * 255);
}
-Common::Rect GFXtests::drawCursor(bool cursorPaletteDisabled, const char *gfxModeName, int cursorTargetScale) {
+Common::Rect GFXtests::drawCursor(bool cursorPaletteDisabled, int cursorTargetScale) {
// Buffer initialized with yellow color
byte buffer[500];
memset(buffer, 2, sizeof(buffer));
@@ -244,12 +244,12 @@ void rotatePalette(byte *palette, int size) {
*/
void GFXtests::setupMouseLoop(bool disableCursorPalette, const char *gfxModeName, int cursorTargetScale) {
bool isFeaturePresent;
- isFeaturePresent = g_system->hasFeature(OSystem::kFeatureCursorHasPalette);
+ isFeaturePresent = g_system->hasFeature(OSystem::kFeatureCursorPalette);
Common::Rect cursorRect;
if (isFeaturePresent) {
- cursorRect = GFXtests::drawCursor(disableCursorPalette, gfxModeName, cursorTargetScale);
+ cursorRect = GFXtests::drawCursor(disableCursorPalette, cursorTargetScale);
Common::EventManager *eventMan = g_system->getEventManager();
Common::Event event;
@@ -741,7 +741,7 @@ TestExitStatus GFXtests::scaledCursors() {
if (isAspectRatioCorrected) {
info += "\nDisabling Aspect ratio correction, for letting cusors match exactly, will be restored after this test.";
}
-
+
if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) {
Testsuite::logPrintf("Info! Skipping test : Scaled Cursors\n");
return kTestSkipped;
@@ -753,7 +753,7 @@ TestExitStatus GFXtests::scaledCursors() {
}
- if (isAspectRatioCorrected) {
+ if (isAspectRatioCorrected) {
g_system->beginGFXTransaction();
g_system->setFeatureState(OSystem::kFeatureAspectRatioCorrection, false);
g_system->endGFXTransaction();
@@ -766,7 +766,7 @@ TestExitStatus GFXtests::scaledCursors() {
// for every graphics mode display cursors for cursorTargetScale 1, 2 and 3
// Switch Graphics mode
// FIXME: Crashes with "3x" mode now.:
-
+
info = Common::String::format("Testing : Scaled cursors with GFX Mode %s\n", gfxMode->name);
if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) {
Testsuite::logPrintf("\tInfo! Skipping sub-test : Scaled Cursors :: GFX Mode %s\n", gfxMode->name);
@@ -779,7 +779,7 @@ TestExitStatus GFXtests::scaledCursors() {
Testsuite::logPrintf("Info! Explicit exit requested during scaling test, this test may be incomplete\n");
return kTestSkipped;
}
-
+
g_system->beginGFXTransaction();
bool isGFXModeSet = g_system->setGraphicsMode(gfxMode->id);
@@ -807,7 +807,7 @@ TestExitStatus GFXtests::scaledCursors() {
if (Testsuite::handleInteractiveInput(info, "Yes", "No", kOptionRight)) {
Testsuite::logPrintf("\tInfo! Failed sub-test : Scaled Cursors :: GFX Mode %s\n", gfxMode->name);
}
-
+
if (Engine::shouldQuit()) {
// Explicit exit requested
Testsuite::logPrintf("Info! Explicit exit requested during scaling test, this test may be incomplete\n");
@@ -824,7 +824,7 @@ TestExitStatus GFXtests::scaledCursors() {
if (isAspectRatioCorrected) {
g_system->setFeatureState(OSystem::kFeatureAspectRatioCorrection, true);
}
-
+
OSystem::TransactionError gfxError = g_system->endGFXTransaction();
if (gfxError != OSystem::kTransactionSuccess || !isGFXModeSet) {
@@ -962,13 +962,14 @@ TestExitStatus GFXtests::paletteRotation() {
Testsuite::logPrintf("Info! Skipping test : palette Rotation\n");
return kTestSkipped;
}
- Common::Point pt(0, 10);
+
Testsuite::clearEntireScreen();
// Use 256 colors
byte palette[256 * 3] = {0};
int r, g, b;
+ r = g = b = 0;
int colIndx;
for (int i = 0; i < 256; i++) {
@@ -1065,7 +1066,6 @@ TestExitStatus GFXtests::pixelFormats() {
}
Common::List<Graphics::PixelFormat> pfList = g_system->getSupportedFormats();
- Common::List<Graphics::PixelFormat>::const_iterator iter = pfList.begin();
int numFormatsTested = 0;
int numPassed = 0;
@@ -1073,7 +1073,7 @@ TestExitStatus GFXtests::pixelFormats() {
Testsuite::logDetailedPrintf("Testing Pixel Formats. Size of list : %d\n", pfList.size());
- for (iter = pfList.begin(); iter != pfList.end(); iter++) {
+ for (Common::List<Graphics::PixelFormat>::const_iterator iter = pfList.begin(); iter != pfList.end(); iter++) {
numFormatsTested++;
if (iter->bytesPerPixel == 1) {
// Palettes already tested
diff --git a/engines/testbed/graphics.h b/engines/testbed/graphics.h
index 7fa8f9d708..f3013fdf53 100644
--- a/engines/testbed/graphics.h
+++ b/engines/testbed/graphics.h
@@ -32,9 +32,9 @@ namespace GFXtests {
void drawEllipse(int x, int y, int a, int b);
void setupMouseLoop(bool disableCursorPalette = false, const char *gfxModeName = "", int cursorTargetScale = 1);
void initMousePalette();
-Common::Rect computeSize(Common::Rect &cursorRect, int scalingFactor, int cursorTargetScale);
+Common::Rect computeSize(const Common::Rect &cursorRect, int scalingFactor, int cursorTargetScale);
void HSVtoRGB(int &rComp, int &gComp, int &bComp, int hue, int sat, int val);
-Common::Rect drawCursor(bool cursorPaletteDisabled = false, const char *gfxModeName = "", int cursorTargetScale = 1);
+Common::Rect drawCursor(bool cursorPaletteDisabled = false, int cursorTargetScale = 1);
// will contain function declarations for GFX tests
TestExitStatus cursorTrails();
diff --git a/engines/testbed/midi.cpp b/engines/testbed/midi.cpp
index 54be866b4c..69d361b0d6 100644
--- a/engines/testbed/midi.cpp
+++ b/engines/testbed/midi.cpp
@@ -142,12 +142,12 @@ MidiTestSuite::MidiTestSuite() {
// add some fallback test if filesystem loading failed
Testsuite::logPrintf("Warning! Midi: Sound data file music.mid not found\n");
_isMidiDataFound = false;
- enable(false);
+ MidiTestSuite::enable(false);
}
}
void MidiTestSuite::enable(bool flag) {
- Testsuite::enable(_isMidiDataFound & flag);
+ Testsuite::enable(_isMidiDataFound ? flag : false);
}
}
diff --git a/engines/testbed/misc.cpp b/engines/testbed/misc.cpp
index 35b3c6bfe2..034d3eb27e 100644
--- a/engines/testbed/misc.cpp
+++ b/engines/testbed/misc.cpp
@@ -24,13 +24,12 @@
namespace Testbed {
-Common::String MiscTests::getHumanReadableFormat(TimeDate &td) {
+Common::String MiscTests::getHumanReadableFormat(const TimeDate &td) {
return Common::String::format("%d:%d:%d on %d/%d/%d (dd/mm/yyyy)", td.tm_hour, td.tm_min, td.tm_sec, td.tm_mday, td.tm_mon + 1, td.tm_year + 1900);
}
void MiscTests::timerCallback(void *arg) {
// Increment arg which actually points to an int
- // arg must point to a static data, threads otherwise have their own stack
int &valToModify = *((int *) arg);
valToModify = 999; // some arbitrary value
}
@@ -110,7 +109,7 @@ TestExitStatus MiscTests::testDateTime() {
}
TestExitStatus MiscTests::testTimers() {
- static int valToModify = 0;
+ int valToModify = 0;
if (g_system->getTimerManager()->installTimerProc(timerCallback, 100000, &valToModify)) {
g_system->delayMillis(150);
g_system->getTimerManager()->removeTimerProc(timerCallback);
@@ -132,7 +131,7 @@ TestExitStatus MiscTests::testMutexes() {
Testsuite::writeOnScreen("Installing mutex", Common::Point(0, 100));
}
- static SharedVars sv = {1, 1, true, g_system->createMutex()};
+ SharedVars sv = {1, 1, true, g_system->createMutex()};
if (g_system->getTimerManager()->installTimerProc(criticalSection, 100000, &sv)) {
g_system->delayMillis(150);
diff --git a/engines/testbed/misc.h b/engines/testbed/misc.h
index 415fe82903..3f0772c6e5 100644
--- a/engines/testbed/misc.h
+++ b/engines/testbed/misc.h
@@ -40,7 +40,7 @@ namespace MiscTests {
// Miscellaneous tests include testing datetime, timers and mutexes
// Helper functions for Misc tests
-Common::String getHumanReadableFormat(TimeDate &td);
+Common::String getHumanReadableFormat(const TimeDate &td);
void timerCallback(void *arg);
void criticalSection(void *arg);
diff --git a/engines/testbed/savegame.cpp b/engines/testbed/savegame.cpp
index b19c8e3872..226e9880a6 100644
--- a/engines/testbed/savegame.cpp
+++ b/engines/testbed/savegame.cpp
@@ -133,11 +133,11 @@ TestExitStatus SaveGametests::testListingSavefile() {
writeDataToFile("tBedSavefileToList.1", "Save me!");
writeDataToFile("tBedSavefileToList.2", "Save me!");
- Common::Error error = saveFileMan->getError();
+ Common::Error err = saveFileMan->getError();
- if (error.getCode() != Common::kNoError) {
+ if (err.getCode() != Common::kNoError) {
// Abort. Some Error in writing files
- Testsuite::logDetailedPrintf("Error while creating savefiles: %s\n", error.getDesc().c_str());
+ Testsuite::logDetailedPrintf("Error while creating savefiles: %s\n", err.getDesc().c_str());
return kTestFailed;
}
@@ -158,11 +158,9 @@ TestExitStatus SaveGametests::testListingSavefile() {
}
}
return kTestPassed;
- } else {
- Testsuite::logDetailedPrintf("listing Savefiles failed!\n");
- return kTestFailed;
}
+ Testsuite::logDetailedPrintf("listing Savefiles failed!\n");
return kTestFailed;
}
@@ -173,8 +171,8 @@ TestExitStatus SaveGametests::testErrorMessages() {
// Try opening a non existing file
readAndVerifyData("tBedSomeNonExistentSaveFile.0", "File doesn't exists!");
- Common::Error error = saveFileMan->getError();
- if (error.getCode() == Common::kNoError) {
+ Common::Error err = saveFileMan->getError();
+ if (err.getCode() == Common::kNoError) {
// blunder! how come?
Testsuite::logDetailedPrintf("SaveFileMan.getError() failed\n");
return kTestFailed;
diff --git a/engines/testbed/sound.h b/engines/testbed/sound.h
index 76d0c7bb61..fea7d9d45b 100644
--- a/engines/testbed/sound.h
+++ b/engines/testbed/sound.h
@@ -69,10 +69,6 @@ public:
const char *getDescription() const {
return "Sound Subsystem";
}
-
-private:
- bool _isTestDataFound;
-
};
} // End of namespace Testbed
diff --git a/engines/testbed/testbed.cpp b/engines/testbed/testbed.cpp
index 41a705e292..152764eb27 100644
--- a/engines/testbed/testbed.cpp
+++ b/engines/testbed/testbed.cpp
@@ -76,12 +76,16 @@ void TestbedExitDialog::init() {
void TestbedExitDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) {
switch (cmd) {
+ default:
+ break;
+
case kCmdRerunTestbed :
ConfParams.setRerunFlag(true);
cmd = GUI::kCloseCmd;
- default:
- GUI::Dialog::handleCommand(sender, cmd, data);
+ break;
}
+
+ GUI::Dialog::handleCommand(sender, cmd, data);
}
bool TestbedEngine::hasFeature(EngineFeature f) const {
diff --git a/engines/testbed/testsuite.cpp b/engines/testbed/testsuite.cpp
index 77211b3e64..655179aa74 100644
--- a/engines/testbed/testsuite.cpp
+++ b/engines/testbed/testsuite.cpp
@@ -113,7 +113,7 @@ bool Testsuite::handleInteractiveInput(const Common::String &textToDisplay, cons
return prompt.runModal() == result ? true : false;
}
-void Testsuite::displayMessage(const Common::String &textToDisplay, const char *defaultButton, const char *altButton) {
+void Testsuite::displayMessage(const Common::String &textToDisplay, const char *defaultButton) {
GUI::MessageDialog prompt(textToDisplay, defaultButton);
prompt.runModal();
}
@@ -214,10 +214,11 @@ uint Testsuite::parseEvents() {
return kSkipNext;
}
break;
+
case Common::EVENT_QUIT:
case Common::EVENT_RTL:
return kEngineQuit;
- break;
+
default:
break;
}
diff --git a/engines/testbed/testsuite.h b/engines/testbed/testsuite.h
index 3a3a78b9bb..dc159ce25f 100644
--- a/engines/testbed/testsuite.h
+++ b/engines/testbed/testsuite.h
@@ -112,7 +112,7 @@ public:
*/
static bool handleInteractiveInput(const Common::String &textToDisplay, const char *opt1 = "Yes", const char *opt2 = "No", OptionSelected result = kOptionLeft);
- static void displayMessage(const Common::String &textToDisplay, const char *defaultButton = "OK", const char *altButton = 0);
+ static void displayMessage(const Common::String &textToDisplay, const char *defaultButton = "OK");
static Common::Rect writeOnScreen(const Common::String &textToDisplay, const Common::Point &pt, bool flag = false);
static void clearScreen(const Common::Rect &rect);
static void clearEntireScreen() {
@@ -145,7 +145,7 @@ public:
static void logPrintf(const char *s, ...) GCC_PRINTF(1, 2);
static void logDetailedPrintf(const char *s, ...) GCC_PRINTF(1, 2);
-
+
// Progress bar (Information Display) related methods.
/**
* Display region is in the bottom. Probably 1/4th of the game screen.
@@ -180,7 +180,7 @@ protected:
bool _isTsEnabled;
private:
-
+
/**
* Used from the code to decide if the engine needs to exit
*/
diff --git a/engines/tinsel/detection.cpp b/engines/tinsel/detection.cpp
index 0f0e3cd1ef..59a567bc63 100644
--- a/engines/tinsel/detection.cpp
+++ b/engines/tinsel/detection.cpp
@@ -63,7 +63,7 @@ uint16 TinselEngine::getVersion() const {
return _gameDescription->version;
}
-}
+} // End of namespace Tinsel
static const PlainGameDescriptor tinselGames[] = {
{"tinsel", "Tinsel engine game"},
@@ -74,34 +74,11 @@ static const PlainGameDescriptor tinselGames[] = {
#include "tinsel/detection_tables.h"
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Tinsel::gameDescriptions,
- // Size of that superset structure
- sizeof(Tinsel::TinselGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- tinselGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "tinsel",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NONE,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
class TinselMetaEngine : public AdvancedMetaEngine {
public:
- TinselMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ TinselMetaEngine() : AdvancedMetaEngine(Tinsel::gameDescriptions, sizeof(Tinsel::TinselGameDescription), tinselGames) {
+ params.singleid = "tinsel";
+ }
virtual const char *getName() const {
return "Tinsel";
@@ -265,7 +242,7 @@ const ADGameDescription *TinselMetaEngine::fallbackDetect(const Common::FSList &
if (testFile.open(allFiles[fname])) {
tmp.size = (int32)testFile.size();
- tmp.md5 = computeStreamMD5AsString(testFile, detectionParams.md5Bytes);
+ tmp.md5 = computeStreamMD5AsString(testFile, params.md5Bytes);
} else {
tmp.size = -1;
}
@@ -285,7 +262,7 @@ const ADGameDescription *TinselMetaEngine::fallbackDetect(const Common::FSList &
bool fileMissing = false;
- if ((detectionParams.flags & kADFlagUseExtraAsHint) && !extra.empty() && g->desc.extra != extra)
+ if ((params.flags & kADFlagUseExtraAsHint) && !extra.empty() && g->desc.extra != extra)
continue;
bool allFilesPresent = true;
diff --git a/engines/toon/audio.cpp b/engines/toon/audio.cpp
index ae67d1900e..0bf3316209 100644
--- a/engines/toon/audio.cpp
+++ b/engines/toon/audio.cpp
@@ -232,8 +232,8 @@ AudioStreamInstance::AudioStreamInstance(AudioManager *man, Audio::Mixer *mixer,
_mixer = mixer;
_compBuffer = NULL;
_bufferOffset = 0;
- _lastADPCMval1 = 0;
- _lastADPCMval2 = 0;
+ _lastSample = 0;
+ _lastStepIndex = 0;
_file = stream;
_fadingIn = false;
_fadingOut = false;
@@ -307,8 +307,8 @@ bool AudioStreamInstance::readPacket() {
if (_looping) {
_file->seek(8);
_currentReadSize = 8;
- _lastADPCMval1 = 0;
- _lastADPCMval2 = 0;
+ _lastSample = 0;
+ _lastStepIndex = 0;
} else {
_bufferSize = 0;
stopNow();
@@ -342,52 +342,49 @@ bool AudioStreamInstance::readPacket() {
void AudioStreamInstance::decodeADPCM(uint8 *comp, int16 *dest, int32 packetSize) {
debugC(5, kDebugAudio, "decodeADPCM(comp, dest, %d)", packetSize);
+ // standard IMA ADPCM decoding
int32 numSamples = 2 * packetSize;
- int32 v18 = _lastADPCMval1;
- int32 v19 = _lastADPCMval2;
+ int32 samp = _lastSample;
+ int32 stepIndex = _lastStepIndex;
for (int32 i = 0; i < numSamples; i++) {
uint8 comm = *comp;
+ bool isOddSample = (i & 1);
- int32 v29 = i & 1;
- int32 v30;
- if (v29 == 0)
- v30 = comm & 0xf;
+ uint8 code;
+ if (!isOddSample)
+ code = comm & 0xf;
else
- v30 = (comm & 0xf0) >> 4;
+ code = (comm & 0xf0) >> 4;
- int32 v31 = v30 & 0x8;
- int32 v32 = v30 & 0x7;
- int32 v33 = Audio::Ima_ADPCMStream::_imaTable[v19];
- int32 v34 = v33 >> 3;
- if (v32 & 4)
- v34 += v33;
+ uint8 sample = code & 0x7;
- if (v32 & 2)
- v34 += v33 >> 1;
+ int32 step = Audio::Ima_ADPCMStream::_imaTable[stepIndex];
+ int32 E = step >> 3;
+ if (sample & 4)
+ E += step;
+ if (sample & 2)
+ E += step >> 1;
+ if (sample & 1)
+ E += step >> 2;
- if (v32 & 1)
- v34 += v33 >> 2;
+ stepIndex += Audio::ADPCMStream::_stepAdjustTable[sample];
+ stepIndex = CLIP<int32>(stepIndex, 0, ARRAYSIZE(Audio::Ima_ADPCMStream::_imaTable) - 1);
- v19 += Audio::ADPCMStream::_stepAdjustTable[v32];
- v19 = CLIP<int32>(v19, 0, ARRAYSIZE(Audio::Ima_ADPCMStream::_imaTable) - 1);
-
- if (v31)
- v18 -= v34;
+ if (code & 0x8)
+ samp -= E;
else
- v18 += v34;
+ samp += E;
- if (v18 > 32767)
- v18 = 32767;
- else if (v18 < -32768)
- v18 = -32768;
+ samp = CLIP<int32>(samp, -32768, 32767);
- *dest = v18;
- comp += v29;
+ *dest = samp;
+ if (isOddSample)
+ comp++;
dest++;
}
- _lastADPCMval1 = v18;
- _lastADPCMval2 = v19;
+ _lastSample = samp;
+ _lastStepIndex = stepIndex;
}
void AudioStreamInstance::play(bool fade, Audio::Mixer::SoundType soundType) {
diff --git a/engines/toon/audio.h b/engines/toon/audio.h
index 52ca21b075..61a534265e 100644
--- a/engines/toon/audio.h
+++ b/engines/toon/audio.h
@@ -84,8 +84,8 @@ protected:
Audio::SoundHandle _handle;
Audio::Mixer::SoundType _soundType;
Audio::Mixer *_mixer;
- int32 _lastADPCMval1;
- int32 _lastADPCMval2;
+ int32 _lastSample;
+ int32 _lastStepIndex;
bool _stopped;
AudioManager *_man;
int32 _totalSize;
diff --git a/engines/toon/detection.cpp b/engines/toon/detection.cpp
index 1056f6ec0d..8ddfcd4fed 100644
--- a/engines/toon/detection.cpp
+++ b/engines/toon/detection.cpp
@@ -28,7 +28,7 @@
#include "graphics/thumbnail.h"
#include "toon/toon.h"
-static const PlainGameDescriptor ToonGames[] = {
+static const PlainGameDescriptor toonGames[] = {
{ "toon", "Toonstruck" },
{ 0, 0 }
};
@@ -117,35 +117,14 @@ static const char * const directoryGlobs[] = {
0
};
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Toon::gameDescriptions,
- // Size of that superset structure
- sizeof(ADGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- ToonGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "toon",
- // List of files for file-based fallback detection (optional)
- Toon::fileBasedFallback,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NONE,
- // Maximum directory depth
- 3,
- // List of directory globs
- directoryGlobs
-};
-
class ToonMetaEngine : public AdvancedMetaEngine {
public:
- ToonMetaEngine() : AdvancedMetaEngine(detectionParams) {}
-
+ ToonMetaEngine() : AdvancedMetaEngine(Toon::gameDescriptions, sizeof(ADGameDescription), toonGames) {
+ params.singleid = "toon";
+ params.fileBasedFallback = Toon::fileBasedFallback;
+ params.depth = 3;
+ params.directoryGlobs = directoryGlobs;
+ }
virtual const char *getName() const {
return "Toon";
}
diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp
index 93da20fb47..0e0978b3d6 100644
--- a/engines/toon/toon.cpp
+++ b/engines/toon/toon.cpp
@@ -28,6 +28,7 @@
#include "common/savefile.h"
#include "common/memstream.h"
+#include "engines/advancedDetector.h"
#include "engines/util.h"
#include "graphics/palette.h"
#include "graphics/surface.h"
diff --git a/engines/toon/toon.h b/engines/toon/toon.h
index 02828f26d1..65c6ba0234 100644
--- a/engines/toon/toon.h
+++ b/engines/toon/toon.h
@@ -23,7 +23,6 @@
#ifndef TOON_TOON_H
#define TOON_TOON_H
-#include "engines/advancedDetector.h"
#include "engines/engine.h"
#include "graphics/surface.h"
#include "common/random.h"
@@ -44,6 +43,8 @@ namespace Common {
class MemoryWriteStreamDynamic;
}
+struct ADGameDescription;
+
#define TOON_DAT_VER_MAJ 0 // 1 byte
#define TOON_DAT_VER_MIN 3 // 1 byte
#define TOON_SAVEGAME_VERSION 4
diff --git a/engines/touche/detection.cpp b/engines/touche/detection.cpp
index b7f9c092aa..3e324b5685 100644
--- a/engines/touche/detection.cpp
+++ b/engines/touche/detection.cpp
@@ -126,35 +126,16 @@ static const char *directoryGlobs[] = {
0
};
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Touche::gameDescriptions,
- // Size of that superset structure
- sizeof(ADGameDescription),
- // Number of bytes to compute MD5 sum for
- 4096,
- // List of all engine targets
- toucheGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "touche",
- // List of files for file-based fallback detection (optional)
- Touche::fileBasedFallback,
- // Flags
- kADFlagPrintWarningOnFileBasedFallback,
- // Additional GUI options (for every game}
- Common::GUIO_NONE,
- // Maximum directory depth
- 2,
- // List of directory globs
- directoryGlobs
-};
-
class ToucheMetaEngine : public AdvancedMetaEngine {
public:
- ToucheMetaEngine() : AdvancedMetaEngine(detectionParams) {}
-
+ ToucheMetaEngine() : AdvancedMetaEngine(Touche::gameDescriptions, sizeof(ADGameDescription), toucheGames) {
+ params.md5Bytes = 4096;
+ params.singleid = "touche";
+ params.fileBasedFallback = Touche::fileBasedFallback;
+ params.flags = kADFlagPrintWarningOnFileBasedFallback;
+ params.depth = 2;
+ params.directoryGlobs = directoryGlobs;
+ }
virtual const char *getName() const {
return "Touche";
}
diff --git a/engines/tsage/core.cpp b/engines/tsage/core.cpp
index ae337765a2..ed2b03ebc4 100644
--- a/engines/tsage/core.cpp
+++ b/engines/tsage/core.cpp
@@ -521,24 +521,30 @@ void PlayerMover::pathfind(Common::Point *routeList, Common::Point srcPos, Commo
break;
}
- int var6;
- proc1(routeRegions, srcRegion, destRegion, var6);
+ bool tempVar; // This is used only as internal state for the function.
+ calculateRestOfRoute(routeRegions, srcRegion, destRegion, tempVar);
+ // Empty route?
if (!routeRegions[0]) {
regionIndexes.push_back(destRegion);
continue;
}
- _globals->_walkRegions._field18[0]._pt1 = srcPos;
- _globals->_walkRegions._field18[0]._pt2 = srcPos;
- _globals->_walkRegions._field18[1]._pt1 = destPos;
- _globals->_walkRegions._field18[1]._pt2 = destPos;
+ // field 0 holds the start, and field 1 holds the destination
+ WRField18 &currSrcField = _globals->_walkRegions._field18[0];
+ WRField18 &currDestField = _globals->_walkRegions._field18[1];
+
+ currSrcField._pt1 = srcPos;
+ currSrcField._pt2 = srcPos;
+ currDestField._pt1 = destPos;
+ currDestField._pt2 = destPos;
int tempList[REGION_LIST_SIZE];
tempList[0] = 0;
int endIndex = 0;
int idx = 1;
+ // Find the indexes for each entry in the found route.
do {
int breakEntry = routeRegions[idx];
int breakEntry2 = routeRegions[idx + 1];
@@ -556,49 +562,52 @@ void PlayerMover::pathfind(Common::Point *routeList, Common::Point srcPos, Commo
tempList[idx] = 1;
for (int listIndex = 1; listIndex <= endIndex; ++listIndex) {
- int var10 = tempList[listIndex];
- int var12 = tempList[listIndex + 1];
+ int thisIdx = tempList[listIndex];
+ int nextIdx = tempList[listIndex + 1];
+
+ WRField18 &thisField = _globals->_walkRegions._field18[thisIdx];
+ WRField18 &nextField = _globals->_walkRegions._field18[nextIdx];
- if (sub_F8E5(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[var12]._pt1,
- _globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var10]._pt2) &&
- sub_F8E5(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[var12]._pt2,
- _globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var10]._pt2))
+ if (sub_F8E5_calculatePoint(currSrcField._pt1, nextField._pt1,
+ thisField._pt1, thisField._pt2) &&
+ sub_F8E5_calculatePoint(currSrcField._pt1, nextField._pt2,
+ thisField._pt1, thisField._pt2))
continue;
Common::Point tempPt;
- if (sub_F8E5(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[1]._pt1,
- _globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var10]._pt2, &tempPt)) {
+ if (sub_F8E5_calculatePoint(currSrcField._pt1, currDestField._pt1,
+ thisField._pt1, thisField._pt2, &tempPt)) {
// Add point to the route list
- _globals->_walkRegions._field18[0]._pt1 = tempPt;
+ currSrcField._pt1 = tempPt;
*routeList++ = tempPt;
} else {
- int v16 =
- (findDistance(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[var10]._pt1) << 1) +
- (findDistance(_globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[1]._pt1) << 1) +
- findDistance(_globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var12]._pt1) +
- findDistance(_globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var12]._pt2);
-
- int v1A =
- (findDistance(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[var10]._pt2) << 1) +
- (findDistance(_globals->_walkRegions._field18[var10]._pt2, _globals->_walkRegions._field18[1]._pt2) << 1) +
- findDistance(_globals->_walkRegions._field18[var10]._pt2, _globals->_walkRegions._field18[var12]._pt1) +
- findDistance(_globals->_walkRegions._field18[var10]._pt2, _globals->_walkRegions._field18[var12]._pt2);
-
- if (v16 < v1A) {
- checkMovement2(_globals->_walkRegions._field18[var10]._pt1,
- _globals->_walkRegions._field18[var10]._pt2, 1, objPos);
+ int dist1 =
+ (findDistance(currSrcField._pt1, thisField._pt1) << 1) +
+ (findDistance(thisField._pt1, currDestField._pt1) << 1) +
+ findDistance(thisField._pt1, nextField._pt1) +
+ findDistance(thisField._pt1, nextField._pt2);
+
+ int dist2 =
+ (findDistance(currSrcField._pt1, thisField._pt2) << 1) +
+ (findDistance(thisField._pt2, currDestField._pt2) << 1) +
+ findDistance(thisField._pt2, nextField._pt1) +
+ findDistance(thisField._pt2, nextField._pt2);
+
+ // Do 1 step of movement, storing the new position in objPos.
+ if (dist1 < dist2) {
+ doStepsOfNpcMovement(thisField._pt1, thisField._pt2, 1, objPos);
} else {
- checkMovement2(_globals->_walkRegions._field18[var10]._pt2,
- _globals->_walkRegions._field18[var10]._pt1, 1, objPos);
+ doStepsOfNpcMovement(thisField._pt2, thisField._pt1, 1, objPos);
}
- _globals->_walkRegions._field18[0]._pt1 = objPos;
+ // Update the current position.
+ currSrcField._pt1 = objPos;
*routeList++ = objPos;
}
}
// Add in the route entry
- *routeList++ = _globals->_walkRegions._field18[1]._pt1;
+ *routeList++ = currDestField._pt1;
}
// Mark the end of the path
@@ -746,7 +755,7 @@ int PlayerMover::checkMover(Common::Point &srcPos, const Common::Point &destPos)
return regionIndex;
}
-void PlayerMover::checkMovement2(const Common::Point &srcPos, const Common::Point &destPos, int numSteps, Common::Point &ptOut) {
+void PlayerMover::doStepsOfNpcMovement(const Common::Point &srcPos, const Common::Point &destPos, int numSteps, Common::Point &ptOut) {
Common::Point objPos = _sceneObject->_position;
_sceneObject->_position = srcPos;
uint32 regionBitList = _sceneObject->_regionBitList;
@@ -771,9 +780,10 @@ void PlayerMover::checkMovement2(const Common::Point &srcPos, const Common::Poin
_sceneObject->_mover = this;
}
-int PlayerMover::proc1(int *routeList, int srcRegion, int destRegion, int &v) {
+int PlayerMover::calculateRestOfRoute(int *routeList, int srcRegion, int destRegion, bool &foundRoute) {
+ // Make a copy of the provided route. The first entry is the size.
int tempList[REGION_LIST_SIZE + 1];
- v = 0;
+ foundRoute = false;
for (int idx = 0; idx <= *routeList; ++idx)
tempList[idx] = routeList[idx];
@@ -791,24 +801,28 @@ int PlayerMover::proc1(int *routeList, int srcRegion, int destRegion, int &v) {
WalkRegion &srcWalkRegion = _globals->_walkRegions[srcRegion];
int distance;
if (!routeList[0]) {
- // No route
+ // The route is empty (new route).
distance = 0;
} else {
+ // Find the distance from the last region in the route.
WalkRegion &region = _globals->_walkRegions[routeList[*routeList]];
distance = findDistance(srcWalkRegion._pt, region._pt);
}
+ // Add the srcRegion to the end of the route.
tempList[++*tempList] = srcRegion;
- int newIndex = *tempList;
+ int ourListSize = *tempList;
if (srcRegion == destRegion) {
- v = 1;
- for (int idx = newIndex; idx <= *tempList; ++idx) {
+ // We made a route to the destination; copy that route and return.
+ foundRoute = true;
+ for (int idx = ourListSize; idx <= *tempList; ++idx) {
routeList[idx] = tempList[idx];
++*routeList;
}
return distance;
} else {
+ // Find the first connected region leading to our destination.
int foundIndex = 0;
int idx = 0;
int currDest;
@@ -821,27 +835,32 @@ int PlayerMover::proc1(int *routeList, int srcRegion, int destRegion, int &v) {
++idx;
}
- int resultOffset = 31990;
- while (((currDest = _globals->_walkRegions._idxList[srcWalkRegion._idxListIndex + foundIndex]) != 0) && (v == 0)) {
- int newDistance = proc1(tempList, currDest, destRegion, v);
+ // Check every connected region until we find a route to the destination (or we have no more to check).
+ int bestDistance = 31990;
+ while (((currDest = _globals->_walkRegions._idxList[srcWalkRegion._idxListIndex + foundIndex]) != 0) && (!foundRoute)) {
+ int newDistance = calculateRestOfRoute(tempList, currDest, destRegion, foundRoute);
- if ((newDistance <= resultOffset) || v) {
- routeList[0] = newIndex - 1;
+ if ((newDistance <= bestDistance) || foundRoute) {
+ // We found a shorter possible route, or one leading to the destination.
- for (int i = newIndex; i <= tempList[0]; ++i) {
+ // Overwrite the route with this new one.
+ routeList[0] = ourListSize - 1;
+
+ for (int i = ourListSize; i <= tempList[0]; ++i) {
routeList[i] = tempList[i];
++routeList[0];
}
- resultOffset = newDistance;
+ bestDistance = newDistance;
}
- tempList[0] = newIndex;
+ // Truncate our local list to the size it was before the call.
+ tempList[0] = ourListSize;
++foundIndex;
}
- v = 0;
- return resultOffset + distance;
+ foundRoute = false;
+ return bestDistance + distance;
}
}
@@ -855,71 +874,62 @@ int PlayerMover::findDistance(const Common::Point &pt1, const Common::Point &pt2
return (int)sqrt(xx + yy);
}
-bool PlayerMover::sub_F8E5(const Common::Point &pt1, const Common::Point &pt2, const Common::Point &pt3,
+bool PlayerMover::sub_F8E5_calculatePoint(const Common::Point &pt1, const Common::Point &pt2, const Common::Point &pt3,
const Common::Point &pt4, Common::Point *ptOut) {
- double diff1 = pt2.x - pt1.x;
- double diff2 = pt2.y - pt1.y;
- double diff3 = pt4.x - pt3.x;
- double diff4 = pt4.y - pt3.y;
- double var10 = 0.0, var8 = 0.0;
- double var18 = 0.0, var20 = 0.0;
+ double diffX1 = pt2.x - pt1.x;
+ double diffY1 = pt2.y - pt1.y;
+ double diffX2 = pt4.x - pt3.x;
+ double diffY2 = pt4.y - pt3.y;
+ double ratio1 = 0.0, ratio2 = 0.0;
+ double adjustedY1 = 0.0, adjustedY2 = 0.0;
- if (diff1 != 0.0) {
- var8 = diff2 / diff1;
- var18 = pt1.y - (pt1.x * var8);
+ // Calculate the ratios between the X and Y points.
+ if (diffX1 != 0.0) {
+ ratio1 = diffY1 / diffX1;
+ adjustedY1 = pt1.y - (pt1.x * ratio1);
}
- if (diff3 != 0.0) {
- var10 = diff4 / diff3;
- var20 = pt3.y - (pt3.x * var10);
+ if (diffX2 != 0.0) {
+ ratio2 = diffY2 / diffX2;
+ adjustedY2 = pt3.y - (pt3.x * ratio2);
}
- if (var8 == var10)
+ if (ratio1 == ratio2)
return false;
- double var48, var50;
- if (diff1 == 0) {
- if (diff3 == 0)
+ double xPos, yPos;
+ if (diffX1 == 0) {
+ if (diffX2 == 0)
return false;
- var48 = pt1.x;
- var50 = var10 * var48 + var20;
+ xPos = pt1.x;
+ yPos = ratio2 * xPos + adjustedY2;
} else {
- var48 = (diff3 == 0) ? pt3.x : (var20 - var18) / (var8 - var10);
- var50 = var8 * var48 + var18;
+ xPos = (diffX2 == 0) ? pt3.x : (adjustedY2 - adjustedY1) / (ratio1 - ratio2);
+ yPos = ratio1 * xPos + adjustedY1;
}
- bool var52 = false, var56 = false, var54 = false, var58 = false;
- Common::Point tempPt((int)(var48 + 0.5), (int)(var50 + 0.5));
+ // This is our candidate point, which we must check for validity.
+ Common::Point tempPt((int)(xPos + 0.5), (int)(yPos + 0.5));
- if ((tempPt.x >= pt3.x) && (tempPt.x <= pt4.x))
- var56 = true;
- else if ((tempPt.x >= pt4.x) && (tempPt.x <= pt3.x))
- var56 = true;
- if (var56) {
- if ((tempPt.y >= pt3.y) && (tempPt.y <= pt4.y))
- var58 = true;
- else if ((tempPt.y >= pt4.y) && (tempPt.y <= pt3.y))
- var58 = true;
- }
-
- if ((tempPt.x >= pt1.x) && (tempPt.x <= pt2.x))
- var52 = true;
- else if ((tempPt.x >= pt2.x) && (tempPt.x <= pt1.x))
- var52 = true;
- if (var52) {
- if ((tempPt.y >= pt1.y) && (tempPt.y <= pt2.y))
- var54 = true;
- else if ((tempPt.y >= pt2.y) && (tempPt.y <= pt1.y))
- var54 = true;
- }
+ // Is tempPt inside the second bounds?
+ if (!((tempPt.x >= pt3.x) && (tempPt.x <= pt4.x)))
+ if (!((tempPt.x >= pt4.x) && (tempPt.x <= pt3.x)))
+ return false;
+ if (!((tempPt.y >= pt3.y) && (tempPt.y <= pt4.y)))
+ if (!((tempPt.y >= pt4.y) && (tempPt.y <= pt3.y)))
+ return false;
- if (var52 && var54 && var56 && var58) {
- if (ptOut)
- *ptOut = tempPt;
- return true;
- }
+ // Is tempPt inside the first bounds?
+ if (!((tempPt.x >= pt1.x) && (tempPt.x <= pt2.x)))
+ if (!((tempPt.x >= pt2.x) && (tempPt.x <= pt1.x)))
+ return false;
+ if (!((tempPt.y >= pt1.y) && (tempPt.y <= pt2.y)))
+ if (!((tempPt.y >= pt2.y) && (tempPt.y <= pt1.y)))
+ return false;
- return false;
+ if (ptOut)
+ *ptOut = tempPt;
+ return true;
}
/*--------------------------------------------------------------------------*/
@@ -1353,6 +1363,8 @@ void ScenePalette::changeBackground(const Rect &bounds, FadeMode fadeMode) {
void ScenePalette::synchronize(Serializer &s) {
if (s.getVersion() >= 2)
SavedObject::synchronize(s);
+ if (s.getVersion() >= 5)
+ _listeners.synchronize(s);
s.syncBytes(_palette, 256 * 3);
s.syncAsSint32LE(_colors.foreground);
@@ -2564,6 +2576,9 @@ void SceneText::synchronize(Serializer &s) {
s.syncAsSint16LE(_color2);
s.syncAsSint16LE(_color3);
SYNC_ENUM(_textMode, TextAlign);
+
+ if (s.getVersion() >= 5)
+ _textSurface.synchronize(s);
}
/*--------------------------------------------------------------------------*/
diff --git a/engines/tsage/core.h b/engines/tsage/core.h
index 71130e5b0b..92907addbc 100644
--- a/engines/tsage/core.h
+++ b/engines/tsage/core.h
@@ -229,12 +229,12 @@ protected:
int regionIndexOf(int xp, int yp) { return regionIndexOf(Common::Point(xp, yp)); }
int findClosestRegion(Common::Point &pt, const Common::List<int> &indexList);
int checkMover(Common::Point &srcPos, const Common::Point &destPos);
- void checkMovement2(const Common::Point &pt1, const Common::Point &pt2, int numSteps, Common::Point &ptOut);
- int proc1(int *routeList, int srcRegion, int destRegion, int &v);
+ void doStepsOfNpcMovement(const Common::Point &pt1, const Common::Point &pt2, int numSteps, Common::Point &ptOut);
+ int calculateRestOfRoute(int *routeList, int srcRegion, int destRegion, bool &foundRoute);
static Common::Point *findLinePoint(RouteEnds *routeEnds, Common::Point *objPos, int length, Common::Point *outPos);
static int findDistance(const Common::Point &pt1, const Common::Point &pt2);
- static bool sub_F8E5(const Common::Point &pt1, const Common::Point &pt2, const Common::Point &pt3,
+ static bool sub_F8E5_calculatePoint(const Common::Point &pt1, const Common::Point &pt2, const Common::Point &pt3,
const Common::Point &pt4, Common::Point *ptOut = NULL);
public:
Common::Point _finalDest;
diff --git a/engines/tsage/detection.cpp b/engines/tsage/detection.cpp
index 20c2002257..e9e80312b9 100644
--- a/engines/tsage/detection.cpp
+++ b/engines/tsage/detection.cpp
@@ -66,25 +66,16 @@ static const PlainGameDescriptor tSageGameTitles[] = {
#include "engines/tsage/detection_tables.h"
-static const ADParams detectionParams = {
- (const byte *)tSage::gameDescriptions,
- sizeof(tSage::tSageGameDescription),
- 0,
- tSageGameTitles,
- 0,
- "tsage",
- NULL,
- 0,
- Common::GUIO_NONE,
- 0,
- NULL
+enum {
+ MAX_SAVES = 100
};
-#define MAX_SAVES 100
-
class TSageMetaEngine : public AdvancedMetaEngine {
public:
- TSageMetaEngine() : AdvancedMetaEngine(detectionParams) {
+ TSageMetaEngine() : AdvancedMetaEngine(tSage::gameDescriptions, sizeof(tSage::tSageGameDescription), tSageGameTitles) {
+ params.md5Bytes = 5000;
+ params.singleid = "tsage";
+ params.guioptions = Common::GUIO_NOSPEECH;
}
virtual const char *getName() const {
diff --git a/engines/tsage/detection_tables.h b/engines/tsage/detection_tables.h
index dc55f2a66d..fb97e40449 100644
--- a/engines/tsage/detection_tables.h
+++ b/engines/tsage/detection_tables.h
@@ -24,7 +24,7 @@ namespace tSage {
static const tSageGameDescription gameDescriptions[] = {
- // Ringworld English CD version
+ // Ringworld CD and First Wave versions
{
{
"ring",
@@ -38,26 +38,12 @@ static const tSageGameDescription gameDescriptions[] = {
GType_Ringworld,
GF_CD | GF_ALT_REGIONS
},
- // Ringworld First Wave English CD version
- {
- {
- "ring",
- "CD",
- AD_ENTRY1s("ring.rlb", "0a25b4ee58d44a54425c0b47e5096bbc", 37847618),
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_NO_FLAGS,
- Common::GUIO_NONE
- },
- GType_Ringworld,
- GF_CD | GF_ALT_REGIONS
- },
// Ringworld English Floppy version
{
{
"ring",
"Floppy",
- AD_ENTRY1s("ring.rlb", "61f78f68a56832ae95fe06748c403234", 8438770),
+ AD_ENTRY1s("ring.rlb", "7b7f0c5b37b58fa5ec06ebb2ca0d0d9d", 8438770),
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
@@ -71,7 +57,7 @@ static const tSageGameDescription gameDescriptions[] = {
{
"ring",
"Floppy Demo",
- AD_ENTRY1s("tsage.rlb", "bf4e8525d0cab84b08b57126092eeacd", 833453),
+ AD_ENTRY1s("tsage.rlb", "3b3604a97c06c91f3735d3e9d341f63f", 833453),
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DEMO,
@@ -80,6 +66,8 @@ static const tSageGameDescription gameDescriptions[] = {
GType_Ringworld,
GF_FLOPPY | GF_DEMO
},
+#if 0
+ // FIXME: Compute new MD5s based on 5000 bytes instead of 0 (unlimited)
// Ringworld English Floppy Demo #2 version
{
{
@@ -94,13 +82,13 @@ static const tSageGameDescription gameDescriptions[] = {
GType_Ringworld,
GF_FLOPPY | GF_DEMO | GF_ALT_REGIONS
},
-
- // Blue Force
+ // FIXME: Compute new MD5s based on 5000 bytes instead of 0 (unlimited)
+ // Blue Force floppy
{
{
"blueforce",
- "",
- AD_ENTRY1s("blue.rlb", "467da43c848cc0e800b547c59d84ccb1", 10032614),
+ "Floppy",
+ AD_ENTRY1s("blue.rlb", "17c3993415e8a2cf93040eef7e88ec93", 1156508),
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
@@ -109,12 +97,13 @@ static const tSageGameDescription gameDescriptions[] = {
GType_BlueForce,
GF_FLOPPY
},
- // Blue Force floppy
+#endif
+ // Blue Force
{
{
"blueforce",
- "Floppy",
- AD_ENTRY1s("blue.rlb", "17c3993415e8a2cf93040eef7e88ec93", 1156508),
+ "",
+ AD_ENTRY1s("blue.rlb", "17eabb456cb1546c66baf1aff387ba6a", 10032614),
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
@@ -128,7 +117,7 @@ static const tSageGameDescription gameDescriptions[] = {
{
"blueforce",
"CD",
- AD_ENTRY1s("blue.rlb", "ac29f38184cb3b874ea18523059872ba", 63863322),
+ AD_ENTRY1s("blue.rlb", "99983f48cb218f1f3760cf2f9a7ef11d", 63863322),
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
diff --git a/engines/tsage/dialogs.cpp b/engines/tsage/dialogs.cpp
index 759deebbef..c1bd1d027f 100644
--- a/engines/tsage/dialogs.cpp
+++ b/engines/tsage/dialogs.cpp
@@ -43,21 +43,20 @@ MessageDialog::MessageDialog(const Common::String &message, const Common::String
const Common::String &btn2Message) : GfxDialog() {
// Set up the message
addElements(&_msg, &_btn1, NULL);
-
+
_msg.set(message, 200, ALIGN_LEFT);
- _btn1._bounds.moveTo(_msg._bounds.left, _msg._bounds.bottom + 2);
+ _msg._bounds.moveTo(0, 0);
_defaultButton = &_btn1;
// Set up the first button
_btn1.setText(btn1Message);
- _btn1._bounds.moveTo(_msg._bounds.right - _btn1._bounds.width(), _msg._bounds.bottom);
+ _btn1._bounds.moveTo(_msg._bounds.right - _btn1._bounds.width(), _msg._bounds.bottom + 2);
if (!btn2Message.empty()) {
// Set up the second button
- _defaultButton = &_btn2;
add(&_btn2);
_btn2.setText(btn2Message);
- _btn2._bounds.moveTo(_msg._bounds.right - _btn2._bounds.width(), _msg._bounds.bottom);
+ _btn2._bounds.moveTo(_msg._bounds.right - _btn2._bounds.width(), _msg._bounds.bottom + 2);
_btn1._bounds.translate(-(_btn2._bounds.width() + 4), 0);
}
@@ -82,8 +81,9 @@ int MessageDialog::show2(const Common::String &message, const Common::String &bt
MessageDialog *dlg = new MessageDialog(message, btn1Message, btn2Message);
dlg->draw();
- GfxButton *selectedButton = dlg->execute();
- int result = (selectedButton == &dlg->_btn1) ? 0 : 1;
+ GfxButton *defaultButton = !btn2Message.empty() ? &dlg->_btn2 : &dlg->_btn1;
+ GfxButton *selectedButton = dlg->execute(defaultButton);
+ int result = (selectedButton == defaultButton) ? 1 : 0;
delete dlg;
return result;
@@ -473,7 +473,7 @@ void InventoryDialog::execute() {
g_system->updateScreen();
}
if (_vm->getEventManager()->shouldQuit())
- return;
+ break;
hiliteObj = NULL;
if ((event.eventType == EVENT_BUTTON_DOWN) && !_bounds.contains(event.mousePos))
diff --git a/engines/tsage/events.cpp b/engines/tsage/events.cpp
index e889c56c4d..9df2a7ccd6 100644
--- a/engines/tsage/events.cpp
+++ b/engines/tsage/events.cpp
@@ -304,4 +304,14 @@ void EventsClass::delay(int numFrames) {
_priorFrameTime = g_system->getMillis();
}
+void EventsClass::listenerSynchronize(Serializer &s) {
+ s.syncAsUint32LE(_frameNumber);
+ s.syncAsUint32LE(_prevDelayFrame);
+
+ if (s.getVersion() >= 5) {
+ s.syncAsSint16LE(_currentCursor);
+ s.syncAsSint16LE(_lastCursor);
+ }
+}
+
} // end of namespace tSage
diff --git a/engines/tsage/events.h b/engines/tsage/events.h
index 9a7bdbe82c..a13455d378 100644
--- a/engines/tsage/events.h
+++ b/engines/tsage/events.h
@@ -98,11 +98,7 @@ public:
uint32 getFrameNumber() const { return _frameNumber; }
void delay(int numFrames);
- virtual void listenerSynchronize(Serializer &s) {
- s.syncAsUint32LE(_frameNumber);
- s.syncAsUint32LE(_prevDelayFrame);
- // TODO: Synchronize unknown stuff
- }
+ virtual void listenerSynchronize(Serializer &s);
};
} // End of namespace tSage
diff --git a/engines/tsage/globals.cpp b/engines/tsage/globals.cpp
index e629396501..863f1458b1 100644
--- a/engines/tsage/globals.cpp
+++ b/engines/tsage/globals.cpp
@@ -50,33 +50,42 @@ static SavedObject *classFactoryProc(const Common::String &className) {
/*--------------------------------------------------------------------------*/
-Globals::Globals() :
- _dialogCenter(160, 140),
- _gfxManagerInstance(_screenSurface),
- _randomSource("tsage") {
+Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface),
+ _randomSource("tsage"), _unkColor1(0), _unkColor2(255), _unkColor3(255) {
reset();
_stripNum = 0;
+ _gfxEdgeAdjust = 3;
if (_vm->getFeatures() & GF_DEMO) {
_gfxFontNumber = 0;
_gfxColors.background = 6;
_gfxColors.foreground = 0;
- _fontColors.background = 0;
- _fontColors.foreground = 0;
+ _fontColors.background = 255;
+ _fontColors.foreground = 6;
_dialogCenter.y = 80;
+ // Workaround in order to use later version of the engine
+ _unkColor1 = _gfxColors.foreground;
+ _unkColor2 = _gfxColors.foreground;
+ _unkColor3 = _gfxColors.foreground;
} else if ((_vm->getGameID() == GType_Ringworld) && (_vm->getFeatures() & GF_CD)) {
_gfxFontNumber = 50;
_gfxColors.background = 53;
_gfxColors.foreground = 0;
_fontColors.background = 51;
_fontColors.foreground = 54;
- warning("TODO: Check the 3 additional colors");
+ _unkColor1 = 18;
+ _unkColor2 = 18;
+ _unkColor3 = 18;
} else {
_gfxFontNumber = 50;
_gfxColors.background = 53;
_gfxColors.foreground = 18;
_fontColors.background = 51;
_fontColors.foreground = 54;
+ // Workaround in order to use later version of the engine
+ _unkColor1 = _gfxColors.foreground;
+ _unkColor2 = _gfxColors.foreground;
+ _unkColor3 = _gfxColors.foreground;
}
_screenSurface.setScreenSurface();
_gfxManagers.push_back(&_gfxManagerInstance);
@@ -131,6 +140,12 @@ void Globals::synchronize(Serializer &s) {
s.syncAsSint32LE(_gfxColors.foreground);
s.syncAsSint32LE(_fontColors.background);
s.syncAsSint32LE(_fontColors.foreground);
+
+ if (s.getVersion() >= 4) {
+ s.syncAsByte(_unkColor1);
+ s.syncAsByte(_unkColor2);
+ s.syncAsByte(_unkColor3);
+ }
s.syncAsSint16LE(_dialogCenter.x); s.syncAsSint16LE(_dialogCenter.y);
_sceneListeners.synchronize(s);
diff --git a/engines/tsage/globals.h b/engines/tsage/globals.h
index 6b3df587b6..8212387ed1 100644
--- a/engines/tsage/globals.h
+++ b/engines/tsage/globals.h
@@ -51,6 +51,7 @@ public:
int _gfxFontNumber;
GfxColors _gfxColors;
GfxColors _fontColors;
+ byte _unkColor1, _unkColor2, _unkColor3;
SoundManager _soundManager;
Common::Point _dialogCenter;
WalkRegions _walkRegions;
@@ -67,6 +68,7 @@ public:
SequenceManager _sequenceManager;
Common::RandomSource _randomSource;
int _stripNum;
+ int _gfxEdgeAdjust;
public:
Globals();
~Globals();
diff --git a/engines/tsage/graphics.cpp b/engines/tsage/graphics.cpp
index cc11343c9c..25dc897ecd 100644
--- a/engines/tsage/graphics.cpp
+++ b/engines/tsage/graphics.cpp
@@ -304,6 +304,43 @@ void GfxSurface::unlockSurface() {
}
}
+void GfxSurface::synchronize(Serializer &s) {
+ assert(!_lockSurfaceCtr);
+ assert(!_screenSurface);
+
+ s.syncAsByte(_disableUpdates);
+ _bounds.synchronize(s);
+ s.syncAsSint16LE(_centroid.x);
+ s.syncAsSint16LE(_centroid.y);
+ s.syncAsSint16LE(_transColor);
+
+ if (s.isSaving()) {
+ // Save contents of the surface
+ if (_customSurface) {
+ s.syncAsSint16LE(_customSurface->w);
+ s.syncAsSint16LE(_customSurface->h);
+ s.syncBytes((byte *)_customSurface->pixels, _customSurface->w * _customSurface->h);
+ } else {
+ int zero = 0;
+ s.syncAsSint16LE(zero);
+ s.syncAsSint16LE(zero);
+ }
+ } else {
+ int w, h;
+ s.syncAsSint16LE(w);
+ s.syncAsSint16LE(h);
+
+ if ((w == 0) || (h == 0)) {
+ if (_customSurface)
+ delete _customSurface;
+ _customSurface = NULL;
+ } else {
+ create(w, h);
+ s.syncBytes((byte *)_customSurface->pixels, w * h);
+ }
+ }
+}
+
/**
* Fills a specified rectangle on the surface with the specified color
*
@@ -589,6 +626,9 @@ void GfxElement::setDefaults() {
_fontNumber = _globals->_gfxFontNumber;
_colors = _globals->_gfxColors;
_fontColors = _globals->_fontColors;
+ _unkColor1 = _globals->_unkColor1;
+ _unkColor2 = _globals->_unkColor2;
+ _unkColor3 = _globals->_unkColor3;
}
/**
@@ -602,7 +642,7 @@ void GfxElement::highlight() {
// Scan through the contents of the element, switching any occurances of the foreground
// color with the background color and vice versa
Rect tempRect(_bounds);
- tempRect.collapse(2, 2);
+ tempRect.collapse(_globals->_gfxEdgeAdjust - 1, _globals->_gfxEdgeAdjust - 1);
for (int yp = tempRect.top; yp < tempRect.bottom; ++yp) {
byte *lineP = (byte *)surface.getBasePtr(tempRect.left, yp);
@@ -634,7 +674,7 @@ void GfxElement::drawFrame() {
}
Rect tempRect = _bounds;
- tempRect.collapse(3, 3);
+ tempRect.collapse(_globals->_gfxEdgeAdjust, _globals->_gfxEdgeAdjust);
tempRect.collapse(-1, -1);
gfxManager.fillRect(tempRect, _colors.background);
@@ -783,7 +823,10 @@ void GfxMessage::draw() {
// Set the font and color
gfxManager.setFillFlag(false);
gfxManager._font.setFontNumber(_fontNumber);
- gfxManager._font._colors.foreground = this->_colors.foreground;
+
+ gfxManager._font._colors.foreground = this->_unkColor1;
+ gfxManager._font._colors2.background = this->_unkColor2;
+ gfxManager._font._colors2.foreground = this->_unkColor3;
// Display the text
gfxManager._font.writeLines(_message.c_str(), _bounds, _textAlign);
@@ -803,8 +846,10 @@ void GfxButton::setDefaults() {
gfxManager._font.getStringBounds(_message.c_str(), tempRect, 240);
tempRect.right = ((tempRect.right + 15) / 16) * 16;
- // Set the button bounds to a reduced area
- tempRect.collapse(-3, -3);
+ // Set the button bounds
+ tempRect.collapse(-_globals->_gfxEdgeAdjust, -_globals->_gfxEdgeAdjust);
+ if (_vm->getFeatures() & GF_CD)
+ --tempRect.top;
tempRect.moveTo(_bounds.left, _bounds.top);
_bounds = tempRect;
}
@@ -820,11 +865,17 @@ void GfxButton::draw() {
// Set the font and color
gfxManager._font.setFontNumber(_fontNumber);
- gfxManager._font._colors.foreground = this->_colors.foreground;
+
+ //
+ gfxManager._font._colors.foreground = this->_unkColor1;
+ gfxManager._font._colors2.background = this->_unkColor2;
+ gfxManager._font._colors2.foreground = this->_unkColor3;
// Display the button's text
Rect tempRect(_bounds);
- tempRect.collapse(3, 3);
+ tempRect.collapse(_globals->_gfxEdgeAdjust, _globals->_gfxEdgeAdjust);
+ if (_vm->getFeatures() & GF_CD)
+ ++tempRect.top;
gfxManager._font.writeLines(_message.c_str(), tempRect, ALIGN_CENTER);
gfxManager.unlockSurface();
@@ -885,7 +936,7 @@ void GfxDialog::setDefaults() {
// Set the dialog boundaries
_gfxManager._bounds = tempRect;
- tempRect.collapse(-6, -6);
+ tempRect.collapse(-_globals->_gfxEdgeAdjust * 2, -_globals->_gfxEdgeAdjust * 2);
_bounds = tempRect;
}
@@ -915,7 +966,7 @@ void GfxDialog::draw() {
drawFrame();
// Reset the dialog's graphics manager to only draw within the dialog boundaries
- tempRect.translate(6, 6);
+ tempRect.translate(_globals->_gfxEdgeAdjust * 2, _globals->_gfxEdgeAdjust * 2);
_gfxManager._bounds = tempRect;
// Draw each element in the dialog in order
@@ -952,7 +1003,7 @@ void GfxDialog::addElements(GfxElement *ge, ...) {
}
void GfxDialog::setTopLeft(int xp, int yp) {
- _bounds.moveTo(xp - 6, yp - 6);
+ _bounds.moveTo(xp - _globals->_gfxEdgeAdjust * 2, yp - _globals->_gfxEdgeAdjust * 2);
}
void GfxDialog::setCenter(int xp, int yp) {
diff --git a/engines/tsage/graphics.h b/engines/tsage/graphics.h
index b269520039..e09e1093a3 100644
--- a/engines/tsage/graphics.h
+++ b/engines/tsage/graphics.h
@@ -91,6 +91,7 @@ public:
void setScreenSurface();
Graphics::Surface lockSurface();
void unlockSurface();
+ void synchronize(Serializer &s);
void create(int width, int height);
void setBounds(const Rect &bounds) { _bounds = bounds; }
const Rect &getBounds() const { return _bounds; }
@@ -176,6 +177,7 @@ public:
uint16 _fontNumber;
GfxColors _colors;
GfxColors _fontColors;
+ byte _unkColor1, _unkColor2, _unkColor3;
uint16 _keycode;
public:
GfxElement();
diff --git a/engines/tsage/ringworld_demo.cpp b/engines/tsage/ringworld_demo.cpp
index 3ad414fa20..de8dbf8c12 100644
--- a/engines/tsage/ringworld_demo.cpp
+++ b/engines/tsage/ringworld_demo.cpp
@@ -40,17 +40,7 @@ Scene *RingworldDemoGame::createScene(int sceneNumber) {
}
void RingworldDemoGame::quitGame() {
- _globals->_events.setCursor(CURSOR_ARROW);
- MessageDialog *dlg = new MessageDialog(DEMO_EXIT_MSG, EXIT_BTN_STRING, DEMO_BTN_STRING);
- dlg->draw();
-
- GfxButton *selectedButton = dlg->execute(&dlg->_btn2);
- bool exitFlag = selectedButton != &dlg->_btn2;
-
- delete dlg;
- _globals->_events.hideCursor();
-
- if (exitFlag)
+ if (MessageDialog::show(DEMO_EXIT_MSG, EXIT_BTN_STRING, DEMO_BTN_STRING) == 0)
_vm->quitGame();
}
diff --git a/engines/tsage/ringworld_scenes1.cpp b/engines/tsage/ringworld_scenes1.cpp
index 82f0153d8f..6960788db3 100644
--- a/engines/tsage/ringworld_scenes1.cpp
+++ b/engines/tsage/ringworld_scenes1.cpp
@@ -3102,6 +3102,18 @@ void Scene6100::Action7::signal() {
/*--------------------------------------------------------------------------*/
+void Scene6100::Object::synchronize(Serializer &s) {
+ SceneObject::synchronize(s);
+
+ // Save the double fields of the FloatSet
+ s.syncBytes((byte *)&_floats._float1, sizeof(double));
+ s.syncBytes((byte *)&_floats._float2, sizeof(double));
+ s.syncBytes((byte *)&_floats._float3, sizeof(double));
+ s.syncBytes((byte *)&_floats._float4, sizeof(double));
+}
+
+/*--------------------------------------------------------------------------*/
+
void Scene6100::ProbeMover::dispatch() {
Scene6100 *scene = (Scene6100 *)_globals->_sceneManager._scene;
@@ -3123,14 +3135,43 @@ void Scene6100::Item1::doAction(int action) {
/*--------------------------------------------------------------------------*/
+Scene6100::Scene6100(): Scene() {
+ _objList[0] = &_sunflower1;
+ _objList[1] = &_sunflower2;
+ _objList[2] = &_sunflower3;
+ _objList[3] = &_rocks;
+
+ _speed = 30;
+ _fadePercent = 100;
+ _rocksCheck = false;
+ _hitCount = 0;
+ _turnAmount = 0;
+ _angle = 0;
+ _msgActive = false;
+
+ _globals->_sceneHandler._delayTicks = 8;
+
+ _globals->_player.disableControl();
+ _globals->_events.setCursor(CURSOR_WALK);
+}
+
+void Scene6100::synchronize(Serializer &s) {
+ Scene::synchronize(s);
+
+ s.syncAsSint16LE(_speed);
+ s.syncAsSint16LE(_fadePercent);
+ s.syncAsByte(_rocksCheck);
+ s.syncAsByte(_msgActive);
+ s.syncAsSint16LE(_hitCount);
+ s.syncAsSint16LE(_turnAmount);
+ s.syncAsSint16LE(_angle);
+}
+
void Scene6100::postInit(SceneObjectList *OwnerList) {
loadScene(6100);
Scene::postInit();
setZoomPercents(62, 2, 200, 425);
- _globals->_sceneHandler._delayTicks = 8;
- _globals->_player.disableControl();
- _globals->_events.setCursor(CURSOR_WALK);
_stripManager.addSpeaker(&_speakerQR);
_stripManager.addSpeaker(&_speakerSL);
@@ -3178,11 +3219,6 @@ void Scene6100::postInit(SceneObjectList *OwnerList) {
_probe._floats._float3 = 0.0;
_probe.hide();
- _objList[0] = &_sunflower1;
- _objList[1] = &_sunflower2;
- _objList[2] = &_sunflower3;
- _objList[3] = &_rocks;
-
int baseVal = 2000;
for (int idx = 0; idx < 3; ++idx) {
_objList[idx]->_floats._float1 = _globals->_randomSource.getRandomNumber(999);
@@ -3201,14 +3237,6 @@ void Scene6100::postInit(SceneObjectList *OwnerList) {
_objList[idx]->changeZoom(-1);
}
- _speed = 30;
- _fadePercent = 100;
- _rocksCheck = false;
- _hitCount = 0;
- _turnAmount = 0;
- _angle = 0;
- _msgActive = false;
-
setAction(&_action5);
_globals->_scenePalette.addRotation(96, 143, -1);
diff --git a/engines/tsage/ringworld_scenes1.h b/engines/tsage/ringworld_scenes1.h
index 554b261f2c..abd765473c 100644
--- a/engines/tsage/ringworld_scenes1.h
+++ b/engines/tsage/ringworld_scenes1.h
@@ -483,6 +483,8 @@ class Scene6100 : public Scene {
class Object : public SceneObject {
public:
FloatSet _floats;
+
+ virtual void synchronize(Serializer &s);
};
class ProbeMover : public NpcMover {
public:
@@ -519,6 +521,8 @@ public:
Object *_objList[4];
bool _msgActive;
+ Scene6100();
+ virtual void synchronize(Serializer &s);
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void remove();
virtual void process(Event &event);
diff --git a/engines/tsage/saveload.cpp b/engines/tsage/saveload.cpp
index 56df32146a..522e40c236 100644
--- a/engines/tsage/saveload.cpp
+++ b/engines/tsage/saveload.cpp
@@ -206,7 +206,6 @@ Common::Error Saver::restore(int slot) {
// Final post-restore notifications
_macroRestoreFlag = false;
_loadNotifiers.notify(false);
- _globals->_events.setCursor(_globals->_player._uiEnabled ? CURSOR_WALK : CURSOR_NONE);
return Common::kNoError;
}
diff --git a/engines/tsage/saveload.h b/engines/tsage/saveload.h
index 51b7696590..c1c2851f28 100644
--- a/engines/tsage/saveload.h
+++ b/engines/tsage/saveload.h
@@ -33,7 +33,7 @@ namespace tSage {
typedef void (*SaveNotifierFn)(bool postFlag);
-#define TSAGE_SAVEGAME_VERSION 3
+#define TSAGE_SAVEGAME_VERSION 5
class SavedObject;
diff --git a/engines/tsage/tsage.h b/engines/tsage/tsage.h
index 563fdfcc21..5db45f24ab 100644
--- a/engines/tsage/tsage.h
+++ b/engines/tsage/tsage.h
@@ -23,7 +23,6 @@
#ifndef TSAGE_H
#define TSAGE_H
-#include "engines/advancedDetector.h"
#include "engines/engine.h"
#include "common/rect.h"
#include "audio/mixer.h"
diff --git a/engines/tucker/detection.cpp b/engines/tucker/detection.cpp
index 31d9caef73..3eb3973371 100644
--- a/engines/tucker/detection.cpp
+++ b/engines/tucker/detection.cpp
@@ -102,31 +102,6 @@ static const ADGameDescription tuckerGameDescriptions[] = {
AD_TABLE_END_MARKER
};
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)tuckerGameDescriptions,
- // Size of that superset structure
- sizeof(ADGameDescription),
- // Number of bytes to compute MD5 sum for
- 512,
- // List of all engine targets
- tuckerGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "tucker",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game)
- Common::GUIO_NONE,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
static const ADGameDescription tuckerDemoGameDescription = {
"tucker",
"Non-Interactive Demo",
@@ -139,7 +114,9 @@ static const ADGameDescription tuckerDemoGameDescription = {
class TuckerMetaEngine : public AdvancedMetaEngine {
public:
- TuckerMetaEngine() : AdvancedMetaEngine(detectionParams) {
+ TuckerMetaEngine() : AdvancedMetaEngine(tuckerGameDescriptions, sizeof(ADGameDescription), tuckerGames) {
+ params.md5Bytes = 512;
+ params.singleid = "tucker";
}
virtual const char *getName() const {