void HiRes1Engine::initGameState() { _state.vars.resize(IDI_HR1_NUM_VARS); StreamPtr stream(_files->createReadStream(IDS_HR1_EXE_1)); // Load room data from executable _roomDesc.clear(); stream->seek(IDI_HR1_OFS_ROOMS); for (uint i = 0; i < IDI_HR1_NUM_ROOMS; ++i) { Room room; stream->readByte(); _roomDesc.push_back(stream->readByte()); for (uint j = 0; j < 6; ++j) room.connections[j] = stream->readByte(); room.picture = stream->readByte(); room.curPicture = stream->readByte(); _state.rooms.push_back(room); } // Load item data from executable stream->seek(IDI_HR1_OFS_ITEMS); 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(); byte size = stream->readByte(); for (uint i = 0; i < size; ++i) item.roomPictures.push_back(stream->readByte()); _state.items.push_back(item); } }
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); }
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); }