mirror of
https://github.com/libretro/scummvm.git
synced 2025-03-02 08:19:19 +00:00
AGI: Apple II NIB and WOZ disk image support
This commit is contained in:
parent
23a9f4ed54
commit
2f2f3a59bd
@ -587,6 +587,7 @@ protected:
|
||||
class AgiLoader_A2 : public AgiLoader {
|
||||
public:
|
||||
AgiLoader_A2(AgiEngine *vm) : AgiLoader(vm) {}
|
||||
~AgiLoader_A2() override;
|
||||
|
||||
void init() override;
|
||||
int loadDirs() override;
|
||||
@ -595,7 +596,7 @@ public:
|
||||
int loadWords() override;
|
||||
|
||||
private:
|
||||
Common::Array<Common::String> _imageFiles;
|
||||
Common::Array<Common::SeekableReadStream *> _disks;
|
||||
Common::Array<AgiDiskVolume> _volumes;
|
||||
AgiDir _logDir;
|
||||
AgiDir _picDir;
|
||||
@ -610,7 +611,7 @@ private:
|
||||
static bool readVolumeMap(Common::SeekableReadStream &stream, uint32 position, uint32 bufferLength, Common::Array<uint32> &volumeMap);
|
||||
|
||||
A2DirVersion detectDirVersion(Common::SeekableReadStream &stream);
|
||||
bool loadDir(AgiDir *dir, Common::File &disk, uint32 dirOffset, uint32 dirLength, A2DirVersion dirVersion);
|
||||
bool loadDir(AgiDir *dir, Common::SeekableReadStream &disk, uint32 dirOffset, uint32 dirLength, A2DirVersion dirVersion);
|
||||
};
|
||||
|
||||
class AgiLoader_v1 : public AgiLoader {
|
||||
@ -933,7 +934,7 @@ public:
|
||||
// Objects
|
||||
public:
|
||||
int loadObjects(const char *fname);
|
||||
int loadObjects(Common::File &fp, int flen);
|
||||
int loadObjects(Common::SeekableReadStream &fp, int flen);
|
||||
const char *objectName(uint16 objectNr);
|
||||
int objectGetLocation(uint16 objectNr);
|
||||
void objectSetLocation(uint16 objectNr, int location);
|
||||
|
@ -348,6 +348,7 @@ void AgiMetaEngineDetection::getPotentialDiskImages(
|
||||
if (f->_key.baseName().hasSuffixIgnoreCase(imageExtensions[i])) {
|
||||
debug(3, "potential disk image: %s", f->_key.baseName().c_str());
|
||||
imageFiles.push_back(f->_key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -368,16 +369,8 @@ ADDetectedGame AgiMetaEngineDetection::detectPcDiskImageGame(const FileMap &allF
|
||||
|
||||
// find disk one by reading potential images until a match is found
|
||||
for (const Common::Path &imageFile : imageFiles) {
|
||||
Common::SeekableReadStream *stream = allFiles[imageFile].createReadStream();
|
||||
Common::SeekableReadStream *stream = openPCDiskImage(imageFile, allFiles[imageFile]);
|
||||
if (stream == nullptr) {
|
||||
warning("unable to open disk image: %s", imageFile.baseName().c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
// image file size must be 360k
|
||||
int64 fileSize = stream->size();
|
||||
if (fileSize != PC_DISK_SIZE) {
|
||||
delete stream;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -409,7 +402,7 @@ ADDetectedGame AgiMetaEngineDetection::detectPcDiskImageGame(const FileMap &allF
|
||||
FileProperties fileProps;
|
||||
fileProps.md5 = file->md5;
|
||||
fileProps.md5prop = kMD5Archive;
|
||||
fileProps.size = fileSize;
|
||||
fileProps.size = PC_DISK_SIZE;
|
||||
detectedGame.matchedFiles[imageFile] = fileProps;
|
||||
return detectedGame;
|
||||
}
|
||||
@ -483,20 +476,16 @@ ADDetectedGame AgiMetaEngineDetection::detectA2DiskImageGame(const FileMap &allF
|
||||
|
||||
// find disk one by reading potential images until a match is found
|
||||
for (const Common::Path &imageFile : imageFiles) {
|
||||
Common::SeekableReadStream *stream = allFiles[imageFile].createReadStream();
|
||||
// lazily-load disk image tracks as they're accessed.
|
||||
// prevents decoding entire disks just to read a few dynamic sectors.
|
||||
// this would create a significant delay for images in the .woz format.
|
||||
const bool loadAllTracks = false;
|
||||
Common::SeekableReadStream *stream = openA2DiskImage(imageFile, allFiles[imageFile], loadAllTracks);
|
||||
if (stream == nullptr) {
|
||||
warning("unable to open disk image: %s", imageFile.baseName().c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
// image file size must be 140k.
|
||||
// this simple check will be removed when more image formats are supported.
|
||||
int64 fileSize = stream->size();
|
||||
if (fileSize != A2_DISK_SIZE) {
|
||||
delete stream;
|
||||
continue;
|
||||
}
|
||||
|
||||
// attempt to locate and hash logdir by reading initdir,
|
||||
// and also known logdir locations for games without initdir.
|
||||
Common::String logdirHashInitdir = getLogDirHashFromA2DiskImage(*stream);
|
||||
@ -532,7 +521,7 @@ ADDetectedGame AgiMetaEngineDetection::detectA2DiskImageGame(const FileMap &allF
|
||||
FileProperties fileProps;
|
||||
fileProps.md5 = file->md5;
|
||||
fileProps.md5prop = kMD5Archive;
|
||||
fileProps.size = fileSize;
|
||||
fileProps.size = A2_DISK_SIZE;
|
||||
detectedGame.matchedFiles[imageFile] = fileProps;
|
||||
return detectedGame;
|
||||
}
|
||||
|
123
engines/agi/disk_image.cpp
Normal file
123
engines/agi/disk_image.cpp
Normal file
@ -0,0 +1,123 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/formats/disk_image.h"
|
||||
#include "common/memstream.h"
|
||||
#include "common/path.h"
|
||||
#include "common/textconsole.h"
|
||||
|
||||
#include "agi/disk_image.h"
|
||||
|
||||
namespace Agi {
|
||||
|
||||
/**
|
||||
* DiskImageStream is a stream wrapper around Common::DiskImage.
|
||||
*
|
||||
* This allows DiskImage to lazily decode tracks as a stream is used.
|
||||
* This is important for detection, because the .woz format is noticeably
|
||||
* expensive to decode all tracks at once, and detection has to read
|
||||
* INITDIR to discover which track to read LOGDIR from.
|
||||
*/
|
||||
class DiskImageStream : virtual public Common::SeekableReadStream {
|
||||
public:
|
||||
DiskImageStream(Common::DiskImage *diskImage) : _diskImage(diskImage), _stream(_diskImage->getDiskStream()) {}
|
||||
|
||||
~DiskImageStream() {
|
||||
delete _diskImage;
|
||||
}
|
||||
|
||||
uint32 read(void *dataPtr, uint32 dataSize) override {
|
||||
return _diskImage->read(dataPtr, pos(), dataSize);
|
||||
}
|
||||
|
||||
bool eos() const { return _stream->eos(); }
|
||||
void clearErr() { _stream->clearErr(); }
|
||||
|
||||
int64 pos() const { return _stream->pos(); }
|
||||
int64 size() const { return _stream->size(); }
|
||||
|
||||
bool seek(int64 offs, int whence = SEEK_SET) { return _stream->seek(offs, whence); }
|
||||
|
||||
private:
|
||||
Common::DiskImage *_diskImage;
|
||||
Common::SeekableReadStream *_stream;
|
||||
};
|
||||
|
||||
Common::SeekableReadStream *openPCDiskImage(const Common::Path &path, const Common::FSNode &node) {
|
||||
Common::SeekableReadStream *stream = node.createReadStream();
|
||||
if (stream == nullptr) {
|
||||
warning("unable to open disk image: %s", path.baseName().c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// validate disk size
|
||||
if (stream->size() != PC_DISK_SIZE) {
|
||||
delete stream;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
Common::SeekableReadStream *openA2DiskImage(const Common::Path &path, const Common::FSNode &node, bool loadAllTracks) {
|
||||
Common::String name = path.baseName();
|
||||
|
||||
// Open the image with Common::DiskImage, unless the file extension is ".img".
|
||||
// DiskImage expects ".img" to be a PC disk image, but it also gets used as
|
||||
// an Apple II raw sector disk image, so just open it and and read it.
|
||||
Common::SeekableReadStream *stream = nullptr;
|
||||
if (name.hasSuffixIgnoreCase(".img")) {
|
||||
stream = node.createReadStream();
|
||||
} else {
|
||||
if (loadAllTracks) {
|
||||
// when loading all tracks, open with DiskImage and take the stream.
|
||||
Common::DiskImage diskImage;
|
||||
if (diskImage.open(node)) {
|
||||
stream = diskImage.releaseStream();
|
||||
}
|
||||
} else {
|
||||
// when loading tracks as they're used, create a DiskImage with lazy
|
||||
// decoding and wrap it in a stream.
|
||||
Common::DiskImage *diskImage = new Common::DiskImage();
|
||||
diskImage->setLazyDecoding(true);
|
||||
if (diskImage->open(node)) {
|
||||
stream = new DiskImageStream(diskImage);
|
||||
} else {
|
||||
delete diskImage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (stream == nullptr) {
|
||||
warning("unable to open disk image: %s", path.baseName().c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// validate disk size
|
||||
if (stream->size() != A2_DISK_SIZE) {
|
||||
delete stream;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
} // End of namespace Agi
|
@ -22,6 +22,11 @@
|
||||
#ifndef AGI_DISK_IMAGE_H
|
||||
#define AGI_DISK_IMAGE_H
|
||||
|
||||
namespace Common {
|
||||
class SeekableReadStream;
|
||||
class Path;
|
||||
}
|
||||
|
||||
namespace Agi {
|
||||
|
||||
// PC disk image values and helpers for AgiLoader_v1 and AgiMetaEngineDetection
|
||||
@ -57,7 +62,7 @@ static const char * const pcDiskImageExtensions[] = { ".ima", ".img" };
|
||||
// A2 disk image values and helpers for AgiLoader_A2 and AgiMetaEngineDetection
|
||||
|
||||
// Disk image detection requires that image files have a known extension
|
||||
static const char * const a2DiskImageExtensions[] = { ".do", ".dsk" };
|
||||
static const char * const a2DiskImageExtensions[] = { ".do", ".dsk", ".img", ".nib", ".woz" };
|
||||
|
||||
#define A2_DISK_SIZE (35 * 16 * 256)
|
||||
#define A2_DISK_POSITION(t, s, o) ((((t * 16) + s) * 256) + o)
|
||||
@ -93,6 +98,9 @@ static const char * const a2DiskImageExtensions[] = { ".do", ".dsk" };
|
||||
#define A2_BC_DISK_COUNT 5
|
||||
#define A2_BC_VOLUME_COUNT 9
|
||||
|
||||
Common::SeekableReadStream *openPCDiskImage(const Common::Path &path, const Common::FSNode &node);
|
||||
Common::SeekableReadStream *openA2DiskImage(const Common::Path &path, const Common::FSNode &node, bool loadAllTracks = true);
|
||||
|
||||
} // End of namespace Agi
|
||||
|
||||
#endif /* AGI_DISK_IMAGE_H */
|
||||
|
@ -24,7 +24,9 @@
|
||||
#include "agi/words.h"
|
||||
|
||||
#include "common/config-manager.h"
|
||||
#include "common/formats/disk_image.h"
|
||||
#include "common/fs.h"
|
||||
#include "common/memstream.h"
|
||||
|
||||
namespace Agi {
|
||||
|
||||
@ -33,9 +35,8 @@ namespace Agi {
|
||||
// Floppy disks have two sides; each side is a disk with its own image file.
|
||||
// All disk sides are 140k with 35 tracks and 16 sectors per track.
|
||||
//
|
||||
// Currently, the only supported image format is "raw", with sectors in logical
|
||||
// order. Each image file must be exactly 143,360 bytes.
|
||||
// TODO: Add support for other image formats with ADL's disk iamge code.
|
||||
// Multiple disk image formats are supported; see Common::DiskImage. The file
|
||||
// extension determines the format. For example: .do, .dsk, .nib, .woz.
|
||||
//
|
||||
// The disks do not use a standard file system. Instead, file locations are
|
||||
// stored in an INITDIR structure at a fixed location. KQ2 and BC don't have
|
||||
@ -59,6 +60,12 @@ namespace Agi {
|
||||
|
||||
typedef Common::HashMap<Common::Path, Common::FSNode, Common::Path::IgnoreCase_Hash, Common::Path::IgnoreCase_EqualTo> FileMap;
|
||||
|
||||
AgiLoader_A2::~AgiLoader_A2() {
|
||||
for (uint d = 0; d < _disks.size(); d++) {
|
||||
delete _disks[d];
|
||||
}
|
||||
}
|
||||
|
||||
void AgiLoader_A2::init() {
|
||||
// get all files in game directory
|
||||
Common::FSList allFiles;
|
||||
@ -77,6 +84,7 @@ void AgiLoader_A2::init() {
|
||||
Common::Path path = file.getPath();
|
||||
imageFiles.push_back(path);
|
||||
fileMap[path] = file;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -90,28 +98,21 @@ void AgiLoader_A2::init() {
|
||||
uint diskOneIndex;
|
||||
for (diskOneIndex = 0; diskOneIndex < imageFiles.size(); diskOneIndex++) {
|
||||
const Common::Path &imageFile = imageFiles[diskOneIndex];
|
||||
Common::SeekableReadStream *stream = fileMap[imageFile].createReadStream();
|
||||
Common::SeekableReadStream *stream = openA2DiskImage(imageFile, fileMap[imageFile]);
|
||||
if (stream == nullptr) {
|
||||
warning("AgiLoader_A2: unable to open disk image: %s", imageFile.baseName().c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
// image file size must be 140k
|
||||
int64 fileSize = stream->size();
|
||||
if (fileSize != A2_DISK_SIZE) {
|
||||
delete stream;
|
||||
continue;
|
||||
}
|
||||
|
||||
// read image as disk one
|
||||
diskCount = readDiskOne(*stream, volumeMap);
|
||||
delete stream;
|
||||
|
||||
if (diskCount > 0) {
|
||||
debugC(3, "AgiLoader_A2: disk one found: %s", imageFile.baseName().c_str());
|
||||
_imageFiles.resize(diskCount);
|
||||
_imageFiles[0] = imageFile.baseName();
|
||||
_disks.resize(diskCount);
|
||||
_disks[0] = stream;
|
||||
break;
|
||||
} else {
|
||||
delete stream;
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,23 +133,16 @@ void AgiLoader_A2::init() {
|
||||
uint imageFileIndex = (diskOneIndex + i) % imageFiles.size();
|
||||
Common::Path &imageFile = imageFiles[imageFileIndex];
|
||||
|
||||
Common::SeekableReadStream *stream = fileMap[imageFile].createReadStream();
|
||||
Common::SeekableReadStream *stream = openA2DiskImage(imageFile, fileMap[imageFile]);
|
||||
if (stream == nullptr) {
|
||||
warning("AgiLoader_A2: unable to open disk image: %s", imageFile.baseName().c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
// image file size must be 140k
|
||||
int32 fileSize = stream->size();
|
||||
if (fileSize != A2_DISK_SIZE) {
|
||||
delete stream;
|
||||
continue;
|
||||
}
|
||||
|
||||
// check each disk
|
||||
bool diskFound = false;
|
||||
for (int d = 1; d < diskCount; d++) {
|
||||
// has disk already been found?
|
||||
if (!_imageFiles[d].empty()) {
|
||||
if (_disks[d] != nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -173,13 +167,16 @@ void AgiLoader_A2::init() {
|
||||
}
|
||||
|
||||
if (match) {
|
||||
_imageFiles[d] = imageFile.baseName();
|
||||
_disks[d] = stream;
|
||||
disksFound++;
|
||||
diskFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
delete stream;
|
||||
if (!diskFound) {
|
||||
delete stream;
|
||||
}
|
||||
}
|
||||
|
||||
// populate _volumes with the locations of the ones we will use.
|
||||
@ -332,21 +329,18 @@ bool AgiLoader_A2::readVolumeMap(
|
||||
|
||||
int AgiLoader_A2::loadDirs() {
|
||||
// if init didn't find disks then fail
|
||||
if (_imageFiles.empty()) {
|
||||
if (_disks.empty()) {
|
||||
return errFilesNotFound;
|
||||
}
|
||||
for (uint32 i = 0; i < _imageFiles.size(); i++) {
|
||||
if (_imageFiles.empty()) {
|
||||
warning("AgiLoader_A2: disk %d not found", i);
|
||||
for (uint d = 0; d < _disks.size(); d++) {
|
||||
if (_disks[d] == nullptr) {
|
||||
warning("AgiLoader_A2: disk %d not found", d);
|
||||
return errFilesNotFound;
|
||||
}
|
||||
}
|
||||
|
||||
// open disk one
|
||||
Common::File disk;
|
||||
if (!disk.open(Common::Path(_imageFiles[0]))) {
|
||||
return errBadFileOpen;
|
||||
}
|
||||
// all dirs are on disk one
|
||||
Common::SeekableReadStream &disk = *_disks[0];
|
||||
|
||||
// detect dir format
|
||||
A2DirVersion dirVersion = detectDirVersion(disk);
|
||||
@ -388,7 +382,7 @@ A2DirVersion AgiLoader_A2::detectDirVersion(Common::SeekableReadStream &stream)
|
||||
return A2DirVersionOld;
|
||||
}
|
||||
|
||||
bool AgiLoader_A2::loadDir(AgiDir *dir, Common::File &disk, uint32 dirOffset, uint32 dirLength, A2DirVersion dirVersion) {
|
||||
bool AgiLoader_A2::loadDir(AgiDir *dir, Common::SeekableReadStream &disk, uint32 dirOffset, uint32 dirLength, A2DirVersion dirVersion) {
|
||||
// seek to directory on disk
|
||||
disk.seek(dirOffset);
|
||||
|
||||
@ -440,12 +434,8 @@ uint8 *AgiLoader_A2::loadVolumeResource(AgiDir *agid) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Common::File disk;
|
||||
int diskIndex = _volumes[agid->volume].disk;
|
||||
if (!disk.open(Common::Path(_imageFiles[diskIndex]))) {
|
||||
warning("AgiLoader_A2: unable to open disk image: %s", _imageFiles[diskIndex].c_str());
|
||||
return nullptr;
|
||||
}
|
||||
Common::SeekableReadStream &disk = *_disks[diskIndex];
|
||||
|
||||
// seek to resource and validate header
|
||||
int offset = _volumes[agid->volume].offset + agid->offset;
|
||||
@ -469,22 +459,22 @@ uint8 *AgiLoader_A2::loadVolumeResource(AgiDir *agid) {
|
||||
}
|
||||
|
||||
int AgiLoader_A2::loadObjects() {
|
||||
Common::File disk;
|
||||
if (!disk.open(Common::Path(_imageFiles[0]))) {
|
||||
return errBadFileOpen;
|
||||
if (_disks.empty()) {
|
||||
return errFilesNotFound;
|
||||
}
|
||||
|
||||
Common::SeekableReadStream &disk = *_disks[0];
|
||||
disk.seek(_objects.offset);
|
||||
return _vm->loadObjects(disk, _objects.len);
|
||||
}
|
||||
|
||||
int AgiLoader_A2::loadWords() {
|
||||
Common::File disk;
|
||||
if (!disk.open(Common::Path(_imageFiles[0]))) {
|
||||
return errBadFileOpen;
|
||||
if (_disks.empty()) {
|
||||
return errFilesNotFound;
|
||||
}
|
||||
|
||||
// TODO: pass length and validate in parser
|
||||
Common::SeekableReadStream &disk = *_disks[0];
|
||||
disk.seek(_words.offset);
|
||||
if (_vm->getVersion() < 0x2000) {
|
||||
return _vm->_words->loadDictionary_v1(disk);
|
||||
|
@ -80,16 +80,8 @@ void AgiLoader_v1::init() {
|
||||
uint diskOneIndex;
|
||||
for (diskOneIndex = 0; diskOneIndex < imageFiles.size(); diskOneIndex++) {
|
||||
const Common::Path &imageFile = imageFiles[diskOneIndex];
|
||||
Common::SeekableReadStream *stream = fileMap[imageFile].createReadStream();
|
||||
Common::SeekableReadStream *stream = openPCDiskImage(imageFile, fileMap[imageFile]);
|
||||
if (stream == nullptr) {
|
||||
warning("AgiLoader_v1: unable to open disk image: %s", imageFile.baseName().c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
// image file size must be 360k
|
||||
int32 fileSize = stream->size();
|
||||
if (fileSize != PC_DISK_SIZE) {
|
||||
delete stream;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -139,26 +131,17 @@ void AgiLoader_v1::init() {
|
||||
uint diskTwoIndex = (diskOneIndex + i) % imageFiles.size();
|
||||
Common::Path &imageFile = imageFiles[diskTwoIndex];
|
||||
|
||||
Common::SeekableReadStream *stream = fileMap[imageFile].createReadStream();
|
||||
Common::SeekableReadStream *stream = openPCDiskImage(imageFile, fileMap[imageFile]);
|
||||
if (stream == nullptr) {
|
||||
warning("AgiLoader_v1: unable to open disk image: %s", imageFile.baseName().c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
// image file size must be 360k
|
||||
int64 fileSize = stream->size();
|
||||
if (fileSize != PC_DISK_SIZE) {
|
||||
delete stream;
|
||||
continue;
|
||||
}
|
||||
|
||||
// read resource header
|
||||
uint16 magic = stream->readUint16BE();
|
||||
byte volume = stream->readByte();
|
||||
uint16 size = stream->readUint16LE();
|
||||
delete stream;
|
||||
|
||||
if (magic == 0x1234 && volume == 2 && 5 + size <= PC_DISK_SIZE) {
|
||||
if (magic == 0x1234 && volume == 2) {
|
||||
debugC(3, "AgiLoader_v1: disk two found: %s", imageFile.baseName().c_str());
|
||||
_imageFiles.push_back(imageFile.baseName());
|
||||
_volumes.push_back(AgiDiskVolume(_imageFiles.size() - 1, 0));
|
||||
|
@ -5,6 +5,7 @@ MODULE_OBJS := \
|
||||
checks.o \
|
||||
console.o \
|
||||
cycle.o \
|
||||
disk_image.o \
|
||||
font.o \
|
||||
global.o \
|
||||
graphics.o \
|
||||
@ -57,3 +58,10 @@ DETECT_OBJS += $(MODULE)/detection.o
|
||||
# This is unneeded by the engine module itself,
|
||||
# so separate it completely.
|
||||
DETECT_OBJS += $(MODULE)/wagparser.o
|
||||
|
||||
# Skip building the following objects if a static
|
||||
# module is enabled, because it already has the contents.
|
||||
ifneq ($(ENABLE_AGI), STATIC_PLUGIN)
|
||||
# External dependencies for detection.
|
||||
DETECT_OBJS += $(MODULE)/disk_image.o
|
||||
endif
|
||||
|
@ -95,16 +95,14 @@ int AgiEngine::loadObjects(const char *fname) {
|
||||
* @param fp File pointer
|
||||
* @param flen File length
|
||||
*/
|
||||
int AgiEngine::loadObjects(Common::File &fp, int flen) {
|
||||
int AgiEngine::loadObjects(Common::SeekableReadStream &fp, int flen) {
|
||||
uint8 *mem;
|
||||
|
||||
if ((mem = (uint8 *)calloc(1, flen + 32)) == nullptr) {
|
||||
fp.close();
|
||||
return errNotEnoughMemory;
|
||||
}
|
||||
|
||||
fp.read(mem, flen);
|
||||
fp.close();
|
||||
|
||||
decodeObjects(mem, flen);
|
||||
free(mem);
|
||||
|
Loading…
x
Reference in New Issue
Block a user