mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-04 16:26:53 +00:00
AGOS: Integrate InstallShield support.
This commit is contained in:
parent
f91f0f2756
commit
5346ac18b7
@ -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
|
||||
@ -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;
|
||||
@ -963,6 +1004,10 @@ void AGOSEngine::pause() {
|
||||
}
|
||||
|
||||
Common::Error AGOSEngine::go() {
|
||||
#ifdef ENABLE_AGOS2
|
||||
loadArchives();
|
||||
#endif
|
||||
|
||||
loadGamePcFile();
|
||||
|
||||
addTimeEvent(0, 1);
|
||||
|
@ -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;
|
||||
@ -599,6 +616,8 @@ public:
|
||||
AGOSEngine(OSystem *system, const AGOSGameDescription *gd);
|
||||
virtual ~AGOSEngine();
|
||||
|
||||
ArchiveMan _archives;
|
||||
|
||||
byte *_curSfxFile;
|
||||
uint32 _curSfxFileSize;
|
||||
uint16 _sampleEnd, _sampleWait;
|
||||
@ -608,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);
|
||||
@ -792,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();
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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,19 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
_archives.enableFallback(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // End of namespace AGOS
|
||||
|
@ -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
|
||||
{
|
||||
{
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -46,59 +46,80 @@
|
||||
#include "agos/installshield_cab.h"
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "common/file.h"
|
||||
#include "common/memstream.h"
|
||||
#include "common/zlib.h"
|
||||
|
||||
namespace AGOS {
|
||||
|
||||
InstallShieldCabinet::InstallShieldCabinet() : Common::Archive() {
|
||||
_stream = 0;
|
||||
}
|
||||
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() {
|
||||
close();
|
||||
_map.clear();
|
||||
}
|
||||
|
||||
bool InstallShieldCabinet::open(const Common::String &filename) {
|
||||
close();
|
||||
InstallShieldCabinet::InstallShieldCabinet(const Common::String &filename) : _installShieldFilename(filename) {
|
||||
Common::File installShieldFile;
|
||||
|
||||
_stream = SearchMan.createReadStreamForMember(filename);
|
||||
|
||||
if (!_stream)
|
||||
return false;
|
||||
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 (_stream->readUint32LE() != 0x28635349) {
|
||||
close();
|
||||
return false;
|
||||
if (installShieldFile.readUint32LE() != 0x28635349) {
|
||||
warning("InstallShieldCabinet::InstallShieldCabinet(): Magic ID doesn't match");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 version = _stream->readUint32LE();
|
||||
uint32 version = installShieldFile.readUint32LE();
|
||||
|
||||
if (version != 0x01000004) {
|
||||
warning("Unsupported CAB version %08x", version);
|
||||
close();
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
/* uint32 volumeInfo = */ _stream->readUint32LE();
|
||||
uint32 cabDescriptorOffset = _stream->readUint32LE();
|
||||
/* uint32 cabDescriptorSize = */ _stream->readUint32LE();
|
||||
/* uint32 volumeInfo = */ installShieldFile.readUint32LE();
|
||||
uint32 cabDescriptorOffset = installShieldFile.readUint32LE();
|
||||
/* uint32 cabDescriptorSize = */ installShieldFile.readUint32LE();
|
||||
|
||||
_stream->seek(cabDescriptorOffset);
|
||||
installShieldFile.seek(cabDescriptorOffset);
|
||||
|
||||
_stream->skip(12);
|
||||
uint32 fileTableOffset = _stream->readUint32LE();
|
||||
_stream->skip(4);
|
||||
uint32 fileTableSize = _stream->readUint32LE();
|
||||
uint32 fileTableSize2 = _stream->readUint32LE();
|
||||
uint32 directoryCount = _stream->readUint32LE();
|
||||
_stream->skip(8);
|
||||
uint32 fileCount = _stream->readUint32LE();
|
||||
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");
|
||||
@ -106,49 +127,42 @@ bool InstallShieldCabinet::open(const Common::String &filename) {
|
||||
// We're ignoring file groups and components since we
|
||||
// should not need them. Moving on to the files...
|
||||
|
||||
_stream->seek(cabDescriptorOffset + fileTableOffset);
|
||||
installShieldFile.seek(cabDescriptorOffset + fileTableOffset);
|
||||
uint32 fileTableCount = directoryCount + fileCount;
|
||||
uint32 *fileTableOffsets = new uint32[fileTableCount];
|
||||
for (uint32 i = 0; i < fileTableCount; i++)
|
||||
fileTableOffsets[i] = _stream->readUint32LE();
|
||||
fileTableOffsets[i] = installShieldFile.readUint32LE();
|
||||
|
||||
for (uint32 i = directoryCount; i < fileCount + directoryCount; i++) {
|
||||
_stream->seek(cabDescriptorOffset + fileTableOffset + fileTableOffsets[i]);
|
||||
uint32 nameOffset = _stream->readUint32LE();
|
||||
/* uint32 directoryIndex = */ _stream->readUint32LE();
|
||||
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 = _stream->readUint16LE();
|
||||
entry.uncompressedSize = _stream->readUint32LE();
|
||||
entry.compressedSize = _stream->readUint32LE();
|
||||
_stream->skip(20);
|
||||
entry.offset = _stream->readUint32LE();
|
||||
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
|
||||
_stream->seek(cabDescriptorOffset + fileTableOffset + nameOffset);
|
||||
installShieldFile.seek(cabDescriptorOffset + fileTableOffset + nameOffset);
|
||||
Common::String fileName;
|
||||
|
||||
char c = _stream->readByte();
|
||||
char c = installShieldFile.readByte();
|
||||
while (c) {
|
||||
fileName += c;
|
||||
c = _stream->readByte();
|
||||
c = installShieldFile.readByte();
|
||||
}
|
||||
|
||||
_map[fileName] = entry;
|
||||
}
|
||||
|
||||
delete[] fileTableOffsets;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void InstallShieldCabinet::close() {
|
||||
delete _stream; _stream = 0;
|
||||
_map.clear();
|
||||
}
|
||||
|
||||
bool InstallShieldCabinet::hasFile(const Common::String &name) {
|
||||
warning("hasFile: Filename %s", name.c_str());
|
||||
return _map.contains(name);
|
||||
}
|
||||
|
||||
@ -164,23 +178,25 @@ Common::ArchiveMemberPtr InstallShieldCabinet::getMember(const Common::String &n
|
||||
}
|
||||
|
||||
Common::SeekableReadStream *InstallShieldCabinet::createReadStreamForMember(const Common::String &name) const {
|
||||
if (!_stream || !_map.contains(name))
|
||||
if (!_map.contains(name))
|
||||
return 0;
|
||||
|
||||
const FileEntry &entry = _map[name];
|
||||
|
||||
_stream->seek(entry.offset);
|
||||
Common::File archiveFile;
|
||||
archiveFile.open(_installShieldFilename);
|
||||
archiveFile.seek(entry.offset);
|
||||
|
||||
if (!(entry.flags & 0x04)) {
|
||||
// Not compressed
|
||||
return _stream->readStream(entry.uncompressedSize);
|
||||
return archiveFile.readStream(entry.uncompressedSize);
|
||||
}
|
||||
|
||||
#ifdef USE_ZLIB
|
||||
byte *src = (byte *)malloc(entry.compressedSize);
|
||||
byte *dst = (byte *)malloc(entry.uncompressedSize);
|
||||
|
||||
_stream->read(src, entry.compressedSize);
|
||||
archiveFile.read(src, entry.compressedSize);
|
||||
|
||||
bool result = Common::inflateZlibHeaderless(dst, entry.uncompressedSize, src, entry.compressedSize);
|
||||
free(src);
|
||||
@ -198,4 +214,8 @@ Common::SeekableReadStream *InstallShieldCabinet::createReadStreamForMember(cons
|
||||
#endif
|
||||
}
|
||||
|
||||
Common::Archive *makeInstallShieldArchive(const Common::String &name) {
|
||||
return new InstallShieldCabinet(name);
|
||||
}
|
||||
|
||||
} // End of namespace AGOS
|
||||
|
@ -21,11 +21,6 @@
|
||||
*/
|
||||
|
||||
#include "common/archive.h"
|
||||
#include "common/scummsys.h"
|
||||
#include "common/endian.h"
|
||||
#include "common/file.h"
|
||||
#include "common/hash-str.h"
|
||||
#include "common/hashmap.h"
|
||||
#include "common/str.h"
|
||||
|
||||
#ifndef AGOS_INSTALLSHIELD_CAB_H
|
||||
@ -33,34 +28,13 @@
|
||||
|
||||
namespace AGOS {
|
||||
|
||||
class InstallShieldCabinet : public Common::Archive {
|
||||
public:
|
||||
InstallShieldCabinet();
|
||||
~InstallShieldCabinet();
|
||||
|
||||
bool open(const Common::String &filename);
|
||||
void close();
|
||||
bool isOpen() const { return _stream != 0; }
|
||||
|
||||
// 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;
|
||||
};
|
||||
|
||||
Common::SeekableReadStream *_stream;
|
||||
|
||||
typedef Common::HashMap<Common::String, FileEntry, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> FileMap;
|
||||
FileMap _map;
|
||||
};
|
||||
/**
|
||||
* 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
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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 = false;
|
||||
}
|
||||
|
||||
#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;
|
||||
|
@ -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];
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user