diff options
Diffstat (limited to 'engines/scumm/scumm.cpp')
-rw-r--r-- | engines/scumm/scumm.cpp | 171 |
1 files changed, 140 insertions, 31 deletions
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index 2a14673855..24d676a1ff 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -8,12 +8,12 @@ * 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. @@ -45,25 +45,26 @@ #include "scumm/imuse_digi/dimuse.h" #include "scumm/smush/smush_mixer.h" #include "scumm/smush/smush_player.h" -#include "scumm/player_towns.h" +#include "scumm/players/player_towns.h" #include "scumm/insane/insane.h" #include "scumm/he/animation_he.h" #include "scumm/he/intern_he.h" #include "scumm/he/logic_he.h" #include "scumm/he/sound_he.h" #include "scumm/object.h" -#include "scumm/player_nes.h" -#include "scumm/player_sid.h" -#include "scumm/player_pce.h" -#include "scumm/player_apple2.h" -#include "scumm/player_v1.h" -#include "scumm/player_v2.h" -#include "scumm/player_v2cms.h" -#include "scumm/player_v2a.h" -#include "scumm/player_v3a.h" -#include "scumm/player_v3m.h" -#include "scumm/player_v4a.h" -#include "scumm/player_v5m.h" +#include "scumm/players/player_ad.h" +#include "scumm/players/player_nes.h" +#include "scumm/players/player_sid.h" +#include "scumm/players/player_pce.h" +#include "scumm/players/player_apple2.h" +#include "scumm/players/player_v1.h" +#include "scumm/players/player_v2.h" +#include "scumm/players/player_v2cms.h" +#include "scumm/players/player_v2a.h" +#include "scumm/players/player_v3a.h" +#include "scumm/players/player_v3m.h" +#include "scumm/players/player_v4a.h" +#include "scumm/players/player_v5m.h" #include "scumm/resource.h" #include "scumm/he/resource_he.h" #include "scumm/scumm_v0.h" @@ -204,7 +205,7 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr) _lastInputScriptTime = 0; _bootParam = 0; _dumpScripts = false; - _debugMode = 0; + _debugMode = false; _objectOwnerTable = NULL; _objectRoomTable = NULL; _objectStateTable = NULL; @@ -315,6 +316,7 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr) _NES_lastTalkingActor = 0; _NES_talkColor = 0; _keepText = false; + _msgCount = 0; _costumeLoader = NULL; _costumeRenderer = NULL; _2byteFontPtr = 0; @@ -466,6 +468,8 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr) VAR_NUM_SCRIPT_CYCLES = 0xFF; VAR_SCRIPT_CYCLE = 0xFF; + VAR_QUIT_SCRIPT = 0xFF; + VAR_NUM_GLOBAL_OBJS = 0xFF; // Use g_scumm from error() ONLY @@ -713,7 +717,7 @@ ScummEngine_v2::ScummEngine_v2(OSystem *syst, const DetectorResult &dr) ScummEngine_v0::ScummEngine_v0(OSystem *syst, const DetectorResult &dr) : ScummEngine_v2(syst, dr) { - + _drawDemo = false; _currentMode = 0; _currentLights = 0; @@ -728,6 +732,9 @@ ScummEngine_v0::ScummEngine_v0(OSystem *syst, const DetectorResult &dr) VAR_ACTIVE_OBJECT2 = 0xFF; VAR_IS_SOUND_RUNNING = 0xFF; VAR_ACTIVE_VERB = 0xFF; + + if (strcmp(dr.fp.pattern, "maniacdemo.d64") == 0 ) + _game.features |= GF_DEMO; } ScummEngine_v6::ScummEngine_v6(OSystem *syst, const DetectorResult &dr) @@ -1025,6 +1032,35 @@ Common::Error ScummEngine::init() { } #endif + // Extra directories needed for the Steam versions + if (_filenamePattern.genMethod == kGenDiskNumSteam || _filenamePattern.genMethod == kGenRoomNumSteam) { + if (_game.platform == Common::kPlatformWindows) { + switch (_game.id) { + case GID_INDY3 : + SearchMan.addSubDirectoryMatching(gameDataDir, "indy3"); + break; + case GID_INDY4 : + SearchMan.addSubDirectoryMatching(gameDataDir, "atlantis"); + break; + case GID_LOOM : + SearchMan.addSubDirectoryMatching(gameDataDir, "loom"); + break; +#ifdef ENABLE_SCUMM_7_8 + case GID_DIG : + SearchMan.addSubDirectoryMatching(gameDataDir, "dig"); + SearchMan.addSubDirectoryMatching(gameDataDir, "dig/video"); + break; +#endif + default: + break; + } + } else { + SearchMan.addSubDirectoryMatching(gameDataDir, "Contents"); + SearchMan.addSubDirectoryMatching(gameDataDir, "Contents/MacOS"); + SearchMan.addSubDirectoryMatching(gameDataDir, "Contents/Resources"); + SearchMan.addSubDirectoryMatching(gameDataDir, "Contents/Resources/video"); + } + } // The kGenUnchanged method is only used for 'container files', i.e. files // that contain the real game files bundled together in an archive format. @@ -1059,8 +1095,13 @@ Common::Error ScummEngine::init() { const char *tmpBuf1, *tmpBuf2; assert(_game.id == GID_MANIAC || _game.id == GID_ZAK); if (_game.id == GID_MANIAC) { - tmpBuf1 = "maniac1.d64"; - tmpBuf2 = "maniac2.d64"; + if (_game.features & GF_DEMO) { + tmpBuf1 = "maniacdemo.d64"; + tmpBuf2 = "maniacdemo.d64"; + } else { + tmpBuf1 = "maniac1.d64"; + tmpBuf2 = "maniac2.d64"; + } } else { tmpBuf1 = "zak1.d64"; tmpBuf2 = "zak2.d64"; @@ -1125,15 +1166,30 @@ Common::Error ScummEngine::init() { error("Couldn't find known subfile inside container file '%s'", _containerFile.c_str()); _fileHandle->close(); - } else { error("kGenUnchanged used with unsupported platform"); } } else { - // Regular access, no container file involved - _fileHandle = new ScummFile(); + if (_filenamePattern.genMethod == kGenDiskNumSteam || _filenamePattern.genMethod == kGenRoomNumSteam) { + // Steam game versions have the index file embedded in the main executable + const SteamIndexFile *indexFile = lookUpSteamIndexFile(_filenamePattern.pattern, _game.platform); + if (!indexFile || indexFile->id != _game.id) { + error("Couldn't find index file description for Steam version"); + } else { + _fileHandle = new ScummSteamFile(*indexFile); + } + } else { + // Regular access, no container file involved + _fileHandle = new ScummFile(); + } } + // Steam Win and Mac versions share the same DOS data files. We show Windows or Mac + // for the platform the detector, but internally we force the platform to DOS, so that + // the code for handling the original DOS data files is used. + if (_filenamePattern.genMethod == kGenDiskNumSteam || _filenamePattern.genMethod == kGenRoomNumSteam) + _game.platform = Common::kPlatformDOS; + // Load CJK font, if present // Load it earlier so _useCJKMode variable could be set loadCJKFont(); @@ -1217,7 +1273,7 @@ Common::Error ScummEngine::init() { void ScummEngine::setupScumm() { // On some systems it's not safe to run CD audio games from the CD. - if (_game.features & GF_AUDIOTRACKS) { + if (_game.features & GF_AUDIOTRACKS && !Common::File::exists("CDDA.SOU")) { checkCD(); int cd_num = ConfMan.getInt("cdrom"); @@ -1841,6 +1897,15 @@ void ScummEngine::setupMusic(int midi) { _musicEngine = _townsPlayer = new Player_Towns_v1(this, _mixer); if (!_townsPlayer->init()) error("Failed to initialize FM-Towns audio driver"); + } else if (_game.platform == Common::kPlatformDOS && (_sound->_musicType == MDT_ADLIB) && (_game.id == GID_LOOM || _game.id == GID_INDY3)) { + // For Indy3 DOS and Loom DOS we use an implementation of the original + // AD player when AdLib is selected. This fixes sound effects in those + // games (see for example bug #2027877 "INDY3: Non-Looping Sound + // Effects"). The player itself is also used in Monkey Island DOS + // EGA/VGA. However, we support multi MIDI for that game and we cannot + // support this with the Player_AD code at the moment. The reason here + // is that multi MIDI is supported internally by our iMuse output. + _musicEngine = new Player_AD(this); } else if (_game.version >= 3 && _game.heversion <= 62) { MidiDriver *nativeMidiDriver = 0; MidiDriver *adlibMidiDriver = 0; @@ -2019,6 +2084,7 @@ Common::Error ScummEngine::go() { if (shouldQuit()) { // TODO: Maybe perform an autosave on exit? + runQuitScript(); } } @@ -2271,7 +2337,7 @@ void ScummEngine::scummLoop_updateScummVars() { VAR(VAR_MOUSE_Y) = _mouse.y; if (VAR_DEBUGMODE != 0xFF) { // This is NOT for the Mac version of Indy3/Loom - VAR(VAR_DEBUGMODE) = _debugMode; + VAR(VAR_DEBUGMODE) = (_debugMode ? 1 : 0); } } else if (_game.version >= 1) { // We use shifts below instead of dividing by V12_X_MULTIPLIER resp. @@ -2297,15 +2363,16 @@ void ScummEngine::scummLoop_handleSaveLoad() { if (_game.version == 8 && _saveTemporaryState) VAR(VAR_GAME_LOADED) = 0; + Common::String filename; if (_saveLoadFlag == 1) { - success = saveState(_saveLoadSlot, _saveTemporaryState); + success = saveState(_saveLoadSlot, _saveTemporaryState, filename); if (!success) errMsg = _("Failed to save game state to file:\n\n%s"); if (success && _saveTemporaryState && VAR_GAME_LOADED != 0xFF && _game.version <= 7) VAR(VAR_GAME_LOADED) = 201; } else { - success = loadState(_saveLoadSlot, _saveTemporaryState); + success = loadState(_saveLoadSlot, _saveTemporaryState, filename); if (!success) errMsg = _("Failed to load game state from file:\n\n%s"); @@ -2313,7 +2380,6 @@ void ScummEngine::scummLoop_handleSaveLoad() { VAR(VAR_GAME_LOADED) = (_game.version == 8) ? 1 : 203; } - Common::String filename = makeSavegameName(_saveLoadSlot, _saveTemporaryState); if (!success) { displayMessage(0, errMsg, filename.c_str()); } else if (_saveLoadFlag == 1 && _saveLoadSlot != 0 && !_saveTemporaryState) { @@ -2515,7 +2581,7 @@ void ScummEngine::runBootscript() { int args[NUM_SCRIPT_LOCAL]; memset(args, 0, sizeof(args)); args[0] = _bootParam; - if (_game.id == GID_MANIAC && (_game.features & GF_DEMO)) + if (_game.id == GID_MANIAC && (_game.features & GF_DEMO) && (_game.platform != Common::kPlatformC64)) runScript(9, 0, 0, args); else runScript(1, 0, 0, args); @@ -2532,9 +2598,52 @@ void ScummEngine_v90he::runBootscript() { } #endif -void ScummEngine::startManiac() { - debug(0, "stub startManiac()"); - displayMessage(0, "%s", _("Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' directory inside the Tentacle game directory.")); +bool ScummEngine::startManiac() { + Common::String currentPath = ConfMan.get("path"); + Common::String maniacTarget; + + if (!ConfMan.hasKey("easter_egg")) { + // Look for a game with a game path pointing to a 'Maniac' directory + // as a subdirectory to the current game. + Common::ConfigManager::DomainMap::iterator iter = ConfMan.beginGameDomains(); + for (; iter != ConfMan.endGameDomains(); ++iter) { + Common::ConfigManager::Domain &dom = iter->_value; + Common::String path = dom.getVal("path"); + + if (path.hasPrefix(currentPath)) { + path.erase(0, currentPath.size() + 1); + if (path.equalsIgnoreCase("maniac")) { + maniacTarget = iter->_key; + break; + } + } + } + } else { + maniacTarget = ConfMan.get("easter_egg"); + } + + if (!maniacTarget.empty()) { + // Request a temporary save game to be made. + _saveLoadFlag = 1; + _saveLoadSlot = 100; + _saveTemporaryState = true; + + // Set up the chanined games to Maniac Mansion, and then back + // to the current game again with that save slot. + ChainedGamesMan.push(maniacTarget); + ChainedGamesMan.push(ConfMan.getActiveDomainName(), 100); + + // Force a return to the launcher. This will start the first + // chained game. + Common::EventManager *eventMan = g_system->getEventManager(); + Common::Event event; + event.type = Common::EVENT_RTL; + eventMan->pushEvent(event); + return true; + } else { + displayMessage(0, "%s", _("Usually, Maniac Mansion would start now. But for that to work, the game files for Maniac Mansion have to be in the 'Maniac' directory inside the Tentacle game directory, and the game has to be added to ScummVM.")); + return false; + } } #pragma mark - |