aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/adl/adl.cpp5
-rw-r--r--engines/adl/hires6.cpp163
-rw-r--r--engines/adl/hires6.h20
3 files changed, 136 insertions, 52 deletions
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index c17855d47c..761b60c717 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -219,6 +219,9 @@ byte AdlEngine::inputKey(bool showCursor) const {
void AdlEngine::loadWords(Common::ReadStream &stream, WordMap &map, Common::StringArray &pri) const {
uint index = 0;
+ map.clear();
+ pri.clear();
+
while (1) {
++index;
@@ -255,6 +258,8 @@ void AdlEngine::loadWords(Common::ReadStream &stream, WordMap &map, Common::Stri
}
void AdlEngine::readCommands(Common::ReadStream &stream, Commands &commands) {
+ commands.clear();
+
while (1) {
Command command;
command.room = stream.readByte();
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index eaf468c3cc..c3c4138bf0 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -109,13 +109,13 @@ void HiRes6Engine::runIntro() const {
}
void HiRes6Engine::init() {
- DiskImage_DSK *boot(new DiskImage_DSK());
+ _boot = new DiskImage_DSK();
_graphics = new Graphics_v2(*_display);
- if (!boot->open(disks[0]))
+ if (!_boot->open(disks[0]))
error("Failed to open disk image '%s'", disks[0]);
- StreamPtr stream(loadSectors(boot, 0x7));
+ StreamPtr stream(loadSectors(_boot, 0x7));
// Read parser messages
_strings.verbError = readStringAt(*stream, 0x666);
@@ -140,13 +140,13 @@ void HiRes6Engine::init() {
_messageIds.thanksForPlaying = IDI_HR6_MSG_THANKS_FOR_PLAYING;
// Item descriptions
- stream.reset(loadSectors(boot, 0x6, 0xb, 2));
+ 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));
// Load dropped item offsets
- stream.reset(boot->createReadStream(0x8, 0x9, 0x16));
+ stream.reset(_boot->createReadStream(0x8, 0x9, 0x16));
for (uint i = 0; i < IDI_HR6_NUM_ITEM_OFFSETS; ++i) {
Common::Point p;
p.x = stream->readByte();
@@ -154,68 +154,129 @@ void HiRes6Engine::init() {
_itemOffsets.push_back(p);
}
+ // Location of game data for each disc
+ stream.reset(_boot->createReadStream(0x5, 0xa, 0x03));
+ for (uint i = 0; i < sizeof(disks); ++i) {
+ DiskDataDesc desc;
+ desc.track = stream->readByte();
+ desc.sector = stream->readByte();
+ desc.offset = stream->readByte();
+ desc.volume = stream->readByte();
+ _diskDataDesc.push_back(desc);
+ }
+}
+
+void HiRes6Engine::loadDisk(byte disk) {
+ delete _disk;
_disk = new DiskImage_NIB();
- if (!_disk->open(disks[1]))
- error("Failed to open disk image '%s'", disks[1]);
+ if (!_disk->open(disks[disk]))
+ error("Failed to open disk image '%s'", disks[disk]);
- // Load item picture data
- stream.reset(boot->createReadStream(0xb, 0xd, 0x08));
- for (uint i = 0; i < IDI_HR6_NUM_ITEM_PICS; ++i) {
- stream->readByte();
- _itemPics.push_back(readDataBlockPtr(*stream));
- }
+ _curDisk = disk;
- // Load global picture data
- stream.reset(_disk->createReadStream(0x1f, 0xf, 0x16));
- byte picNr;
- while ((picNr = stream->readByte()) != 0xff) {
- if (stream->eos() || stream->err())
- error("Error reading global pic list");
- _pictures[picNr] = readDataBlockPtr(*stream);
- }
+ byte track = _diskDataDesc[disk].track;
+ byte sector = _diskDataDesc[disk].sector;
+ uint offset = _diskDataDesc[disk].offset;
- // Load message offsets
- stream.reset(_disk->createReadStream(0x1f, 0xb, 0x16, 4));
- for (uint i = 0; i < IDI_HR6_NUM_MESSAGES; ++i)
- _messages.push_back(readDataBlockPtr(*stream));
+ applyDataBlockOffset(track, sector);
- // Load commands
- stream.reset(_disk->createReadStream(0x21, 0x4, 0x85, 7));
- readCommands(*stream, _roomCommands);
+ StreamPtr stream;
- stream.reset(_disk->createReadStream(0x20, 0xf, 0x82, 5));
- readCommands(*stream, _globalCommands);
+ for (uint block = 0; block < 7; ++block) {
+ stream.reset(_disk->createReadStream(track, sector, offset, 1));
- // Load verbs
- stream.reset(_disk->createReadStream(0x1f, 0xf, 0x56, 6));
- loadWords(*stream, _verbs, _priVerbs);
+ uint16 addr = stream->readUint16LE();
+ uint16 size = stream->readUint16LE();
- // Load nouns
- stream.reset(_disk->createReadStream(0x20, 0x5, 0x8e, 8));
- loadWords(*stream, _nouns, _priNouns);
+ stream.reset(_disk->createReadStream(track, sector, offset, size / 256 + 1));
+ stream->skip(4);
- delete boot;
+ switch (addr) {
+ case 0x9000: {
+ // Messages
+ _messages.clear();
+ uint count = size / 4;
+ for (uint i = 0; i < count; ++i)
+ _messages.push_back(readDataBlockPtr(*stream));
+ break;
+ }
+ case 0x4a80: {
+ // Global pics
+ _pictures.clear();
+ byte picNr;
+ while ((picNr = stream->readByte()) != 0xff) {
+ if (stream->eos() || stream->err())
+ error("Error reading global pic list");
+ _pictures[picNr] = readDataBlockPtr(*stream);
+ }
+ break;
+ }
+ case 0x4000:
+ // Verbs
+ loadWords(*stream, _verbs, _priVerbs);
+ break;
+ case 0x1800:
+ // Nouns
+ loadWords(*stream, _nouns, _priNouns);
+ break;
+ case 0x0e00: {
+ // Rooms
+ uint count = size / 14 - 1;
+ 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);
+ }
+ break;
+ }
+ case 0x7b00:
+ // Global commands
+ readCommands(*stream, _globalCommands);
+ break;
+ case 0x9500:
+ // Room commands
+ readCommands(*stream, _roomCommands);
+ break;
+ default:
+ error("Unknown data block found (addr %04x; size %04x)", addr, size);
+ }
+
+ offset += 4 + size;
+ while (offset >= 256) {
+ offset -= 256;
+ ++sector;
+ if (sector >= 16) {
+ sector = 0;
+ ++track;
+ }
+ }
+ }
+
+ // Load item picture data (indexed on boot disk)
+ stream.reset(_boot->createReadStream(0xb, 0xd, 0x08));
+ _itemPics.clear();
+ for (uint i = 0; i < IDI_HR6_NUM_ITEM_PICS; ++i) {
+ stream->readByte();
+ _itemPics.push_back(readDataBlockPtr(*stream));
+ }
}
void HiRes6Engine::initGameState() {
_state.vars.resize(IDI_HR6_NUM_VARS);
- StreamPtr stream(_disk->createReadStream(0x20, 0xd, 0x94, 2));
-
- for (uint i = 0; i < IDI_HR6_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);
- }
+ loadDisk(1);
- stream.reset(_disk->createReadStream(0x22, 0x0, 0x07, 0));
+ StreamPtr stream(_boot->createReadStream(0x3, 0xe, 0x03));
byte id;
while ((id = stream->readByte()) != 0xff) {
diff --git a/engines/adl/hires6.h b/engines/adl/hires6.h
index 443a9ca5a9..aa3dbf5e77 100644
--- a/engines/adl/hires6.h
+++ b/engines/adl/hires6.h
@@ -49,9 +49,23 @@ namespace Adl {
#define IDI_HR6_MSG_ITEM_NOT_HERE 254
#define IDI_HR6_MSG_THANKS_FOR_PLAYING 252
+struct DiskDataDesc {
+ byte track;
+ byte sector;
+ byte offset;
+ byte volume;
+};
+
class HiRes6Engine : public AdlEngine_v3 {
public:
- HiRes6Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine_v3(syst, gd), _currVerb(0), _currNoun(0) { }
+ HiRes6Engine(OSystem *syst, const AdlGameDescription *gd) :
+ AdlEngine_v3(syst, gd),
+ _boot(nullptr),
+ _currVerb(0),
+ _currNoun(0) {
+ }
+
+ ~HiRes6Engine() { delete _boot; }
private:
// AdlEngine
@@ -65,7 +79,11 @@ private:
void printString(const Common::String &str);
void applyDataBlockOffset(byte &track, byte &sector) const;
+ void loadDisk(byte disk);
+
+ DiskImage_DSK *_boot;
byte _currVerb, _currNoun;
+ Common::Array<DiskDataDesc> _diskDataDesc;
};
} // End of namespace Adl