ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

speech.cpp

Go to the documentation of this file.
00001 /* ResidualVM - A 3D game interpreter
00002  *
00003  * ResidualVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the AUTHORS
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "engines/stark/resources/speech.h"
00024 
00025 #include "engines/stark/formats/xrc.h"
00026 
00027 #include "engines/stark/services/services.h"
00028 #include "engines/stark/services/dialogplayer.h"
00029 #include "engines/stark/services/global.h"
00030 #include "engines/stark/services/stateprovider.h"
00031 
00032 #include "engines/stark/resources/anim.h"
00033 #include "engines/stark/resources/item.h"
00034 #include "engines/stark/resources/level.h"
00035 #include "engines/stark/resources/lipsync.h"
00036 #include "engines/stark/resources/location.h"
00037 #include "engines/stark/resources/sound.h"
00038 
00039 namespace Stark {
00040 namespace Resources {
00041 
00042 Speech::~Speech() {
00043 }
00044 
00045 Speech::Speech(Object *parent, byte subType, uint16 index, const Common::String &name) :
00046         Object(parent, subType, index, name),
00047         _character(0),
00048         _soundResource(nullptr),
00049         _playTalkAnim(true),
00050         _removeTalkAnimWhenComplete(true),
00051         _lipSync(nullptr),
00052         _waitTimeRemaining(-1) {
00053     _type = TYPE;
00054 }
00055 
00056 Common::String Speech::getPhrase() const {
00057     return _phrase;
00058 }
00059 
00060 void Speech::playSound() {
00061     StarkGlobal->setNormalSpeed();
00062 
00063     if (_playTalkAnim) {
00064         setCharacterTalkAnim();
00065     }
00066 
00067     stopOtherSpeechesFromSameCharacter();
00068 
00069     _soundResource = findChild<Sound>();
00070     _soundResource->play();
00071 }
00072 
00073 void Speech::setCharacterTalkAnim() {
00074     ItemVisual *characterItem = getCharacterItem();
00075     if (characterItem) {
00076         characterItem->setAnimActivity(Anim::kActorActivityTalk);
00077 
00078         _lipSync = findChild<LipSync>();
00079         if (_lipSync) {
00080             _lipSync->setItem(characterItem, _playTalkAnim);
00081         }
00082     }
00083 }
00084 
00085 void Speech::removeCharacterTalkAnim() const {
00086     ItemVisual *characterItem = getCharacterItem();
00087     if (characterItem && characterItem->getAnimActivity() == Anim::kActorActivityTalk) {
00088         characterItem->setAnimActivity(Anim::kActorActivityIdle);
00089     }
00090 }
00091 
00092 ItemVisual *Speech::getCharacterItem() const {
00093     Current *current = StarkGlobal->getCurrent();
00094     if (!current) {
00095         return nullptr;
00096     }
00097 
00098     Location *location = current->getLocation();
00099     if (!location) {
00100         return nullptr;
00101     }
00102 
00103     return location->getCharacterItem(_character);
00104 }
00105 
00106 int32 Speech::getCharacterId() {
00107     return _character;
00108 }
00109 
00110 bool Speech::isPlaying() {
00111     return _soundResource || _waitTimeRemaining > 0;
00112 }
00113 
00114 void Speech::stop() {
00115     if (_soundResource) {
00116         _soundResource->stop();
00117         _soundResource = nullptr;
00118     }
00119 
00120     _waitTimeRemaining = -1;
00121 
00122     if (_lipSync) {
00123         _lipSync->reset();
00124     }
00125 
00126     if (_removeTalkAnimWhenComplete) {
00127         removeCharacterTalkAnim();
00128     }
00129 
00130     _removeTalkAnimWhenComplete = true;
00131     _playTalkAnim = true;
00132 }
00133 
00134 bool Speech::characterIsApril() const {
00135     int32 aprilCharacterIndex = StarkGlobal->getApril()->getCharacterIndex();
00136     return _character == aprilCharacterIndex;
00137 }
00138 
00139 int32 Speech::getPauseAfterSpeechDuration() const {
00140     if (_phrase.hasSuffix("...")) {
00141         return 1400;
00142     } else if (_phrase.hasSuffix("--")) {
00143         return 0;
00144     } else {
00145         return 1000;
00146     }
00147 }
00148 
00149 void Speech::readData(Formats::XRCReadStream *stream) {
00150     Object::readData(stream);
00151 
00152     _phrase = stream->readString();
00153     _character = stream->readSint32LE();
00154 }
00155 
00156 void Speech::onGameLoop() {
00157     Object::onGameLoop();
00158 
00159     if (_soundResource && !_soundResource->isPlaying()) {
00160         _soundResource->stop();
00161         _soundResource = nullptr;
00162         _waitTimeRemaining = getPauseAfterSpeechDuration();
00163     }
00164 
00165     if (_waitTimeRemaining >= 0) {
00166         _waitTimeRemaining -= StarkGlobal->getMillisecondsPerGameloop();
00167 
00168         if (StarkGlobal->isFastForward()) {
00169             _waitTimeRemaining = -1;
00170         }
00171 
00172         if (_waitTimeRemaining <= 0) {
00173             stop();
00174         }
00175     }
00176 }
00177 
00178 void Speech::onExitLocation() {
00179     stop();
00180 }
00181 
00182 void Speech::onPreDestroy() {
00183     stop();
00184 }
00185 
00186 void Speech::printData() {
00187     Object::printData();
00188 
00189     debug("phrase: %s", _phrase.c_str());
00190     debug("character: %d", _character);
00191 }
00192 
00193 void Speech::setPlayTalkAnim(bool playTalkAnim) {
00194     _playTalkAnim = playTalkAnim;
00195 }
00196 
00197 void Speech::stopOtherSpeechesFromSameCharacter() {
00198     Level *globalLevel = StarkGlobal->getLevel();
00199     Level *currentLevel = StarkGlobal->getCurrent()->getLevel();
00200     Location *currentLocation = StarkGlobal->getCurrent()->getLocation();
00201 
00202     Common::Array<Speech *> globalLevelSpeeches = globalLevel->listChildrenRecursive<Speech>();
00203     Common::Array<Speech *> currentLevelSpeeches = currentLevel->listChildrenRecursive<Speech>();
00204     Common::Array<Speech *> currentLocationSpeeches = currentLocation->listChildrenRecursive<Speech>();
00205 
00206     Common::Array<Speech *> speeches;
00207     speeches.push_back(globalLevelSpeeches);
00208     speeches.push_back(currentLevelSpeeches);
00209     speeches.push_back(currentLocationSpeeches);
00210 
00211     for (uint i = 0; i < speeches.size(); i++) {
00212         Speech *speech = speeches[i];
00213         if (speech->_character == _character && speech->isPlaying()) {
00214             speech->stop();
00215         }
00216     }
00217 }
00218 
00219 void Speech::saveLoadCurrent(ResourceSerializer *serializer) {
00220     bool playing = isPlaying();
00221     serializer->syncAsUint32LE(playing);
00222 
00223     if (playing) {
00224         serializer->syncAsUint32LE(_removeTalkAnimWhenComplete);
00225         serializer->syncAsResourceReference(&_soundResource);
00226         serializer->syncAsResourceReference(&_lipSync);
00227 
00228         if (serializer->isLoading()) {
00229             StarkDialogPlayer->playSingle(this);
00230         }
00231     }
00232 }
00233 
00234 } // End of namespace Resources
00235 } // End of namespace Stark


Generated on Sat Oct 19 2019 05:01:11 for ResidualVM by doxygen 1.7.1
curved edge   curved edge