1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include "bladerunner/outtake.h"
24
25 #include "bladerunner/bladerunner.h"
26 #include "bladerunner/chapters.h"
27 #include "bladerunner/subtitles.h"
28 #include "bladerunner/vqa_player.h"
29 #include "bladerunner/time.h"
30 #include "bladerunner/ambient_sounds.h"
31 #include "bladerunner/audio_player.h"
32 #include "bladerunner/game_constants.h"
33 #include "bladerunner/game_info.h"
34
35 #include "common/debug.h"
36 #include "common/events.h"
37 #include "common/system.h"
38
39 namespace BladeRunner {
40
OuttakePlayer(BladeRunnerEngine * vm)41 OuttakePlayer::OuttakePlayer(BladeRunnerEngine *vm) {
42 _vm = vm;
43 _surfaceVideo.create(_vm->_surfaceBack.w, _vm->_surfaceBack.h, _vm->_surfaceBack.format);
44 }
45
~OuttakePlayer()46 OuttakePlayer::~OuttakePlayer() {
47 _surfaceVideo.free();
48 }
49
play(const Common::String & name,bool noLocalization,int container)50 void OuttakePlayer::play(const Common::String &name, bool noLocalization, int container) {
51 Common::String oldOuttakeFile = Common::String::format("OUTTAKE%d.MIX", _vm->_chapters->currentResourceId());
52 Common::String newOuttakeFile = Common::String::format("OUTTAKE%d.MIX", container);
53
54 if (container > 0) {
55 if (_vm->isArchiveOpen(oldOuttakeFile)) {
56 _vm->closeArchive(oldOuttakeFile);
57 }
58
59 _vm->openArchive(newOuttakeFile);
60 }
61
62 _vm->playerLosesControl();
63
64 Common::String resName = name;
65 if (!noLocalization) {
66 resName = resName + "_" + _vm->_languageCode;
67 }
68 Common::String resNameNoVQASuffix = resName;
69 resName = resName + ".VQA";
70
71 VQAPlayer vqaPlayer(_vm, &_surfaceVideo, resName); // in original game _surfaceFront is used here, but for proper subtitles rendering we need separate surface
72 vqaPlayer.open();
73
74 _vm->_vqaIsPlaying = true;
75 _vm->_vqaStopIsRequested = false;
76
77 while (!_vm->_vqaStopIsRequested && !_vm->shouldQuit()) {
78 _vm->handleEvents();
79
80 if (!_vm->_windowIsActive) {
81 continue;
82 }
83
84 int frame = vqaPlayer.update();
85 blit(_surfaceVideo, _vm->_surfaceFront); // This helps to make subtitles disappear properly, if the video is rendered in separate surface and then pushed to the front surface
86 if (frame == -3) { // end of video
87 if (_vm->_cutContent && resName.equals("FLYTRU_E.VQA")) {
88 _vm->_ambientSounds->removeAllNonLoopingSounds(true);
89 _vm->_ambientSounds->removeAllLoopingSounds(1u);
90 }
91 break;
92 }
93
94 if (frame >= 0) {
95 _vm->_subtitles->loadOuttakeSubsText(resNameNoVQASuffix, frame);
96 _vm->_subtitles->tickOuttakes(_vm->_surfaceFront);
97 _vm->blitToScreen(_vm->_surfaceFront);
98 if (_vm->_cutContent && resName.equals("FLYTRU_E.VQA")) {
99 // This FLYTRU_E outtake has 150 frames
100 //
101 // We can have at most kLoopingSounds (3) looping ambient tracks
102 // Outtakes in general use a specific Mixer Sound Type (ie. VQAPlayer::kVQASoundType)
103 // so the sounds here should conform too.
104 // (see VQAPlayer::update())
105 //
106 // No need for _ambientSounds->tick() since it's not required for looping ambient tracks,
107 // nor for explicitly played Sounds (via playSound())
108 // It is harmless however, so it could remain.
109 //_vm->_ambientSounds->tick();
110 switch (frame) {
111 case 0:
112 _vm->_ambientSounds->addLoopingSound(kSfxLABAMB1, 95, 0, 0u, VQAPlayer::kVQASoundType);
113 _vm->_ambientSounds->addLoopingSound(kSfxROOFAIR1, 100, 0, 0u, VQAPlayer::kVQASoundType);
114 _vm->_ambientSounds->addLoopingSound(kSfxPSPA6, 74, 0, 1u, VQAPlayer::kVQASoundType);
115 break;
116 case 18:
117 _vm->_ambientSounds->playSound(kSfxSPIN2A, 100, 90, 20, 99, VQAPlayer::kVQASoundType);
118 break;
119 case 24:
120 _vm->_ambientSounds->playSound(kSfxSWEEP4, 45, 90, 20, 99, VQAPlayer::kVQASoundType);
121 break;
122 case 32:
123 if (_vm->_rnd.getRandomNumberRng(1, 5) < 4)
124 _vm->_ambientSounds->playSound(kSfxTHNDER3, 82, -20, -20, 99, VQAPlayer::kVQASoundType);
125 break;
126 case 41:
127 _vm->_ambientSounds->playSound(kSfxMUSVOL8, 22, 46, 46, 99, VQAPlayer::kVQASoundType);
128 break;
129 case 52:
130 if (_vm->_rnd.getRandomNumberRng(1, 4) < 4)
131 _vm->_ambientSounds->playSound(kSfxTHNDR3, 90, 10, 10, 89, VQAPlayer::kVQASoundType);
132 break;
133 case 78:
134 if (_vm->_rnd.getRandomNumberRng(1, 5) < 5)
135 _vm->_ambientSounds->playSound(kSfxSIREN2, 62, -60, 45, 99, VQAPlayer::kVQASoundType);
136 break;
137 case 105:
138 _vm->_ambientSounds->playSound(kSfxSWEEP3, 22, 20, 95, 99, VQAPlayer::kVQASoundType);
139 break;
140 case 112:
141 if (_vm->_rnd.getRandomNumberRng(1, 5) < 4)
142 _vm->_ambientSounds->playSound(kSfxTHNDER4, 95, -20, -20, 99, VQAPlayer::kVQASoundType);
143 break;
144 }
145 }
146 }
147 }
148
149 if ((_vm->_vqaStopIsRequested || _vm->shouldQuit())
150 && _vm->_cutContent && resName.equals("FLYTRU_E.VQA")) {
151 _vm->_ambientSounds->removeAllNonLoopingSounds(true);
152 _vm->_ambientSounds->removeAllLoopingSounds(0u);
153 _vm->_audioPlayer->stopAll();
154 }
155
156 _vm->_vqaIsPlaying = false;
157 _vm->_vqaStopIsRequested = false;
158 vqaPlayer.close();
159
160 _vm->playerGainsControl();
161
162 if (container > 0) {
163 if (_vm->isArchiveOpen(newOuttakeFile)) {
164 _vm->closeArchive(newOuttakeFile);
165 }
166
167 _vm->openArchive(oldOuttakeFile);
168 }
169 }
170
171 } // End of namespace BladeRunner
172