ADL: Add support for more hires2 variants
This commit is contained in:
parent
691392a109
commit
87a75ad02b
6 changed files with 93 additions and 47 deletions
|
@ -147,6 +147,24 @@ Common::String AdlEngine::readStringAt(Common::SeekableReadStream &stream, uint
|
||||||
return readString(stream, until);
|
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) {
|
void AdlEngine::printMessage(uint idx) {
|
||||||
printString(loadMessage(idx));
|
printString(loadMessage(idx));
|
||||||
}
|
}
|
||||||
|
|
|
@ -269,6 +269,7 @@ protected:
|
||||||
virtual void saveState(Common::WriteStream &stream);
|
virtual void saveState(Common::WriteStream &stream);
|
||||||
Common::String readString(Common::ReadStream &stream, byte until = 0) const;
|
Common::String readString(Common::ReadStream &stream, byte until = 0) const;
|
||||||
Common::String readStringAt(Common::SeekableReadStream &stream, uint offset, 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 void printString(const Common::String &str) = 0;
|
||||||
virtual Common::String loadMessage(uint idx) const = 0;
|
virtual Common::String loadMessage(uint idx) const = 0;
|
||||||
|
|
|
@ -568,6 +568,9 @@ int AdlEngine_v2::o_tellTime(ScriptEnv &e) {
|
||||||
|
|
||||||
Common::String time = _strings_v2.time;
|
Common::String time = _strings_v2.time;
|
||||||
|
|
||||||
|
if (time.size() <= 16)
|
||||||
|
error("Invalid time string");
|
||||||
|
|
||||||
const char zeroChar = _display->asciiToNative('0');
|
const char zeroChar = _display->asciiToNative('0');
|
||||||
|
|
||||||
time.setChar(zeroChar + _state.time.hours / 10, 12);
|
time.setChar(zeroChar + _state.time.hours / 10, 12);
|
||||||
|
|
|
@ -277,9 +277,45 @@ static const AdlGameDescription gameDiskDescriptions[] = {
|
||||||
GAME_TYPE_HIRES1,
|
GAME_TYPE_HIRES1,
|
||||||
GAME_VER_HR1_PD
|
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
|
{ // Hi-Res Adventure #2: Wizard and the Princess - Apple II - Roberta Williams Anthology
|
||||||
{
|
{
|
||||||
"hires2", "",
|
"hires2", "Green Valley [B]",
|
||||||
AD_ENTRY1s("wizard", "72b114bf8f94fafe5672daac2a70c765", 143360),
|
AD_ENTRY1s("wizard", "72b114bf8f94fafe5672daac2a70c765", 143360),
|
||||||
Common::EN_ANY,
|
Common::EN_ANY,
|
||||||
Common::kPlatformApple2,
|
Common::kPlatformApple2,
|
||||||
|
@ -375,7 +411,7 @@ static const AdlGameDescription gameDiskDescriptions[] = {
|
||||||
},
|
},
|
||||||
{ // Hi-Res Adventure #6: The Dark Crystal - Apple II - Roberta Williams Anthology / SierraVenture
|
{ // Hi-Res Adventure #6: The Dark Crystal - Apple II - Roberta Williams Anthology / SierraVenture
|
||||||
{
|
{
|
||||||
"hires6", "SierraVenture [version A]",
|
"hires6", "SierraVenture [A]",
|
||||||
{
|
{
|
||||||
{ "dark1a", 0, "9a5968a8f378c84454d88f4cd4e143a9", 143360 },
|
{ "dark1a", 0, "9a5968a8f378c84454d88f4cd4e143a9", 143360 },
|
||||||
{ "dark1b", 3, "1271ff9c3e1bdb4942301dd37dd0ef87", 143360 },
|
{ "dark1b", 3, "1271ff9c3e1bdb4942301dd37dd0ef87", 143360 },
|
||||||
|
@ -393,7 +429,7 @@ static const AdlGameDescription gameDiskDescriptions[] = {
|
||||||
},
|
},
|
||||||
{ // Hi-Res Adventure #6: The Dark Crystal - Apple II - SierraVenture
|
{ // Hi-Res Adventure #6: The Dark Crystal - Apple II - SierraVenture
|
||||||
{
|
{
|
||||||
"hires6", "SierraVenture [version B]",
|
"hires6", "SierraVenture [B]",
|
||||||
{
|
{
|
||||||
{ "dark1a", 0, "d0b8e808b02564b6ce58b5ea5cc61ead", 143360 },
|
{ "dark1a", 0, "d0b8e808b02564b6ce58b5ea5cc61ead", 143360 },
|
||||||
{ "dark1b", 3, "1271ff9c3e1bdb4942301dd37dd0ef87", 143360 },
|
{ "dark1b", 3, "1271ff9c3e1bdb4942301dd37dd0ef87", 143360 },
|
||||||
|
|
|
@ -90,7 +90,6 @@ protected:
|
||||||
void loadRoom(byte roomNr) override;
|
void loadRoom(byte roomNr) override;
|
||||||
void showRoom() override;
|
void showRoom() override;
|
||||||
|
|
||||||
void extractExeStrings(Common::ReadStream &stream, Common::StringArray &strings);
|
|
||||||
void showInstructions(Common::SeekableReadStream &stream);
|
void showInstructions(Common::SeekableReadStream &stream);
|
||||||
void wordWrap(Common::String &str) const;
|
void wordWrap(Common::String &str) const;
|
||||||
|
|
||||||
|
@ -108,24 +107,6 @@ protected:
|
||||||
} _gameStrings;
|
} _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) {
|
void HiRes1Engine::showInstructions(Common::SeekableReadStream &stream) {
|
||||||
_display->setMode(Display::kModeText);
|
_display->setMode(Display::kModeText);
|
||||||
|
|
||||||
|
@ -301,7 +282,7 @@ void HiRes1Engine::init() {
|
||||||
StreamPtr stream(_files->createReadStream(IDS_HR1_EXE_1));
|
StreamPtr stream(_files->createReadStream(IDS_HR1_EXE_1));
|
||||||
|
|
||||||
Common::StringArray exeStrings;
|
Common::StringArray exeStrings;
|
||||||
extractExeStrings(*stream, exeStrings);
|
extractExeStrings(*stream, 0x1576, exeStrings);
|
||||||
|
|
||||||
if (exeStrings.size() != 18)
|
if (exeStrings.size() != 18)
|
||||||
error("Failed to load strings from executable");
|
error("Failed to load strings from executable");
|
||||||
|
|
|
@ -70,28 +70,37 @@ void HiResBaseEngine::init() {
|
||||||
StreamPtr stream(_disk->createReadStream(0x1f, 0x2, 0x00, 4));
|
StreamPtr stream(_disk->createReadStream(0x1f, 0x2, 0x00, 4));
|
||||||
loadMessages(*stream, _numMsgs);
|
loadMessages(*stream, _numMsgs);
|
||||||
|
|
||||||
// Read parser messages
|
stream.reset(_disk->createReadStream(0x19, 0x0, 0x00, 25, 13));
|
||||||
stream.reset(_disk->createReadStream(0x1a, 0x1));
|
Common::StringArray exeStrings;
|
||||||
_strings.verbError = readStringAt(*stream, 0x4f);
|
extractExeStrings(*stream, 0x1566, exeStrings);
|
||||||
_strings.nounError = readStringAt(*stream, 0x8e);
|
|
||||||
_strings.enterCommand = readStringAt(*stream, 0xbc);
|
|
||||||
|
|
||||||
// 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));
|
stream.reset(_disk->createReadStream(0x19, 0x7, 0xd7));
|
||||||
_strings_v2.time = readString(*stream, 0xff);
|
_strings_v2.time = readString(*stream, 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
// Read line feeds
|
// Read line feeds
|
||||||
stream.reset(_disk->createReadStream(0x19, 0xb, 0xf8, 1));
|
_strings.lineFeeds = exeStrings[0];
|
||||||
_strings.lineFeeds = readString(*stream);
|
|
||||||
|
|
||||||
// Read opcode strings
|
// Read opcode strings
|
||||||
stream.reset(_disk->createReadStream(0x1a, 0x6, 0x00, 2));
|
_strings_v2.saveInsert = exeStrings[5];
|
||||||
_strings_v2.saveInsert = readStringAt(*stream, 0x5f);
|
_strings_v2.saveReplace = exeStrings[6];
|
||||||
_strings_v2.saveReplace = readStringAt(*stream, 0xe5);
|
_strings_v2.restoreInsert = exeStrings[7];
|
||||||
_strings_v2.restoreInsert = readStringAt(*stream, 0x132);
|
_strings_v2.restoreReplace = exeStrings[8];
|
||||||
_strings_v2.restoreReplace = readStringAt(*stream, 0x1c2);
|
_strings.playAgain = exeStrings[9];
|
||||||
_strings.playAgain = readStringAt(*stream, 0x225);
|
_strings.pressReturn = exeStrings[10];
|
||||||
_strings.pressReturn = readStringAt(*stream, 0x25f);
|
|
||||||
|
|
||||||
// Load global picture data
|
// Load global picture data
|
||||||
stream.reset(_disk->createReadStream(0x19, 0xa, 0x80, 0));
|
stream.reset(_disk->createReadStream(0x19, 0xa, 0x80, 0));
|
||||||
|
@ -105,7 +114,7 @@ void HiResBaseEngine::init() {
|
||||||
stream.reset(_disk->createReadStream(0x1d, 0x7, 0x00, 4));
|
stream.reset(_disk->createReadStream(0x1d, 0x7, 0x00, 4));
|
||||||
readCommands(*stream, _roomCommands);
|
readCommands(*stream, _roomCommands);
|
||||||
|
|
||||||
stream.reset(_disk->createReadStream(0x1f, 0x7, 0x00, 3));
|
stream.reset(_disk->createReadStream((oldEngine ? 0x19 : 0x1f), 0x7, 0x00, 3));
|
||||||
readCommands(*stream, _globalCommands);
|
readCommands(*stream, _globalCommands);
|
||||||
|
|
||||||
// Load dropped item offsets
|
// Load dropped item offsets
|
||||||
|
@ -151,10 +160,10 @@ HiRes2Engine::HiRes2Engine(OSystem *syst, const AdlGameDescription *gd) :
|
||||||
}
|
}
|
||||||
|
|
||||||
void HiRes2Engine::runIntro() {
|
void HiRes2Engine::runIntro() {
|
||||||
// This only works for the 16-sector re-release. The original
|
// Only the Green Valley version has a title screen
|
||||||
// release is not supported at this time, because we don't have
|
if (_disk->getSectorsPerTrack() != 16)
|
||||||
// access to it.
|
return;
|
||||||
_disk->setSectorLimit(0);
|
|
||||||
StreamPtr stream(_disk->createReadStream(0x00, 0xd, 0x17, 1));
|
StreamPtr stream(_disk->createReadStream(0x00, 0xd, 0x17, 1));
|
||||||
|
|
||||||
_display->setMode(Display::kModeText);
|
_display->setMode(Display::kModeText);
|
||||||
|
@ -166,8 +175,6 @@ void HiRes2Engine::runIntro() {
|
||||||
|
|
||||||
_display->printString(str);
|
_display->printString(str);
|
||||||
delay(2000);
|
delay(2000);
|
||||||
|
|
||||||
_disk->setSectorLimit(13);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class HiRes3Engine : public HiResBaseEngine {
|
class HiRes3Engine : public HiResBaseEngine {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue