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);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue