[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 &sector, 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 &sector) 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 &sector, 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 &sector, byte &offset, byte &size) const;
 
 	void applyDiskOffset(byte &track, byte &sector) 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 &sector, 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 &sector, 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 &sector, 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 &sector, 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 &sector, byte &offset, byte &size) const;
+	void adjustDataBlockPtr(byte &track, byte &sector, 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