Rigs of Rods 2023.09
Soft-body Physics Simulation
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
SoundScriptManager.h
Go to the documentation of this file.
1/*
2 This source file is part of Rigs of Rods
3 Copyright 2005-2012 Pierre-Michel Ricordel
4 Copyright 2007-2012 Thomas Fischer
5 Copyright 2017-2018 Petr Ohlidal
6
7 For more information, see http://www.rigsofrods.org/
8
9 Rigs of Rods is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License version 3, as
11 published by the Free Software Foundation.
12
13 Rigs of Rods is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Rigs of Rods. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#ifdef USE_OPENAL
23
24#pragma once
25
26#include "AngelScriptBindings.h"
27#include "Application.h"
29#include "Sound.h"
30#include "SoundManager.h"
31
32#include <OgreScriptLoader.h>
33
34#define SOUND_PLAY_ONCE(_ACTOR_, _TRIG_) App::GetSoundScriptManager()->trigOnce ( (_ACTOR_), (_TRIG_) )
35#define SOUND_START(_ACTOR_, _TRIG_) App::GetSoundScriptManager()->trigStart ( (_ACTOR_), (_TRIG_) )
36#define SOUND_STOP(_ACTOR_, _TRIG_) App::GetSoundScriptManager()->trigStop ( (_ACTOR_), (_TRIG_) )
37#define SOUND_TOGGLE(_ACTOR_, _TRIG_) App::GetSoundScriptManager()->trigToggle ( (_ACTOR_), (_TRIG_) )
38#define SOUND_KILL(_ACTOR_, _TRIG_) App::GetSoundScriptManager()->trigKill ( (_ACTOR_), (_TRIG_) )
39#define SOUND_GET_STATE(_ACTOR_, _TRIG_) App::GetSoundScriptManager()->getTrigState( (_ACTOR_), (_TRIG_) )
40#define SOUND_MODULATE(_ACTOR_, _MOD_, _VALUE_) App::GetSoundScriptManager()->modulate ( (_ACTOR_), (_MOD_), (_VALUE_) )
41
42namespace RoR {
43
46
47enum {
50};
51
122
157
175
176class SoundScriptTemplate : public RefCountingObject<SoundScriptTemplate>
177{
178 friend class SoundScriptManager;
180
181public:
182
183 SoundScriptTemplate(Ogre::String name, Ogre::String groupname, Ogre::String filename, bool baseTemplate);
184 virtual ~SoundScriptTemplate() override {};
185
186 // 'sound' attribute getters for AngelScript
187 int getNumSounds() { return free_sound; }
188 Ogre::String getSoundName(int pos) { if (pos >= 0 && pos < free_sound) { return sound_names[pos]; } else { return ""; } }
189 float getSoundPitch(int pos) { if (pos >= 0 && pos < free_sound) { return sound_pitches[pos]; } else { return 0.f; } }
190
191 // start/stop sound attribute getters for AngelScript
192 Ogre::String getStartSoundName() { return start_sound_name; }
194 Ogre::String getStopSoundName() { return stop_sound_name; }
196
197 // other getters for AngelScript
198 Ogre::String getName() { return name; }
199 Ogre::String getFileName() { return file_name; }
200 Ogre::String getGroupName() { return group_name; }
201 bool isBaseTemplate() { return base_template; }
202
203private:
204
205 int parseModulation(Ogre::String str);
206 bool setParameter(Ogre::StringVector vec);
207
208 Ogre::String name;
209 Ogre::String file_name;
210 Ogre::String group_name;
211
216
221
226
229 Ogre::String start_sound_name;
231 Ogre::String stop_sound_name;
233
236};
237
238class SoundScriptInstance : public RefCountingObject<SoundScriptInstance>
239{
240 friend class SoundScriptManager;
241
242public:
243
244 SoundScriptInstance(int actor_id, SoundScriptTemplatePtr templ, SoundManager* sm, Ogre::String instancename, int soundLinkType=SL_DEFAULT, int soundLinkItemId=-1);
245 virtual ~SoundScriptInstance() override {};
246
247 void runOnce();
248 void setEnabled(bool e);
249 void setGain(float value);
250 void setPitch(float value);
251 void setPosition(Ogre::Vector3 pos);
252 void setVelocity(Ogre::Vector3 velo);
253 void start();
254 void stop();
255 void kill();
256
258 const SoundPtr& getStartSound() { return start_sound; }
259 const SoundPtr& getStopSound() { return stop_sound; }
260 const SoundPtr& getSound(int pos) { if (pos >= 0 && pos < templ->free_sound) { return sounds[pos]; } else { return SOUNDPTR_NULL; } }
263 float getSoundPitchgain(int pos) { if (pos >= 0 && pos < templ->free_sound) { return sounds_pitchgain[pos]; } else { return 0.f; } }
264 int getActorInstanceId() { return actor_id; }
265 const Ogre::String& getInstanceName() { return instance_name; }
266
267 static const float PITCHDOWN_FADE_FACTOR;
268 static const float PITCHDOWN_CUTOFF_FACTOR;
269 static const int ACTOR_ID_UNKNOWN = -1;
270 static const int ACTOR_ID_TERRAIN_OBJECT = -2;
271 static const SoundPtr SOUNDPTR_NULL; // Dummy value to be returned as const reference.
272
273private:
274
275 float pitchgain_cutoff(float sourcepitch, float targetpitch);
276
277 Ogre::String instance_name;
286 float lastgain;
287
288 int actor_id; // ID of the actor this sound belongs to, or an `ACTOR_ID_*` constant.
289 int sound_link_type; // holds the SL_ type this is bound to
290 int sound_link_item_id; // holds the item number this is for
291};
292
293class SoundScriptManager : public Ogre::ScriptLoader
294{
295public:
296
299
300 // ScriptLoader interface
301 const Ogre::StringVector& getScriptPatterns(void) const;
302 void parseScript(Ogre::DataStreamPtr& stream, const Ogre::String& groupName);
303 Ogre::Real getLoadingOrder(void) const;
304
305 SoundScriptInstancePtr createInstance(Ogre::String templatename, int actor_id, int soundLinkType=SL_DEFAULT, int soundLinkItemId=-1);
306 void removeInstance(const SoundScriptInstancePtr& ssi);
307 std::vector<SoundScriptInstancePtr>& getAllInstances() { return instances; }
308 SoundScriptTemplatePtr& getTemplate(Ogre::String name) { return templates[name]; }
309 std::map <Ogre::String, SoundScriptTemplatePtr>& getAllTemplates() { return templates; }
310
311 // functions
312 void trigOnce (int actor_id, int trig, int linkType = SL_DEFAULT, int linkItemID=-1);
313 void trigOnce (const ActorPtr& actor, int trig, int linkType = SL_DEFAULT, int linkItemID=-1);
314 void trigStart (int actor_id, int trig, int linkType = SL_DEFAULT, int linkItemID=-1);
315 void trigStart (const ActorPtr& actor, int trig, int linkType = SL_DEFAULT, int linkItemID=-1);
316 void trigStop (int actor_id, int trig, int linkType = SL_DEFAULT, int linkItemID=-1);
317 void trigStop (const ActorPtr& actor, int trig, int linkType = SL_DEFAULT, int linkItemID=-1);
318 void trigToggle (int actor_id, int trig, int linkType = SL_DEFAULT, int linkItemID=-1);
319 void trigToggle (const ActorPtr& actor, int trig, int linkType = SL_DEFAULT, int linkItemID=-1);
320 void trigKill (int actor_id, int trig, int linkType = SL_DEFAULT, int linkItemID = -1);
321 void trigKill (const ActorPtr& actor, int trig, int linkType = SL_DEFAULT, int linkItemID = -1);
322 bool getTrigState(int actor_id, int trig, int linkType = SL_DEFAULT, int linkItemID=-1);
323 bool getTrigState(const ActorPtr& actor, int trig, int linkType = SL_DEFAULT, int linkItemID=-1);
324 void modulate (int actor_id, int mod, float value, int linkType = SL_DEFAULT, int linkItemID=-1);
325 void modulate (const ActorPtr& actor, int mod, float value, int linkType = SL_DEFAULT, int linkItemID=-1);
326
327 void setEnabled(bool state);
328
329 void SetListener(Ogre::Vector3 position, Ogre::Vector3 direction, Ogre::Vector3 up, Ogre::Vector3 velocity);
330 void setLoadingBaseSounds(bool value) { loading_base = value; };
331
332 bool isDisabled() { return disabled; }
333
334 void update(float dt);
335
337
338private:
339
340 SoundScriptTemplatePtr createTemplate(Ogre::String name, Ogre::String groupname, Ogre::String filename);
341 void skipToNextCloseBrace(Ogre::DataStreamPtr& chunk);
342 void skipToNextOpenBrace(Ogre::DataStreamPtr& chunk);
343
350 Ogre::StringVector script_patterns;
351
352 std::map <Ogre::String, SoundScriptTemplatePtr> templates;
353 std::vector<SoundScriptInstancePtr> instances;
354
355 // instances lookup tables - using `std::array<>` because it does bounds checking under VisualStudio/Debug.
356 std::array<int, SS_MAX_TRIG> free_trigs;
357 std::array<SoundScriptInstancePtr, SS_MAX_TRIG* MAX_INSTANCES_PER_GROUP> trigs;
358
359 std::array<int, SS_MAX_MOD> free_pitches;
360 std::array<SoundScriptInstancePtr, SS_MAX_MOD* MAX_INSTANCES_PER_GROUP> pitches;
361
362 std::array<int, SS_MAX_MOD> free_gains;
363 std::array<SoundScriptInstancePtr, SS_MAX_MOD* MAX_INSTANCES_PER_GROUP> gains;
364
365 // state map
366 // soundLinks, soundItems, actor_ids, triggers
367 std::map <int, std::map <int, std::map <int, std::map <int, bool > > > > state_map;
368
369 void SetListenerEnvironment(Ogre::Vector3 position);
370
372};
373
375
376} // namespace RoR
377
378#else // USE_OPENAL
379
380#define SOUND_PLAY_ONCE(_ACTOR_, _TRIG_)
381#define SOUND_START(_ACTOR_, _TRIG_)
382#define SOUND_STOP(_ACTOR_, _TRIG_)
383#define SOUND_TOGGLE(_ACTOR_, _TRIG_)
384#define SOUND_KILL(_ACTOR_, _TRIG_)
385#define SOUND_GET_STATE(_ACTOR_, _TRIG_) (false)
386#define SOUND_MODULATE(_ACTOR_, _MOD_, _VALUE_)
387
388#endif // USE_OPENAL
Central state/object manager and communications hub.
Self reference-counting objects, as requred by AngelScript garbage collector.
static const float PITCHDOWN_CUTOFF_FACTOR
SoundScriptTemplatePtr templ
const SoundPtr & getStopSound()
void setPosition(Ogre::Vector3 pos)
static const int ACTOR_ID_UNKNOWN
SoundScriptTemplatePtr & getTemplate()
static const float PITCHDOWN_FADE_FACTOR
static const int ACTOR_ID_TERRAIN_OBJECT
float sounds_pitchgain[MAX_SOUNDS_PER_SCRIPT]
const SoundPtr & getSound(int pos)
void setVelocity(Ogre::Vector3 velo)
virtual ~SoundScriptInstance() override
float pitchgain_cutoff(float sourcepitch, float targetpitch)
SoundPtr sounds[MAX_SOUNDS_PER_SCRIPT]
const Ogre::String & getInstanceName()
const SoundPtr & getStartSound()
static const SoundPtr SOUNDPTR_NULL
void trigToggle(int actor_id, int trig, int linkType=SL_DEFAULT, int linkItemID=-1)
std::map< int, std::map< int, std::map< int, std::map< int, bool > > > > state_map
std::array< int, SS_MAX_MOD > free_pitches
SoundScriptTemplatePtr createTemplate(Ogre::String name, Ogre::String groupname, Ogre::String filename)
Ogre::StringVector script_patterns
const Ogre::StringVector & getScriptPatterns(void) const
SoundScriptTemplatePtr & getTemplate(Ogre::String name)
void skipToNextCloseBrace(Ogre::DataStreamPtr &chunk)
std::vector< SoundScriptInstancePtr > & getAllInstances()
std::array< int, SS_MAX_MOD > free_gains
void parseScript(Ogre::DataStreamPtr &stream, const Ogre::String &groupName)
void modulate(int actor_id, int mod, float value, int linkType=SL_DEFAULT, int linkItemID=-1)
void skipToNextOpenBrace(Ogre::DataStreamPtr &chunk)
bool getTrigState(int actor_id, int trig, int linkType=SL_DEFAULT, int linkItemID=-1)
std::map< Ogre::String, SoundScriptTemplatePtr > templates
std::array< SoundScriptInstancePtr, SS_MAX_TRIG *MAX_INSTANCES_PER_GROUP > trigs
void removeInstance(const SoundScriptInstancePtr &ssi)
void setLoadingBaseSounds(bool value)
void trigOnce(int actor_id, int trig, int linkType=SL_DEFAULT, int linkItemID=-1)
void trigKill(int actor_id, int trig, int linkType=SL_DEFAULT, int linkItemID=-1)
std::map< Ogre::String, SoundScriptTemplatePtr > & getAllTemplates()
std::array< int, SS_MAX_TRIG > free_trigs
void trigStart(int actor_id, int trig, int linkType=SL_DEFAULT, int linkItemID=-1)
SoundManager * getSoundManager()
std::vector< SoundScriptInstancePtr > instances
SoundScriptInstancePtr createInstance(Ogre::String templatename, int actor_id, int soundLinkType=SL_DEFAULT, int soundLinkItemId=-1)
std::array< SoundScriptInstancePtr, SS_MAX_MOD *MAX_INSTANCES_PER_GROUP > pitches
void trigStop(int actor_id, int trig, int linkType=SL_DEFAULT, int linkItemID=-1)
void SetListenerEnvironment(Ogre::Vector3 position)
void SetListener(Ogre::Vector3 position, Ogre::Vector3 direction, Ogre::Vector3 up, Ogre::Vector3 velocity)
std::array< SoundScriptInstancePtr, SS_MAX_MOD *MAX_INSTANCES_PER_GROUP > gains
Ogre::Real getLoadingOrder(void) const
bool setParameter(Ogre::StringVector vec)
Ogre::String getSoundName(int pos)
int parseModulation(Ogre::String str)
float sound_pitches[MAX_SOUNDS_PER_SCRIPT]
virtual ~SoundScriptTemplate() override
Ogre::String sound_names[MAX_SOUNDS_PER_SCRIPT]
@ SS_TRIG_GPWS_PULLUP
@ SS_TRIG_AFTERBURNER4
@ SS_TRIG_AEROENGINE7
@ SS_TRIG_GPWS_APDISCONNECT
@ SS_TRIG_AEROENGINE2
@ SS_TRIG_AFTERBURNER2
@ SS_TRIG_AEROENGINE3
@ SS_TRIG_AFTERBURNER5
@ SS_TRIG_AFTERBURNER7
@ SS_TRIG_TURBOBACKFIRE
@ SS_TRIG_LINKED_COMMAND
@ SS_TRIG_AEROENGINE1
@ SS_TRIG_TURN_SIGNAL
@ SS_TRIG_AEROENGINE5
@ SS_TRIG_TURBOWASTEGATE
@ SS_TRIG_TURN_SIGNAL_WARN_TICK
@ SS_TRIG_AEROENGINE6
@ SS_TRIG_TURN_SIGNAL_TICK
@ SS_TRIG_AFTERBURNER6
@ SS_TRIG_GPWS_MINIMUMS
@ SS_TRIG_AIR_PURGE
@ SS_TRIG_AEROENGINE8
@ SS_TRIG_AFTERBURNER1
@ SS_TRIG_AEROENGINE4
@ SS_TRIG_GEARSLIDE
@ SS_TRIG_AFTERBURNER3
@ SS_TRIG_REVERSE_GEAR
@ SS_TRIG_AFTERBURNER8
@ MAX_INSTANCES_PER_GROUP
@ MAX_SOUNDS_PER_SCRIPT
@ SS_MOD_LINKED_COMMANDRATE
@ SS_MOD_MUSIC_VOLUME