From 5b18aee7435bd6659574527cd0f7c15063498ee5 Mon Sep 17 00:00:00 2001 From: Thanasis Antoniou Date: Tue, 30 Apr 2019 17:54:09 +0300 Subject: BLADERUNNER: Spinner GPS Talkie restored --- engines/bladerunner/ui/spinner.cpp | 165 ++++++++++++++++++++++++++++++++++--- engines/bladerunner/ui/spinner.h | 13 +++ 2 files changed, 167 insertions(+), 11 deletions(-) diff --git a/engines/bladerunner/ui/spinner.cpp b/engines/bladerunner/ui/spinner.cpp index eb3b1977f8..d47a28c63a 100644 --- a/engines/bladerunner/ui/spinner.cpp +++ b/engines/bladerunner/ui/spinner.cpp @@ -23,6 +23,11 @@ #include "bladerunner/ui/spinner.h" #include "bladerunner/bladerunner.h" +#include "bladerunner/actor.h" +#include "bladerunner/audio_player.h" +#include "bladerunner/ambient_sounds.h" +#include "bladerunner/game_info.h" +#include "bladerunner/subtitles.h" #include "bladerunner/game_constants.h" #include "bladerunner/mouse.h" #include "bladerunner/savefile.h" @@ -65,6 +70,9 @@ bool Spinner::querySelectableDestinationFlag(int destination) const { } int Spinner::chooseDestination(int loopId, bool immediately) { + if (_vm->_cutContent) { + resetDescription(); + } _selectedDestination = 0; if (!_vm->openArchive("MODE.MIX")) { return 0; @@ -87,7 +95,6 @@ int Spinner::chooseDestination(int loopId, bool immediately) { } _vm->_mouse->setCursor(0); - // Determine which map we need to show to include the active destinations uint8 mapmask = 0; uint8 mapmaskv[kSpinnerDestinations] = { 1, 1, 1, 1, 1, 3, 3, 3, 7, 7 }; @@ -148,13 +155,26 @@ int Spinner::chooseDestination(int loopId, bool immediately) { ); } - _imagePicker->activate( - nullptr, - nullptr, - nullptr, - mouseUpCallback, - this - ); + if (_vm->_cutContent) { + _imagePicker->activate( + mouseInCallback, + mouseOutCallback, + mouseDownCallback, + mouseUpCallback, + this + ); +// _vm->_ambientSounds->playSpeech(kActorAnsweringMachine, 480, 50, 0, 0, 100); + playSpeechLine(kActorAnsweringMachine, 480, 0.5f); + _vm->_ambientSounds->addSound(kSfxSPINAMB2, 5, 30, 30, 45, 0, 0, -101, -101, 0, 0); + } else { + _imagePicker->activate( + nullptr, + nullptr, + nullptr, + mouseUpCallback, + this + ); + } _vm->_time->pause(); @@ -181,12 +201,30 @@ int Spinner::chooseDestination(int loopId, bool immediately) { _vm->_time->resume(); _vm->_scene->resume(); + if (_vm->_cutContent) { + _vm->_ambientSounds->removeNonLoopingSound(kSfxSPINAMB2, true); + } return _selectedDestination; } -void Spinner::mouseUpCallback(int image, void *self) { - if (image >= 0 && image < 10) { - ((Spinner *)self)->setSelectedDestination(image); +// cut content +void Spinner::mouseInCallback(int destinationImage, void *self) { + ((Spinner *)self)->destinationFocus(destinationImage); +} + +// cut content +void Spinner::mouseOutCallback(int, void *self) { + ((Spinner *)self)->destinationFocus(-1); +} + +// cut content +void Spinner::mouseDownCallback(int, void *self) { + ((Spinner *)self)->_vm->_audioPlayer->playAud(((Spinner *)self)->_vm->_gameInfo->getSfxTrack(kSfxSPNBEEP9), 100, 0, 0, 50, 0); +} + +void Spinner::mouseUpCallback(int destinationImage, void *self) { + if (destinationImage >= 0 && destinationImage < 10) { + ((Spinner *)self)->setSelectedDestination(destinationImage); } } @@ -230,7 +268,13 @@ void Spinner::tick() { _vm->_mouse->draw(_vm->_surfaceFront, p.x, p.y); _imagePicker->drawTooltip(_vm->_surfaceFront, p.x, p.y); + if (_vm->_cutContent) { + _vm->_subtitles->tick(_vm->_surfaceFront); + } _vm->blitToScreen(_vm->_surfaceFront); + if (_vm->_cutContent) { + tickDescription(); + } _vm->_system->delayMillis(10); } @@ -248,6 +292,10 @@ void Spinner::reset() { _selectedDestination = -1; _imagePicker = nullptr; + _actorId = -1; + _sentenceId = -1; + _timeSpeakDescription = 0; + for (int i = 0; i != (int)_shapes.size(); ++i) { delete _shapes[i]; } @@ -323,4 +371,99 @@ const Spinner::Destination *Spinner::getDestinationsNear() { return destinations; } +void Spinner::destinationFocus(int destinationImage) { + // TODO 590, 600 are "Third Sector", "Fourth Sector" maybe restore those too? + switch (destinationImage) { + case kSpinnerDestinationPoliceStation: + setupDescription(kActorAnsweringMachine, 500); + break; + case kSpinnerDestinationMcCoysApartment: + setupDescription(kActorAnsweringMachine, 510); + break; + case kSpinnerDestinationRuncitersAnimals: + setupDescription(kActorAnsweringMachine, 490); + break; + case kSpinnerDestinationChinatown: + setupDescription(kActorAnsweringMachine, 520); + break; + case kSpinnerDestinationAnimoidRow: + setupDescription(kActorAnsweringMachine, 550); + break; + case kSpinnerDestinationTyrellBuilding: + setupDescription(kActorAnsweringMachine, 560); + break; + case kSpinnerDestinationDNARow: + setupDescription(kActorAnsweringMachine, 530); + break; + case kSpinnerDestinationBradburyBuilding: + setupDescription(kActorAnsweringMachine, 540); + break; + case kSpinnerDestinationNightclubRow: + setupDescription(kActorAnsweringMachine, 570); + break; + case kSpinnerDestinationHysteriaHall: + setupDescription(kActorAnsweringMachine, 580); + break; + default: + resetDescription(); + break; + } +} + +// copied from elevator.cpp code +void Spinner::setupDescription(int actorId, int sentenceId) { + _actorId = actorId; + _sentenceId = sentenceId; + _timeSpeakDescription = _vm->_time->current() + 600; +} + +// copied from elevator.cpp code +void Spinner::resetDescription() { + _actorId = -1; + _sentenceId = -1; + _timeSpeakDescription = 0; +} + +// copied from elevator.cpp code +void Spinner::tickDescription() { + int now = _vm->_time->current(); + if (_actorId <= 0 || now < _timeSpeakDescription) { + return; + } + + _vm->_actors[_actorId]->speechPlay(_sentenceId, false); + _actorId = -1; + _sentenceId = -1; +} + +void Spinner::playSpeechLine(int actorId, int sentenceId, float duration) { + _vm->gameWaitForActive(); + + _vm->_mouse->disable(); + Actor *actor = _vm->_actors[actorId]; + actor->speechPlay(sentenceId, true); + + while (_vm->_gameIsRunning) { + _vm->_actorIsSpeaking = true; + _vm->_actorSpeakStopIsRequested = false; + _vm->gameTick(); + _vm->_actorIsSpeaking = false; + if (_vm->_actorSpeakStopIsRequested || !actor->isSpeeching()) { + actor->speechStop(); + break; + } + } + + if (duration > 0.0f && !_vm->_actorSpeakStopIsRequested) { + int timeEnd = duration * 1000.0f + _vm->_time->current(); + while ((timeEnd > _vm->_time->current()) && _vm->_gameIsRunning) { + _vm->gameTick(); + } + } + + _vm->_actorSpeakStopIsRequested = false; + + _vm->_mouse->enable(); +} + } // End of namespace BladeRunner diff --git a/engines/bladerunner/ui/spinner.h b/engines/bladerunner/ui/spinner.h index d2d666e8e1..a637cefdcc 100644 --- a/engines/bladerunner/ui/spinner.h +++ b/engines/bladerunner/ui/spinner.h @@ -52,6 +52,10 @@ class Spinner { Common::Array _shapes; UIImagePicker *_imagePicker; + int _actorId; + int _sentenceId; + int _timeSpeakDescription; + public: Spinner(BladeRunnerEngine *vm); ~Spinner(); @@ -72,10 +76,19 @@ public: void reset(); void resume(); + void playSpeechLine(int actorId, int sentenceId, float duration); + void destinationFocus(int destination); + void setupDescription(int actorId, int sentenceId); + void resetDescription(); + void tickDescription(); + void save(SaveFileWriteStream &f); void load(SaveFileReadStream &f); private: + static void mouseInCallback(int, void *); + static void mouseOutCallback(int, void *); + static void mouseDownCallback(int, void *); static void mouseUpCallback(int, void *); static const Destination *getDestinationsFar(); static const Destination *getDestinationsMedium(); -- cgit v1.2.3