Isle
Loading...
Searching...
No Matches
mxbackgroundaudiomanager.cpp
Go to the documentation of this file.
2
3#include "legomain.h"
4#include "misc.h"
5#include "mxaudiopresenter.h"
7#include "mxdssound.h"
8#include "mxmisc.h"
10#include "mxpresenter.h"
11#include "mxstreamer.h"
12#include "mxticklemanager.h"
13#include "mxutilities.h"
14
16
17// FUNCTION: LEGO1 0x1007ea90
19{
21 m_unk0xa0 = 0;
22 m_unk0x138 = 0;
23 m_tickleState = MxPresenter::e_idle;
24 m_speed = 0;
25 m_targetVolume = 0;
26 m_unk0x148 = 0;
27 m_enabled = FALSE;
28}
29
30// FUNCTION: LEGO1 0x1007ec20
32{
35 DestroyMusic();
36}
37
38// FUNCTION: LEGO1 0x1007ece0
40{
41 MxResult result = OpenMusic(p_script);
42
43 if (result == SUCCESS) {
44 TickleManager()->RegisterClient(this, p_frequencyMS);
45 m_enabled = TRUE;
46 }
47
48 return result;
49}
50
51// FUNCTION: LEGO1 0x1007ed20
52MxResult MxBackgroundAudioManager::OpenMusic(MxAtomId& p_script)
53{
54 if (m_script.GetInternal()) {
55 DestroyMusic();
56 }
57
58 MxResult result = FAILURE;
59
60 if (Streamer()->Open(p_script.GetInternal(), 0)) {
61 m_script = p_script;
62 result = SUCCESS;
63 }
64
65 return result;
66}
67
68// FUNCTION: LEGO1 0x1007ed70
69void MxBackgroundAudioManager::DestroyMusic()
70{
71 if (m_script.GetInternal()) {
72 MxDSAction ds;
73 ds.SetAtomId(m_script);
74 ds.SetUnknown24(-2);
75 DeleteObject(ds);
76 Streamer()->Close(m_script.GetInternal());
77 m_enabled = FALSE;
78 }
79}
80
81// FUNCTION: LEGO1 0x1007ee40
83{
84 switch (m_tickleState) {
87 break;
90 break;
93 }
94
95 return SUCCESS;
96}
97
98// FUNCTION: LEGO1 0x1007ee70
100{
101 if (m_unk0xa0 && m_unk0xa0->GetAction()) {
102 DeleteObject(*m_unk0x138->GetAction());
103 }
104
105 if (m_unk0x138) {
106 m_unk0xa0 = m_unk0x138;
107 m_action1 = m_action2;
108 m_unk0x138 = NULL;
109 m_action2.SetObjectId(-1);
110 m_action2.SetAtomId(MxAtomId());
111 m_tickleState = MxPresenter::e_idle;
112 }
113}
114
115// FUNCTION: LEGO1 0x1007ef40
117{
118 MxS32 compare, volume;
119
120 if (m_unk0xa0 == NULL) {
121 if (m_unk0x138) {
122 if (m_unk0x148 != 0) {
123 compare = 30;
124 }
125 else {
126 compare = m_targetVolume;
127 }
128
129 volume = m_unk0x138->GetVolume();
130 if (volume < compare) {
131 if (m_speed + m_unk0x138->GetVolume() <= compare) {
132 compare = m_speed + m_unk0x138->GetVolume();
133 }
134
135 m_unk0x138->SetVolume(compare);
136 }
137 else {
138 m_unk0x138->SetVolume(compare);
139 m_unk0xa0 = m_unk0x138;
140 m_action1 = m_action2;
141 m_unk0x138 = NULL;
142 m_action2.SetObjectId(-1);
143 m_action2.SetAtomId(MxAtomId());
144 m_tickleState = MxPresenter::e_idle;
145 }
146 }
147 }
148 else if (m_unk0xa0->GetAction() != NULL) {
149 if (m_unk0xa0->GetVolume() == 0) {
150 DeleteObject(*m_unk0xa0->GetAction());
151 }
152 else {
153 if (m_unk0xa0->GetVolume() - m_speed > 0) {
154 volume = m_unk0xa0->GetVolume() - m_speed;
155 }
156 else {
157 volume = 0;
158 }
159
160 m_unk0xa0->SetVolume(volume);
161 }
162 }
163}
164
165// FUNCTION: LEGO1 0x1007f0e0
166// FUNCTION: BETA10 0x100e8d8d
168{
169 MxS32 volume, compare;
170
171 if (m_unk0xa0 != NULL) {
172 volume = m_unk0xa0->GetVolume();
173
174 if (m_unk0x148 != 0) {
175 compare = 30;
176 }
177 else {
178 compare = m_targetVolume;
179 }
180
181 if (volume < compare) {
182 m_unk0xa0->SetVolume(volume + m_speed < compare ? volume + m_speed : compare);
183 }
184 else if (compare < volume) {
185 m_unk0xa0->SetVolume(volume - m_speed > compare ? volume - m_speed : compare);
186 }
187 else {
188 m_unk0xa0->SetVolume(volume);
189 m_tickleState = MxPresenter::e_idle;
190 }
191 }
192 else {
193 m_tickleState = MxPresenter::e_idle;
194 }
195}
196
197// FUNCTION: LEGO1 0x1007f170
198// FUNCTION: BETA10 0x100e8eb6
200{
201 MxNotificationParam& param = (MxNotificationParam&) p_param;
202
203 switch (param.GetNotification()) {
205 StartAction(p_param);
206 return 1;
208 StopAction(p_param);
209 return 1;
210 }
211 return 0;
212}
213
214// FUNCTION: LEGO1 0x1007f1b0
216{
217 // TODO: the sender is most likely a MxAudioPresenter?
218 m_unk0x138 = (MxAudioPresenter*) ((MxNotificationParam&) p_param).GetSender();
219 m_action2.SetAtomId(m_unk0x138->GetAction()->GetAtomId());
220 m_action2.SetObjectId(m_unk0x138->GetAction()->GetObjectId());
221 m_targetVolume = ((MxDSSound*) (m_unk0x138->GetAction()))->GetVolume();
222 m_unk0x138->SetVolume(0);
223}
224
225// FUNCTION: LEGO1 0x1007f200
227{
228 if (((MxNotificationParam&) p_param).GetSender() == m_unk0xa0) {
229 m_unk0xa0 = NULL;
230 m_action1.SetAtomId(MxAtomId());
231 m_action1.SetObjectId(-1);
232 }
233 else if (((MxNotificationParam&) p_param).GetSender() == m_unk0x138) {
234 m_unk0x138 = NULL;
235 m_action2.SetAtomId(MxAtomId());
236 m_action2.SetObjectId(-1);
237 }
238
239 Lego()->HandleEndAction(p_param);
240}
241
242// FUNCTION: LEGO1 0x1007f2f0
243// FUNCTION: BETA10 0x100e90fc
245 MxDSAction& p_action,
246 undefined4 p_speed,
247 MxPresenter::TickleState p_tickleState
248)
249{
250 assert(p_speed > 0);
251
252 if (!m_enabled) {
253 return SUCCESS;
254 }
255
256 if (m_action2.GetObjectId() == -1 && m_action1.GetObjectId() != p_action.GetObjectId()) {
257 MxDSAction action;
258 action.SetAtomId(GetCurrentAction().GetAtomId());
259 action.SetObjectId(GetCurrentAction().GetObjectId());
260 action.SetUnknown24(GetCurrentAction().GetUnknown24());
261
262 m_action2.SetAtomId(p_action.GetAtomId());
263 m_action2.SetObjectId(p_action.GetObjectId());
264 m_action2.SetUnknown84(this);
265 m_action2.SetOrigin(this);
266
267 MxResult result = Start(&m_action2);
268
272
273 if (result == SUCCESS) {
274 m_tickleState = p_tickleState;
275 m_speed = p_speed;
276 }
277
278 return result;
279 }
280
281 return FAILURE;
282}
283
284// FUNCTION: LEGO1 0x1007f470
285// FUNCTION: BETA10 0x100e9388
287{
288 if (m_action2.GetObjectId() != -1) {
289 DeleteObject(m_action2);
290 }
291
292 m_unk0x138 = 0;
293 m_action2.SetAtomId(MxAtomId());
294 m_action2.SetObjectId(-1);
295
296 if (m_action1.GetObjectId() != -1) {
297 DeleteObject(m_action1);
298 }
299
300 m_unk0xa0 = 0;
301 m_action1.SetAtomId(MxAtomId());
302 m_unk0x148 = 0;
303 m_action1.SetObjectId(-1);
304 m_tickleState = MxPresenter::e_idle;
305}
306
307// FUNCTION: LEGO1 0x1007f570
308// FUNCTION: BETA10 0x100e94e6
310{
311 if (m_unk0x148 == 0) {
312 if (m_tickleState == 0) {
313 m_tickleState = MxPresenter::e_starting;
314 }
315 m_speed = 20;
316 }
317 m_unk0x148++;
318}
319
320// FUNCTION: LEGO1 0x1007f5b0
321// FUNCTION: BETA10 0x100e9543
323{
324 if (m_unk0x148 != 0) {
325 m_unk0x148--;
326 if (m_unk0x148 == 0) {
327 if (m_tickleState == 0) {
328 m_tickleState = MxPresenter::e_starting;
329 }
330 m_speed = 10;
331 }
332 }
333}
334
335// FUNCTION: LEGO1 0x1007f5f0
337{
338 if (this->m_enabled != p_enable) {
339 this->m_enabled = p_enable;
340
341 if (!p_enable) {
342 Stop();
343 }
344 }
345}
346
347// FUNCTION: LEGO1 0x1007f610
348// FUNCTION: BETA10 0x100e95ee
350 MxPresenter* p_unk0x138,
351 MxS32 p_speed,
352 MxPresenter::TickleState p_tickleState
353)
354
355{
356 m_unk0x138 = (MxAudioPresenter*) p_unk0x138;
357 m_targetVolume = ((MxDSSound*) m_unk0x138->GetAction())->GetVolume();
358
359 ((MxCompositePresenter*) m_unk0x138)->VTable0x60(NULL);
360
361 m_speed = p_speed;
362 m_tickleState = p_tickleState;
363 return 0;
364}
365
366// FUNCTION: LEGO1 0x1007f650
367// FUNCTION: BETA10 0x100e9663
369{
370 this->m_unk0xa0 = 0;
371 this->m_tickleState = MxPresenter::e_idle;
372}
[AI] Atomized (unique) string identifier, managed by reference counting.
Definition: mxatom.h:124
const char * GetInternal() const
[AI] Returns a pointer to the internal string, or nullptr if not set.
Definition: mxatom.h:194
[AI] Presents (plays/streams) audio (WAV, MID, etc.) as part of the Omni engine's media handler syste...
virtual MxS32 GetVolume()
[AI] Returns the current runtime audio volume for this presenter (0-100).
virtual void SetVolume(MxS32 p_volume)
[AI] Sets the presentation volume for playback (0-100).
[AI] Background music manager that handles playback, volume, state transitions, and notifications for...
void Init()
[AI] Reinitializes manager's active presenter and tickle state; typically called at the start of a sc...
undefined4 FUN_1007f610(MxPresenter *p_unk0x138, MxS32 p_speed, MxPresenter::TickleState p_tickleState)
[AI] Helper for queued volume changing: Sets up a coming presenter/action for activation with given s...
void FUN_1007ef40()
[AI] Handles music volume raising/lowering and track transitions in the e_repeating tickle state,...
void Enable(MxBool p_enable)
[AI] Enables or disables the background audio manager.
void StopAction(MxParam &p_param)
[AI] Handles incoming end action notification, resets state and clears finished presenters/actions; n...
void RaiseVolume()
[AI] Requests that the background music volume is raised (decrements suppression counter); triggers f...
~MxBackgroundAudioManager() override
[AI] Destructor unregisters from notification and tickle managers and stops any playing music.
void LowerVolume()
[AI] Requests a reduction in current background music volume, queuing for fade out (increments suppre...
MxLong Notify(MxParam &p_param) override
[AI] Handles notification events such as start/stop actions relating to audio.
void StartAction(MxParam &p_param)
[AI] Handles incoming start action notification, sets up pending audio presenter and prepares (but do...
MxResult PlayMusic(MxDSAction &p_action, undefined4 p_speed, MxPresenter::TickleState p_tickleState)
[AI] Initiates playback of a new background music action with specified speed and target tickle state...
void Stop()
[AI] Immediately stops all background music, clears all actions and presenters, and resets tickle sta...
void FadeInOrFadeOut()
[AI] Performs volume fade in/fade out logic, adjusting music volume towards target; sets tickle state...
void FUN_1007ee70()
[AI] Implements state update for e_streaming tickle state. Handles music track transition (fade out p...
MxResult Tickle() override
[AI] Called periodically by the tickle manager.
virtual MxResult Create(MxAtomId &p_script, MxU32 p_frequencyMS)
[AI] Opens the music script (SI file) for streaming and registers this background audio manager as a ...
[AI] Composite presenter that manages a collection of child presenters, orchestrating their actions a...
[AI] Represents an action deserialized from SI chunks, holding key animation or script parameters suc...
Definition: mxdsaction.h:17
void SetOrigin(MxCore *p_origin)
[AI] Sets the origin core pointer for this action, if spatially transforming/localizing this action.
Definition: mxdsaction.h:265
void SetUnknown84(MxCore *p_unk0x84)
[AI] Sets the auxiliary core pointer for this action.
Definition: mxdsaction.h:254
const MxAtomId & GetAtomId()
[AI] Returns a const-reference to the object's atom identifier.
Definition: mxdsobject.h:133
virtual void SetAtomId(MxAtomId p_atomId)
[AI] Sets the atom id for this object instance, used for indexing or lookup.
Definition: mxdsobject.h:118
void SetUnknown24(MxS16 p_unk0x24)
[AI] Sets the unknown field at 0x24 (possibly version/state).
Definition: mxdsobject.h:151
MxS16 GetUnknown24()
[AI] Returns the unknown 0x24 value (may be data version or usage state). [AI]
Definition: mxdsobject.h:136
void SetObjectId(MxU32 p_objectId)
[AI] Sets the object id (for serialization or lookup).
Definition: mxdsobject.h:147
MxU32 GetObjectId()
[AI] Returns the object id numeric value.
Definition: mxdsobject.h:130
[AI] Represents a sound action extracted from an SI script and used in the data-driven action system.
Definition: mxdssound.h:14
void Unregister(MxCore *p_listener)
[AI] Removes a previously registered listener and flushes any pending notifications for it.
void Register(MxCore *p_listener)
[AI] Registers a listener object to receive notifications.
[AI] Parameter object representing a single notification or event, carrying an identifier and sender ...
NotificationId GetNotification() const
[AI] Retrieves the current notification type of this parameter.
MxLong HandleEndAction(MxParam &p_param)
[AI] Handles the engine's response to action end notifications (c_notificationEndAction),...
Definition: mxomni.cpp:337
[AI] MxParam serves as a polymorphic base class for parameter passing in event and notification syste...
Definition: mxparam.h:7
[AI] Abstract base class for all presenter types in the LEGO Island engine, responsible for managing ...
Definition: mxpresenter.h:20
TickleState
[AI] Represents the state of the presenter's tickle (update) lifecycle.
Definition: mxpresenter.h:23
@ e_repeating
[AI] Presentation is repeating (e.g., looping media).
Definition: mxpresenter.h:28
@ e_idle
[AI] Not processing an action.
Definition: mxpresenter.h:24
@ e_starting
[AI] In the process of starting playback/presentation.
Definition: mxpresenter.h:26
@ e_streaming
[AI] Streaming or rendering actively.
Definition: mxpresenter.h:27
MxDSAction * GetAction() const
[AI] Returns the current action being presented.
Definition: mxpresenter.h:175
MxLong Close(const char *p_name)
Close a named stream and remove its controller from the open list [AI].
Definition: mxstreamer.cpp:98
virtual void UnregisterClient(MxCore *p_client)
[AI] Unregisters (marks for destruction) a previously registered client.
virtual void RegisterClient(MxCore *p_client, MxTime p_interval)
[AI] Registers an MxCore object to receive periodic tickles.
#define TRUE
Definition: d3drmdef.h:28
#define FALSE
Definition: d3drmdef.h:27
#define DECOMP_SIZE_ASSERT(T, S)
Definition: decomp.h:19
unsigned int undefined4
Definition: decomp.h:28
#define NULL
[AI] Null pointer value (C/C++ semantics).
Definition: legotypes.h:26
#define FAILURE
[AI] Used to indicate a failed operation in result codes.
Definition: legotypes.h:34
#define SUCCESS
[AI] Used to indicate a successful operation in result codes.
Definition: legotypes.h:30
MxDSAction & GetCurrentAction()
[AI] Accessor for the currently running MxDSAction (e.g.
Definition: misc.cpp:195
LegoOmni * Lego()
[AI] Retrieves the global LegoOmni singleton instance, providing access to core subsystems.
Definition: misc.cpp:16
MxResult Start(MxDSAction *p_dsAction)
[AI] Schedules and initiates execution of a script action.
Definition: mxmisc.cpp:97
MxStreamer * Streamer()
[AI] Returns the global streamer used for all chunked media streaming (SI file, audio,...
Definition: mxmisc.cpp:49
void DeleteObject(MxDSAction &p_dsAction)
[AI] Deletes the specified action object, removing it from the global action list.
Definition: mxmisc.cpp:105
MxNotificationManager * NotificationManager()
[AI] Returns the notification manager for system-wide state/update notifications.
Definition: mxmisc.cpp:17
MxTickleManager * TickleManager()
[AI] Provides access to the global tickle manager.
Definition: mxmisc.cpp:25
@ c_notificationStartAction
[AI] Indicates the start of an action [AI]
@ c_notificationEndAction
[AI] Indicates the end of an action [AI]
MxU8 MxBool
[AI]
Definition: mxtypes.h:124
MxLong MxResult
[AI]
Definition: mxtypes.h:106
int MxLong
[AI]
Definition: mxtypes.h:83
signed int MxS32
[AI]
Definition: mxtypes.h:38
unsigned int MxU32
[AI]
Definition: mxtypes.h:32