mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-14 05:38:56 +00:00
SCUMM: Add missing Lemonhead lines in English CD Monkey Island 1
Apparently these were lost when the game was converted from floppy to CD version. Not just in the English version, but that's all I have. We should come up with a way to make it easy to add other languages, though.
This commit is contained in:
parent
3d86ab9942
commit
8e8e3225da
@ -1726,6 +1726,16 @@ void ScummEngine::applyWorkaroundIfNeeded(ResType type, int idx) {
|
||||
delete[] patchedScript;
|
||||
} else
|
||||
|
||||
// For some reason, the CD version of Monkey Island 1 removes some of
|
||||
// the text when giving the wimpy idol to the cannibals. It looks like
|
||||
// a mistake, because one of the text that is printed is immediately
|
||||
// overwritten. This probably affects all CD versions, so we just have
|
||||
// to add further patches as they are reported.
|
||||
|
||||
if (_game.id == GID_MONKEY && type == rtRoom && idx == 25) {
|
||||
tryPatchMI1CannibalScript(getResourceAddress(type, idx), size);
|
||||
} else
|
||||
|
||||
// There is a cracked version of Maniac Mansion v2 that attempts to
|
||||
// remove the security door copy protection. With it, any code is
|
||||
// accepted as long as you get the last digit wrong. Unfortunately,
|
||||
@ -1771,5 +1781,72 @@ bool ScummEngine::verifyMI2MacBootScript(byte *buf, int size) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScummEngine::tryPatchMI1CannibalScript(byte *buf, int size) {
|
||||
assert(_game.id == GID_MONKEY);
|
||||
|
||||
int expectedSize = -1;
|
||||
int scriptOffset = -1;
|
||||
int scriptLength = -1;
|
||||
Common::String expectedMd5;
|
||||
int patchOffset = -1;
|
||||
int patchLength = -1;
|
||||
|
||||
switch (_language) {
|
||||
case Common::EN_ANY:
|
||||
expectedSize = 82906;
|
||||
scriptOffset = 73883;
|
||||
scriptLength = 607;
|
||||
expectedMd5 = "98b1126a836ef5bfefff10b605b20555";
|
||||
patchOffset = 167;
|
||||
patchLength = 126;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (size == expectedSize) {
|
||||
// There isn't enough space in the script for the revised
|
||||
// texts, so these abbreviations will be expanded in
|
||||
// decodeParseString().
|
||||
const byte patchData[] = {
|
||||
0x14, 0x03, 0x0F, // print(3,[Text("/LMH.001/");
|
||||
0x2F, 0x4C, 0x4D, 0x48,
|
||||
0x2E, 0x30, 0x30, 0x31,
|
||||
0x2F, 0x00,
|
||||
0xAE, 0x02, // WaitForMessage();
|
||||
0x14, 0x03, 0x0F, // print(3,[Text("/LMH.001/");
|
||||
0x2F, 0x4C, 0x4D, 0x48,
|
||||
0x2E, 0x30, 0x30, 0x32,
|
||||
0x2F, // No terminating 0x00!
|
||||
};
|
||||
|
||||
byte *scriptPtr = buf + scriptOffset;
|
||||
|
||||
// Check that the data is a local script.
|
||||
if (READ_BE_UINT32(scriptPtr) != MKTAG('L','S','C','R'))
|
||||
return false;
|
||||
|
||||
// Check that the first instruction to be patched is o5_print
|
||||
if (scriptPtr[patchOffset] != 0x14)
|
||||
return false;
|
||||
|
||||
// Check that the MD5 sum matches a known patchable script.
|
||||
Common::MemoryReadStream stream(buf + scriptOffset, scriptLength);
|
||||
Common::String md5 = Common::computeStreamMD5AsString(stream);
|
||||
|
||||
if (md5 != expectedMd5)
|
||||
return false;
|
||||
|
||||
// Pad the rest of the replaced script part with spaces before
|
||||
// terminating the string.
|
||||
|
||||
memcpy(scriptPtr + patchOffset, patchData, sizeof(patchData));
|
||||
memset(scriptPtr + patchOffset + sizeof(patchData), 32, patchLength - sizeof(patchData) - 1);
|
||||
scriptPtr[patchOffset + patchLength - 1] = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} // End of namespace Scumm
|
||||
|
@ -2777,6 +2777,8 @@ void ScummEngine_v5::decodeParseString() {
|
||||
strcpy(tmpBuf + diff, "5000");
|
||||
strcpy(tmpBuf + diff + 4, tmp + sizeof("NCREDIT-NOTE-AMOUNT") - 1);
|
||||
printString(textSlot, (byte *)tmpBuf);
|
||||
} if (_game.id == GID_MONKEY && _roomResource == 25 && vm.slot[_currentScript].number == 205) {
|
||||
printPatchedMI1CannibalString(textSlot, _scriptPointer);
|
||||
} else {
|
||||
printString(textSlot, _scriptPointer);
|
||||
}
|
||||
@ -2810,4 +2812,26 @@ void ScummEngine_v5::decodeParseString() {
|
||||
_string[textSlot].saveDefault();
|
||||
}
|
||||
|
||||
void ScummEngine_v5::printPatchedMI1CannibalString(int textSlot, const byte *ptr) {
|
||||
const char *msg = (const char *)ptr;
|
||||
|
||||
#define MSG_WAIT "\xFF\x03"
|
||||
|
||||
if (strncmp((const char *)ptr, "/LMH.001/", 9) == 0) {
|
||||
msg =
|
||||
"Oooh, that's nice." MSG_WAIT
|
||||
"Simple. Just like one of mine." MSG_WAIT
|
||||
"And little. Like mine.";
|
||||
} else if (strncmp((const char *)ptr, "/LMH.002/", 9) == 0) {
|
||||
msg =
|
||||
"And it says, `Made by Lemonhead`^" MSG_WAIT
|
||||
"^just like one of mine!" MSG_WAIT
|
||||
"We should take this to the Great Monkey.";
|
||||
}
|
||||
|
||||
#undef MSG_WAIT
|
||||
|
||||
printString(textSlot, (const byte *)msg);
|
||||
}
|
||||
|
||||
} // End of namespace Scumm
|
||||
|
@ -701,6 +701,8 @@ public:
|
||||
void applyWorkaroundIfNeeded(ResType type, int idx);
|
||||
bool verifyMI2MacBootScript();
|
||||
bool verifyMI2MacBootScript(byte *buf, int size);
|
||||
bool tryPatchMI1CannibalScript(byte *buf, int size);
|
||||
|
||||
int getResourceDataSize(const byte *ptr) const;
|
||||
void dumpResource(const char *tag, int index, const byte *ptr, int length = -1);
|
||||
|
||||
|
@ -65,6 +65,7 @@ protected:
|
||||
void setupScummVars() override;
|
||||
void resetScummVars() override;
|
||||
virtual void decodeParseString();
|
||||
void printPatchedMI1CannibalString(int textSlot, const byte *ptr);
|
||||
|
||||
void saveLoadWithSerializer(Common::Serializer &s) override;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user