ScummVM API documentation
soundrecords.h
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 modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (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, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef NANCY_ACTION_SOUNDRECORDS_H
23 #define NANCY_ACTION_SOUNDRECORDS_H
24 
25 #include "engines/nancy/action/actionrecord.h"
26 
27 namespace Nancy {
28 namespace Action {
29 
30 // Reads a Nancy13+ sound block: a list of candidate names, one of which is picked
31 // at random, followed by the shared channel/loop/volume fields. A block with no
32 // names carries no sound at all and stops after the count. Also resolves the
33 // picked sound's subtitle, which Nancy13+ keys off the sound name.
34 void readMultiNameSound(Common::SeekableReadStream &stream, SoundDescription &sound, Common::String &ccText);
35 
36 // Sets the volume for a particular channel.
37 class SetVolume : public ActionRecord {
38 public:
39  void readData(Common::SeekableReadStream &stream) override;
40  void execute() override;
41 
42  uint16 channel = 0;
43  byte volume = 0;
44 
45  Common::String getRecordExtraInfo() const override { return Common::String::format("Channel %u, volume %u", channel, volume); }
46 
47 protected:
48  Common::String getRecordTypeName() const override { return "SetVolume"; }
49 };
50 
51 // Nancy14 AR 150. Changes the volume of a movie that is already loaded,
52 // addressed by its filename.
53 class SetMovieVolume : public ActionRecord {
54 public:
55  void readData(Common::SeekableReadStream &stream) override;
56  void execute() override;
57 
58  Common::Path movieName;
59  byte volume = 0;
60 
61 protected:
62  Common::String getRecordTypeName() const override { return "SetMovieVolume"; }
63 };
64 
65 // Nancy 11+ AR 147. Linearly ramps a channel's volume down to 0 over
66 // the given time, then stops execution.
68 public:
69  void readData(Common::SeekableReadStream &stream) override;
70  void execute() override;
71 
72  uint16 channel = 0;
73  uint32 fadeTimeMs = 0;
74 
75 protected:
76  Common::String getRecordTypeName() const override { return "FadeSoundToSilence"; }
77 
78 private:
79  uint32 _startTime = 0;
80  uint16 _startVolume = 0;
81 };
82 
83 // Nancy 11+ AR 156. Adjusts a playing 3D sound's position and/or its
84 // min/max audible distance. A field set to kNoChange is left untouched.
85 class Update3DSound : public ActionRecord {
86 public:
87  void readData(Common::SeekableReadStream &stream) override;
88  void execute() override;
89 
90  static const int32 kNoChange = 10000;
91 
92  uint16 _channelID = 0;
93  int32 _posX = 0;
94  int32 _posY = 0;
95  int32 _posZ = 0;
96  int32 _minDistance = 0;
97  int32 _maxDistance = 0;
98 
99 protected:
100  Common::String getRecordTypeName() const override { return "Update3DSound"; }
101 };
102 
103 // Added in Nancy12 (AR 168). Sets a 3D-sound position from a set of coordinates,
104 // most likely the global listener position.
106 public:
107  void readData(Common::SeekableReadStream &stream) override;
108  void execute() override;
109 
110  int32 _posX = 0;
111  int32 _posY = 0;
112  int32 _posZ = 0;
113 
114 protected:
115  Common::String getRecordTypeName() const override { return "Set3DSoundListenerPosition"; }
116 };
117 
118 // Used for sound effects. From nancy3 up it includes 3D sound data, which lets
119 // the sound move in 3D space as the player rotates/changes scenes. Also supports
120 // changing the scene and/or setting a flag
121 class PlaySound : public ActionRecord {
122 public:
123  PlaySound() {}
124  ~PlaySound() { delete _soundEffect; }
125 
126  void readData(Common::SeekableReadStream &stream) override;
127  void execute() override;
128 
129  SoundDescription _sound;
130  SoundEffectDescription *_soundEffect = nullptr;
131  bool _changeSceneImmediately = false;
132  SceneChangeDescription _sceneChange;
133  FlagDescription _flag;
134 
135  // Nancy13+: a list of flags (was a single flag) and a multi-name random sound.
137  byte _afterSoundAction = 0; // Nancy13+: 1 dismisses the text box overlay
138 
139  // Subtitle shown in the game textbox while the sound plays. In Nancy13+ this
140  // is resolved from the sound name (see readDataNancy13); earlier games store
141  // it explicitly in the closed-caption records below.
142  Common::String _ccText;
143 
144  Common::String getRecordExtraInfo() const override;
145 
146 protected:
147  Common::String getRecordTypeName() const override;
148 
149  void readDataNancy13(Common::SeekableReadStream &stream);
150  void applyAfterSoundAction();
151 };
152 
153 // The same as PlaySound, but with the addition of captioning text,
154 // which gets displayed inside the Textbox.
155 class PlaySoundCC : public PlaySound {
156 public:
157  void readData(Common::SeekableReadStream &stream) override;
158  void execute() override;
159 
160  void readCCText(Common::SeekableReadStream &stream, Common::String &out);
161 
162 protected:
163  Common::String getRecordTypeName() const override;
164 };
165 
166 // Short version of PlaySoundCC, no event flag
167 class PlaySoundTerse : public PlaySoundCC {
168 public:
169  void readData(Common::SeekableReadStream &stream) override;
170 
171 protected:
172  Common::String getRecordTypeName() const override { return "PlaySoundTerse"; }
173 };
174 
175 // Short version of PlaySoundCC, with event flag
177 public:
178  void readData(Common::SeekableReadStream &stream) override;
179 
180 protected:
181  Common::String getRecordTypeName() const override { return "PlaySoundEventFlagTerse"; }
182 };
183 
184 // Used for sounds that pan left-right depending on the scene background frame.
185 // Only used in The Vampire Diaries; later games use PlaySound's 3D sound capabilities instead
187 public:
188  void readData(Common::SeekableReadStream &stream) override;
189  void execute() override;
190 
191  SoundDescription _sound;
192 
193 protected:
194  Common::String getRecordTypeName() const override;
195 };
196 
197 // Plays a sound effect; has multiple hotspots, one per scene background frame.
198 // Used in exactly two places; one scene in tvd, and one in nancy1
200 public:
201  void readData(Common::SeekableReadStream &stream) override;
202  void execute() override;
203 
204  SoundDescription _sound; // 0x0
205  SceneChangeDescription _sceneChange; // 0x22
206  FlagDescription _flag; // 0x2A
207  Common::Array<HotspotDescription> _hotspots; // 0x31
208 
209  bool canHaveHotspot() const override { return true; }
210 
211  Common::String getRecordExtraInfo() const override { return Common::String::format("Scene %d", _sceneChange.sceneID); }
212 protected:
213  Common::String getRecordTypeName() const override { return "PlaySoundMultiHS"; }
214 };
215 
216 // Stops a sound if it's loaded and playing. Used very rarely, as sounds (usually)
217 // get auto-stopped on a scene change
218 class StopSound : public ActionRecord {
219 public:
220  void readData(Common::SeekableReadStream &stream) override;
221  void execute() override;
222 
223  uint _channelID;
224  SceneChangeWithFlag _sceneChange;
225 
226 protected:
227  Common::String getRecordTypeName() const override { return "StopSound"; }
228 };
229 
230 // Same as PlaySound, except it randomly picks between one of several provided
231 // sound files; all other settings for the sound are shared. The played sound is
232 // chosen when the record is loaded.
233 class PlayRandomSound : public PlaySound {
234 public:
235  void readData(Common::SeekableReadStream &stream) override;
236 
237  Common::Array<Common::String> _soundNames;
238 
239  uint _selectedSound = 0;
240 
241 protected:
242  Common::String getRecordTypeName() const override { return "PlayRandomSound"; }
243 };
244 
245 // Short version of PlayRandomSound, but ALSO supports closed captioning text.
246 // The played sound is chosen at random when the record is loaded.
248 public:
249  void readData(Common::SeekableReadStream &stream) override;
250 
251  Common::Array<Common::String> _soundNames;
253 
254  uint _selectedSound = 0;
255 
256 protected:
257  Common::String getRecordTypeName() const override { return "PlayRandomSoundTerse"; }
258 };
259 
260 // Same as PlaySound, except it discards the filename provided in the data.
261 // Instead, it takes the current value of an item in TableData, and appends that
262 // value to the end of the base filename provided in the TABL chunk. Does not contain
263 // any CC text inside the record data; instead, that also gets copied over from TABL.
265 public:
266  void readData(Common::SeekableReadStream &stream) override;
267  void execute() override;
268 
269 protected:
270  Common::String getRecordTypeName() const override { return "TableIndexPlaySound"; }
271 
272  uint16 _tableIndex = 0;
273  int16 _lastIndexVal = -1;
274 };
275 
276 // Nancy14 sequenced sound player (AR 143 ConcatSound / 144 MultiSound): plays a
277 // list of grouped sounds one after another on a shared channel, then optionally
278 // changes scene. ConcatSound keeps a set of event flags per group, MultiSound one
279 // shared set.
281 public:
282  void readData(Common::SeekableReadStream &stream) override;
283  void execute() override;
284 
285 protected:
286  struct SequencedSound {
287  Common::String name;
288  byte flag = 0; // when set, this sound's subtitle ends its line
289  int16 delay = 0; // seconds to hold after the sound starts
290  };
291 
292  struct SoundGroup {
294  Common::Array<FlagDescription> flags; // ConcatSound only
295  };
296 
297  // Selects how a group's subtitle is presented. The original picks between two
298  // textbox surfaces, which are the same textbox here, so only the value that
299  // suppresses the subtitle entirely is acted on.
300  static const byte kSubtitleModeNone = 3;
301 
302  // Flags stored per group (ConcatSound) or as one shared set (MultiSound).
303  virtual bool perGroupFlags() const = 0;
304 
305  void showGroupSubtitle();
306  void startCurrentSound();
307 
309  Common::Array<FlagDescription> _sharedFlags; // MultiSound only
310  SoundDescription _sound;
311  int16 _exitSceneID = kNoScene;
312  byte _subtitleMode = 0;
313 
314  // Runtime state
315  uint _currentGroup = 0;
316  uint _currentSound = 0;
317  bool _soundStarted = false;
318  uint32 _delayEnd = 0;
319 };
320 
322 protected:
323  bool perGroupFlags() const override { return true; }
324  Common::String getRecordTypeName() const override { return "ConcatSound"; }
325 };
326 
327 class MultiSound : public ConcatMultiSound {
328 protected:
329  bool perGroupFlags() const override { return false; }
330  Common::String getRecordTypeName() const override { return "MultiSound"; }
331 };
332 
333 } // End of namespace Action
334 } // End of namespace Nancy
335 
336 #endif // NANCY_ACTION_NAVIGATIONRECORDS_H
Definition: str.h:59
static String format(MSVC_PRINTF const char *fmt,...) GCC_PRINTF(1
Definition: soundrecords.h:167
Definition: soundrecords.h:37
Definition: commontypes.h:186
Definition: array.h:52
Definition: soundrecords.h:105
Definition: soundrecords.h:280
Definition: soundrecords.h:321
Definition: path.h:52
Definition: soundrecords.h:85
Definition: soundrecords.h:218
Definition: soundrecords.h:186
Definition: stream.h:745
Definition: soundrecords.h:327
Definition: commontypes.h:269
Definition: soundrecords.h:292
Definition: soundrecords.h:121
Definition: soundrecords.h:53
Definition: commontypes.h:206
Definition: soundrecords.h:155
Definition: actionrecord.h:107
Definition: soundrecords.h:176
Definition: soundrecords.h:264
Definition: soundrecords.h:199
Definition: soundrecords.h:247
Definition: commontypes.h:306
Definition: soundrecords.h:67
Definition: commontypes.h:201
Definition: actionmanager.h:32
Definition: soundrecords.h:233