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     if (_soundResource) {
00112         return _soundResource->isPlaying();
00113     } else {
00114         return _waitTimeRemaining > 0;
00115     }
00116 }
00117 
00118 void Speech::stop() {
00119     if (_soundResource) {
00120         _soundResource->stop();
00121         _soundResource = nullptr;
00122     }
00123 
00124     _waitTimeRemaining = -1;
00125 
00126     if (_lipSync) {
00127         _lipSync->reset();
00128     }
00129 
00130     if (_removeTalkAnimWhenComplete) {
00131         removeCharacterTalkAnim();
00132     }
00133 
00134     _removeTalkAnimWhenComplete = true;
00135     _playTalkAnim = true;
00136 }
00137 
00138 bool Speech::characterIsApril() const {
00139     int32 aprilCharacterIndex = StarkGlobal->getApril()->getCharacterIndex();
00140     return _character == aprilCharacterIndex;
00141 }
00142 
00143 int32 Speech::getPauseAfterSpeechDuration() const {
00144     if (_phrase.hasSuffix("...")) {
00145         return 1400;
00146     } else if (_phrase.hasSuffix("--")) {
00147         return 0;
00148     } else {
00149         return 1000;
00150     }
00151 }
00152 
00153 void Speech::readData(Formats::XRCReadStream *stream) {
00154     Object::readData(stream);
00155 
00156     _phrase = stream->readString();
00157     _character = stream->readSint32LE();
00158 }
00159 
00160 void Speech::onGameLoop() {
00161     Object::onGameLoop();
00162 
00163     if (_soundResource && !_soundResource->isPlaying()) {
00164         _soundResource->stop();
00165         _soundResource = nullptr;
00166         _waitTimeRemaining = getPauseAfterSpeechDuration();
00167     }
00168 
00169     if (_waitTimeRemaining >= 0) {
00170         _waitTimeRemaining -= StarkGlobal->getMillisecondsPerGameloop();
00171 
00172         if (StarkGlobal->isFastForward()) {
00173             _waitTimeRemaining = -1;
00174         }
00175 
00176         if (_waitTimeRemaining <= 0) {
00177             stop();
00178         }
00179     }
00180 }
00181 
00182 void Speech::onExitLocation() {
00183     stop();
00184 }
00185 
00186 void Speech::onPreDestroy() {
00187     stop();
00188 }
00189 
00190 void Speech::printData() {
00191     Object::printData();
00192 
00193     debug("phrase: %s", _phrase.c_str());
00194     debug("character: %d", _character);
00195 }
00196 
00197 void Speech::setPlayTalkAnim(bool playTalkAnim) {
00198     _playTalkAnim = playTalkAnim;
00199 }
00200 
00201 void Speech::stopOtherSpeechesFromSameCharacter() {
00202     Level *globalLevel = StarkGlobal->getLevel();
00203     Level *currentLevel = StarkGlobal->getCurrent()->getLevel();
00204     Location *currentLocation = StarkGlobal->getCurrent()->getLocation();
00205 
00206     Common::Array<Speech *> globalLevelSpeeches = globalLevel->listChildrenRecursive<Speech>();
00207     Common::Array<Speech *> currentLevelSpeeches = currentLevel->listChildrenRecursive<Speech>();
00208     Common::Array<Speech *> currentLocationSpeeches = currentLocation->listChildrenRecursive<Speech>();
00209 
00210     Common::Array<Speech *> speeches;
00211     speeches.push_back(globalLevelSpeeches);
00212     speeches.push_back(currentLevelSpeeches);
00213     speeches.push_back(currentLocationSpeeches);
00214 
00215     for (uint i = 0; i < speeches.size(); i++) {
00216         Speech *speech = speeches[i];
00217         if (speech->_character == _character && speech->isPlaying()) {
00218             speech->stop();
00219         }
00220     }
00221 }
00222 
00223 void Speech::saveLoadCurrent(ResourceSerializer *serializer) {
00224     bool playing = isPlaying();
00225     serializer->syncAsUint32LE(playing);
00226 
00227     if (playing) {
00228         serializer->syncAsUint32LE(_removeTalkAnimWhenComplete);
00229         serializer->syncAsResourceReference(&_soundResource);
00230         serializer->syncAsResourceReference(&_lipSync);
00231 
00232         if (serializer->isLoading()) {
00233             StarkDialogPlayer->playSingle(this);
00234         }
00235     }
00236 }
00237 
00238 } // End of namespace Resources
00239 } // End of namespace Stark


Generated on Sat Mar 16 2019 05:01:54 for ResidualVM by doxygen 1.7.1
curved edge   curved edge