diff options
Diffstat (limited to 'engines/agos')
48 files changed, 821 insertions, 366 deletions
diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp index 4d879909c4..465b6e0786 100644 --- a/engines/agos/agos.cpp +++ b/engines/agos/agos.cpp @@ -24,13 +24,13 @@ #include "common/file.h" #include "common/fs.h" #include "common/textconsole.h" -#include "common/system.h" #include "engines/util.h" #include "agos/debugger.h" #include "agos/intern.h" #include "agos/agos.h" +#include "agos/midi.h" #include "backends/audiocd/audiocd.h" @@ -41,18 +41,51 @@ namespace AGOS { static const GameSpecificSettings simon1_settings = { + "", // base_filename + "", // restore_filename + "", // tbl_filename "EFFECTS", // effects_filename "SIMON", // speech_filename }; static const GameSpecificSettings simon2_settings = { + "", // base_filename + "", // restore_filename + "", // tbl_filename "", // effects_filename "SIMON2", // speech_filename }; -static const GameSpecificSettings puzzlepack_settings = { +static const GameSpecificSettings dimp_settings = { + "Gdimp", // base_filename + "", // restore_filename + "", // tbl_filename "", // effects_filename - "MUSIC", // speech_filename + "MUSIC", // speech_filename +}; + +static const GameSpecificSettings jumble_settings = { + "Gjumble", // base_filename + "", // restore_filename + "", // tbl_filename + "", // effects_filename + "MUSIC", // speech_filename +}; + +static const GameSpecificSettings puzzle_settings = { + "Gpuzzle", // base_filename + "", // restore_filename + "", // tbl_filename + "", // effects_filename + "MUSIC", // speech_filename +}; + +static const GameSpecificSettings swampy_settings = { + "Gswampy", // base_filename + "", // restore_filename + "", // tbl_filename + "", // effects_filename + "MUSIC", // speech_filename }; #ifdef ENABLE_AGOS2 @@ -541,16 +574,18 @@ Common::Error AGOSEngine::init() { initGraphics(_screenWidth, _screenHeight, getGameType() == GType_FF || getGameType() == GType_PP); + _midi = new MidiPlayer(); + if ((getGameType() == GType_SIMON2 && getPlatform() == Common::kPlatformWindows) || (getGameType() == GType_SIMON1 && getPlatform() == Common::kPlatformWindows) || ((getFeatures() & GF_TALKIE) && getPlatform() == Common::kPlatformAcorn) || (getPlatform() == Common::kPlatformPC)) { - int ret = _midi.open(getGameType()); + int ret = _midi->open(getGameType()); if (ret) warning("MIDI Player init failed: \"%s\"", MidiDriver::getErrorName(ret)); - _midi.setVolume(ConfMan.getInt("music_volume"), ConfMan.getInt("sfx_volume")); + _midi->setVolume(ConfMan.getInt("music_volume"), ConfMan.getInt("sfx_volume")); _midiEnabled = true; } @@ -597,14 +632,14 @@ Common::Error AGOSEngine::init() { if (ConfMan.hasKey("music_mute") && ConfMan.getBool("music_mute") == 1) { _musicPaused = true; if (_midiEnabled) { - _midi.pause(_musicPaused); + _midi->pause(_musicPaused); } _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, 0); } if (ConfMan.hasKey("sfx_mute") && ConfMan.getBool("sfx_mute") == 1) { if (getGameId() == GID_SIMON1DOS) - _midi._enable_sfx = !_midi._enable_sfx; + _midi->_enable_sfx = !_midi->_enable_sfx; else { _effectsPaused = !_effectsPaused; _sound->effectsPause(_effectsPaused); @@ -640,14 +675,12 @@ Common::Error AGOSEngine::init() { // TODO: Use special debug levels instead of the following hack. _debugMode = (gDebugLevel >= 0); - if (gDebugLevel == 2) - _dumpOpcodes = true; - if (gDebugLevel == 3) - _dumpVgaOpcodes = true; - if (gDebugLevel == 4) - _dumpScripts = true; - if (gDebugLevel == 5) - _dumpVgaScripts = true; + switch (gDebugLevel) { + case 2: _dumpOpcodes = true; break; + case 3: _dumpVgaOpcodes = true; break; + case 4: _dumpScripts = true; break; + case 5: _dumpVgaScripts = true; break; + } return Common::kNoError; } @@ -678,7 +711,15 @@ static const uint16 initialVideoWindows_PN[20] = { #ifdef ENABLE_AGOS2 void AGOSEngine_PuzzlePack::setupGame() { - gss = &puzzlepack_settings; + if (getGameId() == GID_DIMP) { + gss = &dimp_settings; + } else if (getGameId() == GID_JUMBLE) { + gss = &jumble_settings; + } else if (getGameId() == GID_PUZZLE) { + gss = &puzzle_settings; + } else if (getGameId() == GID_SWAMPY) { + gss = &swampy_settings; + } _numVideoOpcodes = 85; _vgaMemSize = 7500000; _itemMemSize = 20000; @@ -708,7 +749,7 @@ void AGOSEngine_Simon2::setupGame() { _itemMemSize = 20000; _tableMemSize = 100000; // Check whether to use MT-32 MIDI tracks in Simon the Sorcerer 2 - if (getGameType() == GType_SIMON2 && _midi.hasNativeMT32()) + if (getGameType() == GType_SIMON2 && _midi->hasNativeMT32()) _musicIndexBase = (1128 + 612) / 4; else _musicIndexBase = 1128 / 4; @@ -911,6 +952,8 @@ AGOSEngine::~AGOSEngine() { _window6BackScn->free(); delete _window6BackScn; + delete _midi; + free(_firstTimeStruct); free(_pendingDeleteTimeEvent); @@ -938,12 +981,12 @@ void AGOSEngine::pauseEngineIntern(bool pauseIt) { _keyPressed.reset(); _pause = true; - _midi.pause(true); + _midi->pause(true); _mixer->pauseAll(true); } else { _pause = false; - _midi.pause(_musicPaused); + _midi->pause(_musicPaused); _mixer->pauseAll(false); } } @@ -961,6 +1004,10 @@ void AGOSEngine::pause() { } Common::Error AGOSEngine::go() { +#ifdef ENABLE_AGOS2 + loadArchives(); +#endif + loadGamePcFile(); addTimeEvent(0, 1); @@ -1027,7 +1074,7 @@ void AGOSEngine::syncSoundSettings() { int soundVolumeSFX = ConfMan.getInt("sfx_volume"); if (_midiEnabled) - _midi.setVolume((mute ? 0 : soundVolumeMusic), (mute ? 0 : soundVolumeSFX)); + _midi->setVolume((mute ? 0 : soundVolumeMusic), (mute ? 0 : soundVolumeSFX)); } } // End of namespace AGOS diff --git a/engines/agos/agos.h b/engines/agos/agos.h index aa68a05eee..ec979abc20 100644 --- a/engines/agos/agos.h +++ b/engines/agos/agos.h @@ -25,6 +25,7 @@ #include "engines/engine.h" +#include "common/archive.h" #include "common/array.h" #include "common/error.h" #include "common/keyboard.h" @@ -33,7 +34,6 @@ #include "common/stack.h" #include "common/util.h" -#include "agos/midi.h" #include "agos/sound.h" #include "agos/vga.h" @@ -50,6 +50,16 @@ * - Simon the Sorcerer 2 * - Simon the Sorcerer Puzzle Pack */ + +namespace Common { +class File; +class SeekableReadStream; +} + +namespace Graphics { +struct Surface; +} + namespace AGOS { uint fileReadItemID(Common::SeekableReadStream *in); @@ -60,6 +70,8 @@ uint fileReadItemID(Common::SeekableReadStream *in); class MoviePlayer; #endif +class MidiPlayer; + struct Child; struct SubObject; @@ -175,6 +187,22 @@ class Debugger; # define _OPCODE(ver, x) { &ver::x, "" } #endif +class ArchiveMan : public Common::SearchSet { +public: + ArchiveMan(); + + void enableFallback(bool val) { _fallBack = val; } + +#ifdef ENABLE_AGOS2 + void registerArchive(const Common::String &filename, int priority); +#endif + + Common::SeekableReadStream *open(const Common::String &filename); + +private: + bool _fallBack; +}; + class AGOSEngine : public Engine { protected: friend class Debugger; @@ -313,7 +341,7 @@ protected: bool _backFlag; uint16 _debugMode; - uint16 _language; + Common::Language _language; bool _copyProtection; bool _pause; bool _dumpScripts; @@ -548,7 +576,7 @@ protected: byte _lettersToPrintBuf[80]; - MidiPlayer _midi; + MidiPlayer *_midi; bool _midiEnabled; int _vgaTickCounter; @@ -588,6 +616,8 @@ public: AGOSEngine(OSystem *system, const AGOSGameDescription *gd); virtual ~AGOSEngine(); + ArchiveMan _archives; + byte *_curSfxFile; uint32 _curSfxFileSize; uint16 _sampleEnd, _sampleWait; @@ -597,6 +627,10 @@ protected: virtual uint16 readUint16Wrapper(const void *src); virtual uint32 readUint32Wrapper(const void *src); +#ifdef ENABLE_AGOS2 + void loadArchives(); +#endif + int allocGamePcVars(Common::SeekableReadStream *in); void createPlayer(); void allocateStringTable(int num); @@ -781,14 +815,14 @@ protected: void loadTextIntoMem(uint16 stringId); uint loadTextFile(const char *filename, byte *dst); - Common::File *openTablesFile(const char *filename); - void closeTablesFile(Common::File *in); + Common::SeekableReadStream *openTablesFile(const char *filename); + void closeTablesFile(Common::SeekableReadStream *in); uint loadTextFile_simon1(const char *filename, byte *dst); - Common::File *openTablesFile_simon1(const char *filename); + Common::SeekableReadStream *openTablesFile_simon1(const char *filename); uint loadTextFile_gme(const char *filename, byte *dst); - Common::File *openTablesFile_gme(const char *filename); + Common::SeekableReadStream *openTablesFile_gme(const char *filename); void invokeTimeEvent(TimeEvent *te); bool kickoffTimeEvents(); diff --git a/engines/agos/animation.cpp b/engines/agos/animation.cpp index d9a585bd05..b05623525f 100644 --- a/engines/agos/animation.cpp +++ b/engines/agos/animation.cpp @@ -251,8 +251,11 @@ bool MoviePlayerDXA::load() { } Common::String videoName = Common::String::format("%s.dxa", baseName); - if (!loadFile(videoName)) + Common::SeekableReadStream *videoStream = _vm->_archives.open(videoName); + if (!videoStream) error("Failed to load video file %s", videoName.c_str()); + if (!loadStream(videoStream)) + error("Failed to load video stream from file %s", videoName.c_str()); debug(0, "Playing video %s", videoName.c_str()); @@ -412,8 +415,11 @@ MoviePlayerSMK::MoviePlayerSMK(AGOSEngine_Feeble *vm, const char *name) bool MoviePlayerSMK::load() { Common::String videoName = Common::String::format("%s.smk", baseName); - if (!loadFile(videoName)) + Common::SeekableReadStream *videoStream = _vm->_archives.open(videoName); + if (!videoStream) error("Failed to load video file %s", videoName.c_str()); + if (!loadStream(videoStream)) + error("Failed to load video stream from file %s", videoName.c_str()); debug(0, "Playing video %s", videoName.c_str()); diff --git a/engines/agos/charset-fontdata.cpp b/engines/agos/charset-fontdata.cpp index b708b4890b..e6b81f54ee 100644 --- a/engines/agos/charset-fontdata.cpp +++ b/engines/agos/charset-fontdata.cpp @@ -20,8 +20,6 @@ * */ - - #include "common/system.h" #include "common/textconsole.h" @@ -2454,4 +2452,3 @@ void AGOSEngine::windowDrawChar(WindowBlock *window, uint x, uint y, byte chr) { } } // End of namespace AGOS - diff --git a/engines/agos/charset.cpp b/engines/agos/charset.cpp index 9d27afaa27..54aef99a47 100644 --- a/engines/agos/charset.cpp +++ b/engines/agos/charset.cpp @@ -20,8 +20,7 @@ * */ - - +#include "common/endian.h" #include "common/system.h" #include "agos/agos.h" @@ -655,4 +654,3 @@ void AGOSEngine::windowScroll(WindowBlock *window) { _videoLockOut &= ~0x8000; } } // End of namespace AGOS - diff --git a/engines/agos/contain.cpp b/engines/agos/contain.cpp index ba60c65ff3..173194d45e 100644 --- a/engines/agos/contain.cpp +++ b/engines/agos/contain.cpp @@ -20,8 +20,6 @@ * */ - - #include "agos/agos.h" #include "agos/intern.h" diff --git a/engines/agos/cursor.cpp b/engines/agos/cursor.cpp index ef4a1406c9..7c64d68048 100644 --- a/engines/agos/cursor.cpp +++ b/engines/agos/cursor.cpp @@ -20,10 +20,8 @@ * */ - - +#include "common/endian.h" #include "common/events.h" -#include "common/system.h" #include "graphics/cursorman.h" diff --git a/engines/agos/debug.cpp b/engines/agos/debug.cpp index 9c44342975..18c4736031 100644 --- a/engines/agos/debug.cpp +++ b/engines/agos/debug.cpp @@ -22,7 +22,6 @@ // AGOS debug functions - #include "common/file.h" #include "common/textconsole.h" diff --git a/engines/agos/debug.h b/engines/agos/debug.h index fd5908997f..fe14ae4860 100644 --- a/engines/agos/debug.h +++ b/engines/agos/debug.h @@ -2843,4 +2843,3 @@ const char *const feeblefiles_videoOpcodeNameTable[] = { } // End of namespace AGOS #endif - diff --git a/engines/agos/debugger.cpp b/engines/agos/debugger.cpp index a313dbbd1e..fc24c6d363 100644 --- a/engines/agos/debugger.cpp +++ b/engines/agos/debugger.cpp @@ -20,12 +20,11 @@ * */ - - #include "common/config-manager.h" #include "agos/debugger.h" #include "agos/agos.h" +#include "agos/midi.h" namespace AGOS { @@ -58,7 +57,7 @@ bool Debugger::Cmd_DebugLevel(int argc, const char **argv) { DebugPrintf("Debugging is currently set at level %d\n", gDebugLevel); } else { // set level gDebugLevel = atoi(argv[1]); - if (gDebugLevel >= 0 && gDebugLevel < 10) { + if (0 <= gDebugLevel && gDebugLevel < 11) { _vm->_debugMode = true; DebugPrintf("Debug level set to level %d\n", gDebugLevel); } else if (gDebugLevel < 0) { @@ -79,7 +78,7 @@ bool Debugger::Cmd_PlayMusic(int argc, const char **argv) { // TODO } else if (_vm->getGameType() == GType_SIMON2) { _vm->loadMusic(music); - _vm->_midi.startTrack(0); + _vm->_midi->startTrack(0); } else { _vm->playMusic(music, 0); } @@ -287,4 +286,3 @@ bool Debugger::Cmd_dumpScript(int argc, const char **argv) { } } // End of namespace AGOS - diff --git a/engines/agos/detection.cpp b/engines/agos/detection.cpp index 2be888b92a..861aa08851 100644 --- a/engines/agos/detection.cpp +++ b/engines/agos/detection.cpp @@ -240,6 +240,22 @@ Common::Platform AGOSEngine::getPlatform() const { } const char *AGOSEngine::getFileName(int type) const { + // Required if the InstallShield cab is been used + if (getGameType() == GType_PP) { + if (type == GAME_BASEFILE) + return gss->base_filename; + } + + // Required if the InstallShield cab is been used + if (getGameType() == GType_FF && getPlatform() == Common::kPlatformWindows) { + if (type == GAME_BASEFILE) + return gss->base_filename; + if (type == GAME_RESTFILE) + return gss->restore_filename; + if (type == GAME_TBLFILE) + return gss->tbl_filename; + } + for (int i = 0; _gameDescription->desc.filesDescriptions[i].fileType; i++) { if (_gameDescription->desc.filesDescriptions[i].fileType == type) return _gameDescription->desc.filesDescriptions[i].fileName; @@ -247,4 +263,17 @@ const char *AGOSEngine::getFileName(int type) const { return NULL; } +#ifdef ENABLE_AGOS2 +void AGOSEngine::loadArchives() { + const ADGameFileDescription *ag; + + if (getFeatures() & GF_PACKED) { + for (ag = _gameDescription->desc.filesDescriptions; ag->fileName; ag++) { + if (!_archives.hasArchive(ag->fileName)) + _archives.registerArchive(ag->fileName, ag->fileType); + } + } +} +#endif + } // End of namespace AGOS diff --git a/engines/agos/detection_tables.h b/engines/agos/detection_tables.h index a43d581173..a7a384a496 100644 --- a/engines/agos/detection_tables.h +++ b/engines/agos/detection_tables.h @@ -1040,7 +1040,7 @@ static const AGOSGameDescription gameDescriptions[] = { }, Common::EN_ANY, Common::kPlatformAcorn, - ADGF_NO_FLAGS, + ADGF_CD, GUIO_NOSUBTITLES }, @@ -1208,7 +1208,7 @@ static const AGOSGameDescription gameDescriptions[] = { }, Common::EN_ANY, Common::kPlatformAmiga, - ADGF_NO_FLAGS, + ADGF_CD, GUIO_NOSUBTITLES | GUIO_NOMIDI }, @@ -1232,7 +1232,7 @@ static const AGOSGameDescription gameDescriptions[] = { }, Common::EN_ANY, Common::kPlatformAmiga, - ADGF_NO_FLAGS, + ADGF_CD, GUIO_NOSUBTITLES | GUIO_NOMIDI }, @@ -1546,7 +1546,7 @@ static const AGOSGameDescription gameDescriptions[] = { }, Common::EN_ANY, Common::kPlatformPC, - ADGF_NO_FLAGS, + ADGF_CD, GUIO_NOSUBTITLES }, @@ -1571,7 +1571,7 @@ static const AGOSGameDescription gameDescriptions[] = { }, Common::EN_ANY, Common::kPlatformPC, - ADGF_NO_FLAGS, + ADGF_CD, GUIO_NOSUBTITLES }, @@ -1596,7 +1596,7 @@ static const AGOSGameDescription gameDescriptions[] = { }, Common::RU_RUS, Common::kPlatformPC, - ADGF_NO_FLAGS, + ADGF_CD, GUIO_NONE }, @@ -1621,7 +1621,7 @@ static const AGOSGameDescription gameDescriptions[] = { }, Common::FR_FRA, Common::kPlatformPC, - ADGF_NO_FLAGS, + ADGF_CD, GUIO_NONE }, @@ -1671,7 +1671,7 @@ static const AGOSGameDescription gameDescriptions[] = { }, Common::HE_ISR, Common::kPlatformPC, - ADGF_NO_FLAGS, + ADGF_CD, GUIO_NONE }, @@ -1696,7 +1696,7 @@ static const AGOSGameDescription gameDescriptions[] = { }, Common::IT_ITA, Common::kPlatformPC, - ADGF_NO_FLAGS, + ADGF_CD, GUIO_NONE }, @@ -1722,7 +1722,7 @@ static const AGOSGameDescription gameDescriptions[] = { // FIXME: DOS version which uses WAV format Common::IT_ITA, Common::kPlatformWindows, - ADGF_NO_FLAGS, + ADGF_CD, GUIO_NONE }, @@ -1747,7 +1747,7 @@ static const AGOSGameDescription gameDescriptions[] = { }, Common::ES_ESP, Common::kPlatformPC, - ADGF_NO_FLAGS, + ADGF_CD, GUIO_NONE }, @@ -1772,7 +1772,7 @@ static const AGOSGameDescription gameDescriptions[] = { }, Common::EN_ANY, Common::kPlatformWindows, - ADGF_NO_FLAGS, + ADGF_CD, GUIO_NOSUBTITLES }, @@ -1797,7 +1797,7 @@ static const AGOSGameDescription gameDescriptions[] = { }, Common::DE_DEU, Common::kPlatformWindows, - ADGF_NO_FLAGS, + ADGF_CD, GUIO_NOSUBTITLES }, @@ -2022,7 +2022,7 @@ static const AGOSGameDescription gameDescriptions[] = { }, Common::EN_ANY, Common::kPlatformPC, - ADGF_NO_FLAGS, + ADGF_CD, GUIO_NONE }, @@ -2047,7 +2047,7 @@ static const AGOSGameDescription gameDescriptions[] = { }, Common::EN_ANY, Common::kPlatformPC, - ADGF_NO_FLAGS, + ADGF_CD, GUIO_NONE }, @@ -2072,7 +2072,7 @@ static const AGOSGameDescription gameDescriptions[] = { }, Common::FR_FRA, Common::kPlatformPC, - ADGF_NO_FLAGS, + ADGF_CD, GUIO_NONE }, @@ -2097,7 +2097,7 @@ static const AGOSGameDescription gameDescriptions[] = { }, Common::DE_DEU, Common::kPlatformPC, - ADGF_NO_FLAGS, + ADGF_CD, GUIO_NONE }, @@ -2122,7 +2122,7 @@ static const AGOSGameDescription gameDescriptions[] = { }, Common::DE_DEU, Common::kPlatformPC, - ADGF_NO_FLAGS, + ADGF_CD, GUIO_NONE }, @@ -2147,7 +2147,7 @@ static const AGOSGameDescription gameDescriptions[] = { }, Common::HE_ISR, Common::kPlatformPC, - ADGF_NO_FLAGS, + ADGF_CD, GUIO_NONE }, @@ -2173,7 +2173,7 @@ static const AGOSGameDescription gameDescriptions[] = { // FIXME: DOS version which uses WAV format Common::IT_ITA, Common::kPlatformWindows, - ADGF_NO_FLAGS, + ADGF_CD, GUIO_NONE }, @@ -2198,7 +2198,7 @@ static const AGOSGameDescription gameDescriptions[] = { }, Common::ES_ESP, Common::kPlatformPC, - ADGF_NO_FLAGS, + ADGF_CD, GUIO_NONE }, @@ -2223,7 +2223,7 @@ static const AGOSGameDescription gameDescriptions[] = { }, Common::CZ_CZE, Common::kPlatformWindows, - ADGF_NO_FLAGS, + ADGF_CD, GUIO_NONE }, @@ -2248,7 +2248,7 @@ static const AGOSGameDescription gameDescriptions[] = { }, Common::EN_ANY, Common::kPlatformWindows, - ADGF_NO_FLAGS, + ADGF_CD, GUIO_NONE }, @@ -2273,7 +2273,7 @@ static const AGOSGameDescription gameDescriptions[] = { }, Common::FR_FRA, Common::kPlatformWindows, - ADGF_NO_FLAGS, + ADGF_CD, GUIO_NONE }, @@ -2298,7 +2298,7 @@ static const AGOSGameDescription gameDescriptions[] = { }, Common::DE_DEU, Common::kPlatformWindows, - ADGF_NO_FLAGS, + ADGF_CD, GUIO_NONE }, @@ -2323,7 +2323,7 @@ static const AGOSGameDescription gameDescriptions[] = { }, Common::PL_POL, Common::kPlatformWindows, - ADGF_NO_FLAGS, + ADGF_CD, GUIO_NONE }, @@ -2519,6 +2519,27 @@ static const AGOSGameDescription gameDescriptions[] = { GF_OLD_BUNDLE | GF_ZLIBCOMP | GF_TALKIE }, + // The Feeble Files - English Windows 2CD (with InstallShield cab) + { + { + "feeble", + "2CD", + + { + { "data1.cab", 0, "600db08891e7a21badc8215e604cd88f", 28845430}, + { NULL, 0, NULL, 0} + }, + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOMUSIC + }, + + GType_FF, + GID_FEEBLEFILES, + GF_OLD_BUNDLE | GF_TALKIE | GF_PACKED + }, + // The Feeble Files - English Windows 2CD { { @@ -2565,6 +2586,27 @@ static const AGOSGameDescription gameDescriptions[] = { GF_OLD_BUNDLE | GF_TALKIE }, + // The Feeble Files - English Windows 4CD (with InstallShield cab) + { + { + "feeble", + "4CD", + + { + { "data1.cab", 0, "65804cbc9036ac4b1275d97e0de3be2f", 28943062}, + { NULL, 0, NULL, 0} + }, + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOMUSIC + }, + + GType_FF, + GID_FEEBLEFILES, + GF_OLD_BUNDLE | GF_TALKIE | GF_PACKED + }, + // The Feeble Files - English Windows 4CD { { @@ -2703,6 +2745,27 @@ static const AGOSGameDescription gameDescriptions[] = { GF_OLD_BUNDLE | GF_TALKIE }, + // Simon the Sorcerer's Puzzle Pack - Demon in my Pocket (with InstallShield cab) + { + { + "dimp", + "CD", + + { + { "data1.cab", 0, "36dd86c1d872cea81ac1de7753dd684a", 40394693}, + { NULL, 0, NULL, 0} + }, + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOMUSIC + }, + + GType_PP, + GID_DIMP, + GF_OLD_BUNDLE | GF_TALKIE | GF_PACKED + }, + // Simon the Sorcerer's Puzzle Pack - Demon in my Pocket { { @@ -2724,6 +2787,27 @@ static const AGOSGameDescription gameDescriptions[] = { GF_OLD_BUNDLE | GF_TALKIE }, + // Simon the Sorcerer's Puzzle Pack - Jumble (with InstallShield cab) + { + { + "jumble", + "CD", + + { + { "data1.cab", 0, "36dd86c1d872cea81ac1de7753dd684a", 40394693}, + { NULL, 0, NULL, 0} + }, + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES + }, + + GType_PP, + GID_JUMBLE, + GF_OLD_BUNDLE | GF_TALKIE | GF_PACKED + }, + // Simon the Sorcerer's Puzzle Pack - Jumble { { @@ -2745,6 +2829,27 @@ static const AGOSGameDescription gameDescriptions[] = { GF_OLD_BUNDLE | GF_TALKIE }, + // Simon the Sorcerer's Puzzle Pack - NoPatience (with InstallShield cab) + { + { + "puzzle", + "CD", + + { + { "data1.cab", 0, "36dd86c1d872cea81ac1de7753dd684a", 40394693}, + { NULL, 0, NULL, 0} + }, + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES + }, + + GType_PP, + GID_PUZZLE, + GF_OLD_BUNDLE | GF_TALKIE | GF_PACKED + }, + // Simon the Sorcerer's Puzzle Pack - NoPatience { { @@ -2766,6 +2871,27 @@ static const AGOSGameDescription gameDescriptions[] = { GF_OLD_BUNDLE | GF_TALKIE }, + // Simon the Sorcerer's Puzzle Pack - Swampy Adventures - English (with InstallShield cab) + { + { + "swampy", + "CD", + + { + { "data1.cab", 0, "36dd86c1d872cea81ac1de7753dd684a", 40394693}, + { NULL, 0, NULL, 0} + }, + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES + }, + + GType_PP, + GID_SWAMPY, + GF_OLD_BUNDLE | GF_TALKIE | GF_PACKED + }, + // Simon the Sorcerer's Puzzle Pack - Swampy Adventures - English { { diff --git a/engines/agos/draw.cpp b/engines/agos/draw.cpp index 4d66b56a96..9fc5cedbf9 100644 --- a/engines/agos/draw.cpp +++ b/engines/agos/draw.cpp @@ -20,8 +20,7 @@ * */ - - +#include "common/endian.h" #include "common/system.h" #include "graphics/surface.h" diff --git a/engines/agos/event.cpp b/engines/agos/event.cpp index 3411e6d632..ed26b96381 100644 --- a/engines/agos/event.cpp +++ b/engines/agos/event.cpp @@ -20,8 +20,6 @@ * */ - - #include "agos/agos.h" #include "agos/animation.h" #include "agos/debugger.h" diff --git a/engines/agos/feeble.cpp b/engines/agos/feeble.cpp index 4c82b7e19d..e9a91e3b76 100644 --- a/engines/agos/feeble.cpp +++ b/engines/agos/feeble.cpp @@ -45,6 +45,9 @@ AGOSEngine_Feeble::~AGOSEngine_Feeble() { } static const GameSpecificSettings feeblefiles_settings = { + "game22", // base_filename + "save.999", // restore_filename + "tbllist", // tbl_filename "", // effects_filename "VOICES", // speech_filename }; diff --git a/engines/agos/gfx.cpp b/engines/agos/gfx.cpp index 0b045bae01..fbf7f416ed 100644 --- a/engines/agos/gfx.cpp +++ b/engines/agos/gfx.cpp @@ -20,8 +20,7 @@ * */ - - +#include "common/endian.h" #include "common/system.h" #include "common/textconsole.h" diff --git a/engines/agos/icons.cpp b/engines/agos/icons.cpp index ead4e49ebb..7db2d85f21 100644 --- a/engines/agos/icons.cpp +++ b/engines/agos/icons.cpp @@ -20,8 +20,6 @@ * */ - - #include "common/file.h" #include "common/system.h" #include "common/textconsole.h" diff --git a/engines/agos/input.cpp b/engines/agos/input.cpp index 2ab543a943..24e5339420 100644 --- a/engines/agos/input.cpp +++ b/engines/agos/input.cpp @@ -20,13 +20,12 @@ * */ - - #include "common/config-manager.h" #include "common/file.h" #include "agos/intern.h" #include "agos/agos.h" +#include "agos/midi.h" #include "agos/vga.h" namespace AGOS { @@ -582,14 +581,14 @@ bool AGOSEngine::processSpecialKeys() { break; case '+': if (_midiEnabled) { - _midi.setVolume(_midi.getMusicVolume() + 16, _midi.getSFXVolume() + 16); + _midi->setVolume(_midi->getMusicVolume() + 16, _midi->getSFXVolume() + 16); } ConfMan.setInt("music_volume", _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) + 16); syncSoundSettings(); break; case '-': if (_midiEnabled) { - _midi.setVolume(_midi.getMusicVolume() - 16, _midi.getSFXVolume() - 16); + _midi->setVolume(_midi->getMusicVolume() - 16, _midi->getSFXVolume() - 16); } ConfMan.setInt("music_volume", _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) - 16); syncSoundSettings(); @@ -597,13 +596,13 @@ bool AGOSEngine::processSpecialKeys() { case 'm': _musicPaused = !_musicPaused; if (_midiEnabled) { - _midi.pause(_musicPaused); + _midi->pause(_musicPaused); } syncSoundSettings(); break; case 's': if (getGameId() == GID_SIMON1DOS) { - _midi._enable_sfx = !_midi._enable_sfx; + _midi->_enable_sfx = !_midi->_enable_sfx; } else { _effectsPaused = !_effectsPaused; _sound->effectsPause(_effectsPaused); diff --git a/engines/agos/input_pn.cpp b/engines/agos/input_pn.cpp index 9cc97ff10f..b3a44f2b2f 100644 --- a/engines/agos/input_pn.cpp +++ b/engines/agos/input_pn.cpp @@ -20,8 +20,6 @@ * */ - - #include "agos/agos.h" #include "agos/intern.h" diff --git a/engines/agos/installshield_cab.cpp b/engines/agos/installshield_cab.cpp new file mode 100644 index 0000000000..f7b49a64c5 --- /dev/null +++ b/engines/agos/installshield_cab.cpp @@ -0,0 +1,221 @@ +/* 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. + * + */ + +// The following code is based on unshield +// Original copyright: + +// Copyright (c) 2003 David Eriksson <twogood@users.sourceforge.net> +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +// of the Software, and to permit persons to whom the Software is furnished to do +// so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#include "agos/installshield_cab.h" + +#include "common/debug.h" +#include "common/file.h" +#include "common/memstream.h" +#include "common/zlib.h" + +namespace AGOS { + +class InstallShieldCabinet : public Common::Archive { + Common::String _installShieldFilename; + +public: + InstallShieldCabinet(const Common::String &filename); + ~InstallShieldCabinet(); + + // Common::Archive API implementation + bool hasFile(const Common::String &name); + int listMembers(Common::ArchiveMemberList &list); + Common::ArchiveMemberPtr getMember(const Common::String &name); + Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const; + +private: + struct FileEntry { + uint32 uncompressedSize; + uint32 compressedSize; + uint32 offset; + uint16 flags; + }; + + typedef Common::HashMap<Common::String, FileEntry, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> FileMap; + FileMap _map; +}; + +InstallShieldCabinet::~InstallShieldCabinet() { + _map.clear(); +} + +InstallShieldCabinet::InstallShieldCabinet(const Common::String &filename) : _installShieldFilename(filename) { + Common::File installShieldFile; + + if (!installShieldFile.open(_installShieldFilename)) { + warning("InstallShieldCabinet::InstallShieldCabinet(): Could not find the archive file %s", _installShieldFilename.c_str()); + return; + } + + // Note that we only support a limited subset of cabinet files + // Only single cabinet files and ones without data shared between + // cabinets. + + // Check for the magic uint32 + if (installShieldFile.readUint32LE() != 0x28635349) { + warning("InstallShieldCabinet::InstallShieldCabinet(): Magic ID doesn't match"); + return; + } + + uint32 version = installShieldFile.readUint32LE(); + + if (version != 0x01000004) { + warning("Unsupported CAB version %08x", version); + return; + } + + /* uint32 volumeInfo = */ installShieldFile.readUint32LE(); + uint32 cabDescriptorOffset = installShieldFile.readUint32LE(); + /* uint32 cabDescriptorSize = */ installShieldFile.readUint32LE(); + + installShieldFile.seek(cabDescriptorOffset); + + installShieldFile.skip(12); + uint32 fileTableOffset = installShieldFile.readUint32LE(); + installShieldFile.skip(4); + uint32 fileTableSize = installShieldFile.readUint32LE(); + uint32 fileTableSize2 = installShieldFile.readUint32LE(); + uint32 directoryCount = installShieldFile.readUint32LE(); + installShieldFile.skip(8); + uint32 fileCount = installShieldFile.readUint32LE(); + + if (fileTableSize != fileTableSize2) + warning("file table sizes do not match"); + + // We're ignoring file groups and components since we + // should not need them. Moving on to the files... + + installShieldFile.seek(cabDescriptorOffset + fileTableOffset); + uint32 fileTableCount = directoryCount + fileCount; + uint32 *fileTableOffsets = new uint32[fileTableCount]; + for (uint32 i = 0; i < fileTableCount; i++) + fileTableOffsets[i] = installShieldFile.readUint32LE(); + + for (uint32 i = directoryCount; i < fileCount + directoryCount; i++) { + installShieldFile.seek(cabDescriptorOffset + fileTableOffset + fileTableOffsets[i]); + uint32 nameOffset = installShieldFile.readUint32LE(); + /* uint32 directoryIndex = */ installShieldFile.readUint32LE(); + + // First read in data needed by us to get at the file data + FileEntry entry; + entry.flags = installShieldFile.readUint16LE(); + entry.uncompressedSize = installShieldFile.readUint32LE(); + entry.compressedSize = installShieldFile.readUint32LE(); + installShieldFile.skip(20); + entry.offset = installShieldFile.readUint32LE(); + + // Then let's get the string + installShieldFile.seek(cabDescriptorOffset + fileTableOffset + nameOffset); + Common::String fileName; + + char c = installShieldFile.readByte(); + while (c) { + fileName += c; + c = installShieldFile.readByte(); + } + _map[fileName] = entry; + } + + delete[] fileTableOffsets; +} + +bool InstallShieldCabinet::hasFile(const Common::String &name) { + warning("hasFile: Filename %s", name.c_str()); + return _map.contains(name); +} + +int InstallShieldCabinet::listMembers(Common::ArchiveMemberList &list) { + for (FileMap::const_iterator it = _map.begin(); it != _map.end(); it++) + list.push_back(getMember(it->_key)); + + return _map.size(); +} + +Common::ArchiveMemberPtr InstallShieldCabinet::getMember(const Common::String &name) { + return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this)); +} + +Common::SeekableReadStream *InstallShieldCabinet::createReadStreamForMember(const Common::String &name) const { + if (!_map.contains(name)) + return 0; + + const FileEntry &entry = _map[name]; + + Common::File archiveFile; + archiveFile.open(_installShieldFilename); + archiveFile.seek(entry.offset); + + if (!(entry.flags & 0x04)) { + // Not compressed + return archiveFile.readStream(entry.uncompressedSize); + } + +#ifdef USE_ZLIB + byte *src = (byte *)malloc(entry.compressedSize); + byte *dst = (byte *)malloc(entry.uncompressedSize); + + archiveFile.read(src, entry.compressedSize); + + bool result = Common::inflateZlibHeaderless(dst, entry.uncompressedSize, src, entry.compressedSize); + free(src); + + if (!result) { + warning("failed to inflate CAB file '%s'", name.c_str()); + free(dst); + return 0; + } + + return new Common::MemoryReadStream(dst, entry.uncompressedSize, DisposeAfterUse::YES); +#else + warning("zlib required to extract compressed CAB file '%s'", name.c_str()); + return 0; +#endif +} + +Common::Archive *makeInstallShieldArchive(const Common::String &name) { + return new InstallShieldCabinet(name); +} + +} // End of namespace AGOS diff --git a/engines/agos/installshield_cab.h b/engines/agos/installshield_cab.h new file mode 100644 index 0000000000..f7e8bed277 --- /dev/null +++ b/engines/agos/installshield_cab.h @@ -0,0 +1,41 @@ +/* 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. + * + */ + +#include "common/archive.h" +#include "common/str.h" + +#ifndef AGOS_INSTALLSHIELD_CAB_H +#define AGOS_INSTALLSHIELD_CAB_H + +namespace AGOS { + +/** + * This factory method creates an Archive instance corresponding to the content + * of the InstallShield compressed file with the given name. + * + * May return 0 in case of a failure. + */ +Common::Archive *makeInstallShieldArchive(const Common::String &name); + +} // End of namespace AGOS + +#endif diff --git a/engines/agos/intern.h b/engines/agos/intern.h index 18f56be4a4..773b9c15bd 100644 --- a/engines/agos/intern.h +++ b/engines/agos/intern.h @@ -193,6 +193,9 @@ struct TimeEvent { }; struct GameSpecificSettings { + const char *base_filename; + const char *restore_filename; + const char *tbl_filename; const char *effects_filename; const char *speech_filename; }; @@ -251,7 +254,8 @@ enum GameFeatures { GF_32COLOR = 1 << 5, GF_EGA = 1 << 6, GF_PLANAR = 1 << 7, - GF_DEMO = 1 << 8 + GF_DEMO = 1 << 8, + GF_PACKED = 1 << 9 }; enum GameFileTypes { diff --git a/engines/agos/items.cpp b/engines/agos/items.cpp index 0fb873a733..3bb5a132ef 100644 --- a/engines/agos/items.cpp +++ b/engines/agos/items.cpp @@ -20,8 +20,6 @@ * */ - - #include "common/file.h" #include "common/textconsole.h" diff --git a/engines/agos/menus.cpp b/engines/agos/menus.cpp index 4d62e34820..a0d2bdcaa0 100644 --- a/engines/agos/menus.cpp +++ b/engines/agos/menus.cpp @@ -20,8 +20,6 @@ * */ - - #include "common/file.h" #include "common/system.h" #include "common/textconsole.h" diff --git a/engines/agos/midi.cpp b/engines/agos/midi.cpp index 88f6dd80d1..9a93e0a273 100644 --- a/engines/agos/midi.cpp +++ b/engines/agos/midi.cpp @@ -20,14 +20,12 @@ * */ - - #include "common/config-manager.h" #include "common/file.h" -#include "common/system.h" #include "common/textconsole.h" #include "agos/agos.h" +#include "agos/midi.h" namespace AGOS { diff --git a/engines/agos/midiparser_s1d.cpp b/engines/agos/midiparser_s1d.cpp index 01690247f0..9ca87436fc 100644 --- a/engines/agos/midiparser_s1d.cpp +++ b/engines/agos/midiparser_s1d.cpp @@ -31,20 +31,22 @@ namespace AGOS { /** * Simon 1 Demo version of MidiParser. - * - * This parser is the result of eyeballing the one MUS file that's included - * with simon1demo. So there might be some things missing. I've tried to notate - * question-mark areas where they occur. */ class MidiParser_S1D : public MidiParser { -protected: +private: byte *_data; bool _no_delta; + struct Loop { + uint16 timer; + byte *start, *end; + } _loops[16]; + + uint32 readVLQ2(byte *&data); + void chainEvent(EventInfo &info); protected: void parseNextEvent(EventInfo &info); void resetTracking(); - uint32 readVLQ2(byte * &data); public: MidiParser_S1D() : _data(0), _no_delta(false) {} @@ -52,145 +54,128 @@ public: bool loadMusic(byte *data, uint32 size); }; +uint32 MidiParser_S1D::readVLQ2(byte *&data) { + uint32 delta = 0; -// The VLQs for simon1demo seem to be -// in Little Endian format. -uint32 MidiParser_S1D::readVLQ2(byte * &data) { - byte str; - uint32 value = 0; - int i; - - for (i = 0; i < 4; ++i) { - str = data[0]; - ++data; - value |= (str & 0x7F) << (i * 7); - if (!(str & 0x80)) - break; + // LE format VLQ, which is 2 bytes long at max. + delta = *data++; + if (delta & 0x80) { + delta &= 0x7F; + delta |= *data++ << 7; } - return value; + + return delta; +} + +void MidiParser_S1D::chainEvent(EventInfo &info) { + // When we chain an event, we add up the old delta. + uint32 delta = info.delta; + parseNextEvent(info); + info.delta += delta; } void MidiParser_S1D::parseNextEvent(EventInfo &info) { info.start = _position._play_pos; + info.length = 0; info.delta = _no_delta ? 0 : readVLQ2(_position._play_pos); - _no_delta = false; - info.event = *(_position._play_pos++); - if (info.command() < 0x8) { + + info.event = *_position._play_pos++; + if (!(info.event & 0x80)) { _no_delta = true; - info.event += 0x80; + info.event |= 0x80; } - switch (info.command()) { - case 0x8: - info.basic.param1 = *(_position._play_pos++); - info.basic.param2 = 0; - info.length = 0; - break; - - case 0x9: - info.basic.param1 = *(_position._play_pos++); - info.basic.param2 = *(_position._play_pos++); // I'm ASSUMING this byte is velocity! - info.length = 0; - break; - - case 0xA: - case 0xB: - // I'm not sure what these are meant to do, or what the - // parameter is. Elvira 1 needs them, though, and who am I to - // argue with her? - info.basic.param1 = *(_position._play_pos++); - info.basic.param2 = 0; - break; - - case 0xC: - info.basic.param1 = *(_position._play_pos++); - info.basic.param2 = 0; - ++_position._play_pos; // I have NO IDEA what the second byte is for. - break; - - case 0xD: - // Triggered by MOD0/MOD1/MOD2/MOD3/MOD4/MOD6/MOD7/MOD8/MOD9 in Elvira 2 - // Triggered by MOD0/MOD2/MOD3/MOD5/MOD6/MOD7/MOD8/MOD9/MOD10/MOD12/MOD14/MOD15/MOD20 in Waxworks - break; - - case 0xE: - // Triggered by MOD9 in Elvira 1 - // Triggered by MOD3/MOD5 in Elvira 2 - // Triggered by MOD3/MOD7/MOD8/MOD13 in Waxworks - break; - - case 0xF: - switch (info.event & 0x0F) { - case 0x0: - // Trigged by MOD2/MOD6/MOD15 in Waxworks - // Pure guesswork - info.ext.type = *(_position._play_pos++); - info.length = readVLQ(_position._play_pos); - info.ext.data = _position._play_pos; - break; - - case 0x3: // Not sure, Song Select? - // Trigged by MOD1/MOD7/MOD10 in Elvira 1 - info.basic.param1 = *(_position._play_pos++); + if (info.event == 0xFC) { + // This means End of Track. + // Rewrite in SMF (MIDI transmission) form. + info.event = 0xFF; + info.ext.type = 0x2F; + } else { + switch (info.command()) { + case 0x8: // note off + info.basic.param1 = *_position._play_pos++; info.basic.param2 = 0; break; - case 0x4: - // Trigged by MOD8 in Elvira 1 - break; - - case 0x7: - // Trigged by MOD6 in Elvira 2 - // Trigged by MOD5 in Waxworks + case 0x9: // note on + info.basic.param1 = *_position._play_pos++; + info.basic.param2 = *_position._play_pos++; break; - case 0x8: // Not sure, ? - // Trigged by MOD19 in Waxworks - info.basic.param1 = info.basic.param2 = 0; + case 0xA: { // loop control + // In case the stop mode(?) is set to 0x80 this will stop the + // track over here. + + const int16 loopIterations = int8(*_position._play_pos++); + if (!loopIterations) { + _loops[info.channel()].start = _position._play_pos; + } else { + if (!_loops[info.channel()].timer) { + if (_loops[info.channel()].start) { + _loops[info.channel()].timer = uint16(loopIterations); + _loops[info.channel()].end = _position._play_pos; + + // Go to the start of the loop + _position._play_pos = _loops[info.channel()].start; + } + } else { + if (_loops[info.channel()].timer) + _position._play_pos = _loops[info.channel()].start; + --_loops[info.channel()].timer; + } + } + + // We need to read the next midi event here. Since we can not + // safely pass this event to the MIDI event processing. + chainEvent(info); + } break; + + case 0xB: // auto stop marker(?) + // In case the stop mode(?) is set to 0x80 this will stop the + // track. + + // We need to read the next midi event here. Since we can not + // safely pass this event to the MIDI event processing. + chainEvent(info); break; - case 0xA: - // Trigged by MOD5 in Elvira 2 + case 0xC: // program change + info.basic.param1 = *_position._play_pos++; + info.basic.param2 = 0; break; - case 0xC: - // This means End of Track. - // Rewrite in SMF (MIDI transmission) form. - info.event = 0xFF; - info.ext.type = 0x2F; - info.length = 0; - break; + case 0xD: // jump to loop end + if (_loops[info.channel()].end) + _position._play_pos = _loops[info.channel()].end; - case 0xF: // Not sure, META event? - // Trigged by MOD8/MOD9/MOD11/MOD12/MOD13 in Waxworks - info.ext.type = *(_position._play_pos++); - info.length = readVLQ(_position._play_pos); - info.ext.data = _position._play_pos; - _position._play_pos += info.length; + // We need to read the next midi event here. Since we can not + // safely pass this event to the MIDI event processing. + chainEvent(info); break; default: - error("MidiParser_S1D: Unexpected type 0x%02X found", (int) info.event); + // The original called some other function from here, which seems + // not to be MIDI related. + warning("MidiParser_S1D: default case %d", info.channel()); + + // We need to read the next midi event here. Since we can not + // safely pass this event to the MIDI event processing. + chainEvent(info); break; } - break; - default: - error("MidiParser_S1D: Unexpected event 0x%02X found", (int) info.command()); - break; } } bool MidiParser_S1D::loadMusic(byte *data, uint32 size) { unloadMusic(); + // The original actually just ignores the first two bytes. byte *pos = data; if (*(pos++) != 0xFC) debug(1, "Expected 0xFC header but found 0x%02X instead", (int) *pos); - // The next 3 bytes MIGHT be tempo, but we skip them and use the default. -// setTempo (*(pos++) | (*(pos++) << 8) | (*(pos++) << 16)); - pos += 3; + pos += 1; // And now we're at the actual data. Only one track. _num_tracks = 1; @@ -208,7 +193,9 @@ bool MidiParser_S1D::loadMusic(byte *data, uint32 size) { void MidiParser_S1D::resetTracking() { MidiParser::resetTracking(); - _no_delta = false; + // The first event never contains any delta. + _no_delta = true; + memset(_loops, 0, sizeof(_loops)); } MidiParser *MidiParser_createS1D() { return new MidiParser_S1D; } diff --git a/engines/agos/module.mk b/engines/agos/module.mk index 7069d8005b..7ae5e17bf2 100644 --- a/engines/agos/module.mk +++ b/engines/agos/module.mk @@ -51,6 +51,7 @@ ifdef ENABLE_AGOS2 MODULE_OBJS += \ animation.o \ feeble.o \ + installshield_cab.o \ oracle.o \ script_dp.o \ script_ff.o \ diff --git a/engines/agos/oracle.cpp b/engines/agos/oracle.cpp index 2a3c668c08..025a833b77 100644 --- a/engines/agos/oracle.cpp +++ b/engines/agos/oracle.cpp @@ -25,7 +25,6 @@ #ifdef ENABLE_AGOS2 #include "common/savefile.h" -#include "common/system.h" #include "graphics/surface.h" diff --git a/engines/agos/res.cpp b/engines/agos/res.cpp index a71d4d8150..0baae11e89 100644 --- a/engines/agos/res.cpp +++ b/engines/agos/res.cpp @@ -31,11 +31,30 @@ #include "agos/agos.h" #include "agos/intern.h" #include "agos/sound.h" +#include "agos/installshield_cab.h" #include "common/zlib.h" namespace AGOS { +ArchiveMan::ArchiveMan() { + _fallBack = true; +} + +#ifdef ENABLE_AGOS2 +void ArchiveMan::registerArchive(const Common::String &filename, int priority) { + add(filename, makeInstallShieldArchive(filename), priority); +} +#endif + +Common::SeekableReadStream *ArchiveMan::open(const Common::String &filename) { + if (_fallBack && SearchMan.hasFile(filename)) { + return SearchMan.createReadStreamForMember(filename); + } + + return createReadStreamForMember(filename); +} + #ifdef ENABLE_AGOS2 uint16 AGOSEngine_Feeble::to16Wrapper(uint value) { return TO_LE_16(value); @@ -150,21 +169,21 @@ int AGOSEngine::allocGamePcVars(Common::SeekableReadStream *in) { } void AGOSEngine_PN::loadGamePcFile() { - Common::File in; + Common::SeekableReadStream *in; if (getFileName(GAME_BASEFILE) != NULL) { // Read dataBase - in.open(getFileName(GAME_BASEFILE)); - if (in.isOpen() == false) { + in = _archives.open(getFileName(GAME_BASEFILE)); + if (!in) { error("loadGamePcFile: Can't load database file '%s'", getFileName(GAME_BASEFILE)); } - _dataBaseSize = in.size(); + _dataBaseSize = in->size(); _dataBase = (byte *)malloc(_dataBaseSize); if (_dataBase == NULL) error("loadGamePcFile: Out of memory for dataBase"); - in.read(_dataBase, _dataBaseSize); - in.close(); + in->read(_dataBase, _dataBaseSize); + delete in; if (_dataBase[31] != 0) error("Later version of system requested"); @@ -172,17 +191,17 @@ void AGOSEngine_PN::loadGamePcFile() { if (getFileName(GAME_TEXTFILE) != NULL) { // Read textBase - in.open(getFileName(GAME_TEXTFILE)); - if (in.isOpen() == false) { + in = _archives.open(getFileName(GAME_TEXTFILE)); + if (!in) { error("loadGamePcFile: Can't load textbase file '%s'", getFileName(GAME_TEXTFILE)); } - _textBaseSize = in.size(); + _textBaseSize = in->size(); _textBase = (byte *)malloc(_textBaseSize); if (_textBase == NULL) error("loadGamePcFile: Out of memory for textBase"); - in.read(_textBase, _textBaseSize); - in.close(); + in->read(_textBase, _textBaseSize); + delete in; if (_textBase[getlong(30L)] != 128) error("Unknown compression format"); @@ -190,20 +209,20 @@ void AGOSEngine_PN::loadGamePcFile() { } void AGOSEngine::loadGamePcFile() { - Common::File in; + Common::SeekableReadStream *in; int fileSize; if (getFileName(GAME_BASEFILE) != NULL) { /* Read main gamexx file */ - in.open(getFileName(GAME_BASEFILE)); - if (in.isOpen() == false) { + in = _archives.open(getFileName(GAME_BASEFILE)); + if (!in) { error("loadGamePcFile: Can't load gamexx file '%s'", getFileName(GAME_BASEFILE)); } if (getFeatures() & GF_CRUNCHED_GAMEPC) { - uint srcSize = in.size(); + uint srcSize = in->size(); byte *srcBuf = (byte *)malloc(srcSize); - in.read(srcBuf, srcSize); + in->read(srcBuf, srcSize); uint dstSize = READ_BE_UINT32(srcBuf + srcSize - 4); byte *dstBuf = (byte *)malloc(dstSize); @@ -214,25 +233,25 @@ void AGOSEngine::loadGamePcFile() { readGamePcFile(&stream); free(dstBuf); } else { - readGamePcFile(&in); + readGamePcFile(in); } - in.close(); + delete in; } if (getFileName(GAME_TBLFILE) != NULL) { /* Read list of TABLE resources */ - in.open(getFileName(GAME_TBLFILE)); - if (in.isOpen() == false) { + in = _archives.open(getFileName(GAME_TBLFILE)); + if (!in) { error("loadGamePcFile: Can't load table resources file '%s'", getFileName(GAME_TBLFILE)); } - fileSize = in.size(); + fileSize = in->size(); _tblList = (byte *)malloc(fileSize); if (_tblList == NULL) error("loadGamePcFile: Out of memory for strip table list"); - in.read(_tblList, fileSize); - in.close(); + in->read(_tblList, fileSize); + delete in; /* Remember the current state */ _subroutineListOrg = _subroutineList; @@ -242,71 +261,71 @@ void AGOSEngine::loadGamePcFile() { if (getFileName(GAME_STRFILE) != NULL) { /* Read list of TEXT resources */ - in.open(getFileName(GAME_STRFILE)); - if (in.isOpen() == false) + in = _archives.open(getFileName(GAME_STRFILE)); + if (!in) error("loadGamePcFile: Can't load text resources file '%s'", getFileName(GAME_STRFILE)); - fileSize = in.size(); + fileSize = in->size(); _strippedTxtMem = (byte *)malloc(fileSize); if (_strippedTxtMem == NULL) error("loadGamePcFile: Out of memory for strip text list"); - in.read(_strippedTxtMem, fileSize); - in.close(); + in->read(_strippedTxtMem, fileSize); + delete in; } if (getFileName(GAME_STATFILE) != NULL) { /* Read list of ROOM STATE resources */ - in.open(getFileName(GAME_STATFILE)); - if (in.isOpen() == false) { + in = _archives.open(getFileName(GAME_STATFILE)); + if (!in) { error("loadGamePcFile: Can't load state resources file '%s'", getFileName(GAME_STATFILE)); } - _numRoomStates = in.size() / 8; + _numRoomStates = in->size() / 8; _roomStates = (RoomState *)calloc(_numRoomStates, sizeof(RoomState)); if (_roomStates == NULL) error("loadGamePcFile: Out of memory for room state list"); for (uint s = 0; s < _numRoomStates; s++) { - uint16 num = in.readUint16BE() - (_itemArrayInited - 2); + uint16 num = in->readUint16BE() - (_itemArrayInited - 2); - _roomStates[num].state = in.readUint16BE(); - _roomStates[num].classFlags = in.readUint16BE(); - _roomStates[num].roomExitStates = in.readUint16BE(); + _roomStates[num].state = in->readUint16BE(); + _roomStates[num].classFlags = in->readUint16BE(); + _roomStates[num].roomExitStates = in->readUint16BE(); } - in.close(); + delete in; } if (getFileName(GAME_RMSLFILE) != NULL) { /* Read list of ROOM ITEMS resources */ - in.open(getFileName(GAME_RMSLFILE)); - if (in.isOpen() == false) { + in = _archives.open(getFileName(GAME_RMSLFILE)); + if (!in) { error("loadGamePcFile: Can't load room resources file '%s'", getFileName(GAME_RMSLFILE)); } - fileSize = in.size(); + fileSize = in->size(); _roomsList = (byte *)malloc(fileSize); if (_roomsList == NULL) error("loadGamePcFile: Out of memory for room items list"); - in.read(_roomsList, fileSize); - in.close(); + in->read(_roomsList, fileSize); + delete in; } if (getFileName(GAME_XTBLFILE) != NULL) { /* Read list of XTABLE resources */ - in.open(getFileName(GAME_XTBLFILE)); - if (in.isOpen() == false) { + in = _archives.open(getFileName(GAME_XTBLFILE)); + if (!in) { error("loadGamePcFile: Can't load xtable resources file '%s'", getFileName(GAME_XTBLFILE)); } - fileSize = in.size(); + fileSize = in->size(); _xtblList = (byte *)malloc(fileSize); if (_xtblList == NULL) error("loadGamePcFile: Out of memory for strip xtable list"); - in.read(_xtblList, fileSize); - in.close(); + in->read(_xtblList, fileSize); + delete in; /* Remember the current state */ _xsubroutineListOrg = _subroutineList; diff --git a/engines/agos/res_ami.cpp b/engines/agos/res_ami.cpp index b83d10364a..32adfa29e6 100644 --- a/engines/agos/res_ami.cpp +++ b/engines/agos/res_ami.cpp @@ -26,6 +26,8 @@ #include "agos/agos.h" #include "agos/intern.h" +#include "common/endian.h" + namespace AGOS { enum { diff --git a/engines/agos/res_snd.cpp b/engines/agos/res_snd.cpp index 819af4fa40..1d4e2d1060 100644 --- a/engines/agos/res_snd.cpp +++ b/engines/agos/res_snd.cpp @@ -27,12 +27,12 @@ #include "agos/intern.h" #include "agos/agos.h" +#include "agos/midi.h" #include "agos/vga.h" #include "backends/audiocd/audiocd.h" #include "audio/audiostream.h" -#include "audio/mididrv.h" #include "audio/mods/protracker.h" namespace AGOS { @@ -125,10 +125,10 @@ void AGOSEngine::loadMusic(uint16 music) { _gameFile->read(buf, 4); if (!memcmp(buf, "FORM", 4)) { _gameFile->seek(_gameOffsetsPtr[_musicIndexBase + music - 1], SEEK_SET); - _midi.loadXMIDI(_gameFile); + _midi->loadXMIDI(_gameFile); } else { _gameFile->seek(_gameOffsetsPtr[_musicIndexBase + music - 1], SEEK_SET); - _midi.loadMultipleSMF(_gameFile); + _midi->loadMultipleSMF(_gameFile); } _lastMusicPlayed = music; @@ -242,20 +242,20 @@ void AGOSEngine_Simon1::playMusic(uint16 music, uint16 track) { if (music == 35) return; - _midi.setLoop(true); // Must do this BEFORE loading music. (GMF may have its own override.) + _midi->setLoop(true); // Must do this BEFORE loading music. (GMF may have its own override.) _gameFile->seek(_gameOffsetsPtr[_musicIndexBase + music], SEEK_SET); _gameFile->read(buf, 4); if (!memcmp(buf, "GMF\x1", 4)) { _gameFile->seek(_gameOffsetsPtr[_musicIndexBase + music], SEEK_SET); - _midi.loadSMF(_gameFile, music); + _midi->loadSMF(_gameFile, music); } else { _gameFile->seek(_gameOffsetsPtr[_musicIndexBase + music], SEEK_SET); - _midi.loadMultipleSMF(_gameFile); + _midi->loadMultipleSMF(_gameFile); } - _midi.startTrack(0); - _midi.startTrack(track); + _midi->startTrack(0); + _midi->startTrack(track); } else if (getPlatform() == Common::kPlatformAcorn) { // TODO: Add support for Desktop Tracker format in Acorn disk version } else { @@ -266,15 +266,15 @@ void AGOSEngine_Simon1::playMusic(uint16 music, uint16 track) { if (f.isOpen() == false) error("playMusic: Can't load music from '%s'", filename); - _midi.setLoop(true); // Must do this BEFORE loading music. (GMF may have its own override.) + _midi->setLoop(true); // Must do this BEFORE loading music. (GMF may have its own override.) if (getFeatures() & GF_DEMO) - _midi.loadS1D(&f); + _midi->loadS1D(&f); else - _midi.loadSMF(&f, music); + _midi->loadSMF(&f, music); - _midi.startTrack(0); - _midi.startTrack(track); + _midi->startTrack(0); + _midi->startTrack(track); } } @@ -286,7 +286,7 @@ void AGOSEngine::playMusic(uint16 music, uint16 track) { } else if (getPlatform() == Common::kPlatformAtariST) { // TODO: Add support for music formats used } else { - _midi.setLoop(true); // Must do this BEFORE loading music. + _midi->setLoop(true); // Must do this BEFORE loading music. char filename[15]; Common::File f; @@ -295,21 +295,21 @@ void AGOSEngine::playMusic(uint16 music, uint16 track) { if (f.isOpen() == false) error("playMusic: Can't load music from '%s'", filename); - _midi.loadS1D(&f); - _midi.startTrack(0); - _midi.startTrack(track); + _midi->loadS1D(&f); + _midi->startTrack(0); + _midi->startTrack(track); } } void AGOSEngine::stopMusic() { if (_midiEnabled) { - _midi.stop(); + _midi->stop(); } _mixer->stopHandle(_modHandle); } void AGOSEngine::playSting(uint16 soundId) { - if (!_midi._enable_sfx) + if (!_midi->_enable_sfx) return; char filename[15]; @@ -328,8 +328,8 @@ void AGOSEngine::playSting(uint16 soundId) { error("playSting: Can't read sting %d offset", soundId); mus_file.seek(mus_offset, SEEK_SET); - _midi.loadSMF(&mus_file, soundId, true); - _midi.startTrack(0); + _midi->loadSMF(&mus_file, soundId, true); + _midi->startTrack(0); } static const byte elvira1_soundTable[100] = { @@ -450,17 +450,17 @@ static const char *dimpSoundList[32] = { void AGOSEngine::loadSoundFile(const char* filename) { - Common::File in; + Common::SeekableReadStream *in; - in.open(filename); - if (in.isOpen() == false) + in = _archives.open(filename); + if (!in) error("loadSound: Can't load %s", filename); - uint32 dstSize = in.size(); + uint32 dstSize = in->size(); byte *dst = (byte *)malloc(dstSize); - if (in.read(dst, dstSize) != dstSize) + if (in->read(dst, dstSize) != dstSize) error("loadSound: Read failed"); - in.close(); + delete in; _sound->playSfxData(dst, 0, 0, 0); } @@ -469,21 +469,21 @@ void AGOSEngine::loadSound(uint16 sound, int16 pan, int16 vol, uint16 type) { byte *dst; if (getGameId() == GID_DIMP) { - Common::File in; + Common::SeekableReadStream *in; char filename[15]; assert(sound >= 1 && sound <= 32); sprintf(filename, "%s.wav", dimpSoundList[sound - 1]); - in.open(filename); - if (in.isOpen() == false) + in = _archives.open(filename); + if (!in) error("loadSound: Can't load %s", filename); - uint32 dstSize = in.size(); + uint32 dstSize = in->size(); dst = (byte *)malloc(dstSize); - if (in.read(dst, dstSize) != dstSize) + if (in->read(dst, dstSize) != dstSize) error("loadSound: Read failed"); - in.close(); + delete in; } else if (getFeatures() & GF_ZLIBCOMP) { char filename[15]; diff --git a/engines/agos/rooms.cpp b/engines/agos/rooms.cpp index f2629e419e..fb7b313e9c 100644 --- a/engines/agos/rooms.cpp +++ b/engines/agos/rooms.cpp @@ -401,9 +401,9 @@ bool AGOSEngine::loadRoomItems(uint16 room) { filename[i] = 0; p++; - for (;;) { - _roomsListPtr = p; + _roomsListPtr = p; + for (;;) { minNum = READ_BE_UINT16(p); p += 2; if (minNum == 0) break; diff --git a/engines/agos/saveload.cpp b/engines/agos/saveload.cpp index e6cce36b22..6779eabdbf 100644 --- a/engines/agos/saveload.cpp +++ b/engines/agos/saveload.cpp @@ -22,7 +22,6 @@ #include "common/file.h" #include "common/savefile.h" -#include "common/system.h" #include "common/textconsole.h" #include "common/translation.h" @@ -1020,9 +1019,7 @@ bool AGOSEngine::loadGame(const char *filename, bool restartMode) { if (restartMode) { // Load restart state - Common::File *file = new Common::File(); - file->open(filename); - f = file; + f = _archives.open(filename); } else { f = _saveFileMan->openForLoading(filename); } @@ -1196,9 +1193,7 @@ bool AGOSEngine_Elvira2::loadGame(const char *filename, bool restartMode) { if (restartMode) { // Load restart state - Common::File *file = new Common::File(); - file->open(filename); - f = file; + f = _archives.open(filename); } else { f = _saveFileMan->openForLoading(filename); } diff --git a/engines/agos/script.cpp b/engines/agos/script.cpp index 68a90e405b..1c36454278 100644 --- a/engines/agos/script.cpp +++ b/engines/agos/script.cpp @@ -22,8 +22,7 @@ // Item script opcodes for Simon1/Simon2 - - +#include "common/endian.h" #include "common/system.h" #include "common/textconsole.h" diff --git a/engines/agos/script_dp.cpp b/engines/agos/script_dp.cpp index a4ee249f47..f51e15dc67 100644 --- a/engines/agos/script_dp.cpp +++ b/engines/agos/script_dp.cpp @@ -24,8 +24,6 @@ #ifdef ENABLE_AGOS2 -#include "common/system.h" - #include "agos/agos.h" namespace AGOS { diff --git a/engines/agos/script_pn.cpp b/engines/agos/script_pn.cpp index 3bd8ce19a3..196350b9bf 100644 --- a/engines/agos/script_pn.cpp +++ b/engines/agos/script_pn.cpp @@ -23,6 +23,7 @@ #include "agos/agos.h" #include "agos/vga.h" +#include "common/endian.h" #include "common/textconsole.h" namespace AGOS { diff --git a/engines/agos/script_s1.cpp b/engines/agos/script_s1.cpp index 0e7e66778e..a07c05b4fc 100644 --- a/engines/agos/script_s1.cpp +++ b/engines/agos/script_s1.cpp @@ -20,8 +20,8 @@ * */ - #include "common/system.h" +#include "common/localization.h" #include "graphics/palette.h" @@ -308,34 +308,9 @@ void AGOSEngine_Simon1::os1_pauseGame() { // 135: pause game _system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true); - // If all else fails, use English as fallback. - Common::KeyCode keyYes = Common::KEYCODE_y; - Common::KeyCode keyNo = Common::KEYCODE_n; - - switch (_language) { - case Common::RU_RUS: - break; - case Common::PL_POL: - keyYes = Common::KEYCODE_t; - break; - case Common::HE_ISR: - keyYes = Common::KEYCODE_f; - break; - case Common::ES_ESP: - keyYes = Common::KEYCODE_s; - break; - case Common::IT_ITA: - keyYes = Common::KEYCODE_s; - break; - case Common::FR_FRA: - keyYes = Common::KEYCODE_o; - break; - case Common::DE_DEU: - keyYes = Common::KEYCODE_j; - break; - default: - break; - } + Common::KeyCode keyYes, keyNo; + + Common::getLanguageYesNo(_language, keyYes, keyNo); while (!shouldQuit()) { delay(1); diff --git a/engines/agos/script_s2.cpp b/engines/agos/script_s2.cpp index c646397ac3..c35771f8ec 100644 --- a/engines/agos/script_s2.cpp +++ b/engines/agos/script_s2.cpp @@ -23,6 +23,7 @@ #include "agos/agos.h" +#include "agos/midi.h" #include "common/textconsole.h" @@ -342,11 +343,11 @@ void AGOSEngine_Simon2::os2_playTune() { // effectively preloaded so there's no latency when // starting playback). - _midi.setLoop(loop != 0); + _midi->setLoop(loop != 0); if (_lastMusicPlayed != music) _nextMusicToPlay = music; else - _midi.startTrack(track); + _midi->startTrack(track); } void AGOSEngine_Simon2::os2_screenTextPObj() { diff --git a/engines/agos/script_ww.cpp b/engines/agos/script_ww.cpp index 29a91a15aa..873f258743 100644 --- a/engines/agos/script_ww.cpp +++ b/engines/agos/script_ww.cpp @@ -22,8 +22,6 @@ -#include "common/system.h" - #include "agos/agos.h" namespace AGOS { diff --git a/engines/agos/sound.cpp b/engines/agos/sound.cpp index 03932aa4de..11a1cd792e 100644 --- a/engines/agos/sound.cpp +++ b/engines/agos/sound.cpp @@ -22,6 +22,7 @@ #include "common/file.h" #include "common/memstream.h" +#include "common/ptr.h" #include "common/textconsole.h" #include "common/util.h" @@ -43,11 +44,10 @@ namespace AGOS { class BaseSound : Common::NonCopyable { protected: - Common::File *_file; + Common::DisposablePtr<Common::File> _file; uint32 *_offsets; Audio::Mixer *_mixer; bool _freeOffsets; - DisposeAfterUse::Flag _disposeFile; public: BaseSound(Audio::Mixer *mixer, Common::File *file, uint32 base, bool bigEndian, DisposeAfterUse::Flag disposeFileAfterUse = DisposeAfterUse::YES); @@ -62,7 +62,7 @@ public: }; BaseSound::BaseSound(Audio::Mixer *mixer, Common::File *file, uint32 base, bool bigEndian, DisposeAfterUse::Flag disposeFileAfterUse) - : _mixer(mixer), _file(file), _disposeFile(disposeFileAfterUse) { + : _mixer(mixer), _file(file, disposeFileAfterUse) { uint res = 0; uint32 size; @@ -96,7 +96,7 @@ BaseSound::BaseSound(Audio::Mixer *mixer, Common::File *file, uint32 base, bool } BaseSound::BaseSound(Audio::Mixer *mixer, Common::File *file, uint32 *offsets, DisposeAfterUse::Flag disposeFileAfterUse) - : _mixer(mixer), _file(file), _disposeFile(disposeFileAfterUse) { + : _mixer(mixer), _file(file, disposeFileAfterUse) { _offsets = offsets; _freeOffsets = false; @@ -105,8 +105,6 @@ BaseSound::BaseSound(Audio::Mixer *mixer, Common::File *file, uint32 *offsets, D BaseSound::~BaseSound() { if (_freeOffsets) free(_offsets); - if (_disposeFile == DisposeAfterUse::YES) - delete _file; } /////////////////////////////////////////////////////////////////////////////// @@ -234,7 +232,7 @@ Audio::AudioStream *WavSound::makeAudioStream(uint sound) { return NULL; _file->seek(_offsets[sound], SEEK_SET); - return Audio::makeWAVStream(_file, DisposeAfterUse::NO); + return Audio::makeWAVStream(_file.get(), DisposeAfterUse::NO); } void WavSound::playSound(uint sound, uint loopSound, Audio::Mixer::SoundType type, Audio::SoundHandle *handle, bool loop, int vol) { @@ -257,7 +255,7 @@ public: Audio::AudioStream *VocSound::makeAudioStream(uint sound) { assert(_offsets); _file->seek(_offsets[sound], SEEK_SET); - return Audio::makeVOCStream(_file, _flags); + return Audio::makeVOCStream(_file.get(), _flags); } void VocSound::playSound(uint sound, uint loopSound, Audio::Mixer::SoundType type, Audio::SoundHandle *handle, bool loop, int vol) { diff --git a/engines/agos/sound.h b/engines/agos/sound.h index a7c4cd73db..ab4a3a963d 100644 --- a/engines/agos/sound.h +++ b/engines/agos/sound.h @@ -28,6 +28,10 @@ #include "agos/intern.h" #include "common/str.h" +namespace Common { +class File; +} + namespace AGOS { class BaseSound; diff --git a/engines/agos/subroutine.cpp b/engines/agos/subroutine.cpp index bd9abb16b5..10c1c1aaf9 100644 --- a/engines/agos/subroutine.cpp +++ b/engines/agos/subroutine.cpp @@ -258,22 +258,21 @@ void AGOSEngine::endCutscene() { _runScriptReturn1 = true; } -Common::File *AGOSEngine::openTablesFile(const char *filename) { +Common::SeekableReadStream *AGOSEngine::openTablesFile(const char *filename) { if (getFeatures() & GF_OLD_BUNDLE) return openTablesFile_simon1(filename); else return openTablesFile_gme(filename); } -Common::File *AGOSEngine::openTablesFile_simon1(const char *filename) { - Common::File *fo = new Common::File(); - fo->open(filename); - if (fo->isOpen() == false) +Common::SeekableReadStream *AGOSEngine::openTablesFile_simon1(const char *filename) { + Common::SeekableReadStream *in = _archives.open(filename); + if (!in) error("openTablesFile: Can't open '%s'", filename); - return fo; + return in; } -Common::File *AGOSEngine::openTablesFile_gme(const char *filename) { +Common::SeekableReadStream *AGOSEngine::openTablesFile_gme(const char *filename) { uint res; uint32 offs; @@ -287,7 +286,7 @@ Common::File *AGOSEngine::openTablesFile_gme(const char *filename) { bool AGOSEngine::loadTablesIntoMem(uint16 subrId) { byte *p; uint16 min_num, max_num, file_num; - Common::File *in; + Common::SeekableReadStream *in; char filename[30]; if (_tblList == NULL) @@ -336,7 +335,7 @@ bool AGOSEngine::loadTablesIntoMem(uint16 subrId) { bool AGOSEngine_Waxworks::loadTablesIntoMem(uint16 subrId) { byte *p; uint min_num, max_num; - Common::File *in; + Common::SeekableReadStream *in; p = _tblList; if (p == NULL) @@ -403,7 +402,7 @@ bool AGOSEngine::loadXTablesIntoMem(uint16 subrId) { int i; uint min_num, max_num; char filename[30]; - Common::File *in; + Common::SeekableReadStream *in; p = _xtblList; if (p == NULL) @@ -453,9 +452,8 @@ bool AGOSEngine::loadXTablesIntoMem(uint16 subrId) { return 0; } -void AGOSEngine::closeTablesFile(Common::File *in) { +void AGOSEngine::closeTablesFile(Common::SeekableReadStream *in) { if (getFeatures() & GF_OLD_BUNDLE) { - in->close(); delete in; } } diff --git a/engines/agos/verb.cpp b/engines/agos/verb.cpp index abc45c1ace..dec05f6703 100644 --- a/engines/agos/verb.cpp +++ b/engines/agos/verb.cpp @@ -22,7 +22,6 @@ // Verb and hitarea handling - #include "common/system.h" #include "graphics/surface.h" diff --git a/engines/agos/vga.cpp b/engines/agos/vga.cpp index de6a6976e5..8541f579d6 100644 --- a/engines/agos/vga.cpp +++ b/engines/agos/vga.cpp @@ -27,6 +27,7 @@ #include "agos/intern.h" #include "agos/vga.h" +#include "common/endian.h" #include "common/system.h" #include "common/textconsole.h" diff --git a/engines/agos/vga_e2.cpp b/engines/agos/vga_e2.cpp index 1bde6945f0..d4aafd3d7b 100644 --- a/engines/agos/vga_e2.cpp +++ b/engines/agos/vga_e2.cpp @@ -26,6 +26,7 @@ #include "agos/agos.h" #include "agos/intern.h" +#include "common/endian.h" #include "common/system.h" #include "graphics/surface.h" diff --git a/engines/agos/vga_s2.cpp b/engines/agos/vga_s2.cpp index 1021ea8f94..9b9ed4e297 100644 --- a/engines/agos/vga_s2.cpp +++ b/engines/agos/vga_s2.cpp @@ -20,10 +20,9 @@ * */ - - #include "agos/agos.h" #include "agos/intern.h" +#include "agos/midi.h" #include "graphics/surface.h" @@ -146,8 +145,8 @@ void AGOSEngine::vc69_playSeq() { // specifying a non-valid track number (999 or -1) // as a means of stopping what music is currently // playing. - _midi.setLoop(loop != 0); - _midi.startTrack(track); + _midi->setLoop(loop != 0); + _midi->startTrack(track); } void AGOSEngine::vc70_joinSeq() { @@ -161,9 +160,9 @@ void AGOSEngine::vc70_joinSeq() { // track and, if not, whether to switch to // a different track upon completion. if (track != 0xFFFF && track != 999) - _midi.queueTrack(track, loop != 0); + _midi->queueTrack(track, loop != 0); else - _midi.setLoop(loop != 0); + _midi->setLoop(loop != 0); } void AGOSEngine::vc71_ifSeqWaiting() { @@ -171,7 +170,7 @@ void AGOSEngine::vc71_ifSeqWaiting() { // This command skips the next instruction // unless (1) there is a track playing, AND // (2) there is a track queued to play after it. - if (!_midi.isPlaying(true)) + if (!_midi->isPlaying(true)) vcSkipNextInstruction(); } @@ -195,8 +194,8 @@ void AGOSEngine::vc72_segue() { if (track == -1 || track == 999) { stopMusic(); } else { - _midi.setLoop(loop != 0); - _midi.startTrack(track); + _midi->setLoop(loop != 0); + _midi->startTrack(track); } } diff --git a/engines/agos/window.cpp b/engines/agos/window.cpp index c55e3dcdda..0365c736d8 100644 --- a/engines/agos/window.cpp +++ b/engines/agos/window.cpp @@ -21,7 +21,6 @@ */ - #include "common/system.h" #include "common/textconsole.h" diff --git a/engines/agos/zones.cpp b/engines/agos/zones.cpp index 61efbcb89a..483b9949eb 100644 --- a/engines/agos/zones.cpp +++ b/engines/agos/zones.cpp @@ -214,5 +214,3 @@ void AGOSEngine::checkZonePtrs() { } } // End of namespace AGOS - - |