Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/Global/Music.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: Music Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectMusic *Music;
11
12
void Music_Update(void)
13
{
14
RSDK_THIS(Music);
15
16
StateMachine_Run(self->state);
17
}
18
19
void Music_LateUpdate(void) {}
20
21
void Music_StaticUpdate(void) {}
22
23
void Music_Draw(void) {}
24
25
void Music_Create(void *data)
26
{
27
RSDK_THIS(Music);
28
29
if (!SceneInfo->inEditor) {
30
// if frozen, ACTIVE_ALWAYS, else ACTIVE_NORMAL
31
self->active = ACTIVE_ALWAYS + ((SceneInfo->state & 3) != ENGINESTATE_FROZEN);
32
33
if (self->trackFile.length) {
34
if (self->trackID != TRACK_SOUNDTEST) {
35
char trackName[0x20];
36
RSDK.GetCString(trackName, &self->trackFile);
37
Music_SetMusicTrack(trackName, self->trackID, self->trackLoop);
38
39
if (self->playOnLoad)
40
self->state = Music_State_PlayOnLoad;
41
else
42
destroyEntity(self);
43
}
44
}
45
}
46
}
47
48
void Music_StageLoad(void)
49
{
50
// Slot 0: stage music
51
Music_SetMusicTrack("Invincible.ogg", TRACK_INVINCIBLE, 139263);
52
Music_SetMusicTrack("Sneakers.ogg", TRACK_SNEAKERS, 120960);
53
Music_SetMusicTrack("BossMini.ogg", TRACK_MINIBOSS, 276105);
54
Music_SetMusicTrack("BossHBH.ogg", TRACK_HBHBOSS, 70560);
55
Music_SetMusicTrack("BossEggman1.ogg", TRACK_EGGMAN1, 282240);
56
Music_SetMusicTrack("BossEggman2.ogg", TRACK_EGGMAN2, 264600);
57
Music_SetMusicTrack("ActClear.ogg", TRACK_ACTCLEAR, false);
58
Music_SetMusicTrack("Drowning.ogg", TRACK_DROWNING, false);
59
Music_SetMusicTrack("GameOver.ogg", TRACK_GAMEOVER, false);
60
Music_SetMusicTrack("Super.ogg", TRACK_SUPER, 165375);
61
Music_SetMusicTrack("HBHMischief.ogg", TRACK_HBHMISCHIEF, 381405);
62
// Slot 12 (slot 11 in pre-plus): "no load"
63
Music_SetMusicTrack("1up.ogg", TRACK_1UP, false);
64
65
#if GAME_VERSION != VER_100
66
if (globals->suppressAutoMusic) {
67
if (globals->restartMusicID > TRACK_STAGE)
68
Music->activeTrack = globals->restartMusicID;
69
}
70
else {
71
Music->activeTrack = TRACK_STAGE;
72
}
73
74
globals->restartMusicID = TRACK_STAGE;
75
Music->nextTrack = TRACK_NONE;
76
#else
77
if (!globals->suppressAutoMusic)
78
Music->activeTrack = TRACK_STAGE;
79
80
Music->prevTrack = TRACK_NONE;
81
Music->nextTrack = TRACK_NONE;
82
Music->playingDrownTrack = false;
83
Music->playing1UPTrack = false;
84
#endif
85
86
#if MANIA_USE_PLUS
87
if (sku_platform == PLATFORM_DEV)
88
RSDK.AddViewableVariable("Vape Mode", &globals->vapeMode, VIEWVAR_BOOL, false, true);
89
#endif
90
}
91
92
void Music_SetMusicTrack(const char *path, uint8 track, uint32 loopPoint)
93
{
94
track &= 0xF;
95
96
int32 charID = 0;
97
for (; charID < 0x20; ++charID) {
98
if (!path[charID])
99
break;
100
else
101
Music->trackNames[track][charID] = path[charID];
102
}
103
Music->trackNames[track][charID] = 0;
104
Music->trackLoops[track] = loopPoint;
105
}
106
107
void Music_Stop(void) { RSDK.StopChannel(Music->channelID); }
108
void Music_Pause(void) { RSDK.PauseChannel(Music->channelID); }
109
void Music_Resume(void) { RSDK.ResumeChannel(Music->channelID); }
110
bool32 Music_IsPlaying(void) { return RSDK.ChannelActive(Music->channelID); }
111
112
void Music_State_PlayOnLoad(void)
113
{
114
RSDK_THIS(Music);
115
116
if (globals->suppressAutoMusic) {
117
globals->suppressAutoMusic = false;
118
119
#if MANIA_USE_PLUS
120
switch (Music->activeTrack) {
121
case TRACK_INVINCIBLE:
122
case TRACK_SNEAKERS:
123
case TRACK_1UP: Music_TransitionTrack(self->trackID, 0.025); break;
124
case TRACK_SUPER: Music_PlayAutoMusicQueuedTrack(Music->activeTrack); break;
125
default: break;
126
}
127
#endif
128
}
129
else {
130
Music_PlayTrack(self->trackID);
131
}
132
133
destroyEntity(self);
134
}
135
136
void Music_PlayJingle(uint8 trackID)
137
{
138
trackID &= 0xF;
139
140
#if MANIA_USE_PLUS
141
// remove any existing vers of this on the stack
142
for (int32 slot = SLOT_MUSICSTACK_START; slot < SLOT_MUSICSTACK_END; ++slot) {
143
EntityMusic *music = RSDK_GET_ENTITY(slot, Music);
144
if (music->classID == Music->classID && music->trackID == trackID) {
145
destroyEntity(music);
146
}
147
}
148
149
EntityMusic *entity = NULL;
150
// get the first empty stack slot
151
for (int32 slot = SLOT_MUSICSTACK_START; slot < SLOT_MUSICSTACK_END; ++slot) {
152
entity = RSDK_GET_ENTITY(slot, Music);
153
if (entity->classID != Music->classID) {
154
RSDK.ResetEntity(entity, Music->classID, NULL);
155
break;
156
}
157
}
158
159
entity->trackID = trackID;
160
entity->state = Music_State_Jingle;
161
entity->trackPriority = TRACK_PRIORITY_NONE;
162
entity->fadeSpeed = 0.08;
163
164
switch (trackID) {
165
case TRACK_INVINCIBLE:
166
case TRACK_SNEAKERS:
167
Music_HandleMusicStack_Powerups(entity);
168
entity->trackPriority = TRACK_PRIORITY_POWERUP;
169
entity->restartTrack = true;
170
break;
171
172
case TRACK_DROWNING:
173
entity->timer = 960;
174
entity->trackPriority = TRACK_PRIORITY_DROWN;
175
entity->restartTrack = true;
176
break;
177
178
case TRACK_SUPER:
179
entity->trackPriority = TRACK_PRIORITY_SUPER;
180
entity->restartTrack = true;
181
break;
182
183
case TRACK_1UP:
184
entity->timer = 224;
185
entity->trackPriority = TRACK_PRIORITY_1UP;
186
break;
187
188
default: break;
189
}
190
191
Music_GetNextTrackStartPos(entity);
192
193
for (int32 slot = SLOT_MUSICSTACK_START; slot < SLOT_MUSICSTACK_END; ++slot) {
194
EntityMusic *music = RSDK_GET_ENTITY(slot, Music);
195
if (music->classID == Music->classID && music != entity) {
196
if (music->trackPriority > entity->trackPriority) {
197
entity->volume = 0.0;
198
return;
199
}
200
}
201
}
202
203
Music_Stop();
204
Music->activeTrack = trackID;
205
Music->channelID = RSDK.PlayStream(Music->trackNames[Music->activeTrack], 0, 0, Music->trackLoops[Music->activeTrack], true);
206
207
#if MANIA_USE_PLUS
208
if (globals->vapeMode)
209
RSDK.SetChannelAttributes(Music->channelID, 1.0, 0.0, 0.75);
210
#endif
211
212
entity->volume = 1.0;
213
#else
214
215
switch (trackID) {
216
case TRACK_1UP: {
217
Music->playing1UPTrack = true;
218
219
EntityMusic *music = RSDK_GET_ENTITY(SLOT_MUSIC, Music);
220
RSDK.ResetEntity(music, Music->classID, NULL);
221
music->state = Music_State_1UPJingle;
222
music->volume = 0.0;
223
music->fadeSpeed = 0.08;
224
225
if (Music->activeTrack != TRACK_1UP) {
226
Music->trackStartPos = RSDK.GetChannelPos(Music->channelID);
227
Music->queuedTrack = Music->activeTrack;
228
}
229
230
Music_Stop();
231
Music->activeTrack = TRACK_1UP;
232
Music->channelID = RSDK.PlayStream(Music->trackNames[Music->activeTrack], 0, 0, Music->trackLoops[Music->activeTrack], true);
233
break;
234
}
235
236
default:
237
if (Music->playing1UPTrack || Music->playingDrownTrack) {
238
Music->nextTrack = trackID;
239
}
240
else {
241
destroyEntitySlot(SLOT_MUSIC);
242
Music_Stop();
243
244
if (!Music->playingRegularTrack)
245
Music->nextTrack = Music->activeTrack;
246
247
Music->playingRegularTrack = true;
248
249
Music->nextTrack = TRACK_NONE;
250
Music->activeTrack = trackID;
251
Music->trackStartPos = 0;
252
Music->channelID = RSDK.PlayStream(Music->trackNames[Music->activeTrack], 0, 0, Music->trackLoops[Music->activeTrack], true);
253
}
254
break;
255
}
256
#endif
257
}
258
259
void Music_PlayTrack(uint8 trackID)
260
{
261
trackID &= 0xF;
262
263
#if MANIA_USE_PLUS
264
if (trackID != TRACK_ACTCLEAR && Music_CheckMusicStack_Active()) {
265
Music->nextTrack = trackID;
266
}
267
else {
268
if (trackID == TRACK_ACTCLEAR)
269
Music_ClearMusicStack();
270
271
destroyEntitySlot(SLOT_MUSIC);
272
Music_Stop();
273
274
Music->activeTrack = trackID;
275
Music->trackStartPos = 0;
276
Music->channelID = RSDK.PlayStream(Music->trackNames[trackID], 0, 0, Music->trackLoops[trackID], true);
277
278
if (globals->vapeMode)
279
RSDK.SetChannelAttributes(Music->channelID, 1.0, 0.0, 0.75);
280
}
281
#else
282
if (Music->playing1UPTrack || Music->playingDrownTrack) {
283
Music->nextTrack = trackID;
284
}
285
else {
286
EntityMusic *music = RSDK_GET_ENTITY(SLOT_MUSIC, Music);
287
RSDK.ResetEntity(music, Music->classID, NULL);
288
289
if (!Music->playingRegularTrack)
290
Music->prevTrack = Music->activeTrack;
291
292
bool32 regularTrack = true;
293
switch (trackID) {
294
default: break;
295
296
case TRACK_INVINCIBLE:
297
case TRACK_SNEAKERS:
298
case TRACK_SUPER:
299
case TRACK_SOUNDTEST:
300
case TRACK_HBHMISCHIEF:
301
case TRACK_1UP: regularTrack = false; break;
302
}
303
304
if (regularTrack)
305
Music->playingRegularTrack = true;
306
307
Music->nextTrack = TRACK_NONE;
308
Music->activeTrack = trackID;
309
Music->trackStartPos = 0;
310
Music->channelID = RSDK.PlayStream(Music->trackNames[trackID], 0, 0, Music->trackLoops[trackID], true);
311
}
312
#endif
313
}
314
315
void Music_PlayTrackPtr(EntityMusic *entity)
316
{
317
RSDK.GetCString(Music->trackNames[0], &entity->trackFile);
318
Music->trackLoops[0] = entity->trackLoop;
319
320
destroyEntitySlot(SLOT_MUSIC);
321
Music_Stop();
322
323
Music->activeTrack = 0;
324
Music->trackStartPos = 0;
325
Music->channelID = RSDK.PlayStream(Music->trackNames[0], 0, 0, Music->trackLoops[0], true);
326
327
#if MANIA_USE_PLUS
328
if (globals->vapeMode)
329
RSDK.SetChannelAttributes(Music->channelID, 1.0, 0.0, 0.75);
330
#endif
331
}
332
333
#if MANIA_USE_PLUS
334
void Music_PlayAutoMusicQueuedTrack(uint8 trackID)
335
{
336
trackID &= 0xF;
337
Music->nextTrack = TRACK_STAGE;
338
339
// remove any existing vers of this on the stack
340
for (int32 slot = SLOT_MUSICSTACK_START; slot < SLOT_MUSICSTACK_END; ++slot) {
341
EntityMusic *music = RSDK_GET_ENTITY(slot, Music);
342
if (music->classID == Music->classID && music->trackID == trackID) {
343
destroyEntity(music);
344
}
345
}
346
347
EntityMusic *entity = NULL;
348
// get the first empty stack slot
349
for (int32 slot = SLOT_MUSICSTACK_START; slot < SLOT_MUSICSTACK_END; ++slot) {
350
entity = RSDK_GET_ENTITY(slot, Music);
351
if (entity->classID != Music->classID) {
352
destroyEntity(entity);
353
break;
354
}
355
}
356
357
entity->trackID = trackID;
358
entity->state = Music_State_Jingle;
359
entity->trackPriority = TRACK_PRIORITY_NONE;
360
entity->volume = 1.0;
361
entity->fadeSpeed = 0.08;
362
363
switch (trackID) {
364
case TRACK_INVINCIBLE:
365
case TRACK_SNEAKERS:
366
Music_HandleMusicStack_Powerups(entity);
367
entity->trackPriority = TRACK_PRIORITY_POWERUP;
368
entity->restartTrack = true;
369
break;
370
371
case TRACK_DROWNING:
372
entity->timer = 960;
373
entity->trackPriority = TRACK_PRIORITY_DROWN;
374
entity->restartTrack = true;
375
break;
376
377
case TRACK_SUPER:
378
entity->trackPriority = TRACK_PRIORITY_SUPER;
379
entity->restartTrack = true;
380
break;
381
382
case TRACK_1UP:
383
entity->timer = 224;
384
entity->trackPriority = TRACK_PRIORITY_1UP;
385
break;
386
387
default: break;
388
}
389
}
390
391
void Music_HandleMusicStack_Powerups(EntityMusic *entity)
392
{
393
for (int32 slot = SLOT_MUSICSTACK_START; slot < SLOT_MUSICSTACK_END; ++slot) {
394
EntityMusic *music = RSDK_GET_ENTITY(slot, Music);
395
if (music->classID == Music->classID && music->trackPriority == TRACK_PRIORITY_POWERUP && music->trackID != entity->trackID
396
&& music != entity)
397
music->trackPriority = TRACK_PRIORITY_ANY;
398
}
399
}
400
401
bool32 Music_CheckMusicStack_Active(void)
402
{
403
bool32 active = false;
404
405
for (int32 slot = SLOT_MUSICSTACK_START; slot < SLOT_MUSICSTACK_END; ++slot) {
406
EntityMusic *music = RSDK_GET_ENTITY(slot, Music);
407
if (music->classID == Music->classID && music->trackPriority > TRACK_PRIORITY_NONE)
408
active = true;
409
}
410
411
return active;
412
}
413
414
void Music_GetNextTrackStartPos(EntityMusic *entity)
415
{
416
int32 stackCount = 0;
417
418
for (int32 slot = SLOT_MUSICSTACK_START; slot < SLOT_MUSICSTACK_END; ++slot) {
419
EntityMusic *music = RSDK_GET_ENTITY(slot, Music);
420
if (music->classID == Music->classID && entity != music) {
421
if (music->trackID == Music->activeTrack) {
422
entity->trackStartPos = RSDK.GetChannelPos(Music->channelID);
423
entity->volume = 0.0;
424
}
425
stackCount++;
426
}
427
}
428
429
if (!stackCount) {
430
if (Music->activeTrack > TRACK_NONE) {
431
if (Music->nextTrack == TRACK_NONE)
432
Music->nextTrack = Music->activeTrack;
433
434
Music->trackStartPos = RSDK.GetChannelPos(Music->channelID);
435
}
436
}
437
}
438
#endif
439
440
void Music_JingleFadeOut(uint8 trackID, bool32 transitionFade)
441
{
442
trackID &= 0xF;
443
444
#if MANIA_USE_PLUS
445
for (int32 slot = SLOT_MUSICSTACK_START; slot < SLOT_MUSICSTACK_END; ++slot) {
446
EntityMusic *music = RSDK_GET_ENTITY(slot, Music);
447
if (music->classID == Music->classID && music->trackID == trackID) {
448
if (transitionFade) {
449
music->state = Music_State_JingleFade;
450
music->fadeSpeed = 0.05;
451
}
452
else {
453
music->timer = 1;
454
}
455
break;
456
}
457
}
458
#else
459
switch (trackID) {
460
default: break;
461
462
case TRACK_INVINCIBLE:
463
case TRACK_SNEAKERS:
464
case TRACK_SUPER:
465
Music->playingRegularTrack = false;
466
467
if (Music->nextTrack == TRACK_NONE)
468
Music_TransitionTrack(trackID, 0.025);
469
break;
470
471
case TRACK_DROWNING:
472
if (Music->playingDrownTrack) {
473
Music->playingDrownTrack = false;
474
475
if (Music->playing1UPTrack) {
476
if (Music->nextTrack == TRACK_NONE) {
477
Music->queuedTrack = Music->prevTrack == TRACK_NONE ? TRACK_STAGE : Music->prevTrack;
478
}
479
else {
480
Music->queuedTrack = Music->nextTrack;
481
Music->nextTrack = TRACK_NONE;
482
}
483
}
484
else {
485
if (Music->nextTrack == TRACK_NONE) {
486
Music->activeTrack = Music->activeTrack == TRACK_NONE ? TRACK_STAGE : Music->prevTrack;
487
}
488
else {
489
Music->activeTrack = Music->nextTrack;
490
Music->nextTrack = TRACK_NONE;
491
}
492
493
Music_Stop();
494
Music->channelID = RSDK.PlayStream(Music->trackNames[Music->activeTrack], 0, 0, Music->trackLoops[Music->activeTrack], true);
495
}
496
}
497
break;
498
}
499
#endif
500
}
501
502
#if MANIA_USE_PLUS
503
void Music_FinishJingle(EntityMusic *entity)
504
{
505
if (entity) {
506
EntityMusic *music = RSDK_GET_ENTITY(SLOT_MUSIC, Music);
507
if (music->classID == Music->classID && music->state == Music_State_PlayOnFade) {
508
destroyEntity(entity);
509
}
510
else {
511
destroyEntity(music);
512
513
// remove all of these buggers that have higher priority and thus wont be played
514
for (int32 slot = SLOT_MUSICSTACK_START; slot < SLOT_MUSICSTACK_END; ++slot) {
515
EntityMusic *stack = RSDK_GET_ENTITY(slot, Music);
516
if (stack->classID == Music->classID && stack != entity && entity->trackPriority <= stack->trackPriority) {
517
destroyEntity(entity);
518
return;
519
}
520
}
521
522
bool32 shouldRestartTrack = entity->restartTrack;
523
destroyEntity(entity);
524
int32 priority = TRACK_PRIORITY_NONE;
525
526
EntityMusic *trackPtr = NULL;
527
// the next track to be played will be the track with the highest priority on the stack (may be none)
528
for (int32 slot = SLOT_MUSICSTACK_START; slot < SLOT_MUSICSTACK_END; ++slot) {
529
EntityMusic *stack = RSDK_GET_ENTITY(slot, Music);
530
if (stack->classID == Music->classID && stack->trackPriority > priority) {
531
trackPtr = stack;
532
priority = stack->trackPriority;
533
}
534
}
535
536
if (trackPtr) { // another track is on the music stack still
537
Music_Stop();
538
539
if (trackPtr->trackID == Music->activeTrack) {
540
trackPtr->trackStartPos = 0;
541
}
542
else {
543
Music->activeTrack = trackPtr->trackID;
544
if (shouldRestartTrack)
545
trackPtr->trackStartPos = 0;
546
Music->channelID = RSDK.PlayStream(Music->trackNames[Music->activeTrack], 0, trackPtr->trackStartPos,
547
Music->trackLoops[Music->activeTrack], true);
548
if (trackPtr->trackStartPos) {
549
RSDK.SetChannelAttributes(Music->channelID, 0.0, 0.0, globals->vapeMode ? 0.75 : 1.0);
550
}
551
else if (globals->vapeMode) {
552
RSDK.SetChannelAttributes(Music->channelID, 1.0, 0.0, 0.75);
553
}
554
}
555
}
556
else if (Music->nextTrack > TRACK_NONE) { // next track is queued
557
Music_Stop();
558
559
Music->activeTrack = Music->nextTrack;
560
Music->nextTrack = TRACK_NONE;
561
562
if (shouldRestartTrack)
563
Music->trackStartPos = 0;
564
565
Music->channelID =
566
RSDK.PlayStream(Music->trackNames[Music->activeTrack], 0, Music->trackStartPos, Music->trackLoops[Music->activeTrack], true);
567
568
if (Music->trackStartPos) {
569
RSDK.SetChannelAttributes(Music->channelID, 0.0, 0.0, globals->vapeMode ? 0.75 : 1.0);
570
music = RSDK_GET_ENTITY(SLOT_MUSIC, Music);
571
RSDK.ResetEntity(music, Music->classID, NULL);
572
music->state = Music_State_FadeTrackIn;
573
music->volume = 0.0;
574
music->fadeSpeed = 0.08;
575
}
576
else if (globals->vapeMode) {
577
RSDK.SetChannelAttributes(Music->channelID, 1.0, 0.0, 0.75);
578
}
579
}
580
}
581
}
582
}
583
584
void Music_ClearMusicStack(void)
585
{
586
for (int32 slot = SLOT_MUSICSTACK_START; slot < SLOT_MUSICSTACK_END; ++slot) destroyEntity(RSDK_GET_ENTITY(slot, Music));
587
}
588
#endif
589
590
void Music_TransitionTrack(uint8 trackID, float fadeSpeed)
591
{
592
trackID &= 0xF;
593
594
EntityMusic *music = NULL;
595
#if MANIA_USE_PLUS
596
switch (trackID) {
597
case TRACK_ACTCLEAR:
598
Music_ClearMusicStack();
599
// [Fallthrough]
600
601
case TRACK_MINIBOSS:
602
case TRACK_HBHBOSS:
603
case TRACK_EGGMAN1:
604
case TRACK_EGGMAN2:
605
case TRACK_HBHMISCHIEF: music = RSDK_GET_ENTITY(SLOT_MUSIC, Music); break;
606
607
default:
608
if (!Music_CheckMusicStack_Active())
609
music = RSDK_GET_ENTITY(SLOT_MUSIC, Music);
610
break;
611
}
612
613
Music->nextTrack = trackID;
614
#else
615
if (Music->playing1UPTrack || Music->playingDrownTrack) {
616
Music->nextTrack = Music->prevTrack;
617
}
618
else if (Music->activeTrack == trackID) {
619
Music->nextTrack = Music->prevTrack & 0xF;
620
music = RSDK_GET_ENTITY(SLOT_MUSIC, Music);
621
}
622
else {
623
Music->nextTrack = trackID & 0xF;
624
music = RSDK_GET_ENTITY(SLOT_MUSIC, Music);
625
}
626
#endif
627
628
if (music && (music->classID != Music->classID || music->state != Music_State_PlayOnFade)) {
629
RSDK.ResetEntity(music, Music->classID, NULL);
630
music->state = Music_State_PlayOnFade;
631
music->volume = 1.0;
632
music->fadeSpeed = fadeSpeed;
633
}
634
}
635
636
void Music_FadeOut(float fadeSpeed)
637
{
638
if (Music->activeTrack != TRACK_DROWNING) {
639
EntityMusic *music = RSDK_GET_ENTITY(SLOT_MUSIC, Music);
640
RSDK.ResetEntity(music, Music->classID, NULL);
641
music->state = Music_State_StopOnFade;
642
music->volume = 1.0;
643
music->fadeSpeed = fadeSpeed;
644
}
645
}
646
647
#if MANIA_USE_PLUS
648
void Music_State_Jingle(void)
649
{
650
RSDK_THIS(Music);
651
652
if (Music->activeTrack == self->trackID && RSDK.GetChannelPos(Music->channelID) > (uint32)self->trackStartPos) {
653
self->trackStartPos = 0;
654
if (self->volume < 1.0) {
655
self->volume += self->fadeSpeed;
656
RSDK.SetChannelAttributes(Music->channelID, self->volume, 0.0, 1.0);
657
if (self->volume >= 1.0)
658
self->volume = 1.0;
659
}
660
}
661
662
if (self->timer > 0) {
663
if (!--self->timer)
664
Music_FinishJingle(self);
665
}
666
}
667
void Music_State_JingleFade(void)
668
{
669
RSDK_THIS(Music);
670
671
if (self->volume > -0.5) {
672
self->volume -= self->fadeSpeed;
673
674
if (Music->activeTrack == self->trackID)
675
RSDK.SetChannelAttributes(Music->channelID, self->volume, 0.0, 1.0);
676
677
if (self->volume <= -0.5)
678
Music_FinishJingle(self);
679
}
680
}
681
#endif
682
683
void Music_State_FadeTrackIn(void)
684
{
685
RSDK_THIS(Music);
686
687
#if MANIA_USE_PLUS
688
if (RSDK.GetChannelPos(Music->channelID) > (uint32)Music->trackStartPos) {
689
Music->trackStartPos = 0;
690
self->volume += self->fadeSpeed;
691
692
RSDK.SetChannelAttributes(Music->channelID, self->volume, 0.0, 1.0);
693
if (self->volume >= 1.0) {
694
self->volume = 1.0;
695
destroyEntity(self);
696
}
697
}
698
#else
699
self->volume += self->fadeSpeed;
700
RSDK.SetChannelAttributes(Music->channelID, self->volume, 0.0, 1.0);
701
if (self->volume >= 1.0) {
702
self->volume = 1.0;
703
destroyEntity(self);
704
}
705
#endif
706
}
707
void Music_State_StopOnFade(void)
708
{
709
RSDK_THIS(Music);
710
711
self->volume -= self->fadeSpeed;
712
RSDK.SetChannelAttributes(Music->channelID, self->volume, 0.0, 1.0);
713
714
if (self->volume < -0.5) {
715
Music_Stop();
716
destroyEntity(self);
717
}
718
}
719
720
void Music_State_PlayOnFade(void)
721
{
722
RSDK_THIS(Music);
723
724
self->volume -= self->fadeSpeed;
725
RSDK.SetChannelAttributes(Music->channelID, self->volume, 0.0, 1.0);
726
727
if (self->volume < -0.5) {
728
#if MANIA_USE_PLUS
729
Music_Stop();
730
731
Music->activeTrack = Music->nextTrack;
732
Music->trackStartPos = 0;
733
Music->channelID = RSDK.PlayStream(Music->trackNames[Music->activeTrack], 0, 0, Music->trackLoops[Music->activeTrack], true);
734
735
if (globals->vapeMode)
736
RSDK.SetChannelAttributes(Music->channelID, 1.0, 0.0, 0.75);
737
#else
738
int32 trackID = Music->nextTrack & 0xF;
739
if (Music->playing1UPTrack || Music->playingDrownTrack) {
740
Music->nextTrack = trackID;
741
}
742
else {
743
destroyEntitySlot(SLOT_MUSIC);
744
Music_Stop();
745
746
if (!Music->playingRegularTrack)
747
Music->prevTrack = Music->activeTrack;
748
749
bool32 regularTrack = true;
750
switch (trackID) {
751
default: break;
752
753
case TRACK_INVINCIBLE:
754
case TRACK_SNEAKERS:
755
case TRACK_SUPER:
756
case TRACK_SOUNDTEST:
757
case TRACK_HBHMISCHIEF:
758
case TRACK_1UP: regularTrack = false; break;
759
}
760
761
if (regularTrack)
762
Music->playingRegularTrack = true;
763
764
Music->nextTrack = TRACK_NONE;
765
Music->activeTrack = trackID;
766
Music->trackStartPos = 0;
767
Music->channelID = RSDK.PlayStream(Music->trackNames[Music->activeTrack], 0, 0, Music->trackLoops[Music->activeTrack], true);
768
}
769
#endif
770
771
Music->nextTrack = TRACK_NONE;
772
destroyEntity(self);
773
}
774
}
775
776
#if !MANIA_USE_PLUS
777
void Music_State_1UPJingle(void)
778
{
779
RSDK_THIS(Music);
780
781
self->timer++;
782
if (self->timer == 224) {
783
Music_Stop();
784
785
if (Music->nextTrack == TRACK_NONE) {
786
Music->activeTrack = Music->queuedTrack;
787
}
788
else {
789
Music->activeTrack = Music->nextTrack;
790
Music->trackStartPos = 0;
791
Music->nextTrack = TRACK_NONE;
792
}
793
794
if (Music->playingDrownTrack) {
795
if (Music->activeTrack != TRACK_DROWNING)
796
Music->trackStartPos = 0;
797
798
Music->activeTrack = TRACK_DROWNING;
799
}
800
801
Music->playing1UPTrack = false;
802
Music->channelID =
803
RSDK.PlayStream(Music->trackNames[Music->activeTrack], 0, Music->trackStartPos, Music->trackLoops[Music->activeTrack], true);
804
805
if (Music->trackStartPos)
806
RSDK.SetChannelAttributes(Music->channelID, self->volume, 0.0, 1.0);
807
else
808
destroyEntity(self);
809
}
810
else if (self->timer > 224) {
811
if (RSDK.GetChannelPos(Music->channelID) > Music->trackStartPos) {
812
self->timer = 0;
813
Music->trackStartPos = 0;
814
self->state = Music_State_FadeTrackIn;
815
}
816
}
817
}
818
#endif
819
820
#if GAME_INCLUDE_EDITOR
821
void Music_EditorDraw(void)
822
{
823
RSDK_THIS(Music);
824
825
RSDK.SetSpriteAnimation(Music->aniFrames, 0, &self->animator, true, 1);
826
RSDK.DrawSprite(&self->animator, NULL, false);
827
}
828
829
void Music_EditorLoad(void)
830
{
831
Music->aniFrames = RSDK.LoadSpriteAnimation("Editor/EditorIcons.bin", SCOPE_STAGE);
832
833
RSDK_ACTIVE_VAR(Music, trackID);
834
RSDK_ENUM_VAR("Zone Act", TRACK_STAGE);
835
RSDK_ENUM_VAR("Invincible", TRACK_INVINCIBLE);
836
RSDK_ENUM_VAR("Power Sneakers", TRACK_SNEAKERS);
837
RSDK_ENUM_VAR("Mini Boss", TRACK_MINIBOSS);
838
RSDK_ENUM_VAR("HBH Boss", TRACK_HBHBOSS);
839
RSDK_ENUM_VAR("Eggman Boss 1", TRACK_EGGMAN1);
840
RSDK_ENUM_VAR("Eggman Boss 2", TRACK_EGGMAN2);
841
RSDK_ENUM_VAR("Act Clear", TRACK_ACTCLEAR);
842
RSDK_ENUM_VAR("Drowning", TRACK_DROWNING);
843
RSDK_ENUM_VAR("Game Over", TRACK_GAMEOVER);
844
RSDK_ENUM_VAR("Super Sonic", TRACK_SUPER);
845
#if MANIA_USE_PLUS
846
RSDK_ENUM_VAR("HBH Mischief", TRACK_HBHMISCHIEF);
847
RSDK_ENUM_VAR("Sound Test", TRACK_SOUNDTEST);
848
#else
849
RSDK_ENUM_VAR("Sound Test", TRACK_SOUNDTEST);
850
RSDK_ENUM_VAR("HBH Mischief", TRACK_HBHMISCHIEF);
851
#endif
852
RSDK_ENUM_VAR("1UP", TRACK_1UP);
853
}
854
#endif
855
856
void Music_Serialize(void)
857
{
858
RSDK_EDITABLE_VAR(Music, VAR_STRING, trackFile);
859
RSDK_EDITABLE_VAR(Music, VAR_STRING, soundTestTitle);
860
RSDK_EDITABLE_VAR(Music, VAR_ENUM, trackID);
861
RSDK_EDITABLE_VAR(Music, VAR_UINT32, trackLoop);
862
RSDK_EDITABLE_VAR(Music, VAR_BOOL, playOnLoad);
863
}
864
865