X Tutup
Skip to content

SCUMM: Add workaround for MI1 Sega CD clobbering bit variables#6557

Merged
bluegr merged 2 commits intoscummvm:masterfrom
eriktorbjorn:scumm-scary-sega-fix
Apr 23, 2025
Merged

SCUMM: Add workaround for MI1 Sega CD clobbering bit variables#6557
bluegr merged 2 commits intoscummvm:masterfrom
eriktorbjorn:scumm-scary-sega-fix

Conversation

@eriktorbjorn
Copy link
Member

Here's a scary one!

Any conversation in the Sega CD version of MI1 is likely - perhaps even guaranteed - to set one or more bit variables that are intended for other things. Luckily none of them appear to be game breaking, but still...

Since this is a global bug, I've been relying on NUTCracker for dissecting the scripts. While I'm a bit fuzzy on some of the details, MI1 uses nine bit flags numbered 384 through 392. They are set when conversation options are presented. In the DOS CD version it can look like this:

	V.100 = ((120 + 1) - 1)
	verb V.100 at 2,V.229 name "So what was your name, anyway?" on key V.230
	V.229 += 8
	V.100 -= 120
	++V.230
	B.384[V.100] = 1

And then the script that handles conversation trees test and clears these variables. (They're cleared manually in some cases too.) The conversation tree handling in the Sega version is different, and doesn't use these variables but still clears them.

It also sets them, and that's where the bug comes in. Because here's the corresponding code from the Sega version:

	V.100 = ((120 + 1) - 1)
	V.435 = (V.229 * V.452)
	V.435 += 145
	verb V.100 at 8,V.435 name "So what was your name, anyway?" off key V.230
	V.412[V.432] = V.100
	++V.432
	++V.229
	++V.230
	B.384[V.100] = 1

The V.100 -= 120 line is missing. So the Sega version will set bits 504 through 512 instead. And they're used for completely different things throughout the game. I didn't notice until I got to the cannibals, and found that when they asked if they could do anything for them I couldn't ask them for a ship or for money. But the easiest one to reproduce is with Cobb: Guybrush will never say "Geeze, what an obvious sales pitch." to him:

	if (!B.504) {
		B.504 = 1
		V.100 = ((120 + 4) - 1)
		V.435 = (V.229 * V.452)
		V.435 += 145
		verb V.100 at 8,V.435 name "Geeze, what an obvious sales pitch." off key V.230
		V.412[V.432] = V.100
		++V.432
		++V.229
		++V.230
		B.384[V.100] = 1

The good news is that the pattern B.384[V.100] = 1 only appears in these buggy conversation scripts. We can detect and correct that pattern. The bad news is that it appears more than 500 times, so testing them all is not reasonable.

Any conversation in the game is likely to set one or more bit variables
that are intended for other things. Luckily none of them appear to be
game breaking, but still... We detect and correct the faulty pattern,
but old savegames will still be impacted.
@eriktorbjorn
Copy link
Member Author

Note that I've only tested this with an English version. Apparently there are others?

This workaround is scary enough as it is. Someone who owns and
understand the Japanese version will have to validate that one.
@eriktorbjorn
Copy link
Member Author

This is the list of bit flags that I put in the comment for the workaround:

// 504 - Saying "Geeze, what an obvious sales pitch." to Cobb.
// 505 - Saying "You know, you really should quit smoking." to Smirk.
// 506 - Something unknown around the line "I give up!  You win!"
// 507 - unused
// 508 - Saying "I need a ship." / "Can you guys crew a ship?" to the cannibals.
// 509 - Saying "Money.  I want money." to the cannibals.
// 510 - Saying "What's in your standard potion of exorcism?" to the cannibals.
// 511 - Saying "Where is he hiding it?" to the cannibals.
// 512 - Saying "How do I get to these catacombs?" to the cannibals.
//       This is also unavailable if Herman already told you.

I think these convertsation options are enough to set the flags incorrectly. Note that it's enough that you see them, you don't actually need to choose them:

504 - The pirate leaders, "I want to be a fireman."
505 - The pirate leaders, "I mean to kill you all."
506 - The pirate leaders, "I want to be a pirate."
507 - Men of Low Moral Fiber, "Say, are you guys pirates."
508 - Men of Low Moral Fiber, "I'll just be running along now."
509 - The shopkeeper, "I think I'd just like to browse."
510 - The pirate leaders, "You're a bunch of foul-smelling, grog-swilling pigs!"
511 - The pirate leaders, "I'll just be running along now."
512 - The pirate leaders, "What's in that grog stuff, anyway?"

So what I should do next (but it'll probably be a few days before I have the time to even begin) is to trigger these (or equivalent) conversation options, and then see if they actually suppress what I think they do. While at the same time doing a parallel playthrough where the workaround is active, to see that the messages aren't suppressed and that the game is still completable.

To tell them apart, I'll be using Sega graphics mode for the run with enhancements enabled.

The only case I've tried so far is asking Cobb about Loom:

scummvm-monkey-sega-2-00000

scummvm-monkey-sega-1-00000

So that one works, at least. It used to be impossible to get that conversation option, because talking to Cobb would always set flag 504.

@eriktorbjorn
Copy link
Member Author

Talking to Smirk sets bit 505, so this option used to be impossible to get:

scummvm-monkey-sega-2-00001

scummvm-monkey-sega-1-00001

@eriktorbjorn
Copy link
Member Author

I'm still not sure what bit 506 does, but my theory is that the first time you lose a sword fight Guybrush should always say "I give up! You win!". On subsequent losses, the game picks a random message. ("UNCLE! UNCLE!", "Yikes! Nice move.", etc.)

@eriktorbjorn
Copy link
Member Author

eriktorbjorn commented Apr 20, 2025

But at least the testing I did did not disprove my theory. I'll settle for that! Talking to Smirk immediately sets bit 506, so this would also be unavoidable.

scummvm-monkey-sega-2-00002

scummvm-monkey-sega-1-00002

@eriktorbjorn
Copy link
Member Author

eriktorbjorn commented Apr 22, 2025

Just a reminder, there are some restored conversation options that aren't part of this pull request. This one:

scummvm-monkey-sega-2-00003

scummvm-monkey-sega-1-00003

And this one:

scummvm-monkey-sega-2-00004

scummvm-monkey-sega-1-00004

For these the missing options are not removed, they're just drawn outside the screen and you can still select them with the arrow keys. So for these, the workaround is kEnhSubFmtCntChanges (Subtitles Format/Content Changes). The ones addressed by this pull request really are gone because variables have been set incorrectly. For for them I opted for kEnhRestoredContent (Restored Content). I don't know if that makes it needlessly confusing?

There are also some cut lines from the bridge troll conversation, but since they were actually removed from the script I will not make any attempt to restore them.

@bluegr
Copy link
Member

bluegr commented Apr 22, 2025

The ones addressed by this pull request really are gone because variables have been set incorrectly. For for them I opted for kEnhRestoredContent (Restored Content). I don't know if that makes it needlessly confusing?

This may cause problems for players, as the new code that fixes these clobbered variables may break existing saves when toggled

@eriktorbjorn
Copy link
Member Author

eriktorbjorn commented Apr 22, 2025

This may cause problems for players, as the new code that fixes these clobbered variables may break existing saves when toggled

I don't see how it would. At worst, turning off the workaround will allow the game to write to the wrong bit-variables again and of course there's nothing you can do to repair it after it's happened. But the breakage is pretty small, as shown in the screenshots. There is nothing in the workaround that should introduce any new breakage when you turn it on, since it's just redirecting the conversation trees to write to the same variables as the DOS version does. And in the Sega version, that group of variables is unused. Only the code that clears them remains, not the code that reads them.

I'm still a bit fuzzy on exactly what they're used for in the DOS version. I think it may be so force the game to automatically pick a conversation option if there's only one available. E.g. if you talk to the shopkeeper and all you can tell him is that you'd like to browse. (Edit: No, that doesn't seem to be it.)

@eriktorbjorn
Copy link
Member Author

Screenshots covering bit-variables 508 and 509. Things are still working as expected:

scummvm-monkey-sega-2-00005

scummvm-monkey-sega-1-00005

@eriktorbjorn
Copy link
Member Author

eriktorbjorn commented Apr 23, 2025

The conversation tree here is a bit convoluted, and at least one message appears more than once under different circumstances. In these two screenshots I did take the same options, though:

  • Where are LeChuck and his crew hiding?
  • Sounds neat. Can I see it?

And yet I get completely different outcomes. This is where it uses bit-variables 510, 511, and 512. I'm going to assume the workaround is correct here too.

scummvm-monkey-sega-2-00006

scummvm-monkey-sega-1-00006

@eriktorbjorn
Copy link
Member Author

Game is completable in both modes. I didn't notice any regressions.

scummvm-monkey-sega-2-00007

scummvm-monkey-sega-1-00007

@bluegr
Copy link
Member

bluegr commented Apr 23, 2025

Thanks for your work, and for your thorough testing, @eriktorbjorn!

Since this fix is isolated for a specific game platform version, and since that version has been tested in full, your changes are good to merge.

Thanks again! Merging

@bluegr bluegr merged commit a682aae into scummvm:master Apr 23, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

X Tutup