diff options
author | Walter van Niftrik | 2016-04-15 23:49:00 +0200 |
---|---|---|
committer | Walter van Niftrik | 2016-06-06 20:35:49 +0200 |
commit | 92b1b287b1686424a58abfb06661916bf3dfcaeb (patch) | |
tree | faf30ce003f5573c4da4317f663e37b3d331f97c | |
parent | e755f8fcba4d3dfc746d83f60b70d2aad86360b9 (diff) | |
download | scummvm-rg350-92b1b287b1686424a58abfb06661916bf3dfcaeb.tar.gz scummvm-rg350-92b1b287b1686424a58abfb06661916bf3dfcaeb.tar.bz2 scummvm-rg350-92b1b287b1686424a58abfb06661916bf3dfcaeb.zip |
ADL: Preliminary support for hires6 disk changing
-rw-r--r-- | engines/adl/adl.cpp | 5 | ||||
-rw-r--r-- | engines/adl/hires6.cpp | 163 | ||||
-rw-r--r-- | engines/adl/hires6.h | 20 |
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 §or) const; + void loadDisk(byte disk); + + DiskImage_DSK *_boot; byte _currVerb, _currNoun; + Common::Array<DiskDataDesc> _diskDataDesc; }; } // End of namespace Adl |