aboutsummaryrefslogtreecommitdiff
path: root/engines/agos
diff options
context:
space:
mode:
authorMatthew Hoops2011-10-07 14:34:22 -0400
committerMatthew Hoops2011-10-07 14:34:22 -0400
commite1dc4db7aa53d1bbc4cdb03d1163c97d049702f5 (patch)
tree9d57b5fdd6737bc3449851a87e573abe7be984a6 /engines/agos
parentdeab5b28753155863062746ef1239535f562fd0b (diff)
parent842b471e45ae8b7c1b4516b9bd5bf39d61112077 (diff)
downloadscummvm-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.cpp61
-rw-r--r--engines/agos/agos.h32
-rw-r--r--engines/agos/animation.cpp12
-rw-r--r--engines/agos/animation.h2
-rw-r--r--engines/agos/debug.cpp26
-rw-r--r--engines/agos/detection.cpp31
-rw-r--r--engines/agos/detection_tables.h126
-rw-r--r--engines/agos/feeble.cpp4
-rw-r--r--engines/agos/installshield_cab.cpp221
-rw-r--r--engines/agos/installshield_cab.h41
-rw-r--r--engines/agos/intern.h6
-rw-r--r--engines/agos/midi.cpp1
-rw-r--r--engines/agos/module.mk1
-rw-r--r--engines/agos/res.cpp143
-rw-r--r--engines/agos/res_snd.cpp26
-rw-r--r--engines/agos/saveload.cpp8
-rw-r--r--engines/agos/string_pn.cpp2
-rw-r--r--engines/agos/subroutine.cpp22
-rw-r--r--engines/agos/verb_pn.cpp2
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",