From 0300979bdd8d2ca451110d77cb8e05c84365bbec Mon Sep 17 00:00:00 2001 From: Walter van Niftrik Date: Sun, 4 Feb 2018 16:11:59 +0100 Subject: [PATCH] ADL: Add support for another hires1 variant --- engines/adl/detection.cpp | 30 +++++++-- engines/adl/detection.h | 22 ++++++- engines/adl/hires1.cpp | 130 +++++++++++++++++++++++--------------- 3 files changed, 121 insertions(+), 61 deletions(-) diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp index 7c196d34cb4e..e63beb2c0769 100644 --- a/engines/adl/detection.cpp +++ b/engines/adl/detection.cpp @@ -94,7 +94,23 @@ struct AdlGameDescription { }; static const AdlGameDescription gameFileDescriptions[] = { - { // Hi-Res Adventure #1: Mystery House - Apple II - 2nd release + { // Hi-Res Adventure #1: Mystery House - Apple II - Contains Simi Valley address + { + "hires1", 0, + { + { "ADVENTURE", 0, "22d9e63a11d69fa033ba1738715ad09a", 29952 }, + { "AUTO LOAD OBJ", 0, "a2ab7be25842e1fa9f1343b0894a8b6f", 4095 }, + AD_LISTEND + }, + Common::EN_ANY, + Common::kPlatformApple2, + ADGF_NO_FLAGS, + GUIO2(GAMEOPTION_COLOR_DEFAULT_OFF, GAMEOPTION_SCANLINES) + }, + GAME_TYPE_HIRES1, + GAME_VER_HR1_SIMI + }, + { // Hi-Res Adventure #1: Mystery House - Apple II - Contains Coarsegold address { "hires1", 0, { @@ -131,11 +147,11 @@ static const AdlGameDescription gameFileDescriptions[] = { }; static const AdlGameDescription gameDiskDescriptions[] = { - { // Hi-Res Adventure #1: Mystery House - Apple II - Roberta Williams Anthology + { // Hi-Res Adventure #1: Mystery House - Apple II - Contains Coarsegold address { "hires1", 0, { - { "mysthous", 0, "54d20eb1ef0084ac3c2d16c31c5b7eb7", 143360 }, + { "mysthous", 0, "8df0b3b3e609a2e40237e2419c1cb767", 116480 }, AD_LISTEND }, Common::EN_ANY, @@ -144,13 +160,13 @@ static const AdlGameDescription gameDiskDescriptions[] = { GUIO2(GAMEOPTION_COLOR_DEFAULT_OFF, GAMEOPTION_SCANLINES) }, GAME_TYPE_HIRES1, - GAME_VER_HR1_PD + GAME_VER_HR1_COARSE }, - { // Hi-Res Adventure #1: Mystery House - Apple II - 2nd release + { // Hi-Res Adventure #1: Mystery House - Apple II - Roberta Williams Anthology { "hires1", 0, { - { "mysthous", 0, "8df0b3b3e609a2e40237e2419c1cb767", 116480 }, + { "mysthous", 0, "54d20eb1ef0084ac3c2d16c31c5b7eb7", 143360 }, AD_LISTEND }, Common::EN_ANY, @@ -159,7 +175,7 @@ static const AdlGameDescription gameDiskDescriptions[] = { GUIO2(GAMEOPTION_COLOR_DEFAULT_OFF, GAMEOPTION_SCANLINES) }, GAME_TYPE_HIRES1, - GAME_VER_HR1_COARSE + GAME_VER_HR1_PD }, { // Hi-Res Adventure #2: Wizard and the Princess - Apple II - Roberta Williams Anthology { diff --git a/engines/adl/detection.h b/engines/adl/detection.h index 6f0ae6795b86..bd009d2cb25b 100644 --- a/engines/adl/detection.h +++ b/engines/adl/detection.h @@ -39,11 +39,27 @@ enum GameType { GAME_TYPE_HIRES6 }; +/* + * ====== Mystery House supported versions ====== + * GAME_VER_HR1_SIMI: + * - Instructions always shown (no prompt) + * - Instructions contain Simi Valley address + * - On-Line Systems title screen in main executable only and waits for key + * GAME_VER_HR1_COARSE: + * - Longer instructions, now containing Coarsegold address + * - On-Line Systems title screen with instructions prompt + * GAME_VER_HR1_PD: + * - Public Domain disclaimer on startup + * - Sierra On-Line title screen with instructions prompt + * + * Note: there are probably at least two or three more variants + */ + enum GameVersion { GAME_VER_NONE = 0, - GAME_VER_HR1_SIMI = 0, // On-Line Systems (Simi Valley) - GAME_VER_HR1_COARSE, // On-Line Systems (Coarsegold) - GAME_VER_HR1_PD // Sierra On-Line PD release + GAME_VER_HR1_SIMI = 0, + GAME_VER_HR1_COARSE, + GAME_VER_HR1_PD }; struct AdlGameDescription; diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp index fe7ed20b3a51..2cf293189601 100644 --- a/engines/adl/hires1.cpp +++ b/engines/adl/hires1.cpp @@ -108,6 +108,7 @@ class HiRes1Engine : public AdlEngine { void loadRoom(byte roomNr); void showRoom(); + void showInstructions(Common::SeekableReadStream &stream, const uint pages[], bool goHome); void wordWrap(Common::String &str) const; Files *_files; @@ -124,20 +125,46 @@ class HiRes1Engine : public AdlEngine { } _gameStrings; }; -void HiRes1Engine::runIntro() { - StreamPtr stream(_files->createReadStream(IDS_HR1_EXE_0)); +void HiRes1Engine::showInstructions(Common::SeekableReadStream &stream, const uint pages[], bool goHome) { + _display->setMode(DISPLAY_MODE_TEXT); - stream->seek(IDI_HR1_OFS_LOGO_0); - _display->setMode(DISPLAY_MODE_HIRES); - _display->loadFrameBuffer(*stream); - _display->updateHiResScreen(); + uint page = 0; + while (pages[page] != 0) { + if (goHome) + _display->home(); - if (getGameVersion() == GAME_VER_HR1_PD) { - // Only the PD version shows a title screen during the load - delay(4000); + uint count = pages[page++]; + for (uint i = 0; i < count; ++i) { + _display->printString(readString(stream)); + stream.seek(3, SEEK_CUR); + } + + inputString(); if (shouldQuit()) return; + + stream.seek((goHome ? 6 : 3), SEEK_CUR); + } +} + +void HiRes1Engine::runIntro() { + StreamPtr stream(_files->createReadStream(IDS_HR1_EXE_0)); + + // Early version have no bitmap in 'AUTO LOAD OBJ' + if (getGameVersion() >= GAME_VER_HR1_COARSE) { + stream->seek(IDI_HR1_OFS_LOGO_0); + _display->setMode(DISPLAY_MODE_HIRES); + _display->loadFrameBuffer(*stream); + _display->updateHiResScreen(); + + if (getGameVersion() == GAME_VER_HR1_PD) { + // Only the PD version shows a title screen during the load + delay(4000); + + if (shouldQuit()) + return; + } } Common::String str; @@ -166,7 +193,7 @@ void HiRes1Engine::runIntro() { _display->printAsciiString(str + '\r'); inputKey(); - if (g_engine->shouldQuit()) + if (shouldQuit()) return; } @@ -174,59 +201,60 @@ void HiRes1Engine::runIntro() { str = readStringAt(*stream, IDI_HR1_OFS_GAME_OR_HELP); - bool instructions = false; + if (getGameVersion() >= GAME_VER_HR1_COARSE) { + bool instructions = false; - while (1) { - _display->printString(str); - Common::String s = inputString(); + while (1) { + _display->printString(str); + Common::String s = inputString(); - if (g_engine->shouldQuit()) - break; + if (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); + if (s.empty()) + continue; - 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); + if (s[0] == APPLECHAR('I')) { + instructions = true; + break; + } else if (s[0] == APPLECHAR('G')) { + break; } + } - inputString(); - - if (g_engine->shouldQuit()) - return; - - stream->seek(6, SEEK_CUR); + if (instructions) { + // This version shows the last page during the loading of the game + // We wait for a key instead (even though there's no prompt for that). + const uint pages[] = { 6, 6, 4, 5, 8, 7, 0 }; + stream->seek(IDI_HR1_OFS_INTRO_TEXT); + showInstructions(*stream, pages, true); + _display->printAsciiString("\r"); } + } else { + const uint pages[] = { 6, 6, 8, 6, 0 }; + stream->seek(6); + showInstructions(*stream, pages, false); } - _display->printAsciiString("\r"); + stream.reset(_files->createReadStream(IDS_HR1_EXE_1)); + stream->seek(0x1800); + _display->loadFrameBuffer(*stream); + _display->updateHiResScreen(); _display->setMode(DISPLAY_MODE_MIXED); - // As we switch back to graphics mode, the title screen is briefly visible here - // (and in the PD version, it's a different title screen from the initial one). - // As this is probably non-intentional, we skip it and go straight to the game. + if (getGameVersion() == GAME_VER_HR1_SIMI) { + // The original waits for the key after initializing the state. + // This causes it to also wait for a key on a blank screen when + // a game is restarted. We only wait for a key here during the + // intro. + + // This does mean we need to push out some extra line feeds to clear the screen + _display->printString(_strings.lineFeeds); + inputKey(); + if (shouldQuit()) + return; + } } void HiRes1Engine::init() {