aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/wintermute/detection.cpp62
-rw-r--r--engines/wintermute/wintermute.cpp62
-rw-r--r--engines/wintermute/wintermute.h3
3 files changed, 125 insertions, 2 deletions
diff --git a/engines/wintermute/detection.cpp b/engines/wintermute/detection.cpp
index 285c3ffaeb..5e259f717d 100644
--- a/engines/wintermute/detection.cpp
+++ b/engines/wintermute/detection.cpp
@@ -32,6 +32,24 @@
#include "engines/wintermute/detection_tables.h"
+namespace WinterMute {
+
+/**
+ * The fallback game descriptor used by the WinterMute engine's fallbackDetector.
+ * Contents of this struct are overwritten by the fallbackDetector. (logic copied partially
+ * from the SCI-engine).
+ */
+static ADGameDescription s_fallbackDesc = {
+ "",
+ "",
+ AD_ENTRY1(0, 0), // This should always be AD_ENTRY1(0, 0) in the fallback descriptor
+ Common::UNK_LANG,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+};
+static char s_fallbackGameIdBuf[256];
+
class WinterMuteMetaEngine : public AdvancedMetaEngine {
public:
WinterMuteMetaEngine() : AdvancedMetaEngine(WinterMute::gameDescriptions, sizeof(ADGameDescription), WinterMute::wintermuteGames) {
@@ -83,6 +101,44 @@ public:
}
return detectedGames;
}*/
+
+
+ virtual const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const {
+ // Set some defaults
+ s_fallbackDesc.extra = "";
+ s_fallbackDesc.language = Common::UNK_LANG;
+ s_fallbackDesc.flags = ADGF_UNSTABLE;
+ s_fallbackDesc.platform = Common::kPlatformWindows; // default to Windows
+ s_fallbackDesc.gameid = "wintermute";
+ s_fallbackDesc.guioptions = GUIO0();
+
+ if (allFiles.contains("data.dcp")) {
+ Common::String name, caption;
+ if (WinterMuteEngine::getGameInfo(fslist, name, caption)) {
+ for (int32 i = 0; i < name.size(); i++) {
+ // Replace spaces with underscores
+ if (name[i] == ' ') {
+ name.setChar('_', (uint32)i);
+ }
+ }
+ // Prefix to avoid collisions with actually known games
+ name = "wmefan-" + name;
+ strncpy(s_fallbackGameIdBuf, name.c_str(), sizeof(s_fallbackGameIdBuf) - 1);
+ s_fallbackDesc.gameid = s_fallbackGameIdBuf;
+ if (caption != name) {
+ caption += " (fangame) ";
+ char *offset = s_fallbackGameIdBuf + name.size() + 1;
+ uint32 remainingLength = (sizeof(s_fallbackGameIdBuf) - 1) - (name.size() + 1);
+ strncpy(offset, caption.c_str(), remainingLength);
+ s_fallbackDesc.extra = offset;
+ s_fallbackDesc.flags |= ADGF_USEEXTRAASTITLE;
+ }
+ return &s_fallbackDesc;
+ } // Fall through to return 0;
+ }
+ return 0;
+ }
+
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
assert(syst);
assert(engine);
@@ -141,8 +197,10 @@ public:
}
};
+} // end of namespace WinterMute
+
#if PLUGIN_ENABLED_DYNAMIC(WINTERMUTE)
-REGISTER_PLUGIN_DYNAMIC(WINTERMUTE, PLUGIN_TYPE_ENGINE, WinterMuteMetaEngine);
+REGISTER_PLUGIN_DYNAMIC(WINTERMUTE, PLUGIN_TYPE_ENGINE, WinterMute::WinterMuteMetaEngine);
#else
-REGISTER_PLUGIN_STATIC(WINTERMUTE, PLUGIN_TYPE_ENGINE, WinterMuteMetaEngine);
+REGISTER_PLUGIN_STATIC(WINTERMUTE, PLUGIN_TYPE_ENGINE, WinterMute::WinterMuteMetaEngine);
#endif
diff --git a/engines/wintermute/wintermute.cpp b/engines/wintermute/wintermute.cpp
index 69c5df5bc5..9040de66e6 100644
--- a/engines/wintermute/wintermute.cpp
+++ b/engines/wintermute/wintermute.cpp
@@ -29,6 +29,7 @@
#include "common/EventRecorder.h"
#include "common/file.h"
#include "common/fs.h"
+#include "common/tokenizer.h"
#include "engines/util.h"
#include "engines/wintermute/ad/ad_game.h"
@@ -37,12 +38,24 @@
#include "engines/wintermute/base/base_registry.h"
#include "engines/wintermute/base/sound/base_sound_manager.h"
+#include "engines/wintermute/base/base_file_manager.h"
#include "engines/wintermute/base/scriptables/script_engine.h"
namespace WinterMute {
WinterMuteEngine *g_wintermute;
+// Simple constructor for detection - we need to setup the persistence to avoid special-casing in-engine
+// This might not be the prettiest solution
+WinterMuteEngine::WinterMuteEngine() : Engine(g_system) {
+ g_wintermute = this;
+ _classReg = new SystemClassRegistry();
+ _classReg->registerClasses();
+
+ _game = new AdGame();
+ _rnd = NULL;
+}
+
WinterMuteEngine::WinterMuteEngine(OSystem *syst, const ADGameDescription *desc)
: Engine(syst), _gameDescription(desc) {
// Put your engine in a sane state, but do nothing big yet;
@@ -74,7 +87,10 @@ WinterMuteEngine::~WinterMuteEngine() {
debug("WinterMuteEngine::~WinterMuteEngine");
// Dispose your resources here
+ delete _classReg;
delete _rnd;
+ delete _game;
+ g_wintermute = NULL;
// Remove all of our debug levels here
DebugMan.clearAllDebugChannels();
@@ -320,6 +336,52 @@ int WinterMuteEngine::messageLoop() {
void WinterMuteEngine::deinit() {
delete _classReg;
+ _classReg = NULL;
+}
+
+bool WinterMuteEngine::getGameInfo(const Common::FSList &fslist, Common::String &name, Common::String &caption) {
+ bool retVal = false;
+ caption = name = "(invalid)";
+
+ // Quick-fix, instead of possibly breaking the persistence-system, let's just roll with it
+ WinterMuteEngine *engine = new WinterMuteEngine();
+
+ engine->_game->initialize1();
+ engine->_game->_fileManager->registerPackages(fslist);
+ if (engine->_game->loadSettings("startup.settings")) {
+ // We do some manual parsing here, as the engine needs gfx to be initalized to do that.
+ Common::SeekableReadStream *stream = engine->_game->_fileManager->openFile((engine->_game->_settingsGameFile ? engine->_game->_settingsGameFile : "default.game"), false, false);
+ while (!stream->eos() && !stream->err()) {
+ Common::String line = stream->readLine();
+ line.trim(); // Get rid of indentation
+ // Expect "GAME {" or comment, or empty line
+ if (line.size() == 0 || line[0] == ';' || (line.contains("{")))
+ continue;
+ else {
+ Common::StringTokenizer token(line, "=");
+ Common::String key = token.nextToken();
+ Common::String value = token.nextToken();
+ if (value.size() == 0)
+ continue;
+ if (value[0] == '\"')
+ value.deleteChar(0);
+ else
+ continue; // not a string
+ if (value.lastChar() == '\"')
+ value.deleteLastChar();
+ if (key == "NAME") {
+ retVal = true;
+ name = value;
+ } else if (key == "CAPTION") {
+ retVal = true;
+ caption = value;
+ }
+ }
+ }
+ delete stream;
+ }
+ delete engine;
+ return retVal;
}
uint32 WinterMuteEngine::randInt(int from, int to) {
diff --git a/engines/wintermute/wintermute.h b/engines/wintermute/wintermute.h
index b37f495b5e..e850a72196 100644
--- a/engines/wintermute/wintermute.h
+++ b/engines/wintermute/wintermute.h
@@ -44,6 +44,7 @@ enum {
class WinterMuteEngine : public Engine {
public:
WinterMuteEngine(OSystem *syst, const ADGameDescription *desc);
+ WinterMuteEngine();
~WinterMuteEngine();
virtual Common::Error run();
@@ -51,6 +52,8 @@ public:
Common::SaveFileManager *getSaveFileMan() { return _saveFileMan; }
SystemClassRegistry *getClassRegistry(){ return _classReg; }
uint32 randInt(int from, int to);
+ // For detection-purposes:
+ static bool getGameInfo(const Common::FSList &fslist, Common::String &name, Common::String &caption);
private:
int init();
void deinit();