ADL: Add support for more hires2 variants

This commit is contained in:
Walter van Niftrik 2021-07-27 21:36:38 +02:00
parent 691392a109
commit 87a75ad02b
6 changed files with 93 additions and 47 deletions

View file

@ -147,6 +147,24 @@ Common::String AdlEngine::readStringAt(Common::SeekableReadStream &stream, uint
return readString(stream, until);
}
void AdlEngine::extractExeStrings(Common::ReadStream &stream, uint16 printAddr, Common::StringArray &strings) const {
uint32 window = 0;
for (;;) {
window <<= 8;
window |= stream.readByte();
if (stream.eos())
return;
if (stream.err())
error("Failed to extract strings from game executable");
if ((window & 0xffffff) == (0x200000U | printAddr))
strings.push_back(readString(stream));
}
}
void AdlEngine::printMessage(uint idx) {
printString(loadMessage(idx));
}

View file

@ -269,6 +269,7 @@ protected:
virtual void saveState(Common::WriteStream &stream);
Common::String readString(Common::ReadStream &stream, byte until = 0) const;
Common::String readStringAt(Common::SeekableReadStream &stream, uint offset, byte until = 0) const;
void extractExeStrings(Common::ReadStream &stream, uint16 printAddr, Common::StringArray &strings) const;
virtual void printString(const Common::String &str) = 0;
virtual Common::String loadMessage(uint idx) const = 0;

View file

