[Scummvm-git-logs] scummvm master -> bcd5df5c6e94a1d6c9cfb97f27a0306b8ff54e60
waltervn
walter at vanniftrik-it.nl
Sun Aug 28 11:23:58 CEST 2016
This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
0a053e4ce4 ADL: Add support for reading .xfd Atari disk images
70588aecdc ADL: Load hires4 verbs, nouns and items
bcd5df5c6e ADL: Load hires4 rooms
Commit: 0a053e4ce4fa440172792e00ebfaa676b412c846
https://github.com/scummvm/scummvm/commit/0a053e4ce4fa440172792e00ebfaa676b412c846
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-08-28T11:23:34+02:00
Commit Message:
ADL: Add support for reading .xfd Atari disk images
Changed paths:
engines/adl/disk.cpp
engines/adl/disk.h
engines/adl/hires0.cpp
engines/adl/hires2.cpp
diff --git a/engines/adl/disk.cpp b/engines/adl/disk.cpp
index 49e01f9..6a5cf0b 100644
--- a/engines/adl/disk.cpp
+++ b/engines/adl/disk.cpp
@@ -28,15 +28,7 @@
namespace Adl {
-#define TRACKS 35
-// The Apple II uses either 13- or 16-sector disks. We currently pad out
-// 13-sector disks, so we set SECTORS_PER_TRACK to 16 here.
-#define SECTORS_PER_TRACK 16
-#define BYTES_PER_SECTOR 256
-#define RAW_IMAGE_SIZE(S) (TRACKS * (S) * BYTES_PER_SECTOR)
-#define NIB_IMAGE_SIZE (RAW_IMAGE_SIZE(13) * 2)
-
-static Common::SeekableReadStream *readImage_DSK(const Common::String &filename) {
+static Common::SeekableReadStream *readImage(const Common::String &filename) {
Common::File *f = new Common::File;
if (!f->open(filename)) {
@@ -44,9 +36,6 @@ static Common::SeekableReadStream *readImage_DSK(const Common::String &filename)
return nullptr;
}
- if (f->size() != RAW_IMAGE_SIZE(16))
- error("Unrecognized DSK image '%s' of size %d bytes", filename.c_str(), f->size());
-
return f;
}
@@ -63,7 +52,7 @@ static Common::SeekableReadStream *readImage_NIB(const Common::String &filename)
if (!f.open(filename))
return nullptr;
- if (f.size() != NIB_IMAGE_SIZE)
+ if (f.size() != 232960)
error("Unrecognized NIB image '%s' of size %d bytes", filename.c_str(), f.size());
// starting at 0xaa, 32 is invalid (see below)
@@ -73,7 +62,9 @@ static Common::SeekableReadStream *readImage_NIB(const Common::String &filename)
// we always pad it out
const uint sectorsPerTrack = 16;
- byte *diskImage = (byte *)calloc(RAW_IMAGE_SIZE(sectorsPerTrack), 1);
+ const uint bytesPerSector = 256;
+ const uint imageSize = 35 * sectorsPerTrack * bytesPerSector;
+ byte *const diskImage = (byte *)calloc(imageSize, 1);
bool sawAddress = false;
uint8 volNo, track, sector;
@@ -120,13 +111,13 @@ static Common::SeekableReadStream *readImage_NIB(const Common::String &filename)
// We should always find the data field after an address field.
// TODO: we ignore volNo?
- byte *output = diskImage + (track * sectorsPerTrack + sector) * BYTES_PER_SECTOR;
+ byte *output = diskImage + (track * sectorsPerTrack + sector) * bytesPerSector;
if (newStyle) {
// We hardcode the DOS 3.3 mapping here. TODO: Do we also need raw/prodos?
int raw2dos[16] = { 0, 7, 14, 6, 13, 5, 12, 4, 11, 3, 10, 2, 9, 1, 8, 15 };
sector = raw2dos[sector];
- output = diskImage + (track * sectorsPerTrack + sector) * BYTES_PER_SECTOR;
+ output = diskImage + (track * sectorsPerTrack + sector) * bytesPerSector;
// 6-and-2 uses 342 on-disk bytes
byte inbuffer[342];
@@ -216,36 +207,59 @@ static Common::SeekableReadStream *readImage_NIB(const Common::String &filename)
}
}
- return new Common::MemoryReadStream(diskImage, RAW_IMAGE_SIZE(sectorsPerTrack), DisposeAfterUse::YES);
+ return new Common::MemoryReadStream(diskImage, imageSize, DisposeAfterUse::YES);
}
bool DiskImage::open(const Common::String &filename) {
Common::String lcName(filename);
lcName.toLowercase();
- if (lcName.hasSuffix(".dsk"))
- _stream = readImage_DSK(filename);
- else if (lcName.hasSuffix(".nib"))
+ if (lcName.hasSuffix(".dsk")) {
+ _stream = readImage(filename);
+ _tracks = 35;
+ _sectorsPerTrack = 16;
+ _bytesPerSector = 256;
+ } else if (lcName.hasSuffix(".nib")) {
_stream = readImage_NIB(filename);
+ _tracks = 35;
+ _sectorsPerTrack = 16;
+ _bytesPerSector = 256;
+ } else if (lcName.hasSuffix(".xfd")) {
+ _stream = readImage(filename);
+ _tracks = 40;
+ _sectorsPerTrack = 18;
+ _bytesPerSector = 128;
+ }
+
+ int expectedSize = _tracks * _sectorsPerTrack * _bytesPerSector;
+
+ if (!_stream)
+ return false;
+
+ if (_stream->size() != expectedSize)
+ error("Unrecognized disk image '%s' of size %d bytes (expected %d bytes)", filename.c_str(), _stream->size(), expectedSize);
- return _stream != nullptr;
+ return true;
}
const DataBlockPtr DiskImage::getDataBlock(uint track, uint sector, uint offset, uint size) const {
- return DataBlockPtr(new DiskImage::DataBlock(this, track, sector, offset, size, _mode13));
+ return DataBlockPtr(new DiskImage::DataBlock(this, track, sector, offset, size, _sectorLimit));
}
-Common::SeekableReadStream *DiskImage::createReadStream(uint track, uint sector, uint offset, uint size, uint sectorsPerTrackToRead) const {
- const uint bytesToRead = size * BYTES_PER_SECTOR + BYTES_PER_SECTOR - offset;
+Common::SeekableReadStream *DiskImage::createReadStream(uint track, uint sector, uint offset, uint size, uint sectorLimit) const {
+ const uint bytesToRead = size * _bytesPerSector + _bytesPerSector - offset;
byte *const data = (byte *)malloc(bytesToRead);
uint dataOffset = 0;
- if (sector > sectorsPerTrackToRead - 1)
- error("Sector %i is out of bounds for %i-sector reading", sector, sectorsPerTrackToRead);
+ if (sectorLimit == 0)
+ sectorLimit = _sectorsPerTrack;
+
+ if (sector >= sectorLimit)
+ error("Sector %i is out of bounds for %i-sector reading", sector, sectorLimit);
while (dataOffset < bytesToRead) {
- uint bytesRemInTrack = (sectorsPerTrackToRead - 1 - sector) * BYTES_PER_SECTOR + BYTES_PER_SECTOR - offset;
- _stream->seek((track * SECTORS_PER_TRACK + sector) * BYTES_PER_SECTOR + offset);
+ uint bytesRemInTrack = (sectorLimit - 1 - sector) * _bytesPerSector + _bytesPerSector - offset;
+ _stream->seek((track * _sectorsPerTrack + sector) * _bytesPerSector + offset);
if (bytesToRead - dataOffset < bytesRemInTrack)
bytesRemInTrack = bytesToRead - dataOffset;
diff --git a/engines/adl/disk.h b/engines/adl/disk.h
index 1041f0c..653d76f 100644
--- a/engines/adl/disk.h
+++ b/engines/adl/disk.h
@@ -74,7 +74,10 @@ class DiskImage {
public:
DiskImage() :
_stream(nullptr),
- _mode13(false) { }
+ _tracks(0),
+ _sectorsPerTrack(0),
+ _bytesPerSector(0),
+ _sectorLimit(0) { }
~DiskImage() {
delete _stream;
@@ -82,32 +85,33 @@ public:
bool open(const Common::String &filename);
const DataBlockPtr getDataBlock(uint track, uint sector, uint offset = 0, uint size = 0) const;
- Common::SeekableReadStream *createReadStream(uint track, uint sector, uint offset = 0, uint size = 0, uint sectorsPerTrackToRead = 16) const;
- void setMode13(bool enable) { _mode13 = enable; }
+ Common::SeekableReadStream *createReadStream(uint track, uint sector, uint offset = 0, uint size = 0, uint sectorsUsed = 0) const;
+ void setSectorLimit(uint sectorLimit) { _sectorLimit = sectorLimit; } // Maximum number of sectors to read per track before stepping
protected:
class DataBlock : public Adl::DataBlock {
public:
- DataBlock(const DiskImage *disk, uint track, uint sector, uint offset, uint size, bool mode13) :
+ DataBlock(const DiskImage *disk, uint track, uint sector, uint offset, uint size, uint sectorLimit) :
_track(track),
_sector(sector),
_offset(offset),
_size(size),
- _mode13(mode13),
+ _sectorLimit(sectorLimit),
_disk(disk) { }
Common::SeekableReadStream *createReadStream() const {
- return _disk->createReadStream(_track, _sector, _offset, _size, (_mode13 ? 13 : 16));
+ return _disk->createReadStream(_track, _sector, _offset, _size, _sectorLimit);
}
private:
uint _track, _sector, _offset, _size;
- bool _mode13;
+ uint _sectorLimit;
const DiskImage *_disk;
};
Common::SeekableReadStream *_stream;
- bool _mode13; // Older 13-sector format
+ uint _tracks, _sectorsPerTrack, _bytesPerSector;
+ uint _sectorLimit;
};
// Data in plain files
diff --git a/engines/adl/hires0.cpp b/engines/adl/hires0.cpp
index a348779..875a06c 100644
--- a/engines/adl/hires0.cpp
+++ b/engines/adl/hires0.cpp
@@ -35,7 +35,7 @@ void HiRes0Engine::init() {
if (!_disk->open(IDS_HR0_DISK_IMAGE))
error("Failed to open disk image '" IDS_HR0_DISK_IMAGE "'");
- _disk->setMode13(true);
+ _disk->setSectorLimit(13);
StreamPtr stream(_disk->createReadStream(0x1f, 0x2, 0x00, 2));
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 14db237..d0e459c 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -37,7 +37,7 @@ void HiRes2Engine::runIntro() const {
// This only works for the 16-sector re-release. The original
// release is not supported at this time, because we don't have
// access to it.
- _disk->setMode13(false);
+ _disk->setSectorLimit(0);
StreamPtr stream(_disk->createReadStream(0x00, 0xd, 0x17, 1));
_display->setMode(DISPLAY_MODE_TEXT);
@@ -50,7 +50,7 @@ void HiRes2Engine::runIntro() const {
_display->printString(str);
delay(2000);
- _disk->setMode13(true);
+ _disk->setSectorLimit(13);
}
void HiRes2Engine::init() {
@@ -60,7 +60,7 @@ void HiRes2Engine::init() {
if (!_disk->open(IDS_HR2_DISK_IMAGE))
error("Failed to open disk image '" IDS_HR2_DISK_IMAGE "'");
- _disk->setMode13(true);
+ _disk->setSectorLimit(13);
StreamPtr stream(_disk->createReadStream(0x1f, 0x2, 0x00, 4));
Commit: 70588aecdc9df737821dc37c466b4274b5f76549
https://github.com/scummvm/scummvm/commit/70588aecdc9df737821dc37c466b4274b5f76549
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-08-28T11:23:34+02:00
Commit Message:
ADL: Load hires4 verbs, nouns and items
Changed paths:
engines/adl/adl_v2.cpp
engines/adl/adl_v2.h
engines/adl/adl_v3.cpp
engines/adl/adl_v3.h
engines/adl/adl_v4.cpp
engines/adl/adl_v4.h
engines/adl/hires0.cpp
engines/adl/hires2.cpp
engines/adl/hires4.cpp
engines/adl/hires4.h
engines/adl/hires6.cpp
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index e18f333..2b9a1b0 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -359,9 +359,42 @@ DataBlockPtr AdlEngine_v2::readDataBlockPtr(Common::ReadStream &f) const {
if (track == 0 && sector == 0 && offset == 0 && size == 0)
return DataBlockPtr();
+ adjustDataBlockPtr(track, sector, offset, size);
+
return _disk->getDataBlock(track, sector, offset, size);
}
+void AdlEngine_v2::loadItems(Common::SeekableReadStream &stream) {
+ byte id;
+ while ((id = stream.readByte()) != 0xff && !stream.eos() && !stream.err()) {
+ Item item = Item();
+ item.id = id;
+ item.noun = stream.readByte();
+ item.room = stream.readByte();
+ item.picture = stream.readByte();
+ item.isLineArt = stream.readByte(); // Disk number in later games
+ item.position.x = stream.readByte();
+ item.position.y = stream.readByte();
+ item.state = stream.readByte();
+ item.description = stream.readByte();
+
+ stream.readByte(); // Struct size
+
+ byte picListSize = stream.readByte();
+
+ // Flag to keep track of what has been drawn on the screen
+ stream.readByte();
+
+ for (uint i = 0; i < picListSize; ++i)
+ item.roomPictures.push_back(stream.readByte());
+
+ _state.items.push_back(item);
+ }
+
+ if (stream.eos() || stream.err())
+ error("Error loading items");
+}
+
int AdlEngine_v2::o2_isFirstTime(ScriptEnv &e) {
OP_DEBUG_0("\t&& IS_FIRST_TIME()");
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 327b36e..e8894b5 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -52,6 +52,8 @@ protected:
void takeItem(byte noun);
virtual DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
+ virtual void adjustDataBlockPtr(byte &track, byte §or, byte &offset, byte &size) const { }
+ void loadItems(Common::SeekableReadStream &stream);
void checkTextOverflow(char c);
diff --git a/engines/adl/adl_v3.cpp b/engines/adl/adl_v3.cpp
index 6b93acd..6551524 100644
--- a/engines/adl/adl_v3.cpp
+++ b/engines/adl/adl_v3.cpp
@@ -32,6 +32,30 @@ Common::String AdlEngine_v3::getItemDescription(const Item &item) const {
return _itemDesc[item.description - 1];
}
+void AdlEngine_v3::loadItemDescriptions(Common::SeekableReadStream &stream, byte count) {
+ int32 startPos = stream.pos();
+ uint16 baseAddr = stream.readUint16LE();
+debug("%04x", baseAddr);
+ // This code assumes that the first pointer points to a string that
+ // directly follows the pointer table
+ assert(baseAddr != 0);
+ baseAddr -= count * 2;
+
+ for (uint i = 0; i < count; ++i) {
+ stream.seek(startPos + i * 2);
+ uint16 offset = stream.readUint16LE();
+
+ if (offset > 0) {
+ stream.seek(startPos + offset - baseAddr);
+ _itemDesc.push_back(readString(stream, 0xff));
+ } else
+ _itemDesc.push_back(Common::String());
+ }
+
+ if (stream.eos() || stream.err())
+ error("Error loading item descriptions");
+}
+
typedef Common::Functor1Mem<ScriptEnv &, int, AdlEngine_v3> OpcodeV3;
void AdlEngine_v3::setupOpcodeTables() {
diff --git a/engines/adl/adl_v3.h b/engines/adl/adl_v3.h
index 759b17c..b0d40f3 100644
--- a/engines/adl/adl_v3.h
+++ b/engines/adl/adl_v3.h
@@ -38,6 +38,8 @@ protected:
virtual void setupOpcodeTables();
Common::String getItemDescription(const Item &item) const;
+ void loadItemDescriptions(Common::SeekableReadStream &stream, byte count);
+
int o3_isNounNotInRoom(ScriptEnv &e);
int o3_listInv(ScriptEnv &e);
diff --git a/engines/adl/adl_v4.cpp b/engines/adl/adl_v4.cpp
index 602ee25..ed20c82 100644
--- a/engines/adl/adl_v4.cpp
+++ b/engines/adl/adl_v4.cpp
@@ -59,21 +59,8 @@ void AdlEngine_v4::applyDiskOffset(byte &track, byte §or) const {
track += _diskOffsets[_curDisk].track;
}
-DataBlockPtr AdlEngine_v4::readDataBlockPtr(Common::ReadStream &f) const {
- byte track = f.readByte();
- byte sector = f.readByte();
- byte offset = f.readByte();
- byte size = f.readByte();
-
- if (f.eos() || f.err())
- error("Error reading DataBlockPtr");
-
- if (track == 0 && sector == 0 && offset == 0 && size == 0)
- return DataBlockPtr();
-
+void AdlEngine_v4::adjustDataBlockPtr(byte &track, byte §or, byte &offset, byte &size) const {
applyDiskOffset(track, sector);
-
- return _disk->getDataBlock(track, sector, offset, size);
}
typedef Common::Functor1Mem<ScriptEnv &, int, AdlEngine_v4> OpcodeV4;
diff --git a/engines/adl/adl_v4.h b/engines/adl/adl_v4.h
index dc9a275..79aa824 100644
--- a/engines/adl/adl_v4.h
+++ b/engines/adl/adl_v4.h
@@ -49,7 +49,7 @@ protected:
Common::String getItemDescription(const Item &item) const;
// AdlEngine_v2
- virtual DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
+ virtual void adjustDataBlockPtr(byte &track, byte §or, byte &offset, byte &size) const;
void applyDiskOffset(byte &track, byte §or) const;
diff --git a/engines/adl/hires0.cpp b/engines/adl/hires0.cpp
index 875a06c..5bfe482 100644
--- a/engines/adl/hires0.cpp
+++ b/engines/adl/hires0.cpp
@@ -134,31 +134,7 @@ void HiRes0Engine::initGameState() {
stream.reset(_disk->createReadStream(0x21, 0x0));
- byte id;
- while ((id = stream->readByte()) != 0xff) {
- Item item = Item();
- item.id = id;
- item.noun = stream->readByte();
- item.room = stream->readByte();
- item.picture = stream->readByte();
- item.isLineArt = stream->readByte();
- item.position.x = stream->readByte();
- item.position.y = stream->readByte();
- item.state = stream->readByte();
- item.description = stream->readByte();
-
- stream->readByte(); // Struct size
-
- byte picListSize = stream->readByte();
-
- // Flag to keep track of what has been drawn on the screen
- stream->readByte();
-
- for (uint i = 0; i < picListSize; ++i)
- item.roomPictures.push_back(stream->readByte());
-
- _state.items.push_back(item);
- }
+ loadItems(*stream);
}
Engine *HiRes0Engine_create(OSystem *syst, const AdlGameDescription *gd) {
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index d0e459c..34de518 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -157,31 +157,7 @@ void HiRes2Engine::initGameState() {
stream.reset(_disk->createReadStream(0x21, 0x0, 0x00, 2));
- byte id;
- while ((id = stream->readByte()) != 0xff) {
- Item item = Item();
- item.id = id;
- item.noun = stream->readByte();
- item.room = stream->readByte();
- item.picture = stream->readByte();
- item.isLineArt = stream->readByte(); // Is this still used in this way?
- item.position.x = stream->readByte();
- item.position.y = stream->readByte();
- item.state = stream->readByte();
- item.description = stream->readByte();
-
- stream->readByte(); // Struct size
-
- byte picListSize = stream->readByte();
-
- // Flag to keep track of what has been drawn on the screen
- stream->readByte();
-
- for (uint i = 0; i < picListSize; ++i)
- item.roomPictures.push_back(stream->readByte());
-
- _state.items.push_back(item);
- }
+ loadItems(*stream);
}
Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd) {
diff --git a/engines/adl/hires4.cpp b/engines/adl/hires4.cpp
index 22fd9c2..1ce2a44 100644
--- a/engines/adl/hires4.cpp
+++ b/engines/adl/hires4.cpp
@@ -27,24 +27,89 @@
#include "common/stream.h"
#include "adl/hires4.h"
+#include "adl/detection.h"
#include "adl/display.h"
#include "adl/graphics.h"
#include "adl/disk.h"
namespace Adl {
-void HiRes4Engine::runIntro() const {
+HiRes4Engine::~HiRes4Engine() {
+ delete _disk2;
+ delete _disk3;
}
void HiRes4Engine::init() {
_graphics = new Graphics_v2(*_display);
+
+ const char *const *names = getDiskImageNames();
+
+ _disk = new DiskImage();
+ if (!_disk->open(names[0]))
+ error("Failed to open disk image '%s'", names[0]);
+
+ _disk2 = new DiskImage();
+ if (!_disk2->open(names[1]))
+ error("Failed to open disk image '%s'", names[1]);
+
+ _disk3 = new DiskImage();
+ if (!_disk3->open(names[2]))
+ error("Failed to open disk image '%s'", names[2]);
+
+ StreamPtr stream(createReadStream(_disk, 0x06, 0xd, 0x12, 2));
+ loadItemDescriptions(*stream, IDI_HR4_NUM_ITEM_DESCS);
+
+ stream.reset(createReadStream(_disk, 0x05, 0x4, 0x00, 3));
+ loadWords(*stream, _verbs, _priVerbs);
+
+ stream.reset(createReadStream(_disk, 0x03, 0xb, 0x00, 6));
+ loadWords(*stream, _nouns, _priNouns);
}
void HiRes4Engine::initGameState() {
+ StreamPtr stream(createReadStream(_disk, 0x02, 0xc, 0x00, 12));
+ loadItems(*stream);
+}
+
+Common::SeekableReadStream *HiRes4Engine::createReadStream(DiskImage *disk, byte track, byte sector, byte offset, byte size) const {
+ adjustDataBlockPtr(track, sector, offset, size);
+ return disk->createReadStream(track, sector, offset, size);
+}
+
+void HiRes4Engine_Atari::adjustDataBlockPtr(byte &track, byte §or, byte &offset, byte &size) const {
+ // Convert the Apple II disk offsets in the game, to Atari disk offsets
+ uint sectorIndex = (track * 16 + sector + 1) << 1;
+
+ // Atari uses 128 bytes per sector vs. 256 on the Apple II
+ // Note that size indicates *additional* sectors to read after reading one sector
+ size *= 2;
+
+ if (offset >= 128) {
+ // Offset in the second half of an Apple II sector, skip one sector and adjust offset
+ ++sectorIndex;
+ offset -= 128;
+ } else {
+ // Offset in the first half of an Apple II sector, we need to read one additional sector
+ ++size;
+ }
+
+ // Compute track/sector for Atari's 18 sectors per track (sectorIndex is 1-based)
+ track = (sectorIndex - 1) / 18;
+ sector = (sectorIndex - 1) % 18;
+}
+
+const char *const *HiRes4Engine_Atari::getDiskImageNames() const {
+ static const char *const disks[] = { "ULYS1A.XFD", "ULYS1B.XFD", "ULYS2C.XFD" };
+ return disks;
}
Engine *HiRes4Engine_create(OSystem *syst, const AdlGameDescription *gd) {
- return new HiRes4Engine(syst, gd);
+ switch (gd->desc.platform) {
+ case Common::kPlatformAtariST:
+ return new HiRes4Engine_Atari(syst, gd);
+ default:
+ error("Unsupported platform");
+ }
}
} // End of namespace Adl
diff --git a/engines/adl/hires4.h b/engines/adl/hires4.h
index f1c429c..a578080 100644
--- a/engines/adl/hires4.h
+++ b/engines/adl/hires4.h
@@ -29,15 +29,36 @@
namespace Adl {
+#define IDI_HR4_NUM_ITEM_DESCS 44
+
class HiRes4Engine : public AdlEngine_v3 {
public:
+ ~HiRes4Engine();
+
+protected:
HiRes4Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine_v3(syst, gd) { }
-private:
// AdlEngine
- void runIntro() const;
void init();
void initGameState();
+
+ Common::SeekableReadStream *createReadStream(DiskImage *disk, byte track, byte sector, byte offset = 0, byte size = 0) const;
+ virtual const char *const *getDiskImageNames() const = 0;
+
+ // FIXME: use an array?
+ DiskImage *_disk2, *_disk3;
+};
+
+class HiRes4Engine_Atari : public HiRes4Engine {
+public:
+ HiRes4Engine_Atari(OSystem *syst, const AdlGameDescription *gd) : HiRes4Engine(syst, gd) { }
+
+private:
+ // AdlEngine_v2
+ virtual void adjustDataBlockPtr(byte &track, byte §or, byte &offset, byte &size) const;
+
+ // HiRes4Engine
+ virtual const char *const *getDiskImageNames() const;
};
} // End of namespace Adl
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index e9df7b5..cf06591 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -141,9 +141,8 @@ void HiRes6Engine::init() {
// Item descriptions
stream.reset(loadSectors(_boot, 0x6, 0xb, 2));
- stream->seek(0x34);
- for (uint i = 0; i < IDI_HR6_NUM_ITEM_DESCS; ++i)
- _itemDesc.push_back(readString(*stream, 0xff));
+ stream->seek(0x16);
+ loadItemDescriptions(*stream, IDI_HR6_NUM_ITEM_DESCS);
// Load dropped item offsets
stream.reset(_boot->createReadStream(0x8, 0x9, 0x16));
@@ -287,31 +286,7 @@ void HiRes6Engine::initGameState() {
StreamPtr stream(_boot->createReadStream(0x3, 0xe, 0x03));
- byte id;
- while ((id = stream->readByte()) != 0xff) {
- Item item = Item();
- item.id = id;
- item.noun = stream->readByte();
- item.room = stream->readByte();
- item.picture = stream->readByte();
- item.isLineArt = stream->readByte(); // Now seems to be disk number
- item.position.x = stream->readByte();
- item.position.y = stream->readByte();
- item.state = stream->readByte();
- item.description = stream->readByte();
-
- stream->readByte(); // Struct size
-
- byte picListSize = stream->readByte();
-
- // Flag to keep track of what has been drawn on the screen
- stream->readByte();
-
- for (uint i = 0; i < picListSize; ++i)
- item.roomPictures.push_back(stream->readByte());
-
- _state.items.push_back(item);
- }
+ loadItems(*stream);
_currVerb = _currNoun = 0;
}
Commit: bcd5df5c6e94a1d6c9cfb97f27a0306b8ff54e60
https://github.com/scummvm/scummvm/commit/bcd5df5c6e94a1d6c9cfb97f27a0306b8ff54e60
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-08-28T11:23:34+02:00
Commit Message:
ADL: Load hires4 rooms
Changed paths:
engines/adl/adl_v2.cpp
engines/adl/adl_v2.h
engines/adl/adl_v3.cpp
engines/adl/hires0.cpp
engines/adl/hires2.cpp
engines/adl/hires4.cpp
engines/adl/hires4.h
engines/adl/hires6.cpp
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 2b9a1b0..307bf98 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -395,6 +395,25 @@ void AdlEngine_v2::loadItems(Common::SeekableReadStream &stream) {
error("Error loading items");
}
+void AdlEngine_v2::loadRooms(Common::SeekableReadStream &stream, byte count) {
+ for (uint i = 0; i < count; ++i) {
+ Room room;
+
+ stream.readByte(); // number
+ for (uint j = 0; j < 6; ++j)
+ room.connections[j] = stream.readByte();
+ room.data = readDataBlockPtr(stream);
+ room.picture = stream.readByte();
+ room.curPicture = stream.readByte();
+ room.isFirstTime = stream.readByte();
+
+ _state.rooms.push_back(room);
+ }
+
+ if (stream.eos() || stream.err())
+ error("Error loading rooms");
+}
+
int AdlEngine_v2::o2_isFirstTime(ScriptEnv &e) {
OP_DEBUG_0("\t&& IS_FIRST_TIME()");
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index e8894b5..5430085 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -54,6 +54,7 @@ protected:
virtual DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
virtual void adjustDataBlockPtr(byte &track, byte §or, byte &offset, byte &size) const { }
void loadItems(Common::SeekableReadStream &stream);
+ void loadRooms(Common::SeekableReadStream &stream, byte count);
void checkTextOverflow(char c);
diff --git a/engines/adl/adl_v3.cpp b/engines/adl/adl_v3.cpp
index 6551524..ba9e4a0 100644
--- a/engines/adl/adl_v3.cpp
+++ b/engines/adl/adl_v3.cpp
@@ -35,7 +35,7 @@ Common::String AdlEngine_v3::getItemDescription(const Item &item) const {
void AdlEngine_v3::loadItemDescriptions(Common::SeekableReadStream &stream, byte count) {
int32 startPos = stream.pos();
uint16 baseAddr = stream.readUint16LE();
-debug("%04x", baseAddr);
+
// This code assumes that the first pointer points to a string that
// directly follows the pointer table
assert(baseAddr != 0);
diff --git a/engines/adl/hires0.cpp b/engines/adl/hires0.cpp
index 5bfe482..e6ff0bd 100644
--- a/engines/adl/hires0.cpp
+++ b/engines/adl/hires0.cpp
@@ -119,21 +119,9 @@ void HiRes0Engine::initGameState() {
_state.vars.resize(IDI_HR0_NUM_VARS);
StreamPtr stream(_disk->createReadStream(0x21, 0x5, 0x0e, 2));
-
- for (uint i = 0; i < IDI_HR0_NUM_ROOMS; ++i) {
- Room room;
- stream->readByte(); // number
- for (uint j = 0; j < 6; ++j)
- room.connections[j] = stream->readByte();
- room.data = readDataBlockPtr(*stream);
- room.picture = stream->readByte();
- room.curPicture = stream->readByte();
- room.isFirstTime = stream->readByte();
- _state.rooms.push_back(room);
- }
+ loadRooms(*stream, IDI_HR0_NUM_ROOMS);
stream.reset(_disk->createReadStream(0x21, 0x0));
-
loadItems(*stream);
}
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 34de518..b662142 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -142,21 +142,9 @@ void HiRes2Engine::initGameState() {
_state.vars.resize(IDI_HR2_NUM_VARS);
StreamPtr stream(_disk->createReadStream(0x21, 0x5, 0x0e, 7));
-
- for (uint i = 0; i < IDI_HR2_NUM_ROOMS; ++i) {
- Room room;
- stream->readByte(); // number
- for (uint j = 0; j < 6; ++j)
- room.connections[j] = stream->readByte();
- room.data = readDataBlockPtr(*stream);
- room.picture = stream->readByte();
- room.curPicture = stream->readByte();
- room.isFirstTime = stream->readByte();
- _state.rooms.push_back(room);
- }
+ loadRooms(*stream, IDI_HR2_NUM_ROOMS);
stream.reset(_disk->createReadStream(0x21, 0x0, 0x00, 2));
-
loadItems(*stream);
}
diff --git a/engines/adl/hires4.cpp b/engines/adl/hires4.cpp
index 1ce2a44..312cce6 100644
--- a/engines/adl/hires4.cpp
+++ b/engines/adl/hires4.cpp
@@ -35,40 +35,57 @@
namespace Adl {
HiRes4Engine::~HiRes4Engine() {
- delete _disk2;
- delete _disk3;
+ delete _boot;
}
void HiRes4Engine::init() {
_graphics = new Graphics_v2(*_display);
- const char *const *names = getDiskImageNames();
+ _boot = new DiskImage();
+ if (!_boot->open(getDiskImageName(0)))
+ error("Failed to open disk image '%s'", getDiskImageName(0));
- _disk = new DiskImage();
- if (!_disk->open(names[0]))
- error("Failed to open disk image '%s'", names[0]);
-
- _disk2 = new DiskImage();
- if (!_disk2->open(names[1]))
- error("Failed to open disk image '%s'", names[1]);
-
- _disk3 = new DiskImage();
- if (!_disk3->open(names[2]))
- error("Failed to open disk image '%s'", names[2]);
-
- StreamPtr stream(createReadStream(_disk, 0x06, 0xd, 0x12, 2));
+ StreamPtr stream(createReadStream(_boot, 0x06, 0xd, 0x12, 2));
loadItemDescriptions(*stream, IDI_HR4_NUM_ITEM_DESCS);
- stream.reset(createReadStream(_disk, 0x05, 0x4, 0x00, 3));
+ stream.reset(createReadStream(_boot, 0x05, 0x4, 0x00, 3));
loadWords(*stream, _verbs, _priVerbs);
- stream.reset(createReadStream(_disk, 0x03, 0xb, 0x00, 6));
+ stream.reset(createReadStream(_boot, 0x03, 0xb, 0x00, 6));
loadWords(*stream, _nouns, _priNouns);
}
+void HiRes4Engine::goToSideC() {
+ delete _disk;
+
+ _disk = new DiskImage();
+ if (!_disk->open(getDiskImageName(2)))
+ error("Failed to open disk image '%s'", getDiskImageName(2));
+
+ // As room.data is bound to the DiskImage, we need to rebind them here
+ StreamPtr stream(createReadStream(_boot, 0x03, 0x1, 0x0e, 17));
+ for (uint i = 0; i < IDI_HR4_NUM_ROOMS; ++i) {
+ stream->skip(7);
+ _state.rooms[i].data = readDataBlockPtr(*stream);
+ stream->skip(3);
+ }
+}
+
void HiRes4Engine::initGameState() {
- StreamPtr stream(createReadStream(_disk, 0x02, 0xc, 0x00, 12));
+ _disk = new DiskImage();
+ if (!_disk->open(getDiskImageName(1)))
+ error("Failed to open disk image '%s'", getDiskImageName(1));
+
+ _state.vars.resize(IDI_HR4_NUM_VARS);
+
+ StreamPtr stream(createReadStream(_boot, 0x03, 0x1, 0x0e, 9));
+ loadRooms(*stream, IDI_HR4_NUM_ROOMS);
+
+ stream.reset(createReadStream(_boot, 0x02, 0xc, 0x00, 12));
loadItems(*stream);
+
+ // FIXME
+ _display->moveCursorTo(Common::Point(0, 23));
}
Common::SeekableReadStream *HiRes4Engine::createReadStream(DiskImage *disk, byte track, byte sector, byte offset, byte size) const {
@@ -98,9 +115,9 @@ void HiRes4Engine_Atari::adjustDataBlockPtr(byte &track, byte §or, byte &off
sector = (sectorIndex - 1) % 18;
}
-const char *const *HiRes4Engine_Atari::getDiskImageNames() const {
+const char *HiRes4Engine_Atari::getDiskImageName(byte index) const {
static const char *const disks[] = { "ULYS1A.XFD", "ULYS1B.XFD", "ULYS2C.XFD" };
- return disks;
+ return disks[index];
}
Engine *HiRes4Engine_create(OSystem *syst, const AdlGameDescription *gd) {
diff --git a/engines/adl/hires4.h b/engines/adl/hires4.h
index a578080..b522657 100644
--- a/engines/adl/hires4.h
+++ b/engines/adl/hires4.h
@@ -29,6 +29,8 @@
namespace Adl {
+#define IDI_HR4_NUM_ROOMS 164
+#define IDI_HR4_NUM_VARS 40
#define IDI_HR4_NUM_ITEM_DESCS 44
class HiRes4Engine : public AdlEngine_v3 {
@@ -43,10 +45,10 @@ protected:
void initGameState();
Common::SeekableReadStream *createReadStream(DiskImage *disk, byte track, byte sector, byte offset = 0, byte size = 0) const;
- virtual const char *const *getDiskImageNames() const = 0;
+ void goToSideC();
+ virtual const char *getDiskImageName(byte index) const = 0;
- // FIXME: use an array?
- DiskImage *_disk2, *_disk3;
+ DiskImage *_boot;
};
class HiRes4Engine_Atari : public HiRes4Engine {
@@ -55,10 +57,10 @@ public:
private:
// AdlEngine_v2
- virtual void adjustDataBlockPtr(byte &track, byte §or, byte &offset, byte &size) const;
+ void adjustDataBlockPtr(byte &track, byte §or, byte &offset, byte &size) const;
// HiRes4Engine
- virtual const char *const *getDiskImageNames() const;
+ const char *getDiskImageName(byte index) const;
};
} // End of namespace Adl
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index cf06591..553729d 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -242,17 +242,7 @@ void HiRes6Engine::loadDisk(byte disk) {
stream->skip(14); // Skip invalid room 0
_state.rooms.clear();
- for (uint i = 0; i < count; ++i) {
- Room room;
- stream->readByte(); // number
- for (uint j = 0; j < 6; ++j)
- room.connections[j] = stream->readByte();
- room.data = readDataBlockPtr(*stream);
- room.picture = stream->readByte();
- room.curPicture = stream->readByte();
- room.isFirstTime = stream->readByte();
- _state.rooms.push_back(room);
- }
+ loadRooms(*stream, count);
break;
}
case 0x7b00:
More information about the Scummvm-git-logs
mailing list