diff options
Diffstat (limited to 'engines/wintermute')
28 files changed, 984 insertions, 1270 deletions
diff --git a/engines/wintermute/POTFILES b/engines/wintermute/POTFILES new file mode 100644 index 0000000000..e9422415b2 --- /dev/null +++ b/engines/wintermute/POTFILES @@ -0,0 +1 @@ +engines/wintermute/detection.cpp diff --git a/engines/wintermute/base/base_engine.cpp b/engines/wintermute/base/base_engine.cpp index 7c2e9c8468..2166a3e070 100644 --- a/engines/wintermute/base/base_engine.cpp +++ b/engines/wintermute/base/base_engine.cpp @@ -61,10 +61,11 @@ BaseEngine::~BaseEngine() { delete _classReg; } -void BaseEngine::createInstance(const Common::String &targetName, const Common::String &gameId, Common::Language lang) { +void BaseEngine::createInstance(const Common::String &targetName, const Common::String &gameId, Common::Language lang, WMETargetExecutable targetExecutable) { instance()._targetName = targetName; instance()._gameId = gameId; instance()._language = lang; + instance()._targetExecutable = targetExecutable; instance().init(); } diff --git a/engines/wintermute/base/base_engine.h b/engines/wintermute/base/base_engine.h index dd82cf9c29..0f4a6b0775 100644 --- a/engines/wintermute/base/base_engine.h +++ b/engines/wintermute/base/base_engine.h @@ -34,6 +34,8 @@ #include "common/random.h" #include "common/language.h" +#include "engines/wintermute/game_description.h" + namespace Wintermute { class BaseFileManager; @@ -53,10 +55,12 @@ class BaseEngine : public Common::Singleton<Wintermute::BaseEngine> { Common::RandomSource *_rnd; SystemClassRegistry *_classReg; Common::Language _language; + WMETargetExecutable _targetExecutable; public: BaseEngine(); ~BaseEngine(); - static void createInstance(const Common::String &targetName, const Common::String &gameId, Common::Language lang); + static void createInstance(const Common::String &targetName, const Common::String &gameId, Common::Language lang, WMETargetExecutable targetExecutable = LATEST_VERSION); + void setGameRef(BaseGame *gameRef) { _gameRef = gameRef; } Common::RandomSource *getRandomSource() { return _rnd; } @@ -73,6 +77,9 @@ public: const char *getGameTargetName() const { return _targetName.c_str(); } Common::String getGameId() const { return _gameId; } Common::Language getLanguage() const { return _language; } + WMETargetExecutable getTargetExecutable() const { + return _targetExecutable; + } }; } // End of namespace Wintermute diff --git a/engines/wintermute/base/base_game.cpp b/engines/wintermute/base/base_game.cpp index 8df39c825a..668053bb3a 100644 --- a/engines/wintermute/base/base_game.cpp +++ b/engines/wintermute/base/base_game.cpp @@ -3896,6 +3896,11 @@ void BaseGame::expandStringByStringTable(char **str) const { _settings->expandStringByStringTable(str); } +////////////////////////////////////////////////////////////////////////// +void BaseGame::expandStringByStringTable(Common::String &str) const { + _settings->expandStringByStringTable(str); +} + char *BaseGame::getKeyFromStringTable(const char *str) const { return _settings->getKeyFromStringTable(str); } diff --git a/engines/wintermute/base/base_game.h b/engines/wintermute/base/base_game.h index cdbbff6c93..e535cc9618 100644 --- a/engines/wintermute/base/base_game.h +++ b/engines/wintermute/base/base_game.h @@ -123,6 +123,7 @@ public: inline BaseObject *getMainObject() { return _mainObject; } inline BaseFont *getSystemFont() { return _systemFont; } + inline BaseFont *getVideoFont() { return _videoFont; } bool initInput(); bool initLoop(); @@ -140,6 +141,7 @@ public: // String Table void expandStringByStringTable(char **str) const; + void expandStringByStringTable(Common::String &str) const; char *getKeyFromStringTable(const char *str) const; void LOG(bool res, const char *fmt, ...); diff --git a/engines/wintermute/base/base_game_settings.cpp b/engines/wintermute/base/base_game_settings.cpp index 61c5894be3..996bada997 100644 --- a/engines/wintermute/base/base_game_settings.cpp +++ b/engines/wintermute/base/base_game_settings.cpp @@ -215,6 +215,11 @@ void BaseGameSettings::expandStringByStringTable(char **str) const { _stringTable->expand(str); } +////////////////////////////////////////////////////////////////////////// +void BaseGameSettings::expandStringByStringTable(Common::String &str) const { + _stringTable->expand(str); +} + char *BaseGameSettings::getKeyFromStringTable(const char *str) const { return _stringTable->getKey(str); } diff --git a/engines/wintermute/base/base_game_settings.h b/engines/wintermute/base/base_game_settings.h index 2059cb075e..15afb06450 100644 --- a/engines/wintermute/base/base_game_settings.h +++ b/engines/wintermute/base/base_game_settings.h @@ -46,6 +46,7 @@ public: bool loadSettings(const char *filename); bool loadStringTable(const char *filename, bool clearOld); void expandStringByStringTable(char **str) const; + void expandStringByStringTable(Common::String &str) const; char *getKeyFromStringTable(const char *str) const; bool persist(BasePersistenceManager *persistMgr); diff --git a/engines/wintermute/base/base_keyboard_state.cpp b/engines/wintermute/base/base_keyboard_state.cpp index 61087c5836..0babc07586 100644 --- a/engines/wintermute/base/base_keyboard_state.cpp +++ b/engines/wintermute/base/base_keyboard_state.cpp @@ -278,10 +278,24 @@ uint32 BaseKeyboardState::keyCodeToVKey(Common::Event *event) { enum VKeyCodes { kVkEscape = 27, kVkSpace = 32, + kVkHome = 36, kVkLeft = 37, kVkUp = 38, kVkRight = 39, - kVkDown = 40 + kVkDown = 40, + + kVkF1 = 112, + kVkF2 = 113, + kVkF3 = 114, + kVkF4 = 115, + kVkF5 = 116, + kVkF6 = 117, + kVkF7 = 118, + kVkF8 = 119, + kVkF9 = 120, + kVkF10 = 121, + kVkF11 = 122, + kVkF12 = 123 }; ////////////////////////////////////////////////////////////////////////// @@ -290,22 +304,42 @@ Common::KeyCode BaseKeyboardState::vKeyToKeyCode(uint32 vkey) { switch (vkey) { case kVkEscape: return Common::KEYCODE_ESCAPE; - break; case kVkSpace: return Common::KEYCODE_SPACE; - break; + case kVkHome: + return Common::KEYCODE_HOME; case kVkLeft: return Common::KEYCODE_LEFT; - break; case kVkRight: return Common::KEYCODE_RIGHT; - break; case kVkUp: return Common::KEYCODE_UP; - break; case kVkDown: return Common::KEYCODE_DOWN; - break; + case kVkF1: + return Common::KEYCODE_F1; + case kVkF2: + return Common::KEYCODE_F2; + case kVkF3: + return Common::KEYCODE_F3; + case kVkF4: + return Common::KEYCODE_F4; + case kVkF5: + return Common::KEYCODE_F5; + case kVkF6: + return Common::KEYCODE_F6; + case kVkF7: + return Common::KEYCODE_F7; + case kVkF8: + return Common::KEYCODE_F8; + case kVkF9: + return Common::KEYCODE_F9; + case kVkF10: + return Common::KEYCODE_F10; + case kVkF11: + return Common::KEYCODE_F11; + case kVkF12: + return Common::KEYCODE_F12; default: warning("Unknown VKEY: %d", vkey); return (Common::KeyCode)vkey; diff --git a/engines/wintermute/base/base_sprite.cpp b/engines/wintermute/base/base_sprite.cpp index 04060bff32..09e138a1fd 100644 --- a/engines/wintermute/base/base_sprite.cpp +++ b/engines/wintermute/base/base_sprite.cpp @@ -41,6 +41,7 @@ #include "engines/wintermute/base/scriptables/script_value.h" #include "engines/wintermute/base/scriptables/script.h" #include "engines/wintermute/base/scriptables/script_stack.h" +#include "engines/wintermute/game_description.h" namespace Wintermute { @@ -347,9 +348,17 @@ void BaseSprite::reset() { } else { _currentFrame = -1; } - - killAllSounds(); - + if (BaseEngine::instance().getTargetExecutable() >= WME_1_8_6) { + /* + * This was added in WME 1.8.6 + * + * 5MA and possibly other games ship with pre-1.8.6 WME, and + * depends (e.g.: menu sounds, etc) on this not being triggered. + * + * See bug #6647 + */ + killAllSounds(); + } _lastFrameTime = 0; _finished = false; _moveX = _moveY = 0; diff --git a/engines/wintermute/base/base_string_table.cpp b/engines/wintermute/base/base_string_table.cpp index 89407a7b0e..4c750ebc93 100644 --- a/engines/wintermute/base/base_string_table.cpp +++ b/engines/wintermute/base/base_string_table.cpp @@ -147,6 +147,15 @@ void BaseStringTable::expand(char **str) const { } } +////////////////////////////////////////////////////////////////////////// +void BaseStringTable::expand(Common::String &str) const { + char *tmp = new char[str.size()+1]; + strcpy(tmp, str.c_str()); + expand(&tmp); + str = tmp; + delete[] tmp; +} + ////////////////////////////////////////////////////////////////////////// const char *BaseStringTable::expandStatic(const char *string) const { diff --git a/engines/wintermute/base/base_string_table.h b/engines/wintermute/base/base_string_table.h index cdcf11917d..cfa3eeb226 100644 --- a/engines/wintermute/base/base_string_table.h +++ b/engines/wintermute/base/base_string_table.h @@ -41,6 +41,7 @@ class BaseStringTable : public BaseClass { public: bool loadFile(const char *filename, bool deleteAll = true); void expand(char **str) const; + void expand(Common::String &str) const; const char *expandStatic(const char *string) const; bool addString(const char *key, const char *val, bool reportDuplicities = true); BaseStringTable(BaseGame *inGame); diff --git a/engines/wintermute/base/sound/base_sound.cpp b/engines/wintermute/base/sound/base_sound.cpp index fa452cc0d6..b5b12d55f9 100644 --- a/engines/wintermute/base/sound/base_sound.cpp +++ b/engines/wintermute/base/sound/base_sound.cpp @@ -89,7 +89,7 @@ bool BaseSound::setSoundSimple() { _sound->setLooping(_soundLooping); _sound->setPrivateVolume(_soundPrivateVolume); _sound->setLoopStart(_soundLoopStart); - _sound->_freezePaused = _soundFreezePaused; + _sound->setFreezePaused(_soundFreezePaused); if (_soundPlaying) { return _sound->resume(); } else { @@ -130,7 +130,7 @@ bool BaseSound::pause(bool freezePaused) { if (_sound) { _soundPaused = true; if (freezePaused) { - _sound->_freezePaused = true; + _sound->setFreezePaused(true); } return _sound->pause(); } else { @@ -150,13 +150,13 @@ bool BaseSound::resume() { bool BaseSound::persist(BasePersistenceManager *persistMgr) { if (persistMgr->getIsSaving() && _sound) { _soundPlaying = _sound->isPlaying(); - _soundLooping = _sound->_looping; - _soundPrivateVolume = _sound->_privateVolume; + _soundLooping = _sound->isLooping(); + _soundPrivateVolume = _sound->getPrivateVolume(); if (_soundPlaying) { _soundPosition = _sound->getPosition(); } - _soundLoopStart = _sound->_loopStart; - _soundFreezePaused = _sound->_freezePaused; + _soundLoopStart = _sound->getLoopStart(); + _soundFreezePaused = _sound->isFreezePaused(); } if (persistMgr->getIsSaving()) { @@ -232,7 +232,7 @@ bool BaseSound::setPrivateVolume(int volume) { if (!_sound) { return STATUS_FAILED; } else { - _sound->_privateVolume = volume; + _sound->setPrivateVolume(volume); return STATUS_OK; } } @@ -241,7 +241,7 @@ int BaseSound::getVolumePercent() { if (!_sound) { return 0; } else { - return _sound->_privateVolume * 100 / 255; + return _sound->getPrivateVolume() * 100 / 255; } } @@ -249,7 +249,7 @@ int BaseSound::getVolume() { if (!_sound) { return 0; } else { - return _sound->_privateVolume; + return _sound->getPrivateVolume(); } } diff --git a/engines/wintermute/base/sound/base_sound_buffer.cpp b/engines/wintermute/base/sound/base_sound_buffer.cpp index 7ec68ea752..5fdac12cef 100644 --- a/engines/wintermute/base/sound/base_sound_buffer.cpp +++ b/engines/wintermute/base/sound/base_sound_buffer.cpp @@ -143,8 +143,13 @@ bool BaseSoundBuffer::play(bool looping, uint32 startSample) { _stream->seek(startSample); _handle = new Audio::SoundHandle; if (_looping) { - Audio::AudioStream *loopStream = new Audio::LoopingAudioStream(_stream, 0, DisposeAfterUse::NO); - g_system->getMixer()->playStream(_type, _handle, loopStream, -1, _volume, _pan, DisposeAfterUse::YES); + if (_loopStart != 0) { + Audio::AudioStream *loopStream = new Audio::SubLoopingAudioStream(_stream, 0, Audio::Timestamp(_loopStart, _stream->getRate()), _stream->getLength(), DisposeAfterUse::NO); + g_system->getMixer()->playStream(_type, _handle, loopStream, -1, _volume, _pan, DisposeAfterUse::YES); + } else { + Audio::AudioStream *loopStream = new Audio::LoopingAudioStream(_stream, 0, DisposeAfterUse::NO); + g_system->getMixer()->playStream(_type, _handle, loopStream, -1, _volume, _pan, DisposeAfterUse::YES); + } } else { g_system->getMixer()->playStream(_type, _handle, _stream, -1, _volume, _pan, DisposeAfterUse::NO); } @@ -296,4 +301,24 @@ bool BaseSoundBuffer::applyFX(TSFXType type, float param1, float param2, float p return STATUS_OK; } +int32 BaseSoundBuffer::getPrivateVolume() const { + return _privateVolume; +} + +bool BaseSoundBuffer::isLooping() const { + return _looping; +} + +bool BaseSoundBuffer::isFreezePaused() const { + return _freezePaused; +} + +void BaseSoundBuffer::setFreezePaused(bool freezePaused) { + _freezePaused = freezePaused; +} + +Audio::Mixer::SoundType BaseSoundBuffer::getType() const { + return _type; +} + } // End of namespace Wintermute diff --git a/engines/wintermute/base/sound/base_sound_buffer.h b/engines/wintermute/base/sound/base_sound_buffer.h index 94bc8dc6ad..b3f3046674 100644 --- a/engines/wintermute/base/sound/base_sound_buffer.h +++ b/engines/wintermute/base/sound/base_sound_buffer.h @@ -71,23 +71,26 @@ public: void updateVolume(); void setType(Audio::Mixer::SoundType Type); + Audio::Mixer::SoundType getType() const; bool loadFromFile(const Common::String &filename, bool forceReload = false); void setStreaming(bool streamed, uint32 numBlocks = 0, uint32 blockSize = 0); bool applyFX(TSFXType type, float param1, float param2, float param3, float param4); - + int32 getPrivateVolume() const; + void setFreezePaused(bool freezePaused); + bool isFreezePaused() const; + bool isLooping() const; //HSTREAM _stream; //HSYNC _sync; + +private: + Audio::Mixer::SoundType _type; Audio::SeekableAudioStream *_stream; Audio::SoundHandle *_handle; - bool _freezePaused; - uint32 _loopStart; - Audio::Mixer::SoundType _type; bool _looping; - int32 _privateVolume; -private: + uint32 _loopStart; uint32 _startPos; Common::String _filename; bool _streamed; diff --git a/engines/wintermute/base/sound/base_sound_manager.cpp b/engines/wintermute/base/sound/base_sound_manager.cpp index 41cfe5ea62..f1e0c3b1f9 100644 --- a/engines/wintermute/base/sound/base_sound_manager.cpp +++ b/engines/wintermute/base/sound/base_sound_manager.cpp @@ -254,9 +254,9 @@ byte BaseSoundMgr::getMasterVolume() { bool BaseSoundMgr::pauseAll(bool includingMusic) { for (uint32 i = 0; i < _sounds.size(); i++) { - if (_sounds[i]->isPlaying() && (_sounds[i]->_type != Audio::Mixer::kMusicSoundType || includingMusic)) { + if (_sounds[i]->isPlaying() && (_sounds[i]->getType() != Audio::Mixer::kMusicSoundType || includingMusic)) { _sounds[i]->pause(); - _sounds[i]->_freezePaused = true; + _sounds[i]->setFreezePaused(true); } } @@ -268,9 +268,9 @@ bool BaseSoundMgr::pauseAll(bool includingMusic) { bool BaseSoundMgr::resumeAll() { for (uint32 i = 0; i < _sounds.size(); i++) { - if (_sounds[i]->_freezePaused) { + if (_sounds[i]->isFreezePaused()) { _sounds[i]->resume(); - _sounds[i]->_freezePaused = false; + _sounds[i]->setFreezePaused(false); } } diff --git a/engines/wintermute/detection.cpp b/engines/wintermute/detection.cpp index a659c434d0..aca682ae99 100644 --- a/engines/wintermute/detection.cpp +++ b/engines/wintermute/detection.cpp @@ -74,7 +74,7 @@ static const char *directoryGlobs[] = { class WintermuteMetaEngine : public AdvancedMetaEngine { public: - WintermuteMetaEngine() : AdvancedMetaEngine(Wintermute::gameDescriptions, sizeof(ADGameDescription), Wintermute::wintermuteGames, gameGuiOptions) { + WintermuteMetaEngine() : AdvancedMetaEngine(Wintermute::gameDescriptions, sizeof(WMEGameDescription), Wintermute::wintermuteGames, gameGuiOptions) { _singleid = "wintermute"; _guioptions = GUIO2(GUIO_NOMIDI, GAMEOPTION_SHOW_FPS); _maxScanDepth = 2; @@ -127,8 +127,8 @@ public: virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { assert(syst); assert(engine); - - *engine = new Wintermute::WintermuteEngine(syst, desc); + const WMEGameDescription *gd = (const WMEGameDescription *)desc; + *engine = new Wintermute::WintermuteEngine(syst, gd); return true; } diff --git a/engines/wintermute/detection_tables.h b/engines/wintermute/detection_tables.h index 8206ca9643..4e3320159a 100644 --- a/engines/wintermute/detection_tables.h +++ b/engines/wintermute/detection_tables.h @@ -90,1342 +90,458 @@ static const PlainGameDescriptor wintermuteGames[] = { {0, 0} }; -static const ADGameDescription gameDescriptions[] = { +// Duplicates WME_ENTRY1s, for consistency +#define WME_ENTRY1s(f1, h1, s1) { {f1, 0, h1, s1}, AD_LISTEND } +#define WME_ENTRY2s(f1, h1, s1, f2, h2, s2) { {f1, 0, h1, s1}, {f2, 0, h2, s2}, AD_LISTEND } +#define WME_ENTRY3s(f1, h1, s1, f2, h2, s2, f3, h3, s3) { {f1, 0, h1, s1}, {f2, 0, h2, s2}, {f3, 0, h3, s3}, AD_LISTEND } + +#define WME_PLATENTRY(shortName, extraName, hashEntry, lang, plat, status, version) \ + { \ + { \ + shortName, \ + extraName, \ + hashEntry, \ + lang, \ + plat, \ + status, \ + GUIO0(), \ + }, \ + version \ + } + +// Convenience variant, as most of the games are Windows-games +#define WME_WINENTRY(shortName, extraName, hashEntry, lang, status, version) \ + { \ + { \ + shortName, \ + extraName, \ + hashEntry, \ + lang, \ + Common::kPlatformWindows, \ + status, \ + GUIO0(), \ + }, \ + version \ + } + +/* To add new entries: + * Make sure you have a target name defined at the top of the file + * + * If the game has only one language, and can be detected using only one file, + * then use WME_WINENTRY, with WME_ENTRY1s as exemplified below. + * + * If the game has more than one language, and the main data file is common across + * the versions, then you should use WME_WINENTRY with WME_ENTRY2s/WME_ENTRY3s, with + * the language file as the first hit, and the data file as the second. (Make sure to + * NOT create a WME_ENTRY1s matching the same data file as the 2/3 file match) + */ + +static const WMEGameDescription gameDescriptions[] = { // Five Lethal Demons - { - "5ld", - "", - AD_ENTRY1s("data.dcp", "1037a77cbd001e0644898addc022322c", 15407750), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("5ld", "", + WME_ENTRY1s("data.dcp", "1037a77cbd001e0644898addc022322c", 15407750), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Five Magical Amulets - { - "5ma", - "", - AD_ENTRY1s("data.dcp", "0134e92bcd5fd2837df3971087e96067", 163316498), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("5ma", "", + WME_ENTRY1s("data.dcp", "0134e92bcd5fd2837df3971087e96067", 163316498), Common::EN_ANY, ADGF_UNSTABLE, WME_1_7_0), // Actual Destination - { - "actualdest", - "", - AD_ENTRY1s("data.dcp", "6926f44b26f21ceb1d840eaab9aeb510", 9081740), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("actualdest", "", + WME_ENTRY1s("data.dcp", "6926f44b26f21ceb1d840eaab9aeb510", 9081740), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Boredom of Agustin Cordes - { - "agustin", - "", - AD_ENTRY1s("data.dcp", "abb79c16c9b92e9b06525a4c7c3f5861", 2461949), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("agustin", "", + WME_ENTRY1s("data.dcp", "abb79c16c9b92e9b06525a4c7c3f5861", 2461949), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Beyond the Threshold - { - "bthreshold", - "", - AD_ENTRY1s("data.dcp", "d49bf9ccb2e74507447c82d6ad3e2bc4", 12773712), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("bthreshold", "", + WME_ENTRY1s("data.dcp", "d49bf9ccb2e74507447c82d6ad3e2bc4", 12773712), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Bickadoodle - { - "bickadoodle", - "", - AD_ENTRY1s("data.dcp", "84db4d1594cac95e25614985775d10a8", 35303844), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("bickadoodle", "", + WME_ENTRY1s("data.dcp", "84db4d1594cac95e25614985775d10a8", 35303844), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Bickadoodle (Ver 1.1) - { - "bickadoodle", - "Version 1.1", - AD_ENTRY1s("data.dcp", "8bb52ac9a9ee129c5059e8e808b669d7", 35337760), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("bickadoodle", "Version 1.1", + WME_ENTRY1s("data.dcp", "8bb52ac9a9ee129c5059e8e808b669d7", 35337760), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), + // Bickadoodle (Ver 1.2) + WME_WINENTRY("bickadoodle", "Version 1.2", + WME_ENTRY1s("data.dcp", "1796a48f3ed72dd785ce93334ab883cc", 35337760), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Bickadoodle (download from http://aethericgames.com/games/bickadoodle/download-bickadoodle/) - { - "bickadoodle", - "", - AD_ENTRY1s("data.dcp", "1584d83577c32add0fce27fae91141a2", 35337728), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("bickadoodle", "", + WME_ENTRY1s("data.dcp", "1584d83577c32add0fce27fae91141a2", 35337728), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Book of Gron Part One - { - "bookofgron", - "", - AD_ENTRY1s("data.dcp", "e61b2ebee044a82fa0f8ca0fce2c8946", 83129531), - Common::RU_RUS, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("bookofgron", "", + WME_ENTRY1s("data.dcp", "e61b2ebee044a82fa0f8ca0fce2c8946", 83129531), Common::RU_RUS, ADGF_UNSTABLE, LATEST_VERSION), // Carol Reed 4 - East Side Story (Demo) - { - "carolreed4", - "Demo", - AD_ENTRY1s("data.dcp", "b3f8b09bb4b05ee3e9d14697525257f9", 59296246), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE | - ADGF_DEMO, - GUIO0() - }, + WME_WINENTRY("carolreed4", "Demo", + WME_ENTRY1s("data.dcp", "b3f8b09bb4b05ee3e9d14697525257f9", 59296246), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION), // Carol Reed 4 - East Side Story - { - "carolreed4", - "", - AD_ENTRY1s("data.dcp", "b26377797f060afc2d440d820100c1ce", 529320536), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE | - ADGF_DEMO, - GUIO0() - }, + WME_WINENTRY("carolreed4", "", + WME_ENTRY1s("data.dcp", "b26377797f060afc2d440d820100c1ce", 529320536), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION), // Carol Reed 5 - The Colour of Murder - { - "carolreed5", - "", - AD_ENTRY1s("data.dcp", "3fcfca44209545d0e26774156427b494", 603660415), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("carolreed5", "", + WME_ENTRY1s("data.dcp", "3fcfca44209545d0e26774156427b494", 603660415), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Carol Reed 6 - Black Circle - { - "carolreed6", - "", - AD_ENTRY1s("data.dcp", "0e4c532beecf23d85012168753f41189", 456258147), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("carolreed6", "", + WME_ENTRY1s("data.dcp", "0e4c532beecf23d85012168753f41189", 456258147), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Carol Reed 7 - Blue Madonna (Demo) - { - "carolreed7", - "Demo", - AD_ENTRY1s("data.dcp", "0372ad0c775266f6355e9e8ae397a2f1", 103719442), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE | - ADGF_DEMO, - GUIO0() - }, + WME_WINENTRY("carolreed7", "Demo", + WME_ENTRY1s("data.dcp", "0372ad0c775266f6355e9e8ae397a2f1", 103719442), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION), // Carol Reed 7 - Blue Madonna - { - "carolreed7", - "", - AD_ENTRY1s("data.dcp", "24e3db3e2fabfc956713796d87a3efb0", 495471147), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("carolreed7", "", + WME_ENTRY1s("data.dcp", "24e3db3e2fabfc956713796d87a3efb0", 495471147), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Carol Reed 8 - Amber's Blood - { - "carolreed8", - "", - AD_ENTRY1s("data.dcp", "859d16b0d5b9b255e470cbded2c6cedc", 502714557), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("carolreed8", "", + WME_ENTRY1s("data.dcp", "859d16b0d5b9b255e470cbded2c6cedc", 502714557), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Carol Reed 9 - Cold Case Summer - { - "carolreed9", - "", - AD_ENTRY1s("data.dcp", "2b343b48a7aee508d728a546b414a255", 620005266), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("carolreed9", "", + WME_ENTRY1s("data.dcp", "2b343b48a7aee508d728a546b414a255", 620005266), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Chivalry is Not Dead - { - "chivalry", - "", - AD_ENTRY1s("data.dcp", "ebd0915d9a12df5224be22f53bb23eb6", 7278306), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_TESTING, - GUIO0() - }, + WME_WINENTRY("chivalry", "", + WME_ENTRY1s("data.dcp", "ebd0915d9a12df5224be22f53bb23eb6", 7278306), Common::EN_ANY, ADGF_TESTING, LATEST_VERSION), // Chivalry is Not Dead (Version from deirdrakai.com) - { - "chivalry", - "", - AD_ENTRY1s("data.dcp", "ae6d91b9517f4d2851a8ad94c96951c8", 7278302), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_TESTING, - GUIO0() - }, + WME_WINENTRY("chivalry", "", + WME_ENTRY1s("data.dcp", "ae6d91b9517f4d2851a8ad94c96951c8", 7278302), Common::EN_ANY, ADGF_TESTING, LATEST_VERSION), // Conspiracao Dumont - { - "conspiracao", - "", - AD_ENTRY1s("ConspiracaoDumont.exe", "106f3f2c8f18bb5ffffeed634ace256c", 32908032), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE | - ADGF_DEMO, - GUIO0() - }, + WME_WINENTRY("conspiracao", "", + WME_ENTRY1s("ConspiracaoDumont.exe", "106f3f2c8f18bb5ffffeed634ace256c", 32908032), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION), // Corrosion: Cold Winter Waiting - { - "corrosion", - "", - AD_ENTRY1s("data.dcp", "ae885b1a8faa0b27f43c0e8f0df02fc9", 525931618), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_TESTING, - GUIO0() - }, + WME_WINENTRY("corrosion", "", + WME_ENTRY1s("data.dcp", "ae885b1a8faa0b27f43c0e8f0df02fc9", 525931618), Common::EN_ANY, ADGF_TESTING, LATEST_VERSION), // Dead City (Czech) - { - "deadcity", - "", - { - // The Czech data are in data.dcp, so in this case we'll have to - // just detect the english version twice, to give the user a choice. - {"english.dcp", 0, "c591046d6de7e381d76f70e0787b2b1f", 415935}, - {"data.dcp", 0, "7ebfd50d1a22370ed7b079bcaa631d62", 9070205}, - AD_LISTEND - }, - Common::CZ_CZE, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + // The Czech data are in data.dcp, so in this case we'll have to + // just detect the english version twice, to give the user a choice. + WME_WINENTRY("deadcity", "", + WME_ENTRY2s("english.dcp", "c591046d6de7e381d76f70e0787b2b1f", 415935, + "data.dcp", "7ebfd50d1a22370ed7b079bcaa631d62", 9070205), Common::CZ_CZE, ADGF_UNSTABLE, LATEST_VERSION), // Dead City (English) - { - "deadcity", - "", - { - {"english.dcp", 0, "c591046d6de7e381d76f70e0787b2b1f", 415935}, - {"data.dcp", 0, "7ebfd50d1a22370ed7b079bcaa631d62", 9070205}, - AD_LISTEND - }, - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("deadcity", "", + WME_ENTRY2s("english.dcp", "c591046d6de7e381d76f70e0787b2b1f", 415935, + "data.dcp", "7ebfd50d1a22370ed7b079bcaa631d62", 9070205), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Dead City (Italian) - { - "deadcity", - "", - { - {"italian.dcp", 0, "92d8efb94436bec7bd1b7fe0b548192e", 454037}, - {"data.dcp", 0, "7ebfd50d1a22370ed7b079bcaa631d62", 9070205}, - AD_LISTEND - }, - Common::IT_ITA, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("deadcity", "", + WME_ENTRY2s("italian.dcp", "92d8efb94436bec7bd1b7fe0b548192e", 454037, + "data.dcp", "7ebfd50d1a22370ed7b079bcaa631d62", 9070205), Common::IT_ITA, ADGF_UNSTABLE, LATEST_VERSION), // Dead City (Russian) - { - "deadcity", - "", - { - {"russian.dcp", 0, "a0ae71e9e1185596fffb07ad2c951eb9", 653317}, - {"data.dcp", 0, "7ebfd50d1a22370ed7b079bcaa631d62", 9070205}, - AD_LISTEND - }, - Common::RU_RUS, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("deadcity", "", + WME_ENTRY2s("russian.dcp", "a0ae71e9e1185596fffb07ad2c951eb9", 653317, + "data.dcp", "7ebfd50d1a22370ed7b079bcaa631d62", 9070205), Common::RU_RUS, ADGF_UNSTABLE, LATEST_VERSION), // Dirty Split (Czech) - { - "dirtysplit", - "", - { - {"czech.dcp", 0, "08a71446467cf8f9444cfea446b46ad6", 127697934}, - {"data.dcp", 0, "8b4b81b718bf65f30a67fc0b1e329eb5", 88577623}, - }, - Common::CZ_CZE, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("dirtysplit", "", + WME_ENTRY2s("czech.dcp", "08a71446467cf8f9444cfea446b46ad6", 127697934, + "data.dcp", "8b4b81b718bf65f30a67fc0b1e329eb5", 88577623), Common::CZ_CZE, ADGF_UNSTABLE, LATEST_VERSION), // Dirty Split (English) - { - "dirtysplit", - "", - AD_ENTRY1s("data.dcp", "8f3dae199361ece0f59fb20cfff6eed3", 88577621), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("dirtysplit", "", + WME_ENTRY1s("data.dcp", "8f3dae199361ece0f59fb20cfff6eed3", 88577621), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Dirty Split (French) - { - "dirtysplit", - "", - { - {"french.dcp", 0, "a0508dedebd0fe478d0158fa4c2a1136", 125534323}, - {"data.dcp", 0, "e6d70c7f5d181b761cfcf974adf9186a", 88577623}, - AD_LISTEND - }, - Common::FR_FRA, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("dirtysplit", "", + WME_ENTRY2s("french.dcp", "a0508dedebd0fe478d0158fa4c2a1136", 125534323, + "data.dcp", "e6d70c7f5d181b761cfcf974adf9186a", 88577623), Common::FR_FRA, ADGF_UNSTABLE, LATEST_VERSION), // Dirty Split (German) - { - "dirtysplit", - "", - AD_ENTRY1s("data.dcp", "139d8a25579e969f8b37d20e6e3de5f9", 92668291), - Common::DE_DEU, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("dirtysplit", "", + WME_ENTRY1s("data.dcp", "139d8a25579e969f8b37d20e6e3de5f9", 92668291), Common::DE_DEU, ADGF_UNSTABLE, LATEST_VERSION), // Dirty Split (Italian) - { - "dirtysplit", - "", - { - {"italian.dcp", 0, "8108807fbd8af70be1ec452d0fd1131b", 125513726}, - {"data.dcp", 0, "35a150e22af274185883fdbb142c6fb1", 88577623}, - }, - Common::IT_ITA, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("dirtysplit", "", + WME_ENTRY2s("italian.dcp", "8108807fbd8af70be1ec452d0fd1131b", 125513726, + "data.dcp", "35a150e22af274185883fdbb142c6fb1", 88577623), Common::IT_ITA, ADGF_UNSTABLE, LATEST_VERSION), // Dirty Split (Spanish) - { - "dirtysplit", - "", - { - {"spanish.dcp", 0, "b3982c0a5e85b42e1e38240fef004aa4", 164428596}, - {"data.dcp", 0, "63766d6c68b9f00b632ea1736fc8a95c", 88577621}, - }, - Common::ES_ESP, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("dirtysplit", "", + WME_ENTRY2s("spanish.dcp", "b3982c0a5e85b42e1e38240fef004aa4", 164428596, + "data.dcp", "63766d6c68b9f00b632ea1736fc8a95c", 88577621), Common::ES_ESP, ADGF_UNSTABLE, LATEST_VERSION), // Des Reves Elastiques Avec Mille Insectes Nommes Georges - { - "dreaming", - "", - AD_ENTRY1s("data.dcp", "4af26d97ea063fc1277ce30ae431de90", 8804073), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("dreaming", "", + WME_ENTRY1s("data.dcp", "4af26d97ea063fc1277ce30ae431de90", 8804073), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Dreamscape - { - "dreamscape", - "", - AD_ENTRY1s("data.dcp", "7a5752ed4446c862be9f02d7932acf54", 17034377), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("dreamscape", "", + WME_ENTRY1s("data.dcp", "7a5752ed4446c862be9f02d7932acf54", 17034377), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Escape from the Mansion - { - "escapemansion", - "Beta 1", - AD_ENTRY1s("data.dcp", "d8e348b2312cc36a929cad75f12e0b3a", 21452380), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("escapemansion", "Beta 1", + WME_ENTRY1s("data.dcp", "d8e348b2312cc36a929cad75f12e0b3a", 21452380), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Escape from the Mansion - { - "escapemansion", - "Beta 2", - AD_ENTRY1s("data.dcp", "ded5fa6c5f2afdaf2cafb53e52cd3dd8", 21455763), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("escapemansion", "Beta 2", + WME_ENTRY1s("data.dcp", "ded5fa6c5f2afdaf2cafb53e52cd3dd8", 21455763), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Escape from the Mansion - { - "escapemansion", - "1.3", - AD_ENTRY1s("data.dcp", "1e5d231b56c8a228cd15cb690f50253e", 29261972), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("escapemansion", "1.3", + WME_ENTRY1s("data.dcp", "1e5d231b56c8a228cd15cb690f50253e", 29261972), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Four - { - "four", - "", - AD_ENTRY1s("data.dcp", "ec05cd5e37c9a524053b8859635a4234", 62599855), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("four", "", + WME_ENTRY1s("data.dcp", "ec05cd5e37c9a524053b8859635a4234", 62599855), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Framed - { - "framed", - "", - AD_ENTRY1s("data.dcp", "e7259fb36f2c6f9f28242291e0c3de98", 34690568), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("framed", "", + WME_ENTRY1s("data.dcp", "e7259fb36f2c6f9f28242291e0c3de98", 34690568), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Ghost in the Sheet - { - "ghostsheet", - "", - { - {"english.dcp", 0, "e6d0aad2c89996bcabe416105a3d6d3a", 12221017}, - {"data.dcp", 0, "b2f8b05328e4881e15e98e845b63f451", 168003}, - AD_LISTEND - }, - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("ghostsheet", "", + WME_ENTRY2s("english.dcp", "e6d0aad2c89996bcabe416105a3d6d3a", 12221017, + "data.dcp", "b2f8b05328e4881e15e98e845b63f451", 168003), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Ghost in the Sheet (Demo) - { - "ghostsheet", - "Demo", - AD_ENTRY1s("data.dcp", "dc1f6595f412ac25a52eaf47dad4ab81", 169083), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE | - ADGF_DEMO, - GUIO0() - }, + WME_WINENTRY("ghostsheet", "Demo", + WME_ENTRY1s("data.dcp", "dc1f6595f412ac25a52eaf47dad4ab81", 169083), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION), // Hamlet or the last game without MMORPS features, shaders and product placement - { - "hamlet", - "", - AD_ENTRY1s("data.dcp", "f624add957a77c9930529fb28cc2450f", 88183022), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("hamlet", "", + + WME_ENTRY1s("data.dcp", "f624add957a77c9930529fb28cc2450f", 88183022), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Helga Deep In Trouble (English) - { - "helga", - "", - { - {"english.dcp", 0, "bfa136b21bdbc7d8691c0770a6d40bc3", 135931}, - {"data.dcp", 0, "25cb955a60b58326f2eeda1ce288fb37", 183251259}, - AD_LISTEND - }, - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("helga", "", + WME_ENTRY2s("english.dcp", "bfa136b21bdbc7d8691c0770a6d40bc3", 135931, + "data.dcp", "25cb955a60b58326f2eeda1ce288fb37", 183251259), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Helga Deep In Trouble (Demo) (English) - { - "helga", - "Demo", - { - {"english.dcp", 0, "b3a93e678f0ef97200f691cd1724643f", 135864}, - {"data.dcp", 0, "45134ed93bc391edf148b79cdcbf2a09", 154266028}, - AD_LISTEND - }, - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE | - ADGF_DEMO, - GUIO0() - }, + WME_WINENTRY("helga", "Demo", + WME_ENTRY2s("english.dcp", "b3a93e678f0ef97200f691cd1724643f", 135864, + "data.dcp", "45134ed93bc391edf148b79cdcbf2a09", 154266028), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION), // James Peris: No License Nor Control (English) - { - "jamesperis", - "", - AD_ENTRY1s("data.dcp", "a420961e170cb7d168a0d2bae2fe5218", 225294032), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("jamesperis", "", + WME_ENTRY1s("data.dcp", "a420961e170cb7d168a0d2bae2fe5218", 225294032), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // James Peris: No License Nor Control (Spanish) - { - "jamesperis", - "", - AD_ENTRY1s("data.dcp", "a420961e170cb7d168a0d2bae2fe5218", 225294032), - Common::ES_ESP, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("jamesperis", "", + WME_ENTRY1s("data.dcp", "a420961e170cb7d168a0d2bae2fe5218", 225294032), Common::ES_ESP, ADGF_UNSTABLE, LATEST_VERSION), // James Peris: No License Nor Control (Demo) (English) - { - "jamesperis", - "Demo", - AD_ENTRY1s("data.dcp", "edb9f9c7a08993c1e28f4e477b5f9830", 116113507), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE | - ADGF_DEMO, - GUIO0() - }, + WME_WINENTRY("jamesperis", "Demo", + WME_ENTRY1s("data.dcp", "edb9f9c7a08993c1e28f4e477b5f9830", 116113507), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION), // James Peris: No License Nor Control (Demo) (Spanish) - { - "jamesperis", - "Demo", - AD_ENTRY1s("data.dcp", "edb9f9c7a08993c1e28f4e477b5f9830", 116113507), - Common::ES_ESP, - Common::kPlatformWindows, - ADGF_UNSTABLE | - ADGF_DEMO, - GUIO0() - }, + WME_WINENTRY("jamesperis", "Demo", + WME_ENTRY1s("data.dcp", "edb9f9c7a08993c1e28f4e477b5f9830", 116113507), Common::ES_ESP, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION), // J.U.L.I.A. (English) - { - "julia", - "", - AD_ENTRY1s("data.dcp", "c2264b4f8fcd132d2913ff5b6076a24f", 10109741), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("julia", "", + WME_ENTRY1s("data.dcp", "c2264b4f8fcd132d2913ff5b6076a24f", 10109741), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // J.U.L.I.A. (English, Bundle in a box-version) - { - "julia", - "Version 1.2", - AD_ENTRY1s("data.dcp", "fe90023ccc22f35185b40b910e0d03a2", 10101373), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("julia", "Version 1.2", + WME_ENTRY1s("data.dcp", "fe90023ccc22f35185b40b910e0d03a2", 10101373), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // J.U.L.I.A. (English) (Demo) - { - "julia", - "Demo", - AD_ENTRY1s("data.dcp", "f0bbc3394555a9811f6050dae428cab6", 7655237), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE | - ADGF_DEMO, - GUIO0() - }, + WME_WINENTRY("julia", "Demo", + WME_ENTRY1s("data.dcp", "f0bbc3394555a9811f6050dae428cab6", 7655237), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION), // J.U.L.I.A. (English) (Greenlight Demo) - { - "julia", - "Greenlight Demo", - AD_ENTRY1s("data.dcp", "4befd448d36b0dae9c3ab1aa7cb8b78d", 7271886), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE | - ADGF_DEMO, - GUIO0() - }, + WME_WINENTRY("julia", "Greenlight Demo", + WME_ENTRY1s("data.dcp", "4befd448d36b0dae9c3ab1aa7cb8b78d", 7271886), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION), // Kulivocko (Czech) - { - "kulivocko", - "", - AD_ENTRY1s("data.dcp", "44306dc470e9b27474043932eccee02f", 155106392), - Common::CZ_CZE, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("kulivocko", "", + WME_ENTRY1s("data.dcp", "44306dc470e9b27474043932eccee02f", 155106392), Common::CZ_CZE, ADGF_UNSTABLE, LATEST_VERSION), // Kulivocko (Czech) (Demo) - { - "kulivocko", - "Demo", - AD_ENTRY1s("data.dcp", "63b164bdfadecbb0deb5da691afb8154", 48362234), - Common::CZ_CZE, - Common::kPlatformWindows, - ADGF_UNSTABLE | - ADGF_DEMO, - GUIO0() - }, + WME_WINENTRY("kulivocko", "Demo", + WME_ENTRY1s("data.dcp", "63b164bdfadecbb0deb5da691afb8154", 48362234), Common::CZ_CZE, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION), // Life In 3 Minutes - { - "lifein3minutes", - "", - AD_ENTRY1s("data.dcp", "c6368950e37a95bf098b02b4eaa5b929", 141787214), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("lifein3minutes", "", + WME_ENTRY1s("data.dcp", "c6368950e37a95bf098b02b4eaa5b929", 141787214), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Looky Demo (English) - { - "looky", - "Demo", - { - {"english.dcp", 0, "1388e1dd320f4d553dea3b0316812f9d", 1358442}, - {"data.dcp", 0, "7074bcd7bc7ad7eb04c271aafb964c32", 13815660}, - AD_LISTEND - }, - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE | - ADGF_DEMO, - GUIO0() - }, + WME_WINENTRY("looky", "Demo", + WME_ENTRY2s("english.dcp", "1388e1dd320f4d553dea3b0316812f9d", 1358442, + "data.dcp", "7074bcd7bc7ad7eb04c271aafb964c32", 13815660), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION), // Looky Demo (German) - { - "looky", - "Demo", - { - {"german.dcp", 0, "606c048426dfbe94442b59fd34a5c76e", 14339496}, - {"data.dcp", 0, "7074bcd7bc7ad7eb04c271aafb964c32", 13815660}, - AD_LISTEND - }, - Common::DE_DEU, - Common::kPlatformWindows, - ADGF_UNSTABLE | - ADGF_DEMO, - GUIO0() - }, + WME_WINENTRY("looky", "Demo", + WME_ENTRY2s("german.dcp", "606c048426dfbe94442b59fd34a5c76e", 14339496, + "data.dcp", "7074bcd7bc7ad7eb04c271aafb964c32", 13815660), Common::DE_DEU, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION), // Looky (German) - { - "looky", - "", - { - {"german.dcp", 0, "bf4c2b8c26342342441a6d64934ab832", 107027865}, - {"data.dcp", 0, "50de0beaa5ad621aa9f020df901d1e74", 1342214}, - AD_LISTEND - }, - Common::DE_DEU, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("looky", "", + WME_ENTRY2s("german.dcp", "bf4c2b8c26342342441a6d64934ab832", 107027865, + "data.dcp", "50de0beaa5ad621aa9f020df901d1e74", 1342214), Common::DE_DEU, ADGF_UNSTABLE, LATEST_VERSION), // Mirage - { - "mirage", - "", - AD_ENTRY1s("data.dcp", "d230b0b99c0aa77b9ecd094d8ee5573b", 17844056), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("mirage", "", + WME_ENTRY1s("data.dcp", "d230b0b99c0aa77b9ecd094d8ee5573b", 17844056), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Oknytt - { - "oknytt", - "Version 1.0", - AD_ENTRY1s("data.dcp", "6456cf8f429905c83f07509f9da536dd", 109502959), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("oknytt", "Version 1.0", + WME_ENTRY1s("data.dcp", "6456cf8f429905c83f07509f9da536dd", 109502959), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Night Train Demo - { - "nighttrain", - "", - AD_ENTRY1s("data.dcp", "5a027ef84b083a730c9a4c85ec1d3a32", 131760816), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE | - ADGF_DEMO, - GUIO0() - }, + WME_WINENTRY("nighttrain", "", + WME_ENTRY1s("data.dcp", "5a027ef84b083a730c9a4c85ec1d3a32", 131760816), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION), // Paintaria - { - "paintaria", - "", - AD_ENTRY1s("data.dcp", "354c08440c98150ff0d4008dd2865880", 48326040), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("paintaria", "", + WME_ENTRY1s("data.dcp", "354c08440c98150ff0d4008dd2865880", 48326040), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Pigeons in the Park - { - "pigeons", - "", - AD_ENTRY1s("data.dcp", "9143a5b6ff8206aefe3c4c643add3ec7", 2611100), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("pigeons", "", + WME_ENTRY1s("data.dcp", "9143a5b6ff8206aefe3c4c643add3ec7", 2611100), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Project: Doom - { - "projectdoom", - "", - AD_ENTRY1s("data.dcp", "d5894b65a40706845434b99870bcab92", 99223761), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("projectdoom", "", + WME_ENTRY1s("data.dcp", "d5894b65a40706845434b99870bcab92", 99223761), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Project Joe - { - "projectjoe", - "", - AD_ENTRY1s("data.dcp", "ada3c08542901295076b5349e655e73f", 160780037), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE | - ADGF_DEMO, - GUIO0() - }, + WME_WINENTRY("projectjoe", "", + WME_ENTRY1s("data.dcp", "ada3c08542901295076b5349e655e73f", 160780037), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION), // Project Lonely Robot - { - "lonelyrobot", - "beta", - AD_ENTRY1s("data.dcp", "a0cf7ad5bab957416dcda454e9f28ef0", 3420120), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE | - ADGF_DEMO, - GUIO0() - }, + WME_WINENTRY("lonelyrobot", "beta", + WME_ENTRY1s("data.dcp", "a0cf7ad5bab957416dcda454e9f28ef0", 3420120), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION), // Reversion: The Escape Version 1.0 - { - "reversion1", - "Version 1.0", - AD_ENTRY1s("data.dcp", "cd616f98ebfd047e0c540b50b4b70761", 254384531), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("reversion1", "Version 1.0", + WME_ENTRY1s("data.dcp", "cd616f98ebfd047e0c540b50b4b70761", 254384531), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Reversion: The Escape Version 1.1 (Chinese) - { - "reversion1", - "Version 1.1", - { - {"chinese.dcp", 0, "cf97150739499a4c15f51dc534ff85a1", 6330561}, - {"data.dcp", 0, "cb9865dc7e1db2990a8cf4bc13cf4999", 257643032}, - AD_LISTEND - }, - Common::ZH_CNA, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("reversion1", "Version 1.1", + WME_ENTRY2s("chinese.dcp", "cf97150739499a4c15f51dc534ff85a1", 6330561, + "data.dcp", "cb9865dc7e1db2990a8cf4bc13cf4999", 257643032), Common::ZH_CNA, ADGF_UNSTABLE, LATEST_VERSION), // Reversion: The Escape Version 1.1 (English) - { - "reversion1", - "Version 1.1", - { - {"english.dcp", 0, "7b2f061d7c91365c5d04605f1de032b3", 5702699}, - {"data.dcp", 0, "cb9865dc7e1db2990a8cf4bc13cf4999", 257643032}, - AD_LISTEND - }, - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("reversion1", "Version 1.1", + WME_ENTRY2s("english.dcp", "7b2f061d7c91365c5d04605f1de032b3", 5702699, + "data.dcp", "cb9865dc7e1db2990a8cf4bc13cf4999", 257643032), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Reversion: The Escape Version 1.1 (French) - { - "reversion1", - "Version 1.1", - { - {"french.dcp", 0, "214204b6022c5ed67fada44557690faf", 6327400}, - {"data.dcp", 0, "cb9865dc7e1db2990a8cf4bc13cf4999", 257643032}, - AD_LISTEND - }, - Common::FR_FRA, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("reversion1", "Version 1.1", + WME_ENTRY2s("french.dcp", "214204b6022c5ed67fada44557690faf", 6327400, + "data.dcp", "cb9865dc7e1db2990a8cf4bc13cf4999", 257643032), Common::FR_FRA, ADGF_UNSTABLE, LATEST_VERSION), // Reversion: The Escape Version 1.1 (German) - { - "reversion1", - "Version 1.1", - { - {"german.dcp", 0, "96677823b36d580a4a29e3659071071c", 6340699}, - {"data.dcp", 0, "cb9865dc7e1db2990a8cf4bc13cf4999", 257643032}, - AD_LISTEND - }, - Common::DE_DEU, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("reversion1", "Version 1.1", + WME_ENTRY2s("german.dcp", "96677823b36d580a4a29e3659071071c", 6340699, + "data.dcp", "cb9865dc7e1db2990a8cf4bc13cf4999", 257643032), Common::DE_DEU, ADGF_UNSTABLE, LATEST_VERSION), // Reversion: The Escape Version 1.1 (Italian) - { - "reversion1", - "Version 1.1", - { - {"italian.dcp", 0, "9ce80c1835108f10170a02969f71efe1", 6301836}, - {"data.dcp", 0, "cb9865dc7e1db2990a8cf4bc13cf4999", 257643032}, - AD_LISTEND - }, - Common::IT_ITA, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("reversion1", "Version 1.1", + WME_ENTRY2s("italian.dcp", "9ce80c1835108f10170a02969f71efe1", 6301836, + "data.dcp", "cb9865dc7e1db2990a8cf4bc13cf4999", 257643032), Common::IT_ITA, ADGF_UNSTABLE, LATEST_VERSION), // Reversion: The Escape Version 1.1 (Portuguese) - { - "reversion1", - "Version 1.1", - { - {"portugues.dcp", 0, "8772501afa2c630a7c697eb99e9c7bda", 5053303}, - {"data.dcp", 0, "cb9865dc7e1db2990a8cf4bc13cf4999", 257643032}, - AD_LISTEND - }, - Common::PT_BRA, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("reversion1", "Version 1.1", + WME_ENTRY2s("portugues.dcp", "8772501afa2c630a7c697eb99e9c7bda", 5053303, + "data.dcp", "cb9865dc7e1db2990a8cf4bc13cf4999", 257643032), Common::PT_BRA, ADGF_UNSTABLE, LATEST_VERSION), // Reversion: The Escape Version 1.3 (Chinese) - { - "reversion1", - "Version 1.3", - { - {"xlanguage_nz.dcp", 0, "92c4065156e464211685bf799b3279fd", 5130600}, - {"data.dcp", 0, "9ebb12f6fd7c038d079f81beb3bd96d5", 254185907}, - AD_LISTEND - }, - Common::ZH_CNA, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("reversion1", "Version 1.3", + WME_ENTRY2s("xlanguage_nz.dcp", "92c4065156e464211685bf799b3279fd", 5130600, + "data.dcp", "9ebb12f6fd7c038d079f81beb3bd96d5", 254185907), Common::ZH_CNA, ADGF_UNSTABLE, LATEST_VERSION), // Reversion: The Escape Version 1.3 (English) - { - "reversion1", - "Version 1.3", - { - {"xlanguage_en.dcp", 0, "05845e1283920a6e4044f2a54f7a9519", 4818543}, - {"data.dcp", 0, "9ebb12f6fd7c038d079f81beb3bd96d5", 254185907}, - AD_LISTEND - }, - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("reversion1", "Version 1.3", + WME_ENTRY2s("xlanguage_en.dcp", "05845e1283920a6e4044f2a54f7a9519", 4818543, + "data.dcp", "9ebb12f6fd7c038d079f81beb3bd96d5", 254185907), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Reversion: The Escape Version 1.3 (French) - { - "reversion1", - "Version 1.3", - { - {"xlanguage_fr.dcp", 0, "441795490e9307eb2ed07830779881ac", 5425959}, - {"data.dcp", 0, "9ebb12f6fd7c038d079f81beb3bd96d5", 254185907}, - AD_LISTEND - }, - Common::FR_FRA, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("reversion1", "Version 1.3", + WME_ENTRY2s("xlanguage_fr.dcp", "441795490e9307eb2ed07830779881ac", 5425959, + "data.dcp", "9ebb12f6fd7c038d079f81beb3bd96d5", 254185907), Common::FR_FRA, ADGF_UNSTABLE, LATEST_VERSION), // Reversion: The Escape Version 1.3 (German) - { - "reversion1", - "Version 1.3", - { - {"xlanguage_de.dcp", 0, "b588041015b93e54b4c246ca77d01e76", 5423798}, - {"data.dcp", 0, "9ebb12f6fd7c038d079f81beb3bd96d5", 254185907}, - AD_LISTEND - }, - Common::DE_DEU, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("reversion1", "Version 1.3", + WME_ENTRY2s("xlanguage_de.dcp", "b588041015b93e54b4c246ca77d01e76", 5423798, + "data.dcp", "9ebb12f6fd7c038d079f81beb3bd96d5", 254185907), Common::DE_DEU, ADGF_UNSTABLE, LATEST_VERSION), // Reversion: The Escape Version 1.3 (Italian) - { - "reversion1", - "Version 1.3", - { - {"xlanguage_it.dcp", 0, "a1f4199079b75ee10cded41f05b45d5f", 5386424}, - {"data.dcp", 0, "9ebb12f6fd7c038d079f81beb3bd96d5", 254185907}, - AD_LISTEND - }, - Common::IT_ITA, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("reversion1", "Version 1.3", + WME_ENTRY2s("xlanguage_it.dcp", "a1f4199079b75ee10cded41f05b45d5f", 5386424, + "data.dcp", "9ebb12f6fd7c038d079f81beb3bd96d5", 254185907), Common::IT_ITA, ADGF_UNSTABLE, LATEST_VERSION), // Reversion: The Escape Version 1.3 (Portuguese) - { - "reversion1", - "Version 1.3", - { - {"xlanguage_pt.dcp", 0, "3d653debd37e56756a79401e1004c4d2", 4149165}, - {"data.dcp", 0, "9ebb12f6fd7c038d079f81beb3bd96d5", 254185907}, - AD_LISTEND - }, - Common::PT_BRA, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("reversion1", "Version 1.3", + WME_ENTRY2s("xlanguage_pt.dcp", "3d653debd37e56756a79401e1004c4d2", 4149165, + "data.dcp", "9ebb12f6fd7c038d079f81beb3bd96d5", 254185907), Common::PT_BRA, ADGF_UNSTABLE, LATEST_VERSION), // Reversion: The Escape Version 1.3.2369 (Chinese) - { - "reversion1", - "Version 1.3.2369", - { - {"xlanguage_nz.dcp", 0, "7146dfa43ffdf0886e034fffe2c8a0c0", 13722261}, - {"data.dcp", 0, "aecb5deeea7b0baa871fbd0cef35a648", 254219204}, - AD_LISTEND - }, - Common::ZH_CNA, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("reversion1", "Version 1.3.2369", + WME_ENTRY2s("xlanguage_nz.dcp", "7146dfa43ffdf0886e034fffe2c8a0c0", 13722261, + "data.dcp", "aecb5deeea7b0baa871fbd0cef35a648", 254219204), Common::ZH_CNA, ADGF_UNSTABLE, LATEST_VERSION), // Reversion: The Escape Version 1.3.2369 (English) - { - "reversion1", - "Version 1.3.2369", - { - {"xlanguage_en.dcp", 0, "64b6fa7eedc09c231f6ce046e77fee05", 11339619}, - {"data.dcp", 0, "aecb5deeea7b0baa871fbd0cef35a648", 254219204}, - AD_LISTEND - }, - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("reversion1", "Version 1.3.2369", + WME_ENTRY2s("xlanguage_en.dcp", "64b6fa7eedc09c231f6ce046e77fee05", 11339619, + "data.dcp", "aecb5deeea7b0baa871fbd0cef35a648", 254219204), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Reversion: The Escape Version 1.3.2369 (French) - { - "reversion1", - "Version 1.3.2369", - { - {"xlanguage_fr.dcp", 0, "d561d562224afea809153a1fd9fdb0c0", 11963210}, - {"data.dcp", 0, "aecb5deeea7b0baa871fbd0cef35a648", 254219204}, - AD_LISTEND - }, - Common::FR_FRA, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("reversion1", "Version 1.3.2369", + WME_ENTRY2s("xlanguage_fr.dcp", "d561d562224afea809153a1fd9fdb0c0", 11963210, + "data.dcp", "aecb5deeea7b0baa871fbd0cef35a648", 254219204), Common::FR_FRA, ADGF_UNSTABLE, LATEST_VERSION), // Reversion: The Escape Version 1.3.2369 (German) - { - "reversion1", - "Version 1.3.2369", - { - {"xlanguage_de.dcp", 0, "4e3f614c36bd6bae74b8cc83e663a8f0", 14040310}, - {"data.dcp", 0, "aecb5deeea7b0baa871fbd0cef35a648", 254219204}, - AD_LISTEND - }, - Common::DE_DEU, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("reversion1", "Version 1.3.2369", + WME_ENTRY2s("xlanguage_de.dcp", "4e3f614c36bd6bae74b8cc83e663a8f0", 14040310, + "data.dcp", "aecb5deeea7b0baa871fbd0cef35a648", 254219204), Common::DE_DEU, ADGF_UNSTABLE, LATEST_VERSION), // Reversion: The Escape Version 1.3.2369 (Italian) - { - "reversion1", - "Version 1.3.2369", - { - {"xlanguage_it.dcp", 0, "10d09b7fe61946f09dd91d5e8d090f94", 11913752}, - {"data.dcp", 0, "aecb5deeea7b0baa871fbd0cef35a648", 254219204}, - AD_LISTEND - }, - Common::IT_ITA, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("reversion1", "Version 1.3.2369", + WME_ENTRY2s("xlanguage_it.dcp", "10d09b7fe61946f09dd91d5e8d090f94", 11913752, + "data.dcp", "aecb5deeea7b0baa871fbd0cef35a648", 254219204), Common::IT_ITA, ADGF_UNSTABLE, LATEST_VERSION), // Reversion: The Escape Version 1.3.2369 (Latvian) - { - "reversion1", - "Version 1.3.2369", - { - {"xlanguage_lv.dcp", 0, "704359ab5040b0dab6545064d7aa6eb9", 11414925}, - {"data.dcp", 0, "aecb5deeea7b0baa871fbd0cef35a648", 254219204}, - AD_LISTEND - }, - Common::LV_LAT, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("reversion1", "Version 1.3.2369", + WME_ENTRY2s("xlanguage_lv.dcp", "704359ab5040b0dab6545064d7aa6eb9", 11414925, + "data.dcp", "aecb5deeea7b0baa871fbd0cef35a648", 254219204), Common::LV_LAT, ADGF_UNSTABLE, LATEST_VERSION), // Reversion: The Escape Version 1.3.2369 (Polish) - { - "reversion1", - "Version 1.3.2369", - { - {"xlanguage_pl.dcp", 0, "c4ad33f57e1e998169552d521c1d6638", 11532215}, - {"data.dcp", 0, "aecb5deeea7b0baa871fbd0cef35a648", 254219204}, - AD_LISTEND - }, - Common::PL_POL, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("reversion1", "Version 1.3.2369", + WME_ENTRY2s("xlanguage_pl.dcp", "c4ad33f57e1e998169552d521c1d6638", 11532215, + "data.dcp", "aecb5deeea7b0baa871fbd0cef35a648", 254219204), Common::PL_POL, ADGF_UNSTABLE, LATEST_VERSION), // Reversion: The Escape Version 1.3.2369 (Portuguese) - { - "reversion1", - "Version 1.3.2369", - { - {"xlanguage_pt.dcp", 0, "886886b6b14aadac844078de856799a6", 10620797}, - {"data.dcp", 0, "aecb5deeea7b0baa871fbd0cef35a648", 254219204}, - AD_LISTEND - }, - Common::PT_BRA, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("reversion1", "Version 1.3.2369", + WME_ENTRY2s("xlanguage_pt.dcp", "886886b6b14aadac844078de856799a6", 10620797, + "data.dcp", "aecb5deeea7b0baa871fbd0cef35a648", 254219204), Common::PT_BRA, ADGF_UNSTABLE, LATEST_VERSION), // Reversion: The Meeting (Chinese) - { - "reversion2", - "", - { - {"xlanguage_nz.dcp", 0, "8c3709474a87a7876109025dff41ff3f", 8746015}, - {"data.dcp", 0, "cb9865dc7e1db2990a8cf4bc13cf4999", 257643032}, - AD_LISTEND - }, - Common::ZH_CNA, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("reversion2", "", + WME_ENTRY2s("xlanguage_nz.dcp", "8c3709474a87a7876109025dff41ff3f", 8746015, + "data.dcp", "cb9865dc7e1db2990a8cf4bc13cf4999", 257643032), Common::ZH_CNA, ADGF_UNSTABLE, LATEST_VERSION), // Reversion: The Meeting (English) - { - "reversion2", - "", - { - {"xlanguage_en.dcp", 0, "ca357d86618d1ab76a21c913f4403cbd", 8414976}, - {"data.dcp", 0, "f7938cbfdc48f07934550245a3286921", 255672016}, - AD_LISTEND - }, - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("reversion2", "", + WME_ENTRY2s("xlanguage_en.dcp", "ca357d86618d1ab76a21c913f4403cbd", 8414976, + "data.dcp", "f7938cbfdc48f07934550245a3286921", 255672016), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Reversion: The Meeting (Spanish) - { - "reversion2", - "", - AD_ENTRY1s("data.dcp", "f7938cbfdc48f07934550245a3286921", 255672016), - Common::ES_ESP, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("reversion2", "", + WME_ENTRY1s("data.dcp", "f7938cbfdc48f07934550245a3286921", 255672016), Common::ES_ESP, ADGF_UNSTABLE, LATEST_VERSION), // Reversion: The Meeting Version 2.0.2412 (Chinese) - { - "reversion2", - "Version 2.0.2412", - { - {"data.dcp", 0, "f4ffc4df24b7bebad56a24930f33a2bc", 255766600}, - {"xlanguage_nz.dcp", 0, "17c79af4928e24484bee77a7e807cc2a", 10737127}, - {"Linux.dcp", 0, "21858bd77dc86b03f701fd47900e2f51", 984535}, - AD_LISTEND - }, - Common::ZH_CNA, - Common::kPlatformLinux, - ADGF_UNSTABLE, - GUIO0() - }, + WME_PLATENTRY("reversion2", "Version 2.0.2412", + WME_ENTRY3s("data.dcp", "f4ffc4df24b7bebad56a24930f33a2bc", 255766600, + "xlanguage_nz.dcp", "17c79af4928e24484bee77a7e807cc2a", 10737127, + "Linux.dcp", "21858bd77dc86b03f701fd47900e2f51", 984535), Common::ZH_CNA, Common::kPlatformLinux, ADGF_UNSTABLE, LATEST_VERSION), // Reversion: The Meeting Version 2.0.2412 (English) - { - "reversion2", - "Version 2.0.2412", - { - {"data.dcp", 0, "f4ffc4df24b7bebad56a24930f33a2bc", 255766600}, - {"xlanguage_en.dcp", 0, "0598bf752ce93b42bcaf1094df537c7b", 8533057}, - {"Linux.dcp", 0, "21858bd77dc86b03f701fd47900e2f51", 984535}, - AD_LISTEND - }, - Common::EN_ANY, - Common::kPlatformLinux, - ADGF_UNSTABLE, - GUIO0() - }, + WME_PLATENTRY("reversion2", "Version 2.0.2412", + WME_ENTRY3s("data.dcp", "f4ffc4df24b7bebad56a24930f33a2bc", 255766600, + "xlanguage_en.dcp", "0598bf752ce93b42bcaf1094df537c7b", 8533057, + "Linux.dcp", "21858bd77dc86b03f701fd47900e2f51", 984535), Common::EN_ANY, Common::kPlatformLinux, ADGF_UNSTABLE, LATEST_VERSION), // Rhiannon: Curse of the four Branches - { - "rhiannon", - "", - AD_ENTRY1s("data.dcp", "870f348900b735f1cc79c0608ce32b0e", 1046169851), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("rhiannon", "", + WME_ENTRY1s("data.dcp", "870f348900b735f1cc79c0608ce32b0e", 1046169851), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Rhiannon: Curse of the four Branches (English PC DVD) - { - "rhiannon", - "DVD", - AD_ENTRY1s("data.dcp", "6736bbc921bb6ce5161b3ad095a97bd4", 1053441028), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("rhiannon", "DVD", + WME_ENTRY1s("data.dcp", "6736bbc921bb6ce5161b3ad095a97bd4", 1053441028), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // 1 1/2 Ritter: Auf der Suche nach der hinreissenden Herzelinde - { - "ritter", - "", - AD_ENTRY1s("data.dcp", "5ac416cee605d3a30f4d59687b1cdab2", 364260278), - Common::DE_DEU, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("ritter", "", + WME_ENTRY1s("data.dcp", "5ac416cee605d3a30f4d59687b1cdab2", 364260278), Common::DE_DEU, ADGF_UNSTABLE, LATEST_VERSION), // Satan and Son - { - "satanandson", - "", - AD_ENTRY1s("data.dcp", "16a6ba8174b697bbba9299619d1e20c4", 67539054), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE | - ADGF_DEMO, - GUIO0() - }, + WME_WINENTRY("satanandson", "", + WME_ENTRY1s("data.dcp", "16a6ba8174b697bbba9299619d1e20c4", 67539054), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION), // Rosemary - { - "rosemary", - "", - AD_ENTRY1s("data.dcp", "4f2631138bd4d27587d9043f8aeff3df", 29483643), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("rosemary", "", + WME_ENTRY1s("data.dcp", "4f2631138bd4d27587d9043f8aeff3df", 29483643), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Securanote - { - "securanote", - "", - AD_ENTRY1s("data.dcp", "5213d3e59b9e95b7fbd5c56f7de5341a", 2625554), - Common::EN_ANY, - Common::kPlatformIOS, - ADGF_UNSTABLE, - GUIO0() - }, + WME_PLATENTRY("securanote", "", + WME_ENTRY1s("data.dcp", "5213d3e59b9e95b7fbd5c56f7de5341a", 2625554), Common::EN_ANY, Common::kPlatformIOS, ADGF_UNSTABLE, LATEST_VERSION), // Shaban - { - "shaban", - "", - AD_ENTRY1s("data.dcp", "35f702ca9baabc5c620e0be230195c8a", 755388466), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("shaban", "", + WME_ENTRY1s("data.dcp", "35f702ca9baabc5c620e0be230195c8a", 755388466), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // The Shine of a Star - { - "shinestar", - "", - AD_ENTRY1s("data.dcp", "f05abe9e2427a5e4f73648fa09c4ba8e", 94113060), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("shinestar", "", + WME_ENTRY1s("data.dcp", "f05abe9e2427a5e4f73648fa09c4ba8e", 94113060), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Sofia's Debt - { - "sofiasdebt", - "", - AD_ENTRY1s("SD.exe", "e9515f9ba1a2925bb6733476a826a650", 9915047), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("sofiasdebt", "", + WME_ENTRY1s("SD.exe", "e9515f9ba1a2925bb6733476a826a650", 9915047), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Space Invaders (Demo) - { - "spaceinvaders", - "Demo", - AD_ENTRY1s("data.dcp", "3f27adefdf72f2c1601cf555c80a509f", 1308361), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE | - ADGF_DEMO, - GUIO0() - }, + WME_WINENTRY("spaceinvaders", "Demo", + WME_ENTRY1s("data.dcp", "3f27adefdf72f2c1601cf555c80a509f", 1308361), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION), // Space Madness - { - "spacemadness", - "1.0.2", - AD_ENTRY1s("data.dcp", "b9b83135dc7a9e1b4b5f50195dbeb630", 39546622), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("spacemadness", "1.0.2", + WME_ENTRY1s("data.dcp", "b9b83135dc7a9e1b4b5f50195dbeb630", 39546622), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // The Ancient Mark - Episode 1 - { - "theancientmark1", - "", - AD_ENTRY1s("data.dcp", "ca04c26f03b2bd307368b306b297ddd7", 364664692), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("theancientmark1", "", + WME_ENTRY1s("data.dcp", "ca04c26f03b2bd307368b306b297ddd7", 364664692), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // The Box - { - "thebox", - "", - AD_ENTRY1s("data.dcp", "ec5f0c7e8174e307701447b53afe7e2f", 108372483), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("thebox", "", + WME_ENTRY1s("data.dcp", "ec5f0c7e8174e307701447b53afe7e2f", 108372483), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // The Kite (Version 1.1) - { - "thekite", - "Version 1.1", - AD_ENTRY1s("data.dcp", "92d29428f464469bda2d81b03d4d5c3e", 47332296), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("thekite", "Version 1.1", + WME_ENTRY1s("data.dcp", "92d29428f464469bda2d81b03d4d5c3e", 47332296), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // The Kite (Version 1.2.e) - { - "thekite", - "Version 1.2.e", - AD_ENTRY1s("data.dcp", "92451578b1bdd2b32a1db592a4f6d5fc", 47360539), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("thekite", "Version 1.2.e", + WME_ENTRY1s("data.dcp", "92451578b1bdd2b32a1db592a4f6d5fc", 47360539), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // The Kite (Version 1.2.i) (Italian) - { - "thekite", - "Version 1.2.i", - AD_ENTRY1s("data.dcp", "d3435b106a1b3b4c1df8ad596d271586", 47509274), - Common::IT_ITA, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("thekite", "Version 1.2.i", + WME_ENTRY1s("data.dcp", "d3435b106a1b3b4c1df8ad596d271586", 47509274), Common::IT_ITA, ADGF_UNSTABLE, LATEST_VERSION), // The Kite (Version 1.2.r) (Russian) - { - "thekite", - "Version 1.2.r", - AD_ENTRY1s("data.dcp", "d531e097dd884737469da014ed882cde", 47554582 ), - Common::RU_RUS, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("thekite", "Version 1.2.r", + WME_ENTRY1s("data.dcp", "d531e097dd884737469da014ed882cde", 47554582 ), Common::RU_RUS, ADGF_UNSTABLE, LATEST_VERSION), // The Kite (Version 1.3.e) - { - "thekite", - "Version 1.3.e", - AD_ENTRY1s("data.dcp", "9761827b51370263b7623721545d7627", 47382987), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("thekite", "Version 1.3.e", + WME_ENTRY1s("data.dcp", "9761827b51370263b7623721545d7627", 47382987), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Fairy Tales About Toshechka and Boshechka - { - "tib", - "", - AD_ENTRY1s("data.dcp", "87d296ef3f46570ed18f000d3885db77", 340264526), - Common::RU_RUS, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("tib", "", + WME_ENTRY1s("data.dcp", "87d296ef3f46570ed18f000d3885db77", 340264526), Common::RU_RUS, ADGF_UNSTABLE, LATEST_VERSION), // The Trader of Stories - { - "tradestory", - "Demo", - AD_ENTRY1s("data.dcp", "0a0b51191636cc8ead89b905281c3218", 40401902), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE | - ADGF_DEMO, - GUIO0() - }, + WME_WINENTRY("tradestory", "Demo", + WME_ENTRY1s("data.dcp", "0a0b51191636cc8ead89b905281c3218", 40401902), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION), // the white chamber (multi-language) - { - "twc", - "", - AD_ENTRY1s("data.dcp", "0011d01142547c61e51ba24dc42b579e", 186451273), - Common::UNK_LANG, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("twc", "", + WME_ENTRY1s("data.dcp", "0011d01142547c61e51ba24dc42b579e", 186451273), Common::UNK_LANG, ADGF_UNSTABLE, LATEST_VERSION), // Vsevolod Prologue (Demo) - { - "vsevolod", - "Prologue", - AD_ENTRY1s("data.dcp", "f2dcffd2692dbfcc9371fa1a87970fe7", 388669493), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE | - ADGF_DEMO, - GUIO0() - }, + WME_WINENTRY("vsevolod", "Prologue", + WME_ENTRY1s("data.dcp", "f2dcffd2692dbfcc9371fa1a87970fe7", 388669493), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION), // War - { - "war", - "", - AD_ENTRY1s("data.dcp", "003e317cda6d0137bbd5e5d7f089ee4d", 32591890), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("war", "", + WME_ENTRY1s("data.dcp", "003e317cda6d0137bbd5e5d7f089ee4d", 32591890), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Wilma Tetris - { - "wtetris", - "", - AD_ENTRY1s("data.dcp", "946e3a0496e6c12fb344c9ed861ff015", 2780093), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, + WME_WINENTRY("wtetris", "", + WME_ENTRY1s("data.dcp", "946e3a0496e6c12fb344c9ed861ff015", 2780093), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Zilm: A Game of Reflex 1.0 + WME_WINENTRY("Zilm", "1.0", + WME_ENTRY1s("data.dcp", "098dffaf03d8adbb4cb5633e4733e63c", 351726), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), { - "Zilm", - "1.0", - AD_ENTRY1s("data.dcp", "098dffaf03d8adbb4cb5633e4733e63c", 351726), - Common::EN_ANY, - Common::kPlatformWindows, - ADGF_UNSTABLE, - GUIO0() - }, - AD_TABLE_END_MARKER + AD_TABLE_END_MARKER, + LATEST_VERSION + } }; } // End of namespace Wintermute +#undef WEM_ENTRY1s +#undef WEM_ENTRY2s +#undef WEM_ENTRY3s +#undef WME_WINENTRY +#undef WME_PLATENTRY + diff --git a/engines/wintermute/game_description.h b/engines/wintermute/game_description.h new file mode 100644 index 0000000000..313fff8bbf --- /dev/null +++ b/engines/wintermute/game_description.h @@ -0,0 +1,53 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef WINTERMUTE_GAME_DESCRIPTION_H +#define WINTERMUTE_GAME_DESCRIPTION_H + +#include "engines/advancedDetector.h" + +namespace Wintermute { + +enum WMETargetExecutable { + OLDEST_VERSION, + WME_1_0_0, + WME_1_1_0, + WME_1_2_0, + WME_1_3_0, + WME_1_4_0, + WME_1_5_0, + WME_1_6_0, + WME_1_7_0, + WME_1_8_0, + WME_1_8_6, + WME_1_9_0, + LATEST_VERSION +}; + +struct WMEGameDescription { + ADGameDescription adDesc; + WMETargetExecutable targetExecutable; +}; + +} + +#endif /* WINTERMUTE_GAME_DESCRIPTION_H_ */ diff --git a/engines/wintermute/math/rect32.h b/engines/wintermute/math/rect32.h index 93b5c68a30..00326d6747 100644 --- a/engines/wintermute/math/rect32.h +++ b/engines/wintermute/math/rect32.h @@ -50,7 +50,7 @@ struct Point32 { y -= delta.y; return *this; } - + operator FloatPoint() { return FloatPoint(x,y); } diff --git a/engines/wintermute/module.mk b/engines/wintermute/module.mk index 1b6c52e0b7..4c95314a02 100644 --- a/engines/wintermute/module.mk +++ b/engines/wintermute/module.mk @@ -108,7 +108,9 @@ MODULE_OBJS := \ utils/path_util.o \ utils/string_util.o \ utils/utils.o \ + video/subtitle_card.o \ video/video_player.o \ + video/video_subtitler.o \ video/video_theora_player.o \ debugger.o \ wintermute.o \ diff --git a/engines/wintermute/video/subtitle_card.cpp b/engines/wintermute/video/subtitle_card.cpp new file mode 100644 index 0000000000..5d882502fd --- /dev/null +++ b/engines/wintermute/video/subtitle_card.cpp @@ -0,0 +1,56 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* + * This file is based on Wintermute Engine + * http://dead-code.org/redir.php?target=wme + * Copyright (c) 2011 Jan Nedoma + */ + +#include "engines/wintermute/video/subtitle_card.h" +#include "engines/wintermute/base/base_game.h" + +namespace Wintermute { + +SubtitleCard::SubtitleCard(BaseGame *inGame, + const Common::String &text, + const uint &startFrame, + const uint &endFrame) : _gameRef(inGame), + _startFrame(startFrame), + _endFrame(endFrame) { + _text = text; + _gameRef->expandStringByStringTable(_text); +} + +uint32 SubtitleCard::getStartFrame() const { + return _startFrame; +} + +uint32 SubtitleCard::getEndFrame() const { + return _endFrame; +} + +Common::String SubtitleCard::getText() const { + return _text; +} + +} // End of namespace Wintermute diff --git a/engines/wintermute/video/subtitle_card.h b/engines/wintermute/video/subtitle_card.h new file mode 100644 index 0000000000..629df77287 --- /dev/null +++ b/engines/wintermute/video/subtitle_card.h @@ -0,0 +1,53 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* + * This file is based on Wintermute Engine + * http://dead-code.org/redir.php?target=wme + * Copyright (c) 2011 Jan Nedoma + */ + +#ifndef WINTERMUTE_SUBTITLECARD_H +#define WINTERMUTE_SUBTITLECARD_H + +#include "common/str.h" + +namespace Wintermute { + +class BaseGame; + +class SubtitleCard { +public: + SubtitleCard(BaseGame *inGame, const Common::String &text, const uint &startFrame, const uint &endFrame); + uint32 getEndFrame() const; + uint32 getStartFrame() const; + Common::String getText() const; +private: + BaseGame *_gameRef; + uint32 _endFrame; + uint32 _startFrame; + Common::String _text; +}; + +} // End of namespace Wintermute + +#endif diff --git a/engines/wintermute/video/video_subtitler.cpp b/engines/wintermute/video/video_subtitler.cpp new file mode 100644 index 0000000000..95d938574b --- /dev/null +++ b/engines/wintermute/video/video_subtitler.cpp @@ -0,0 +1,266 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* + * This file is based on Wintermute Engine + * http://dead-code.org/redir.php?target=wme + * Copyright (c) 2011 Jan Nedoma + */ + +#include "engines/wintermute/video/video_subtitler.h" +#include "engines/wintermute/base/base_file_manager.h" +#include "engines/wintermute/utils/path_util.h" +#include "engines/wintermute/base/font/base_font.h" +#include "engines/wintermute/base/base_game.h" +#include "engines/wintermute/base/gfx/base_renderer.h" + +namespace Wintermute { + +VideoSubtitler::VideoSubtitler(BaseGame *inGame): BaseClass(inGame) { + _lastSample = -1; + _currentSubtitle = 0; + _showSubtitle = false; +} + +VideoSubtitler::~VideoSubtitler(void) { + _subtitles.clear(); +} + +bool VideoSubtitler::loadSubtitles(const Common::String &filename, const Common::String &subtitleFile) { + if (filename.size() == 0) { + return false; + } + + _subtitles.clear(); + + _lastSample = -1; + _currentSubtitle = 0; + _showSubtitle = false; + + Common::String newFile; + + /* + * Okay, the expected behaviour is this: either we are + * provided with a subtitle file to use by the script when + * calling PlayTheora(), or we try to autodetect a suitable + * one which, for /some/path/movie/ogg is to be called + * /some/path/movie.sub + */ + if (subtitleFile.size() != 0) { + newFile = subtitleFile; + } else { + Common::String path = PathUtil::getDirectoryName(filename); + Common::String name = PathUtil::getFileNameWithoutExtension(filename); + Common::String ext = ".SUB"; + newFile = PathUtil::combine(path, name + ext); + } + + Common::SeekableReadStream *file = BaseFileManager::getEngineInstance()->openFile(newFile, true, false); + + if (file == nullptr) { + return false; // no subtitles + } + + int fileSize = file->size(); + char *buffer = new char[fileSize]; + + file->read(buffer, fileSize); + + /* This is where we parse .sub files. + * Subtitles cards are in the form + * {StartFrame}{EndFrame} FirstLine | SecondLine \n + */ + int pos = 0; + + while (pos < fileSize) { + char *tokenStart = 0; + int tokenLength = 0; + int tokenPos = -1; + int lineLength = 0; + int start = -1; + int end = -1; + bool inToken = false; + + while (pos + lineLength < fileSize && + buffer[pos + lineLength] != '\n' && + buffer[pos + lineLength] != '\0') { + // Measure the line until we hit EOL, EOS or just hit the boundary + lineLength++; + } + + int realLength; + + if (pos + lineLength >= fileSize) { + realLength = lineLength - 0; + } else { + // If we got here the above loop exited after hitting "\0" "\n" + realLength = lineLength - 1; + } + + Common::String cardText; + char *fileLine = (char *)&buffer[pos]; + + for (int i = 0; i < realLength; i++) { + if (fileLine[i] == '{') { + if (!inToken) { + // We've hit the start of a Start/EndFrame token + inToken = true; + tokenStart = fileLine + i + 1; + tokenLength = 0; + tokenPos++; + } else { + // Actually, we were already inside an (invalid) one. + tokenLength++; + } + } else if (fileLine[i] == '}') { + if (inToken) { + // we were /inside/ a {.*} token, so this is the end of the block + inToken = false; + char *token = new char[tokenLength + 1]; + strncpy(token, tokenStart, tokenLength); + token[tokenLength] = '\0'; + if (tokenPos == 0) { + // Was this StartFrame... + start = atoi(token); + } else if (tokenPos == 1) { + // Or the EndFrame? + end = atoi(token); + } + delete[] token; + } else { + // This char is part of the plain text, just append it + cardText += fileLine[i]; + } + } else { + if (inToken) { + tokenLength++; + } else { + if (fileLine[i] == '|') { + // The pipe character signals a linebreak in the text + cardText += '\n'; + } else { + // This char is part of the plain text, just append it + cardText += fileLine[i]; + } + } + } + } + + if (start != -1 && cardText.size() > 0 && (start != 1 || end != 1)){ + // Add a subtitlecard based on the line we have just parsed + _subtitles.push_back(SubtitleCard(_gameRef, cardText, start, end)); + } + + pos += lineLength + 1; + } + + delete[] buffer; + // Succeeded loading subtitles! + + return true; +} + +void VideoSubtitler::display() { + if (_showSubtitle) { + + BaseFont *font; + + if (_gameRef->getVideoFont() == nullptr) { + font = _gameRef->getSystemFont(); + } else { + font = _gameRef->getVideoFont(); + } + + int textHeight = font->getTextHeight( + (const byte *)_subtitles[_currentSubtitle].getText().c_str(), + _gameRef->_renderer->getWidth()); + + font->drawText( + (const byte *)_subtitles[_currentSubtitle].getText().c_str(), + 0, + (_gameRef->_renderer->getHeight() - textHeight - 5), + (_gameRef->_renderer->getWidth()), + TAL_CENTER); + } +} + +void VideoSubtitler::update(uint32 frame) { + if (_subtitles.size() == 0) { + // Edge case: we have loaded subtitles early on... from a blank file. + return; + } + + if ((int32)frame != _lastSample) { + /* + * If the frame count hasn't advanced the previous state still matches + * the current frame (obviously). + */ + + _lastSample = frame; + // Otherwise, we update _lastSample; see above. + + _showSubtitle = false; + + bool overdue = (frame > _subtitles[_currentSubtitle].getEndFrame()); + bool hasNext = (_currentSubtitle + 1 < _subtitles.size()); + bool nextStarted = false; + if (hasNext) { + nextStarted = (_subtitles[_currentSubtitle + 1].getStartFrame() <= frame); + } + + while (_currentSubtitle < _subtitles.size() && + overdue && hasNext && nextStarted) { + /* + * We advance until we get past all overdue subtitles. + * We should exit the cycle when we either reach the first + * subtitle which is not overdue whose subsequent subtitle + * has not started yet (aka the one we must display now or + * the one which WILL be displayed when its time comes) + * and / or when we reach the last one. + */ + + _currentSubtitle++; + + overdue = (frame > _subtitles[_currentSubtitle].getEndFrame()); + hasNext = (_currentSubtitle + 1 < _subtitles.size()); + if (hasNext) { + nextStarted = (_subtitles[_currentSubtitle + 1].getStartFrame() <= frame); + } else { + nextStarted = false; + } + } + + bool currentValid = (_subtitles[_currentSubtitle].getEndFrame() != 0); + /* + * No idea why we do this check, carried over from Mnemonic's code. + * Possibly a workaround for buggy subtitles or some kind of sentinel? :-\ + */ + + bool currentStarted = frame >= _subtitles[_currentSubtitle].getStartFrame(); + + if (currentStarted && !overdue && currentValid) { + _showSubtitle = true; + } + } +} + +} // End of namespace Wintermute diff --git a/engines/wintermute/video/video_subtitler.h b/engines/wintermute/video/video_subtitler.h new file mode 100644 index 0000000000..94f22909a1 --- /dev/null +++ b/engines/wintermute/video/video_subtitler.h @@ -0,0 +1,53 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* + * This file is based on Wintermute Engine + * http://dead-code.org/redir.php?target=wme + * Copyright (c) 2011 Jan Nedoma + */ + +#ifndef WINTERMUTE_VIDSUBTITLER_H +#define WINTERMUTE_VIDSUBTITLER_H + +#include "engines/wintermute/base/base.h" +#include "engines/wintermute/video/subtitle_card.h" + +namespace Wintermute { + +class VideoSubtitler : public BaseClass { +public: + VideoSubtitler(BaseGame *inGame); + virtual ~VideoSubtitler(void); + bool loadSubtitles(const Common::String &filename, const Common::String &subtitleFile); + void display(); + void update(uint32 frame); +private: + Common::Array<SubtitleCard> _subtitles; + int32 _lastSample; + bool _showSubtitle; + uint32 _currentSubtitle; +}; + +} // End of namespace Wintermute + +#endif diff --git a/engines/wintermute/video/video_theora_player.cpp b/engines/wintermute/video/video_theora_player.cpp index e1553580ec..22c235c848 100644 --- a/engines/wintermute/video/video_theora_player.cpp +++ b/engines/wintermute/video/video_theora_player.cpp @@ -85,14 +85,14 @@ void VideoTheoraPlayer::SetDefaults() { _volume = 100; _theoraDecoder = nullptr; - // TODO: Add subtitles-support - //_subtitler = nullptr; + _subtitler = new VideoSubtitler(_gameRef); + _foundSubtitles = false; } ////////////////////////////////////////////////////////////////////////// VideoTheoraPlayer::~VideoTheoraPlayer(void) { cleanup(); -// SAFE_DELETE(_subtitler); + delete _subtitler; } ////////////////////////////////////////////////////////////////////////// @@ -130,6 +130,9 @@ bool VideoTheoraPlayer::initialize(const Common::String &filename, const Common: warning("VideoTheoraPlayer::initialize - Theora support not compiled in, video will be skipped: %s", filename.c_str()); return STATUS_FAILED; #endif + + _foundSubtitles = _subtitler->loadSubtitles(_filename, subtitleFile); + _theoraDecoder->loadStream(_file); if (!_theoraDecoder->isVideoLoaded()) { @@ -214,7 +217,10 @@ bool VideoTheoraPlayer::play(TVideoPlayback type, int x, int y, bool freezeGame, _state = THEORA_STATE_PLAYING; _looping = looping; _playbackType = type; - + if (_subtitler && _foundSubtitles && _gameRef->_subtitles) { + _subtitler->update(_theoraDecoder->getFrameCount()); + _subtitler->display(); + } _startTime = startTime; _volume = volume; _posX = x; @@ -256,7 +262,7 @@ bool VideoTheoraPlayer::play(TVideoPlayback type, int x, int y, bool freezeGame, #if 0 // Stubbed for now as theora isn't seekable if (StartTime) SeekToTime(StartTime); - Update(); + update(); #endif return STATUS_FAILED; } @@ -289,6 +295,10 @@ bool VideoTheoraPlayer::update() { } if (_theoraDecoder) { + if (_subtitler && _foundSubtitles && _gameRef->_subtitles) { + _subtitler->update(_theoraDecoder->getCurFrame()); + } + if (_theoraDecoder->endOfVideo() && _looping) { warning("Should loop movie %s, hacked for now", _filename.c_str()); _theoraDecoder->rewind(); @@ -412,11 +422,10 @@ bool VideoTheoraPlayer::display(uint32 alpha) { } else { res = STATUS_FAILED; } - // TODO: Add subtitles-support -/* if (m_Subtitler && _gameRef->m_VideoSubtitles) { - m_Subtitler->display(); - }*/ + if (_subtitler && _foundSubtitles && _gameRef->_subtitles) { + _subtitler->display(); + } return res; } diff --git a/engines/wintermute/video/video_theora_player.h b/engines/wintermute/video/video_theora_player.h index 8274a1444f..0b9b3d487a 100644 --- a/engines/wintermute/video/video_theora_player.h +++ b/engines/wintermute/video/video_theora_player.h @@ -31,6 +31,7 @@ #include "engines/wintermute/base/base.h" #include "engines/wintermute/persistent.h" +#include "engines/wintermute/video/video_subtitler.h" #include "video/video_decoder.h" #include "common/stream.h" #include "graphics/surface.h" @@ -59,7 +60,7 @@ public: Common::String _filename; BaseSurface *_texture; - //CVidSubtitler *_subtitler; + VideoSubtitler *_subtitler; // control methods bool initialize(const Common::String &filename, const Common::String &subtitleFile = Common::String()); @@ -137,9 +138,10 @@ private: bool _playbackStarted; + bool _foundSubtitles; + // helpers void SetDefaults(); - }; } // End of namespace Wintermute diff --git a/engines/wintermute/wintermute.cpp b/engines/wintermute/wintermute.cpp index 81b6e53c9f..e35bb60c3d 100644 --- a/engines/wintermute/wintermute.cpp +++ b/engines/wintermute/wintermute.cpp @@ -53,7 +53,7 @@ WintermuteEngine::WintermuteEngine() : Engine(g_system) { _gameDescription = nullptr; } -WintermuteEngine::WintermuteEngine(OSystem *syst, const ADGameDescription *desc) +WintermuteEngine::WintermuteEngine(OSystem *syst, const WMEGameDescription *desc) : Engine(syst), _gameDescription(desc) { // Put your engine in a sane state, but do nothing big yet; // in particular, do not load data from files; rather, if you @@ -133,7 +133,7 @@ Common::Error WintermuteEngine::run() { } int WintermuteEngine::init() { - BaseEngine::createInstance(_targetName, _gameDescription->gameid, _gameDescription->language); + BaseEngine::createInstance(_targetName, _gameDescription->adDesc.gameid, _gameDescription->adDesc.language, _gameDescription->targetExecutable); _game = new AdGame(_targetName); if (!_game) { return 1; diff --git a/engines/wintermute/wintermute.h b/engines/wintermute/wintermute.h index 017809d56a..f8f5fc7deb 100644 --- a/engines/wintermute/wintermute.h +++ b/engines/wintermute/wintermute.h @@ -26,6 +26,7 @@ #include "engines/engine.h" #include "engines/advancedDetector.h" #include "gui/debugger.h" +#include "engines/wintermute/game_description.h" namespace Wintermute { @@ -44,7 +45,7 @@ enum { class WintermuteEngine : public Engine { public: - WintermuteEngine(OSystem *syst, const ADGameDescription *desc); + WintermuteEngine(OSystem *syst, const WMEGameDescription *desc); WintermuteEngine(); ~WintermuteEngine(); @@ -67,7 +68,7 @@ private: int messageLoop(); GUI::Debugger *_debugger; BaseGame *_game; - const ADGameDescription *_gameDescription; + const WMEGameDescription *_gameDescription; friend class Console; }; |