@ -568,6 +568,9 @@ int AdlEngine_v2::o_tellTime(ScriptEnv &e) {
Common::String time = _strings_v2.time;
if (time.size() <= 16)
error("Invalid time string");
const char zeroChar = _display->asciiToNative('0');
time.setChar(zeroChar + _state.time.hours / 10, 12);

View file

@ -277,9 +277,45 @@ static const AdlGameDescription gameDiskDescriptions[] = {
GAME_TYPE_HIRES1,
GAME_VER_HR1_PD
},
{ // Hi-Res Adventure #2: Wizard and the Princess - Apple II - DOS 3.2 only
{
"hires2", "On-Line Systems [A]",
AD_ENTRY1s("wizard", "5201c87db24ba7e3fa447471f4f2ec99", 116480),
Common::EN_ANY,
Common::kPlatformApple2,
ADGF_NO_FLAGS,
DEFAULT_OPTIONS
},
GAME_TYPE_HIRES2,
GAME_VER_NONE
},
{ // Hi-Res Adventure #2: Wizard and the Princess - Apple II
{
"hires2", "On-Line Systems [B]",
AD_ENTRY1s("wizard", "1de984859212ff11cf61b29cb9b55f8c", 116480),
Common::EN_ANY,
Common::kPlatformApple2,
ADGF_NO_FLAGS,
DEFAULT_OPTIONS
},
GAME_TYPE_HIRES2,
GAME_VER_NONE
},
{ // Hi-Res Adventure #2: Wizard and the Princess - Apple II - Green Valley Publishing
{
"hires2", "Green Valley [A]",
AD_ENTRY1s("wizard", "73cd373e9a2946c3181b72fdf7a32c77", 143360),
Common::EN_ANY,
Common::kPlatformApple2,
ADGF_NO_FLAGS,
DEFAULT_OPTIONS
},
GAME_TYPE_HIRES2,
GAME_VER_NONE
},
{ // Hi-Res Adventure #2: Wizard and the Princess - Apple II - Roberta Williams Anthology
{
"hires2", "",
"hires2", "Green Valley [B]",
AD_ENTRY1s("wizard", "72b114bf8f94fafe5672daac2a70c765", 143360),
Common::EN_ANY,
Common::kPlatformApple2,
@ -375,7 +411,7 @@ static const AdlGameDescription gameDiskDescriptions[] = {
},
{ // Hi-Res Adventure #6: The Dark Crystal - Apple II - Roberta Williams Anthology / SierraVenture
{
"hires6", "SierraVenture [version A]",
"hires6", "SierraVenture [A]",
{
{ "dark1a", 0, "9a5968a8f378c84454d88f4cd4e143a9", 143360 },
{ "dark1b", 3, "1271ff9c3e1bdb4942301dd37dd0ef87", 143360 },
@ -393,7 +429,7 @@ static const AdlGameDescription gameDiskDescriptions[] = {
},
{ // Hi-Res Adventure #6: The Dark Crystal - Apple II - SierraVenture
{
"hires6", "SierraVenture [version B]",
"hires6", "SierraVenture [B]",
{
{ "dark1a", 0, "d0b8e808b02564b6ce58b5ea5cc61ead", 143360 },
{ "dark1b", 3, "1271ff9c3e1bdb4942301dd37dd0ef87", 143360 },

View file

@ -90,7 +90,6 @@ protected:
void loadRoom(byte roomNr) override;
void showRoom() override;
void extractExeStrings(Common::ReadStream &stream, Common::StringArray &strings);
void showInstructions(Common::SeekableReadStream &stream);
void wordWrap(Common::String &str) const;
@ -108,24 +107,6 @@ protected:
} _gameStrings;
};
void HiRes1Engine::extractExeStrings(Common::ReadStream &stream, Common::StringArray &strings) {
uint32 window = 0;
for (;;) {
window <<= 8;
window |= stream.readByte();
if (stream.eos())
return;
if (stream.err())
error("Failed to extract strings from game executable");
if ((window & 0xffffff) == 0x201576)
strings.push_back(readString(stream));
}
}
void HiRes1Engine::showInstructions(Common::SeekableReadStream &stream) {
_display->setMode(Display::kModeText);
@ -301,7 +282,7 @@ void HiRes1Engine::init() {
StreamPtr stream(_files->createReadStream(IDS_HR1_EXE_1));
Common::StringArray exeStrings;
extractExeStrings(*stream, exeStrings);
extractExeStrings(*stream, 0x1576, exeStrings);
if (exeStrings.size() != 18)
error("Failed to load strings from executable");

View file

@ -70,28 +70,37 @@ void HiResBaseEngine::init() {
StreamPtr stream(_disk->createReadStream(0x1f, 0x2, 0x00, 4));
loadMessages(*stream, _numMsgs);
// Read parser messages
stream.reset(_disk->createReadStream(0x1a, 0x1));
_strings.verbError = readStringAt(*stream, 0x4f);
_strings.nounError = readStringAt(*stream, 0x8e);
_strings.enterCommand = readStringAt(*stream, 0xbc);
stream.reset(_disk->createReadStream(0x19, 0x0, 0x00, 25, 13));
Common::StringArray exeStrings;
extractExeStrings(*stream, 0x1566, exeStrings);
// Read time string
if (exeStrings.size() < 11)
error("Failed to load strings from executable");
// Heuristic to test for early versions that differ slightly
// Later versions have two additional strings for "INIT DISK"
const bool oldEngine = exeStrings.size() < 13;
// Read parser messages
_strings.verbError = exeStrings[2];
_strings.nounError = exeStrings[3];
_strings.enterCommand = exeStrings[4];
if (!oldEngine) {
stream.reset(_disk->createReadStream(0x19, 0x7, 0xd7));
_strings_v2.time = readString(*stream, 0xff);
}
// Read line feeds
stream.reset(_disk->createReadStream(0x19, 0xb, 0xf8, 1));
_strings.lineFeeds = readString(*stream);
_strings.lineFeeds = exeStrings[0];
// Read opcode strings
stream.reset(_disk->createReadStream(0x1a, 0x6, 0x00, 2));
_strings_v2.saveInsert = readStringAt(*stream, 0x5f);
_strings_v2.saveReplace = readStringAt(*stream, 0xe5);
_strings_v2.restoreInsert = readStringAt(*stream, 0x132);
_strings_v2.restoreReplace = readStringAt(*stream, 0x1c2);
_strings.playAgain = readStringAt(*stream, 0x225);
_strings.pressReturn = readStringAt(*stream, 0x25f);
_strings_v2.saveInsert = exeStrings[5];
_strings_v2.saveReplace = exeStrings[6];
_strings_v2.restoreInsert = exeStrings[7];
_strings_v2.restoreReplace = exeStrings[8];
_strings.playAgain = exeStrings[9];
_strings.pressReturn = exeStrings[10];
// Load global picture data
stream.reset(_disk->createReadStream(0x19, 0xa, 0x80, 0));
@ -105,7 +114,7 @@ void HiResBaseEngine::init() {
stream.reset(_disk->createReadStream(0x1d, 0x7, 0x00, 4));
readCommands(*stream, _roomCommands);
stream.reset(_disk->createReadStream(0x1f, 0x7, 0x00, 3));
stream.reset(_disk->createReadStream((oldEngine ? 0x19 : 0x1f), 0x7, 0x00, 3));
readCommands(*stream, _globalCommands);
// Load dropped item offsets
@ -151,10 +160,10 @@ HiRes2Engine::HiRes2Engine(OSystem *syst, const AdlGameDescription *gd) :
}
void HiRes2Engine::runIntro() {
// This only works for the 16-sector re-release. The original
// release is not supported at this time, because we don't have
// access to it.
_disk->setSectorLimit(0);
// Only the Green Valley version has a title screen
if (_disk->getSectorsPerTrack() != 16)
return;
StreamPtr stream(_disk->createReadStream(0x00, 0xd, 0x17, 1));
_display->setMode(Display::kModeText);
@ -166,8 +175,6 @@ void HiRes2Engine::runIntro() {
_display->printString(str);
delay(2000);
_disk->setSectorLimit(13);
}
class HiRes3Engine : public HiResBaseEngine {