void HiRes5Engine::init() { _graphics = new Graphics_v2(*_display); insertDisk(2); StreamPtr stream(_disk->createReadStream(0x5, 0x0, 0x02)); loadRegionLocations(*stream, kRegions); stream.reset(_disk->createReadStream(0xd, 0x2, 0x04)); loadRegionInitDataOffsets(*stream, kRegions); stream.reset(_disk->createReadStream(0x7, 0xe)); _strings.verbError = readStringAt(*stream, 0x4f); _strings.nounError = readStringAt(*stream, 0x8e); _strings.enterCommand = readStringAt(*stream, 0xbc); stream.reset(_disk->createReadStream(0x7, 0xc)); _strings.lineFeeds = readString(*stream); // TODO: opcode strings _messageIds.cantGoThere = 110; _messageIds.dontUnderstand = 112; _messageIds.itemDoesntMove = 114; _messageIds.itemNotHere = 115; _messageIds.thanksForPlaying = 113; stream.reset(_disk->createReadStream(0xe, 0x1, 0x13, 4)); loadItemDescriptions(*stream, kItems); stream.reset(_disk->createReadStream(0x8, 0xd, 0xfd, 1)); loadDroppedItemOffsets(*stream, 16); stream.reset(_disk->createReadStream(0xb, 0xa, 0x05, 1)); loadItemPicIndex(*stream, kItems); stream.reset(_disk->createReadStream(0x7, 0x8, 0x01)); for (uint i = 0; i < kItems; ++i) _itemTimeLimits.push_back(stream->readByte()); if (stream->eos() || stream->err()) error("Failed to read item time limits"); stream.reset(_disk->createReadStream(0x8, 0x2, 0x2d)); _gameStrings.itemTimeLimit = readString(*stream); stream.reset(_disk->createReadStream(0x8, 0x7, 0x02)); _gameStrings.carryingTooMuch = readString(*stream); }
void AdlEngine_v2::loadRoom(byte roomNr) { Room &room = getRoom(roomNr); StreamPtr stream(room.data->createReadStream()); uint16 descOffset = stream->readUint16LE(); uint16 commandOffset = stream->readUint16LE(); _roomData.pictures.clear(); // There's no picture count. The original engine always checks at most // five pictures. We use the description offset to bound our search. uint16 picCount = (descOffset - 4) / 5; for (uint i = 0; i < picCount; ++i) { byte nr = stream->readByte(); _roomData.pictures[nr] = readDataBlockPtr(*stream); } _roomData.description = readStringAt(*stream, descOffset, 0xff); _roomData.commands.clear(); if (commandOffset != 0) { stream->seek(commandOffset); readCommands(*stream, _roomData.commands); } }
void HiRes4Engine_Atari::init() { _graphics = new Graphics_v2(*_display); _boot = new DiskImage(); if (!_boot->open(atariDisks[0])) error("Failed to open disk image '%s'", atariDisks[0]); insertDisk(1); loadCommonData(); StreamPtr stream(createReadStream(_boot, 0x06, 0x2)); _strings.verbError = readStringAt(*stream, 0x4f); _strings.nounError = readStringAt(*stream, 0x83); _strings.enterCommand = readStringAt(*stream, 0xa6); stream.reset(createReadStream(_boot, 0x05, 0xb, 0xd7)); _strings_v2.time = readString(*stream, 0xff); stream.reset(createReadStream(_boot, 0x06, 0x7, 0x00, 2)); _strings_v2.saveInsert = readStringAt(*stream, 0x62); _strings_v2.saveReplace = readStringAt(*stream, 0xdd); _strings_v2.restoreInsert = readStringAt(*stream, 0x12a); _strings_v2.restoreReplace = readStringAt(*stream, 0x1b8); _strings.playAgain = readStringAt(*stream, 0x21b); // TODO: restart sequence has "insert side a/b" strings _messageIds.cantGoThere = IDI_HR4_MSG_CANT_GO_THERE; _messageIds.dontUnderstand = IDI_HR4_MSG_DONT_UNDERSTAND; _messageIds.itemDoesntMove = IDI_HR4_MSG_ITEM_DOESNT_MOVE; _messageIds.itemNotHere = IDI_HR4_MSG_ITEM_NOT_HERE; _messageIds.thanksForPlaying = IDI_HR4_MSG_THANKS_FOR_PLAYING; stream.reset(createReadStream(_boot, 0x06, 0xd, 0x12, 2)); loadItemDescriptions(*stream, IDI_HR4_NUM_ITEM_DESCS); stream.reset(createReadStream(_boot, 0x07, 0x1, 0xf4)); loadDroppedItemOffsets(*stream, IDI_HR4_NUM_ITEM_OFFSETS); stream.reset(createReadStream(_boot, 0x08, 0xe, 0xa5, 5)); readCommands(*stream, _roomCommands); stream.reset(createReadStream(_boot, 0x0a, 0x9, 0x00, 3)); readCommands(*stream, _globalCommands); stream.reset(createReadStream(_boot, 0x05, 0x4, 0x00, 3)); loadWords(*stream, _verbs, _priVerbs); stream.reset(createReadStream(_boot, 0x03, 0xb, 0x00, 6)); loadWords(*stream, _nouns, _priNouns); }
void HiRes1Engine::runIntro() const { StreamPtr stream(_files->createReadStream(IDS_HR1_EXE_0)); stream->seek(IDI_HR1_OFS_LOGO_0); _display->setMode(DISPLAY_MODE_HIRES); _display->loadFrameBuffer(*stream); _display->updateHiResScreen(); delay(4000); if (shouldQuit()) return; _display->setMode(DISPLAY_MODE_TEXT); StreamPtr basic(_files->createReadStream(IDS_HR1_LOADER)); Common::String str; str = readStringAt(*basic, IDI_HR1_OFS_PD_TEXT_0, '"'); _display->printAsciiString(str + '\r'); str = readStringAt(*basic, IDI_HR1_OFS_PD_TEXT_1, '"'); _display->printAsciiString(str + "\r\r"); str = readStringAt(*basic, IDI_HR1_OFS_PD_TEXT_2, '"'); _display->printAsciiString(str + "\r\r"); str = readStringAt(*basic, IDI_HR1_OFS_PD_TEXT_3, '"'); _display->printAsciiString(str + '\r'); inputKey(); if (g_engine->shouldQuit()) return; _display->setMode(DISPLAY_MODE_MIXED); str = readStringAt(*stream, IDI_HR1_OFS_GAME_OR_HELP); bool instructions = false; while (1) { _display->printString(str); Common::String s = inputString(); if (g_engine->shouldQuit()) break; if (s.empty()) continue; if (s[0] == APPLECHAR('I')) { instructions = true; break; } else if (s[0] == APPLECHAR('G')) { break; } }; if (instructions) { _display->setMode(DISPLAY_MODE_TEXT); stream->seek(IDI_HR1_OFS_INTRO_TEXT); const uint pages[] = { 6, 6, 4, 5, 8, 7, 0 }; uint page = 0; while (pages[page] != 0) { _display->home(); uint count = pages[page++]; for (uint i = 0; i < count; ++i) { str = readString(*stream); _display->printString(str); stream->seek(3, SEEK_CUR); } inputString(); if (g_engine->shouldQuit()) return; stream->seek(6, SEEK_CUR); } } _display->printAsciiString("\r"); _display->setMode(DISPLAY_MODE_MIXED); // Title screen shown during loading stream.reset(_files->createReadStream(IDS_HR1_EXE_1)); stream->seek(IDI_HR1_OFS_LOGO_1); _display->loadFrameBuffer(*stream); _display->updateHiResScreen(); delay(2000); }
void HiRes1Engine::init() { if (Common::File::exists("MYSTHOUS.DSK")) { _files = new Files_DOS33(); if (!static_cast<Files_DOS33 *>(_files)->open("MYSTHOUS.DSK")) error("Failed to open MYSTHOUS.DSK"); } else _files = new Files_Plain(); _graphics = new Graphics_v1(*_display); StreamPtr stream(_files->createReadStream(IDS_HR1_EXE_1)); // Some messages have overrides inside the executable _gameStrings.cantGoThere = readStringAt(*stream, IDI_HR1_OFS_STR_CANT_GO_THERE); _gameStrings.dontHaveIt = readStringAt(*stream, IDI_HR1_OFS_STR_DONT_HAVE_IT); _gameStrings.dontUnderstand = readStringAt(*stream, IDI_HR1_OFS_STR_DONT_UNDERSTAND); _gameStrings.gettingDark = readStringAt(*stream, IDI_HR1_OFS_STR_GETTING_DARK); // Load other strings from executable _strings.enterCommand = readStringAt(*stream, IDI_HR1_OFS_STR_ENTER_COMMAND); _strings.verbError = readStringAt(*stream, IDI_HR1_OFS_STR_VERB_ERROR); _strings.nounError = readStringAt(*stream, IDI_HR1_OFS_STR_NOUN_ERROR); _strings.playAgain = readStringAt(*stream, IDI_HR1_OFS_STR_PLAY_AGAIN); _strings.pressReturn = readStringAt(*stream, IDI_HR1_OFS_STR_PRESS_RETURN); _strings.lineFeeds = readStringAt(*stream, IDI_HR1_OFS_STR_LINE_FEEDS); // Set message IDs _messageIds.cantGoThere = IDI_HR1_MSG_CANT_GO_THERE; _messageIds.dontUnderstand = IDI_HR1_MSG_DONT_UNDERSTAND; _messageIds.itemDoesntMove = IDI_HR1_MSG_ITEM_DOESNT_MOVE; _messageIds.itemNotHere = IDI_HR1_MSG_ITEM_NOT_HERE; _messageIds.thanksForPlaying = IDI_HR1_MSG_THANKS_FOR_PLAYING; // Load message offsets stream->seek(IDI_HR1_OFS_MSGS); for (uint i = 0; i < IDI_HR1_NUM_MESSAGES; ++i) _messages.push_back(_files->getDataBlock(IDS_HR1_MESSAGES, stream->readUint16LE())); // Load picture data from executable stream->seek(IDI_HR1_OFS_PICS); for (uint i = 1; i <= IDI_HR1_NUM_PICS; ++i) { byte block = stream->readByte(); Common::String name = Common::String::format("BLOCK%i", block); uint16 offset = stream->readUint16LE(); _pictures[i] = _files->getDataBlock(name, offset); } // Load commands from executable stream->seek(IDI_HR1_OFS_CMDS_1); readCommands(*stream, _roomCommands); stream->seek(IDI_HR1_OFS_CMDS_0); readCommands(*stream, _globalCommands); // Load dropped item offsets stream->seek(IDI_HR1_OFS_ITEM_OFFSETS); loadDroppedItemOffsets(*stream, IDI_HR1_NUM_ITEM_OFFSETS); // Load right-angle line art stream->seek(IDI_HR1_OFS_CORNERS); uint16 cornersCount = stream->readUint16LE(); for (uint i = 0; i < cornersCount; ++i) _corners.push_back(_files->getDataBlock(IDS_HR1_EXE_1, IDI_HR1_OFS_CORNERS + stream->readUint16LE())); if (stream->eos() || stream->err()) error("Failed to read game data from '" IDS_HR1_EXE_1 "'"); stream->seek(IDI_HR1_OFS_VERBS); loadWords(*stream, _verbs, _priVerbs); stream->seek(IDI_HR1_OFS_NOUNS); loadWords(*stream, _nouns, _priNouns); }
const char* ByteData::readString(uint16_t len, uint16_t moveBy) { const char* str = readStringAt(m_pos, len); m_pos += (moveBy == 0) ? len : moveBy; return str; }