SCUMM: Adjust timings for German Sam & Max intro. (Bug #13378)

This commit is contained in:
Torbjörn Andersson 2022-03-31 16:01:25 +02:00 committed by Torbjörn Andersson
parent f3a41f1525
commit 54fd5caac8
3 changed files with 128 additions and 0 deletions

View File

@ -648,6 +648,21 @@ void ScummEngine::writeVar(uint var, int value) {
}
}
// WORKAROUND bug #13378: For whatever reason, the German and
// Italian talkie versions (I can't check the floppy versions)
// set the game to run much too fast in some parts of the intro.
// Some differences are natural because of the different lengths
// of the spoken lines, but 1 or 2 is too fast.
//
// Any modifications here depend on knowing if the script will
// set the timer value back to something sensible afterwards.
if (_game.id == GID_SAMNMAX && vm.slot[_currentScript].number == 65 && var == VAR_TIMER_NEXT && _enableEnhancements) {
// "Wirst Du brutzeln, wie eine grobe Bratwurst!"
if (value == 1 && _language == Common::DE_DEU)
value = 4;
}
_scummVars[var] = value;
// Unlike the PC version, the Macintosh version of Loom appears

View File

@ -1115,6 +1115,20 @@ void ScummEngine_v6::o6_setCameraAt() {
void ScummEngine_v6::o6_loadRoom() {
int room = pop();
// WORKAROUND bug #13378: During Sam's reactions to Max beating up the
// scientist in the intro, we sometimes have to slow down animations
// artificially. This is where we speed them back up again.
if (_game.id == GID_SAMNMAX && vm.slot[_currentScript].number == 65 && room == 6 && _enableEnhancements) {
int actors[] = { 2, 3, 10 };
for (int i = 0; i < ARRAYSIZE(actors); i++) {
Actor *a = derefActorSafe(actors[i], "o6_animateActor");
if (a && a->getAnimSpeed() > 0)
a->setAnimSpeed(0);
}
}
startScene(room, nullptr, 0);
if (_game.heversion >= 61) {
setCameraAt(camera._cur.x, 0);

View File

@ -72,6 +72,22 @@ void ScummEngine::printString(int m, const byte *msg) {
return;
}
// WORKAROUND bug #13378: Sam's reactions during the intro run
// much too quick for the subtitles in some localizations. We
// get around this by slowing down that entire animation, while
// leaving the reset of the animations unchanged.
//
// The animation speed is not very fine grained, though.
if (_game.id == GID_SAMNMAX && vm.slot[_currentScript].number == 65 && _enableEnhancements) {
if (_language == Common::DE_DEU) {
if (memcmp(msg + 16, "Ohh!", 4) == 0) {
Actor *a = derefActorSafe(2, "printString");
if (a)
a->setAnimSpeed(3);
}
}
}
actorTalk(msg);
break;
case 1:
@ -167,6 +183,89 @@ bool ScummEngine::handleNextCharsetCode(Actor *a, int *code) {
_keepText = false;
_msgCount = 0;
endLoop = true;
// WORKAROUND bug #13378: Some of the speech is badly
// synced to the subtitles, particularly in the
// localized versions. This happens because a single
// speech line is used for a text that's broken up by
// one or more embedded "wait" codes. Rather than
// relying on the calculated talk delay, hard-code
// better ones.
if (_game.id == GID_SAMNMAX && _enableEnhancements && isScriptRunning(65)) {
typedef struct {
const char *str;
const int16 talkDelay;
const byte action;
} TimingAdjustment;
TimingAdjustment *adjustments;
int numAdjustments;
// We identify the broken up strings that need
// adjustment by the upcoming text.
TimingAdjustment timingAdjustmentsDE[] = {
{ "Und daf\x81r^", 110, 0 },
{ "Es ist blo\xe1^", 120, 0 },
{ "Hey.", 130, 0 },
{ "Klasse Schlag!", 150, 0 },
{ "Uiii!", 185, 1 },
{ "H\x84h?", 150, 0 },
{ "Kann ich seine", 110, 0 },
{ "Warum, glaubst", 110, 0 },
{ "Vielleicht", 90, 0 },
{ "Kann ich fahren?", 240, 0 }
};
switch (_language) {
case Common::DE_DEU:
adjustments = timingAdjustmentsDE;
numAdjustments = ARRAYSIZE(timingAdjustmentsDE);
break;
default:
adjustments = nullptr;
numAdjustments = 0;
break;
}
byte action = 0;
for (int i = 0; i < numAdjustments; i++) {
int len = strlen(adjustments[i].str);
if (memcmp(buffer, adjustments[i].str, len) == 0) {
_talkDelay = adjustments[i].talkDelay;
action = adjustments[i].action;
break;
}
}
if (_language == Common::DE_DEU) {
Actor *act;
switch (action) {
case 1:
act = derefActorSafe(2, "handleNextCharsetCode");
if (act)
act->setAnimSpeed(2);
// The actor speaks so slowly that the background
// animations have run their course. Try to restart
// them, even though it won't be quite seamless.
int actors[] = { 3, 10 };
for (int i = 0; i < ARRAYSIZE(actors); i++) {
act = derefActorSafe(actors[i], "handleNextCharsetCode");
if (act) {
act->startAnimActor(act->_initFrame);
act->animateActor(249);
}
}
break;
}
}
}
break;
case 8:
// Ignore this code here. Occurs e.g. in MI2 when you