BLADERUNNER: Fix actor voices with wrong balance

Some voices have bad pan, because the actors are not actually in the scene/dr06

This happens because on occasion (eg. TV news) some voices will be coming from an object on screen
but the game would still calculate the actor's position (and produce an awry pan value, since there is no such actor in the scene)
Addresses report: https://bugs.scummvm.org/ticket/11339
But covers more cases than just the TV voices.
This commit is contained in:
antoniou79 2021-06-30 22:37:36 +03:00
parent bbfd04ebbe
commit 4dcbd07148
3 changed files with 157 additions and 43 deletions

View File

@ -1354,8 +1354,122 @@ void Actor::speechPlay(int sentenceId, bool voiceOver) {
int pan = 0;
if (!voiceOver && _id != BladeRunnerEngine::kActorVoiceOver) {
#if BLADERUNNER_ORIGINAL_BUGS
Vector3 screenPosition = _vm->_view->calculateScreenPosition(_position);
pan = (75 * (2 * CLIP<int>(screenPosition.x, 0, 640) - 640)) / 640; // map [0..640] to [-75..75]
#else
// There are a few situations whereby
// the actor is not actually in the set when speaking,
// and the original code would result in audio playing
// from a wrong balance point (bad pan value).
// We capture these situations here and set the pan explicitly.
// Mainly, these are:
// tv news, machine voices (from PCs, Doors etc)
// dispatch calls when used as actor speech and not as ambient sounds
// phone calls (From Guzza, to Guzza, Lucy, Clovis, Dektora, Steele)
// and other special cases, where the actor is not actually in the scene.
//
// pan:: map [0..640] to [-75..75]
if ((_id == kActorNewscaster && sentenceId >= 0 && sentenceId <= 240)
|| (_id == kActorTyrell && sentenceId >= 430 && sentenceId <= 460)
|| (_id == kActorGuzza && sentenceId >= 1540 && sentenceId <= 1600)
|| (_id == kActorGovernorKolvig && sentenceId >= 80 && sentenceId <= 130)) {
// MA04 TV
// x: 149 --> pan: -41
// PS05 TV
// x: 527 --> pan: 48
// These quotes only play in kSetMA04 and kSetPS05
pan = (_vm->_playerActor->getSetId() == kSetMA04) ? -41 : 48;
} else if ((_id == kActorLucy && sentenceId >= 500 && sentenceId <= 640)
|| (_id == kActorClovis && sentenceId >= 310 && sentenceId <= 540)
|| (_id == kActorDektora && sentenceId >= 220 && sentenceId <= 490)
|| (_id == kActorSteele && sentenceId >= 680 && sentenceId <= 820)
|| (_id == kActorGuzza && sentenceId >= 0 && sentenceId <= 70)) {
// MA04 phone
// x: 351 --> pan: 7
// These quotes only play in kSetMA04
pan = 7;
} else if (_id == kActorGuzza && sentenceId >= 1380 && sentenceId <= 1480) {
// NR02 phone (Taffy's)
// x: 300 --> pan: -5
// DR06 phone (Twin's Apartment)
// x: 565 --> pan: 57
// These quotes only play in either kSetNR02 or kSetDR06
pan = (_vm->_playerActor->getSetId() == kSetNR02) ? -5 : 57;
} else if (_id == kActorAnsweringMachine) {
if (sentenceId == 0) {
// kSetBB07 - Bradbury, Sebastian's Lab Computer (0)
// x: 567 --> pan: 58
pan = 58;
} else if (sentenceId >= 10 && sentenceId <= 50) {
// kSetDR06 - Luther & Lance answering machine [10, 50]
// x: 278 --> pan: -11
pan = -11;
} else if (sentenceId == 60) {
// kSetDR06 - Twin's Apartment
// Restored Cut Content quote
// (Twin's Lab has a door announcer -- as heard in the video intro of Act 4 too)
// Pan will be at vidphone spot
// x: 565 --> pan: 57
pan = 57;
} else if (sentenceId >= 330 && sentenceId <= 370) {
// Mainframe terminal - x: 500 --> pan: 42
// These quotes only play in kSetPS06
pan = 42;
}
// Default pan is already set to 0 (ie. center)
// Includes Maze Scenes (kSetPS10_PS11_PS12_PS13) - quotes [280, 320]
// Also ESPER, KIA, VK, Elevator (MA06) and Spinner.
} else {
Vector3 actorScreenPosition;
switch (_id) {
case kActorLance:
// Lance does not have a model, but he is "attached" to his twin Luther
actorScreenPosition = _vm->_view->calculateScreenPosition(_vm->_actors[kActorLuther]->getPosition());
break;
case kActorDispatcher:
// kActorDispatcher does not have a model, but should be "attached" to McCoy or Steele
if (sentenceId >= 0 && sentenceId <= 40) {
// Steele's radio
actorScreenPosition = _vm->_view->calculateScreenPosition(_vm->_actors[kActorSteele]->getPosition());
} else {
// McCoy's radio
actorScreenPosition = _vm->_view->calculateScreenPosition(_vm->_playerActor->getPosition());
}
break;
case kActorOfficerLeary:
// Voice from dispatcher is attached to McCoy (coming from his radio)
if ((sentenceId >= 240 && sentenceId <= 450)
|| (sentenceId == 460 && _vm->_language == Common::DE_DEU)
|| (sentenceId >= 480 && sentenceId <= 530 && _vm->_language == Common::ES_ESP)
|| (sentenceId >= 520 && sentenceId <= 530 && _vm->_language == Common::IT_ITA)
) {
// responding to dispatch
actorScreenPosition = _vm->_view->calculateScreenPosition(_vm->_playerActor->getPosition());
} else {
actorScreenPosition = _vm->_view->calculateScreenPosition(_position);
}
break;
case kActorOfficerGrayford:
// Voice from dispatcher is attached to McCoy (coming from his radio)
if ((sentenceId >= 360 && sentenceId <= 450)
|| (sentenceId == 460 && _vm->_language == Common::DE_DEU)
|| (sentenceId >= 470 && sentenceId <= 550)
|| (sentenceId >= 560 && sentenceId <= 610 && _vm->_language == Common::ES_ESP)
) {
// responding to dispatch
actorScreenPosition = _vm->_view->calculateScreenPosition(_vm->_playerActor->getPosition());
} else {
actorScreenPosition = _vm->_view->calculateScreenPosition(_position);
}
break;
default:
actorScreenPosition = _vm->_view->calculateScreenPosition(_position);
}
pan = (75 * (2 * CLIP<int>(actorScreenPosition.x, 0, 640) - 640)) / 640; // map [0..640] to [-75..75]
}
// debug("actor: %d, pan: %d", _id, pan);
#endif // BLADERUNNER_ORIGINAL_BUGS
}
_vm->_subtitles->loadInGameSubsText(_id, sentenceId);

View File

@ -36,10 +36,10 @@ enum Actors {
kActorIzo = 7,
kActorSadik = 8,
kActorCrazylegs = 9,
kActorLuther = 10,
kActorLuther = 10, // This is the main model and AI for Luther and Lance (twins)
kActorGrigorian = 11,
kActorTransient = 12, // Homeless
kActorLance = 13,
kActorLance = 13, // Used for Lance speech lines (essentially empty AI script) - has Clues DB and Health
kActorBulletBob = 14,
kActorRunciter = 15,
kActorInsectDealer = 16,
@ -47,12 +47,12 @@ enum Actors {
kActorEarlyQ = 18,
kActorZuben = 19,
kActorHasan = 20,
kActorMarcus = 21,
kActorMarcus = 21, // Used for Marcus Eisenduller corpse - has Clues DB and Health
kActorMia = 22,
kActorOfficerLeary = 23,
kActorOfficerGrayford = 24,
kActorHanoi = 25,
kActorBaker = 26,
kActorBaker = 26, // Not actually used in anything (essentially empty AI script) - has Clues DB and Health and a T-pose Guard model
kActorDeskClerk = 27,
kActorHowieLee = 28,
kActorFishDealer = 29,
@ -62,38 +62,38 @@ enum Actors {
kActorHolloway = 33,
kActorSergeantWalls = 34,
kActorMoraji = 35,
kActorTheBard = 36,
kActorTheBard = 36, // Not actually used in anything (essentially empty AI script) - has Health
kActorPhotographer = 37,
kActorDispatcher = 38,
kActorAnsweringMachine = 39,
kActorDispatcher = 38, // Used for actor speech and ambient sound (essentially empty AI script)
kActorAnsweringMachine = 39, // Used for machines's speech (essentially empty AI script)
kActorRajif = 40,
kActorGovernorKolvig = 41,
kActorGovernorKolvig = 41, // Used for actor speech (essentially empty AI script) - has Health
kActorEarlyQBartender = 42,
kActorHawkersParrot = 43,
kActorTaffyPatron = 44,
kActorLockupGuard = 45,
kActorTeenager = 46,
kActorHysteriaPatron1 = 47,
kActorHysteriaPatron2 = 48,
kActorHysteriaPatron3 = 49,
kActorShoeshineMan = 50,
kActorHawkersParrot = 43, // Used for parrot speech (DEU, FRA only) (essentially empty AI script) - has Health
kActorTaffyPatron = 44, // Gordo's hostage (has speech in DEU, FRA)
kActorLockupGuard = 45, // Not actually used in anything (essentially empty AI script) - has Health
kActorTeenager = 46, // Not actually used in anything (essentially empty AI script) - has Health
kActorHysteriaPatron1 = 47, // Early Q's Dancer (has (cut) speech in DEU, FRA, but belongs to patron not dancer)
kActorHysteriaPatron2 = 48, // Early Q's Dancer (has (cut) speech in DEU, FRA, but belongs to patron not dancer)
kActorHysteriaPatron3 = 49, // Early Q's Dancer (Restored) (has (cut) speech in DEU, FRA, but belongs to patron not dancer)
kActorShoeshineMan = 50, // Not actually used in anything (has code remnants in AI script) - has Health
kActorTyrell = 51,
kActorChew = 52,
kActorGaff = 53,
kActorBryant = 54,
kActorTaffy = 55,
kActorBryant = 54, // Used as Sebastian's Bear doll in Bradbury
kActorTaffy = 55, // Not actually used in anything (essentially empty AI script) - has Clues DB and Health
kActorSebastian = 56,
kActorRachael = 57,
kActorGeneralDoll = 58,
kActorIsabella = 59,
kActorBlimpGuy = 60,
kActorNewscaster = 61,
kActorBlimpGuy = 60, // Used for ambient sound (essentially empty AI script)
kActorNewscaster = 61, // Used for TV speech (essentially empty AI script)
kActorLeon = 62,
kActorMaleAnnouncer = 63,
kActorFreeSlotA = 64, // Rat
kActorFreeSlotB = 65,
kActorMaleAnnouncer = 63, // Not actually used in anything (essentially empty AI script)
kActorFreeSlotA = 64, // Rat (also the big Rat on the bridge)
kActorFreeSlotB = 65, // Rat
kActorMaggie = 66,
kActorGenwalkerA = 67,
kActorGenwalkerA = 67, // Generic Walker or Bullet Bob's tracking gun
kActorGenwalkerB = 68,
kActorGenwalkerC = 69,
kActorMutant1 = 70,

View File

@ -49,8 +49,8 @@ void ESPERScript::SCRIPT_ESPER_DLL_Initialize() {
int v0 = 0;
if (Actor_Clue_Query(kActorMcCoy, kClueRuncitersVideo)) {
if (!Actor_Clue_Query(kActorMcCoy, kClueRuncitersViewA)) {
Actor_Says(kActorAnsweringMachine, 160, 3);
Actor_Says(kActorAnsweringMachine, 180, 3);
Actor_Says(kActorAnsweringMachine, 160, kAnimationModeTalk);
Actor_Says(kActorAnsweringMachine, 180, kAnimationModeTalk);
Actor_Clue_Acquire(kActorMcCoy, kClueRuncitersViewA, true, kActorRunciter);
v0 = 1;
}
@ -62,8 +62,8 @@ void ESPERScript::SCRIPT_ESPER_DLL_Initialize() {
}
if (Actor_Clue_Query(kActorMcCoy, kClueEarlyQsClub)) {
if (!Actor_Clue_Query(kActorMcCoy, kClueOuterDressingRoom)) {
Actor_Says(kActorAnsweringMachine, 160, 3);
Actor_Says(kActorAnsweringMachine, 170, 3);
Actor_Says(kActorAnsweringMachine, 160, kAnimationModeTalk);
Actor_Says(kActorAnsweringMachine, 170, kAnimationModeTalk);
Actor_Clue_Acquire(kActorMcCoy, kClueOuterDressingRoom, true, -1);
v0 = 1;
}
@ -83,8 +83,8 @@ void ESPERScript::SCRIPT_ESPER_DLL_Initialize() {
}
if (Actor_Clue_Query(kActorMcCoy, kClueChinaBarSecurityDisc)) {
if (!Actor_Clue_Query(kActorMcCoy, kClueChinaBarSecurityPhoto)) {
Actor_Says(kActorAnsweringMachine, 160, 3);
Actor_Says(kActorAnsweringMachine, 170, 3);
Actor_Says(kActorAnsweringMachine, 160, kAnimationModeTalk);
Actor_Says(kActorAnsweringMachine, 170, kAnimationModeTalk);
Actor_Clue_Acquire(kActorMcCoy, kClueChinaBarSecurityPhoto, true, kActorHawkersBarkeep);
v0 = 1;
}
@ -92,8 +92,8 @@ void ESPERScript::SCRIPT_ESPER_DLL_Initialize() {
}
if (Actor_Clue_Query(kActorMcCoy, kClueTyrellSecurity)) {
if (!Actor_Clue_Query(kActorMcCoy, kClueTyrellSecurityPhoto)) {
Actor_Says(kActorAnsweringMachine, 160, 3);
Actor_Says(kActorAnsweringMachine, 170, 3);
Actor_Says(kActorAnsweringMachine, 160, kAnimationModeTalk);
Actor_Says(kActorAnsweringMachine, 170, kAnimationModeTalk);
Actor_Clue_Acquire(kActorMcCoy, kClueTyrellSecurityPhoto, true, kActorTyrellGuard);
v0 = 1;
}
@ -103,21 +103,21 @@ void ESPERScript::SCRIPT_ESPER_DLL_Initialize() {
ESPER_Add_Photo("KP06.IMG", 9, 9);
}
if (v0) {
Actor_Says(kActorAnsweringMachine, 200, 3);
Actor_Says(kActorAnsweringMachine, 200, kAnimationModeTalk);
}
}
void ESPERScript::SCRIPT_ESPER_DLL_Photo_Selected(int photo) {
switch (photo) {
case 0:
Actor_Says(kActorAnsweringMachine, 220, 3);
Actor_Says(kActorAnsweringMachine, 220, kAnimationModeTalk);
ESPER_Define_Special_Region(0, 490, 511, 496, 517, 400, 440, 580, 580, 380, 260, 900, 710, "RC02ESP1");
ESPER_Define_Special_Region(1, 473, 342, 479, 349, 400, 300, 580, 580, 350, 250, 900, 710, "RC02ESP2");
ESPER_Define_Special_Region(2, 444, 215, 461, 223, 380, 120, 570, 340, 354, 160, 577, 354, "RC02ESP3");
break;
case 1:
Actor_Says(kActorAnsweringMachine, 220, 3);
Actor_Says(kActorAnsweringMachine, 220, kAnimationModeTalk);
ESPER_Define_Special_Region(3, 560, 210, 580, 220, 450, 130, 680, 540, 0, 0, 1279, 959, "RC02ESP4");
ESPER_Define_Special_Region(4, 584, 482, 595, 493, 460, 400, 660, 540, 0, 0, 1279, 959, "RC02ESP5");
ESPER_Define_Special_Region(5, 669, 322, 675, 329, 620, 230, 740, 390, 0, 0, 1279, 959, "RC02ESP6");
@ -125,42 +125,42 @@ void ESPERScript::SCRIPT_ESPER_DLL_Photo_Selected(int photo) {
break;
case 2:
Actor_Says(kActorAnsweringMachine, 260, 3);
Actor_Says(kActorAnsweringMachine, 260, kAnimationModeTalk);
ESPER_Define_Special_Region(7, 102, 809, 108, 861, 20, 720, 200, 930, 191, 95, 1085, 870, "NR06ESP1");
ESPER_Define_Special_Region(8, 661, 437, 664, 443, 530, 320, 720, 600, 330, 200, 945, 750, "NR06ESP2");
break;
case 3:
Actor_Says(kActorAnsweringMachine, 260, 3);
Actor_Says(kActorAnsweringMachine, 260, kAnimationModeTalk);
ESPER_Define_Special_Region(9, 479, 381, 482, 385, 430, 320, 520, 470, 265, 200, 815, 720, "NR07ESP2");
ESPER_Define_Special_Region(10, 893, 298, 901, 306, 770, 230, 980, 500, 340, 216, 942, 747, "NR07ESP1");
break;
case 4:
Actor_Says(kActorAnsweringMachine, 240, 3);
Actor_Says(kActorAnsweringMachine, 240, kAnimationModeTalk);
ESPER_Define_Special_Region(11, 420, 436, 434, 450, 350, 380, 520, 680, 257, 94, 1013, 804, "HC01ESP1");
ESPER_Define_Special_Region(12, 407, 489, 410, 509, 370, 450, 500, 560, 257, 94, 1013, 804, "HC01ESP2");
break;
case 5:
Actor_Says(kActorAnsweringMachine, 240, 3);
Actor_Says(kActorAnsweringMachine, 240, kAnimationModeTalk);
ESPER_Define_Special_Region(13, 720, 485, 728, 491, 640, 390, 780, 630, 257, 94, 1013, 804, "HC01ESP3");
break;
case 6:
Actor_Says(kActorAnsweringMachine, 250, 3);
Actor_Says(kActorAnsweringMachine, 250, kAnimationModeTalk);
ESPER_Define_Special_Region(14, 879, 221, 882, 225, 640, 0, 1000, 512, 265, 146, 1014, 813, "HC02ESP5");
ESPER_Define_Special_Region(15, 660, 550, 678, 572, 560, 480, 850, 910, 265, 146, 1014, 813, "HC02ESP2");
break;
case 7:
Actor_Says(kActorAnsweringMachine, 250, 3);
Actor_Says(kActorAnsweringMachine, 250, kAnimationModeTalk);
ESPER_Define_Special_Region(16, 1171, 457, 1184, 466, 1060, 370, 1279, 730, 910, 300, 1279, 678, "HC02ESP3");
ESPER_Define_Special_Region(17, 328, 398, 340, 413, 250, 350, 460, 640, 100, 236, 530, 612, "HC02ESP4");
break;
case 8:
Actor_Says(kActorAnsweringMachine, 230, 3);
Actor_Says(kActorAnsweringMachine, 230, kAnimationModeTalk);
ESPER_Define_Special_Region(18, 166, 623, 177, 632, 38, 528, 320, 770, 26, 530, 313, 771, "TB06ESP1");
ESPER_Define_Special_Region(19, 156, 356, 164, 360, 60, 280, 250, 460, 14, 251, 257, 459, "TB06ESP2");
ESPER_Define_Special_Region(20, 395, 158, 410, 185, 270, 70, 760, 640, 125, 0, 560, 307, "TB06ESP3");
@ -168,7 +168,7 @@ void ESPERScript::SCRIPT_ESPER_DLL_Photo_Selected(int photo) {
break;
case 9:
Actor_Says(kActorAnsweringMachine, 270, 3);
Actor_Says(kActorAnsweringMachine, 270, kAnimationModeTalk);
ESPER_Define_Special_Region(22, 1208, 330, 1218, 340, 1050, 160, 1279, 550, 956, 203, 1278, 497, "KP06ESP1");
ESPER_Define_Special_Region(23, 854, 371, 858, 375, 790, 320, 940, 560, 722, 220, 1000, 505, "KP06ESP2");
ESPER_Define_Special_Region(24, 615, 325, 648, 365, 440, 220, 820, 959, 326, 140, 948, 474, "KP06ESP3");