diff options
author | Matthew Hoops | 2011-10-07 14:34:22 -0400 |
---|---|---|
committer | Matthew Hoops | 2011-10-07 14:34:22 -0400 |
commit | e1dc4db7aa53d1bbc4cdb03d1163c97d049702f5 (patch) | |
tree | 9d57b5fdd6737bc3449851a87e573abe7be984a6 /engines/agos | |
parent | deab5b28753155863062746ef1239535f562fd0b (diff) | |
parent | 842b471e45ae8b7c1b4516b9bd5bf39d61112077 (diff) | |
download | scummvm-rg350-e1dc4db7aa53d1bbc4cdb03d1163c97d049702f5.tar.gz scummvm-rg350-e1dc4db7aa53d1bbc4cdb03d1163c97d049702f5.tar.bz2 scummvm-rg350-e1dc4db7aa53d1bbc4cdb03d1163c97d049702f5.zip |
Merge remote branch 'upstream/master' into pegasus
Conflicts:
video/qt_decoder.cpp
Diffstat (limited to 'engines/agos')
-rw-r--r-- | engines/agos/agos.cpp | 61 | ||||
-rw-r--r-- | engines/agos/agos.h | 32 | ||||
-rw-r--r-- | engines/agos/animation.cpp | 12 | ||||
-rw-r--r-- | engines/agos/animation.h | 2 | ||||
-rw-r--r-- | engines/agos/debug.cpp | 26 | ||||
-rw-r--r-- | engines/agos/detection.cpp | 31 | ||||
-rw-r--r-- | engines/agos/detection_tables.h | 126 | ||||
-rw-r--r-- | engines/agos/feeble.cpp | 4 | ||||
-rw-r--r-- | engines/agos/installshield_cab.cpp | 221 | ||||
-rw-r--r-- | engines/agos/installshield_cab.h | 41 | ||||
-rw-r--r-- | engines/agos/intern.h | 6 | ||||
-rw-r--r-- | engines/agos/midi.cpp | 1 | ||||
-rw-r--r-- | engines/agos/module.mk | 1 | ||||
-rw-r--r-- | engines/agos/res.cpp | 143 | ||||
-rw-r--r-- | engines/agos/res_snd.cpp | 26 | ||||
-rw-r--r-- | engines/agos/saveload.cpp | 8 | ||||
-rw-r--r-- | engines/agos/string_pn.cpp | 2 | ||||
-rw-r--r-- | engines/agos/subroutine.cpp | 22 | ||||
-rw-r--r-- | engines/agos/verb_pn.cpp | 2 |
19 files changed, 646 insertions, 121 deletions
diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp index 97c594684c..73a37e42ef 100644 --- a/engines/agos/agos.cpp +++ b/engines/agos/agos.cpp @@ -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 @@ -132,6 +165,7 @@ AGOSEngine::AGOSEngine(OSystem *system, const AGOSGameDescription *gd) _numMusic = 0; _numSFX = 0; _numSpeech = 0; + _numZone = 0; _numBitArray1 = 0; _numBitArray2 = 0; @@ -678,7 +712,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; @@ -691,6 +733,8 @@ void AGOSEngine_PuzzlePack::setupGame() { _numTextBoxes = 40; _numVars = 2048; + _numZone = 450; + AGOSEngine::setupGame(); } #endif @@ -725,6 +769,7 @@ void AGOSEngine_Simon2::setupGame() { _numMusic = 93; _numSFX = 222; _numSpeech = 11997; + _numZone = 140; AGOSEngine::setupGame(); } @@ -751,6 +796,7 @@ void AGOSEngine_Simon1::setupGame() { _numMusic = 34; _numSFX = 127; _numSpeech = 3623; + _numZone = 164; AGOSEngine::setupGame(); } @@ -771,6 +817,7 @@ void AGOSEngine_Waxworks::setupGame() { _numVars = 255; _numMusic = 26; + _numZone = 155; AGOSEngine::setupGame(); } @@ -790,6 +837,7 @@ void AGOSEngine_Elvira2::setupGame() { _numVars = 255; _numMusic = 9; + _numZone = 99; AGOSEngine::setupGame(); } @@ -806,6 +854,7 @@ void AGOSEngine_Elvira1::setupGame() { _numVars = 512; _numMusic = 14; + _numZone = 74; AGOSEngine::setupGame(); } @@ -819,6 +868,8 @@ void AGOSEngine_PN::setupGame() { _vgaPeriod = 50; _numVars = 256; + _numZone = 26; + AGOSEngine::setupGame(); } @@ -963,6 +1014,10 @@ void AGOSEngine::pause() { } Common::Error AGOSEngine::go() { +#ifdef ENABLE_AGOS2 + loadArchives(); +#endif + loadGamePcFile(); addTimeEvent(0, 1); diff --git a/engines/agos/agos.h b/engines/agos/agos.h index 820bc0260b..cf75842cdd 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" @@ -186,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; @@ -240,6 +257,7 @@ protected: uint8 _numMusic, _numSFX; uint16 _numSpeech; + uint16 _numZone; uint8 _numBitArray1, _numBitArray2, _numBitArray3, _numItemStore; uint16 _numVars; @@ -599,6 +617,8 @@ public: AGOSEngine(OSystem *system, const AGOSGameDescription *gd); virtual ~AGOSEngine(); + ArchiveMan _archives; + byte *_curSfxFile; uint32 _curSfxFileSize; uint16 _sampleEnd, _sampleWait; @@ -608,6 +628,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); @@ -792,14 +816,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..d9d6b71a2a 100644 --- a/engines/agos/animation.cpp +++ b/engines/agos/animation.cpp @@ -137,7 +137,7 @@ void MoviePlayer::handleNextFrame() { // Movie player for DXA movies /////////////////////////////////////////////////////////////////////////////// -const char * MoviePlayerDXA::_sequenceList[90] = { +const char *const MoviePlayerDXA::_sequenceList[90] = { "agent32", "Airlock", "Badluck", @@ -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/animation.h b/engines/agos/animation.h index e1d7207251..11936aa338 100644 --- a/engines/agos/animation.h +++ b/engines/agos/animation.h @@ -73,7 +73,7 @@ protected: }; class MoviePlayerDXA : public MoviePlayer, Video::DXADecoder { - static const char *_sequenceList[90]; + static const char *const _sequenceList[90]; uint8 _sequenceNum; public: MoviePlayerDXA(AGOSEngine_Feeble *vm, const char *name); diff --git a/engines/agos/debug.cpp b/engines/agos/debug.cpp index 18c4736031..841ac6bb1a 100644 --- a/engines/agos/debug.cpp +++ b/engines/agos/debug.cpp @@ -297,20 +297,18 @@ void AGOSEngine::dumpVgaScriptAlways(const byte *ptr, uint16 res, uint16 id) { } void AGOSEngine::dumpAllVgaImageFiles() { - uint8 start = (getGameType() == GType_PN) ? 0 : 2; - uint16 end = (getGameType() == GType_PN) ? 26 : 450; + const uint8 start = (getGameType() == GType_PN) ? 0 : 2; - for (int z = start; z < end; z++) { + for (int z = start; z < _numZone; z++) { loadZone(z, false); dumpVgaBitmaps(z); } } void AGOSEngine::dumpAllVgaScriptFiles() { - uint8 start = (getGameType() == GType_PN) ? 0 : 2; - uint16 end = (getGameType() == GType_PN) ? 26 : 450; + const uint8 start = (getGameType() == GType_PN) ? 0 : 2; - for (int z = start; z < end; z++) { + for (int z = start; z < _numZone; z++) { uint16 zoneNum = (getGameType() == GType_PN) ? 0 : z; loadZone(z, false); @@ -516,7 +514,7 @@ void AGOSEngine::dumpBitmap(const char *filename, const byte *offs, uint16 w, ui dst += w; src += w; } - } else if ((getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) && w == 320 && (h == 134 || h == 200)) { + } else if ((getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) && w == 320 && (h == 134 || h == 135 || h == 200)) { for (j = 0; j != h; j++) { uint16 count = w / 8; @@ -620,7 +618,7 @@ void AGOSEngine::palLoad(byte *pal, const byte *vga1, int a, int b) { void AGOSEngine::dumpVgaBitmaps(uint16 zoneNum) { uint16 width, height, flags; - uint32 offs, curOffs = 0; + uint32 offs, offsEnd; const byte *p2; byte pal[768]; @@ -636,7 +634,11 @@ void AGOSEngine::dumpVgaBitmaps(uint16 zoneNum) { memset(pal, 0, sizeof(pal)); palLoad(pal, vga1, 0, 0); - for (int i = 1; ; i++) { + offsEnd = readUint32Wrapper(vga2 + 8); + for (uint i = 1; ; i++) { + if ((i * 8) >= offsEnd) + break; + p2 = vga2 + i * 8; offs = readUint32Wrapper(p2); @@ -650,10 +652,8 @@ void AGOSEngine::dumpVgaBitmaps(uint16 zoneNum) { } debug(1, "Zone %d: Image %d. Offs= %d Width=%d, Height=%d, Flags=0x%X", zoneNum, i, offs, width, height, flags); - if (offs < curOffs || offs >= imageBlockSize || width == 0 || height == 0) - return; - - curOffs = offs; + if (offs >= imageBlockSize || width == 0 || height == 0) + break; /* dump bitmap */ char buf[40]; diff --git a/engines/agos/detection.cpp b/engines/agos/detection.cpp index 2be888b92a..116e66820a 100644 --- a/engines/agos/detection.cpp +++ b/engines/agos/detection.cpp @@ -83,7 +83,7 @@ static const PlainGameDescriptor agosGames[] = { #include "agos/detection_tables.h" -static const char *directoryGlobs[] = { +static const char *const directoryGlobs[] = { "execute", // Used by Simon1 Acorn CD 0 }; @@ -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 d9f321d98e..a7a384a496 100644 --- a/engines/agos/detection_tables.h +++ b/engines/agos/detection_tables.h @@ -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/feeble.cpp b/engines/agos/feeble.cpp index 4c82b7e19d..4608969667 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 }; @@ -66,6 +69,7 @@ void AGOSEngine_Feeble::setupGame() { _numVars = 255; _numSpeech = 10000; + _numZone = 450; AGOSEngine::setupGame(); } 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/midi.cpp b/engines/agos/midi.cpp index 9a93e0a273..431f080bf2 100644 --- a/engines/agos/midi.cpp +++ b/engines/agos/midi.cpp @@ -62,6 +62,7 @@ MidiPlayer::~MidiPlayer() { Common::StackLock lock(_mutex); if (_driver) { + _driver->setTimerCallback(0, 0); _driver->close(); delete _driver; } 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/res.cpp b/engines/agos/res.cpp index a71d4d8150..69447f4b83 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; @@ -780,7 +799,7 @@ void AGOSEngine::loadVGABeardFile(uint16 id) { uint32 offs, size; if (getFeatures() & GF_OLD_BUNDLE) { - Common::File in; + Common::SeekableReadStream *in; char filename[15]; if (id == 23) id = 112; @@ -796,22 +815,22 @@ void AGOSEngine::loadVGABeardFile(uint16 id) { sprintf(filename, "0%d.VGA", id); } - in.open(filename); - if (in.isOpen() == false) + in = _archives.open(filename); + if (!in) error("loadSimonVGAFile: Can't load %s", filename); - size = in.size(); + size = in->size(); if (getFeatures() & GF_CRUNCHED) { byte *srcBuffer = (byte *)malloc(size); - if (in.read(srcBuffer, size) != size) + if (in->read(srcBuffer, size) != size) error("loadSimonVGAFile: Read failed"); decrunchFile(srcBuffer, _vgaBufferPointers[11].vgaFile2, size); free(srcBuffer); } else { - if (in.read(_vgaBufferPointers[11].vgaFile2, size) != size) + if (in->read(_vgaBufferPointers[11].vgaFile2, size) != size) error("loadSimonVGAFile: Read failed"); } - in.close(); + delete in; } else { offs = _gameOffsetsPtr[id]; @@ -821,7 +840,7 @@ void AGOSEngine::loadVGABeardFile(uint16 id) { } void AGOSEngine::loadVGAVideoFile(uint16 id, uint8 type, bool useError) { - Common::File in; + Common::SeekableReadStream *in; char filename[15]; byte *dst; uint32 file, offs, srcSize, dstSize; @@ -874,8 +893,8 @@ void AGOSEngine::loadVGAVideoFile(uint16 id, uint8 type, bool useError) { } } - in.open(filename); - if (in.isOpen() == false) { + in = _archives.open(filename); + if (!in) { if (useError) error("loadVGAVideoFile: Can't load %s", filename); @@ -883,11 +902,11 @@ void AGOSEngine::loadVGAVideoFile(uint16 id, uint8 type, bool useError) { return; } - dstSize = srcSize = in.size(); + dstSize = srcSize = in->size(); if (getGameType() == GType_PN && getPlatform() == Common::kPlatformPC && id == 17 && type == 2) { // The A2.out file isn't compressed in PC version of Personal Nightmare dst = allocBlock(dstSize + extraBuffer); - if (in.read(dst, dstSize) != dstSize) + if (in->read(dst, dstSize) != dstSize) error("loadVGAVideoFile: Read failed"); } else if (getGameType() == GType_PN && (getFeatures() & GF_CRUNCHED)) { Common::Stack<uint32> data; @@ -895,7 +914,7 @@ void AGOSEngine::loadVGAVideoFile(uint16 id, uint8 type, bool useError) { int dataOutSize = 0; for (uint i = 0; i < srcSize / 4; ++i) { - uint32 dataVal = in.readUint32BE(); + uint32 dataVal = in->readUint32BE(); // Correct incorrect byte, in corrupt 72.out file, included in some PC versions. if (dataVal == 168042714) data.push(168050906); @@ -909,7 +928,7 @@ void AGOSEngine::loadVGAVideoFile(uint16 id, uint8 type, bool useError) { delete[] dataOut; } else if (getFeatures() & GF_CRUNCHED) { byte *srcBuffer = (byte *)malloc(srcSize); - if (in.read(srcBuffer, srcSize) != srcSize) + if (in->read(srcBuffer, srcSize) != srcSize) error("loadVGAVideoFile: Read failed"); dstSize = READ_BE_UINT32(srcBuffer + srcSize - 4); @@ -918,10 +937,10 @@ void AGOSEngine::loadVGAVideoFile(uint16 id, uint8 type, bool useError) { free(srcBuffer); } else { dst = allocBlock(dstSize + extraBuffer); - if (in.read(dst, dstSize) != dstSize) + if (in->read(dst, dstSize) != dstSize) error("loadVGAVideoFile: Read failed"); } - in.close(); + delete in; } else { id = id * 2 + (type - 1); offs = _gameOffsetsPtr[id]; diff --git a/engines/agos/res_snd.cpp b/engines/agos/res_snd.cpp index 9a04ce2d26..b5612d710d 100644 --- a/engines/agos/res_snd.cpp +++ b/engines/agos/res_snd.cpp @@ -413,7 +413,7 @@ bool AGOSEngine::loadVGASoundFile(uint16 id, uint8 type) { return true; } -static const char *dimpSoundList[32] = { +static const char *const dimpSoundList[32] = { "Beep", "Birth", "Boiling", @@ -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/saveload.cpp b/engines/agos/saveload.cpp index 10830db002..6779eabdbf 100644 --- a/engines/agos/saveload.cpp +++ b/engines/agos/saveload.cpp @@ -1019,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); } @@ -1195,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/string_pn.cpp b/engines/agos/string_pn.cpp index 570fbc6200..ac8c263da3 100644 --- a/engines/agos/string_pn.cpp +++ b/engines/agos/string_pn.cpp @@ -68,7 +68,7 @@ void AGOSEngine_PN::uncomstr(char *c, uint32 x) { *c = 0; } -static const char *objectNames[30] = { +static const char *const objectNames[30] = { "\0", "Take \0", "Inventory\r", 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_pn.cpp b/engines/agos/verb_pn.cpp index 19e8bb2d48..9dd0079b6d 100644 --- a/engines/agos/verb_pn.cpp +++ b/engines/agos/verb_pn.cpp @@ -258,7 +258,7 @@ void AGOSEngine_PN::hitBox9(HitArea *ha) { iconPage(); } -static const char *messageList[9] = { +static const char *const messageList[9] = { "North\r", "East\r", "South\r", |