Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/Menu/LevelSelect.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: LevelSelect Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectLevelSelect *LevelSelect;
11
12
void LevelSelect_Update(void)
13
{
14
RSDK_THIS(LevelSelect);
15
16
#if MANIA_USE_PLUS
17
EntityUIText *text = self->pinballLabel;
18
if (text)
19
text->visible = API.CheckDLC(DLC_PLUS);
20
#endif
21
22
StateMachine_Run(self->state);
23
24
ScreenInfo->position.x = 0x100 - ScreenInfo->center.x;
25
}
26
27
void LevelSelect_LateUpdate(void) {}
28
29
void LevelSelect_StaticUpdate(void)
30
{
31
if (--LevelSelect->bgAniDuration <= 0) {
32
++LevelSelect->bgAniFrame;
33
34
LevelSelect->bgAniFrame &= 3;
35
LevelSelect->bgAniDuration = LevelSelect->bgAniDurationTable[LevelSelect->bgAniFrame];
36
37
TileLayer *background = RSDK.GetTileLayer(0);
38
background->scrollPos = (background->scrollPos + 0x1000000) & 0x7FF0000;
39
}
40
}
41
42
void LevelSelect_Draw(void)
43
{
44
RSDK_THIS(LevelSelect);
45
46
StateMachine_Run(self->stateDraw);
47
}
48
49
void LevelSelect_Create(void *data)
50
{
51
RSDK_THIS(LevelSelect);
52
53
if (!SceneInfo->inEditor) {
54
self->active = ACTIVE_ALWAYS;
55
self->visible = true;
56
self->drawGroup = 12;
57
self->state = LevelSelect_State_Init;
58
self->stateDraw = LevelSelect_Draw_Fade;
59
self->timer = 640;
60
}
61
}
62
63
void LevelSelect_StageLoad(void)
64
{
65
LevelSelect->sfxFail = RSDK.GetSfx("Stage/Fail.wav");
66
#if MANIA_USE_PLUS
67
LevelSelect->sfxRing = RSDK.GetSfx("Global/Ring.wav");
68
LevelSelect->sfxEmerald = RSDK.GetSfx("Special/Emerald.wav");
69
LevelSelect->sfxContinue = RSDK.GetSfx("Special/Continue.wav");
70
LevelSelect->sfxMedalGot = RSDK.GetSfx("Special/MedalCaught.wav");
71
#endif
72
73
RSDK.ResetEntitySlot(0, LevelSelect->classID, NULL);
74
75
UIPicture->aniFrames = RSDK.LoadSpriteAnimation("LSelect/Icons.bin", SCOPE_STAGE);
76
UIText->aniFrames = RSDK.LoadSpriteAnimation("LSelect/Text.bin", SCOPE_STAGE);
77
78
LevelSelect->startMusicID = 0;
79
LevelSelect->soundTestMax = 0;
80
foreach_all(Music, music)
81
{
82
if (!LevelSelect->startMusicID) {
83
LevelSelect->startMusicID = RSDK.GetEntitySlot(music);
84
}
85
++LevelSelect->soundTestMax;
86
}
87
++LevelSelect->startMusicID;
88
--LevelSelect->soundTestMax;
89
90
globals->medalMods |= MEDAL_DEBUGMODE;
91
#if MANIA_USE_PLUS
92
LevelSelect->cheatCodePtrs[0] = LevelSelect->cheat_RickyMode;
93
LevelSelect->cheatCodePtrs[1] = LevelSelect->cheat_AllEmeralds;
94
LevelSelect->cheatCodePtrs[2] = LevelSelect->cheat_MaxContinues;
95
LevelSelect->cheatCodePtrs[3] = LevelSelect->cheat_SwapGameMode;
96
LevelSelect->cheatCodePtrs[4] = LevelSelect->cheat_UnlockAllMedals;
97
LevelSelect->cheatCodePtrs[5] = LevelSelect->cheat_SuperDash;
98
LevelSelect->cheatCodePtrs[6] = LevelSelect->cheat_MaxControl;
99
LevelSelect->cheatCodePtrs[7] = LevelSelect->cheat_ToggleSuperMusic;
100
101
LevelSelect->checkCheatActivated[0] = LevelSelect_Cheat_RickyMode;
102
LevelSelect->checkCheatActivated[1] = LevelSelect_Cheat_AllEmeralds;
103
LevelSelect->checkCheatActivated[2] = LevelSelect_Cheat_MaxContinues;
104
LevelSelect->checkCheatActivated[3] = LevelSelect_Cheat_SwapGameMode;
105
LevelSelect->checkCheatActivated[4] = LevelSelect_Cheat_UnlockAllMedals;
106
LevelSelect->checkCheatActivated[5] = LevelSelect_Cheat_SuperDash;
107
LevelSelect->checkCheatActivated[6] = LevelSelect_Cheat_MaxControl;
108
LevelSelect->checkCheatActivated[7] = LevelSelect_Cheat_ToggleSuperMusic;
109
110
LevelSelect->cheatCodePos[0] = 0;
111
LevelSelect->cheatCodePos[1] = 0;
112
LevelSelect->cheatCodePos[2] = 0;
113
LevelSelect->cheatCodePos[3] = 0;
114
LevelSelect->cheatCodePos[4] = 0;
115
LevelSelect->cheatCodePos[5] = 0;
116
LevelSelect->cheatCodePos[6] = 0;
117
LevelSelect->cheatCodePos[7] = 0;
118
#endif
119
}
120
121
#if MANIA_USE_PLUS
122
void LevelSelect_Cheat_AllEmeralds(void)
123
{
124
Music_FadeOut(0.125);
125
RSDK.PlaySfx(LevelSelect->sfxEmerald, false, 255);
126
127
for (int32 e = 0; e < 7; ++e) SaveGame_SetEmerald(e);
128
}
129
130
void LevelSelect_Cheat_ToggleSuperMusic(void)
131
{
132
RSDK.PlaySfx(LevelSelect->sfxRing, false, 255);
133
globals->superMusicEnabled ^= 1;
134
}
135
136
void LevelSelect_Cheat_MaxContinues(void)
137
{
138
RSDK.PlaySfx(LevelSelect->sfxContinue, false, 255);
139
SaveGame_GetSaveRAM()->continues = 14;
140
}
141
142
void LevelSelect_Cheat_MaxControl(void)
143
{
144
RSDK.PlaySfx(LevelSelect->sfxRing, false, 255);
145
globals->medalMods &= ~MEDAL_NODROPDASH;
146
globals->medalMods |= MEDAL_INSTASHIELD;
147
globals->medalMods |= MEDAL_PEELOUT;
148
}
149
150
void LevelSelect_Cheat_RickyMode(void)
151
{
152
RSDK.PlaySfx(LevelSelect->sfxRing, false, 255);
153
globals->secrets ^= SECRET_RICKYMODE;
154
}
155
156
void LevelSelect_Cheat_SuperDash(void)
157
{
158
RSDK.PlaySfx(LevelSelect->sfxRing, false, 255);
159
globals->secrets ^= SECRET_SUPERDASH;
160
}
161
162
void LevelSelect_Cheat_SwapGameMode(void)
163
{
164
if (API.CheckDLC(DLC_PLUS)) {
165
RSDK.PlaySfx(LevelSelect->sfxRing, false, 255);
166
if (globals->gameMode == MODE_ENCORE) {
167
globals->gameMode = MODE_MANIA;
168
}
169
else {
170
globals->gameMode = MODE_ENCORE;
171
if (globals->medalMods & MEDAL_ANDKNUCKLES)
172
globals->medalMods &= ~MEDAL_ANDKNUCKLES;
173
}
174
}
175
}
176
177
void LevelSelect_Cheat_UnlockAllMedals(void)
178
{
179
if (globals->superSecret && (globals->secrets & SECRET_RICKYMODE)) {
180
RSDK.PlaySfx(LevelSelect->sfxMedalGot, false, 255);
181
GameProgress_UnlockAll();
182
GameProgress_LockAllSpecialClear();
183
}
184
else {
185
RSDK.PlaySfx(LevelSelect->sfxRing, false, 255);
186
}
187
}
188
#endif
189
190
void LevelSelect_Draw_Fade(void)
191
{
192
RSDK_THIS(LevelSelect);
193
RSDK.FillScreen(0x000000, self->timer, self->timer - 128, self->timer - 256);
194
}
195
196
void LevelSelect_State_Init(void)
197
{
198
RSDK_THIS(LevelSelect);
199
200
int32 labelPos[32];
201
int32 lastY = 0;
202
foreach_all(UIText, labelPosPtrL)
203
{
204
if (labelPosPtrL->position.x < 0x1000000 && labelPosPtrL->position.y > lastY) {
205
lastY = labelPosPtrL->position.y;
206
labelPos[self->labelCount++] = labelPosPtrL->position.y;
207
}
208
}
209
210
foreach_all(UIText, labelL)
211
{
212
if (labelL->position.x < 0x1000000) {
213
for (int32 i = 0; i < self->labelCount; ++i) {
214
if (labelL->position.y == labelPos[i]) {
215
switch (labelL->align) {
216
case UITEXT_ALIGN_LEFT: self->zoneNameLabels[i] = labelL; break;
217
218
default:
219
case UITEXT_ALIGN_CENTER: break;
220
221
case UITEXT_ALIGN_RIGHT: self->stageIDLabels[i] = labelL; break;
222
}
223
}
224
}
225
}
226
}
227
228
if (self->labelCount > 0)
229
memset(labelPos, 0, sizeof(int32) * self->labelCount);
230
231
lastY = 0;
232
233
foreach_all(UIText, labelPosPtrR)
234
{
235
if (labelPosPtrR->position.x > 0x1000000 && labelPosPtrR->position.y > lastY) {
236
lastY = labelPosPtrR->position.y;
237
labelPos[self->labelCount++] = labelPosPtrR->position.y;
238
}
239
}
240
241
foreach_all(UIText, labelR)
242
{
243
if (labelR->position.x > 0x1000000 && self->labelCount > 0) {
244
for (int32 i = 0; i < self->labelCount; ++i) {
245
if (labelR->position.y == labelPos[i]) {
246
switch (labelR->align) {
247
case UITEXT_ALIGN_LEFT: self->zoneNameLabels[i] = labelR; break;
248
249
default:
250
case UITEXT_ALIGN_CENTER: break;
251
252
case UITEXT_ALIGN_RIGHT: self->stageIDLabels[i] = labelR;
253
#if MANIA_USE_PLUS
254
if (!labelR->data0 && labelR->data1 == 15)
255
self->pinballLabel = labelR;
256
#endif
257
break;
258
}
259
}
260
}
261
}
262
}
263
264
for (int32 i = 0; i < self->labelCount; ++i) {
265
if (!self->zoneNameLabels[i]) {
266
for (int32 v = i; v >= 0; --v) {
267
if (self->zoneNameLabels[v]) {
268
self->zoneNameLabels[i] = self->zoneNameLabels[v];
269
break;
270
}
271
}
272
}
273
}
274
275
LevelSelect_SetLabelHighlighted(true);
276
277
foreach_all(UIText, soundTestLabel)
278
{
279
if (soundTestLabel->align == UITEXT_ALIGN_CENTER) {
280
self->soundTestLabel = soundTestLabel;
281
soundTestLabel->align = UITEXT_ALIGN_LEFT;
282
}
283
}
284
285
self->leaderCharacterID = HUD_CharacterIndexFromID(GET_CHARACTER_ID(1)) + 1;
286
self->sidekickCharacterID = HUD_CharacterIndexFromID(GET_CHARACTER_ID(2)) + 1;
287
288
foreach_all(UIPicture, picture)
289
{
290
if (picture->listID == 1) {
291
self->zoneIcon = picture;
292
293
// Bug Details(?):
294
// frameID is equal to... playerID...?
295
// this feels like a slight oversight, though idk what it is meant to be
296
picture->animator.frameID = self->leaderCharacterID;
297
}
298
else if (picture->listID == 3) {
299
if (picture->frameID)
300
self->player2Icon = picture;
301
else
302
self->player1Icon = picture;
303
}
304
}
305
306
self->stageIDLabels[self->labelCount - 1] = self->soundTestLabel;
307
308
LevelSelect_ManagePlayerIcon();
309
310
self->state = LevelSelect_State_FadeIn;
311
}
312
313
void LevelSelect_State_FadeIn(void)
314
{
315
RSDK_THIS(LevelSelect);
316
317
if (self->timer <= 0) {
318
self->timer = 0;
319
self->state = LevelSelect_State_Navigate;
320
self->stateDraw = StateMachine_None;
321
}
322
else {
323
self->timer -= 16;
324
}
325
}
326
327
void LevelSelect_State_Navigate(void)
328
{
329
RSDK_THIS(LevelSelect);
330
331
bool32 confirmPress = API_GetConfirmButtonFlip() ? ControllerInfo->keyB.press : ControllerInfo->keyA.press;
332
333
if (ControllerInfo->keyUp.down || AnalogStickInfoL->keyUp.down) {
334
self->timer = (self->timer + 1) & 0xF;
335
336
if (self->timer == 1) {
337
LevelSelect_SetLabelHighlighted(false);
338
#if MANIA_USE_PLUS
339
if (--self->labelID == 28 && !API.CheckDLC(DLC_PLUS))
340
#endif
341
--self->labelID;
342
343
if (self->labelID < 0)
344
self->labelID = self->labelCount - 1;
345
346
LevelSelect_SetLabelHighlighted(true);
347
}
348
}
349
else if (ControllerInfo->keyDown.down || AnalogStickInfoL->keyDown.down) {
350
self->timer = (self->timer + 1) & 0xF;
351
if (self->timer == 1) {
352
LevelSelect_SetLabelHighlighted(false);
353
354
#if MANIA_USE_PLUS
355
if (++self->labelID == 28 && !API.CheckDLC(DLC_PLUS))
356
#endif
357
++self->labelID;
358
359
if (self->labelID == self->labelCount)
360
self->labelID = 0;
361
362
LevelSelect_SetLabelHighlighted(true);
363
}
364
}
365
else if (AnalogStickInfoL->keyLeft.press || ControllerInfo->keyLeft.press || ControllerInfo->keyRight.press || AnalogStickInfoL->keyRight.press) {
366
self->timer = 0;
367
368
if (self->labelID >= self->labelCount - 1) {
369
if (AnalogStickInfoL->keyLeft.press || ControllerInfo->keyLeft.press) {
370
if (--self->soundTestID < 0)
371
self->soundTestID = LevelSelect->soundTestMax - 1;
372
}
373
else if (++self->soundTestID >= LevelSelect->soundTestMax) {
374
self->soundTestID = 0;
375
}
376
377
EntityUIText *soundTest = self->soundTestLabel;
378
soundTest->text.chars[0] = self->soundTestID >> 4;
379
soundTest->text.chars[1] = self->soundTestID & 0xF;
380
}
381
else {
382
LevelSelect_HandleColumnChange();
383
}
384
}
385
else if (confirmPress || ControllerInfo->keyStart.press) {
386
if (self->labelID < self->labelCount - 1 || ControllerInfo->keyStart.press) {
387
#if MANIA_USE_PLUS
388
if (self->labelID != 28 || API.CheckDLC(DLC_PLUS))
389
LevelSelect_HandleNewStagePos();
390
else
391
RSDK.PlaySfx(LevelSelect->sfxFail, false, 255);
392
#else
393
LevelSelect_HandleNewStagePos();
394
#endif
395
}
396
else {
397
EntityMusic *track = RSDK_GET_ENTITY(self->soundTestID + LevelSelect->startMusicID, Music);
398
Music_PlayTrackPtr(track);
399
400
#if MANIA_USE_PLUS
401
self->offsetUFO = self->soundTestID % 14;
402
self->offsetBSS = self->soundTestID & 0x1F;
403
for (int32 i = 0; i < 8; ++i) {
404
if (self->soundTestID != LevelSelect->cheatCodePtrs[i][LevelSelect->cheatCodePos[i]]) {
405
LevelSelect->cheatCodePos[i] = 0;
406
}
407
else {
408
LevelSelect->cheatCodePos[i]++;
409
if (LevelSelect->cheatCodePtrs[i][LevelSelect->cheatCodePos[i]] == 255) {
410
LevelSelect->checkCheatActivated[i]();
411
LevelSelect->cheatCodePos[i] = 0;
412
}
413
}
414
}
415
#endif
416
}
417
}
418
#if GAME_VERSION == VER_100
419
else if (TouchInfo->count) {
420
421
self->timer = (self->timer + 1) & 0xF;
422
if (self->timer == 1) {
423
int32 selectedLabel = -1;
424
425
int32 labelID = self->labelCount - 1;
426
for (int32 l = 0; l < self->labelCount; ++l, labelID--) {
427
EntityUIText *label = self->zoneNameLabels[labelID];
428
429
if (label && labelID != self->labelID) {
430
int32 xOff = 5 * (label->text.length * 0.5);
431
432
for (int32 f = 0; f < TouchInfo->count; ++f) {
433
float tx = TouchInfo->x[f] * ScreenInfo->size.x;
434
float ty = TouchInfo->y[f] * ScreenInfo->size.y;
435
436
if (tx > ((label->position.x >> 16) - xOff) && tx < (xOff + (label->position.x >> 16))) {
437
if (ty < ((label->position.y >> 16) + 10) && ty > ((label->position.y >> 16) - 10))
438
selectedLabel = labelID;
439
}
440
}
441
}
442
}
443
444
if (selectedLabel == -1) {
445
labelID = self->labelCount - 1;
446
for (int32 l = 0; l < self->labelCount; ++l) {
447
EntityUIText *label = self->stageIDLabels[labelID];
448
449
if (label && labelID != self->labelID) {
450
int32 xOff = 5 * (label->text.length * 0.5);
451
452
for (int32 f = 0; f < TouchInfo->count; ++f) {
453
float tx = TouchInfo->x[f] * ScreenInfo->size.x;
454
float ty = TouchInfo->y[f] * ScreenInfo->size.y;
455
456
if (tx > ((label->position.x >> 16) - xOff) && tx < (xOff + (label->position.x >> 16))) {
457
if (ty < ((label->position.y >> 16) + 10) && ty > ((label->position.y >> 16) - 10))
458
selectedLabel = labelID;
459
}
460
}
461
}
462
labelID--;
463
}
464
}
465
466
for (int32 f = 0; f < TouchInfo->count; ++f) {
467
float tx = TouchInfo->x[f] * ScreenInfo->size.x;
468
float ty = TouchInfo->y[f] * ScreenInfo->size.y;
469
470
if (tx > 250.0 && ty > 170.0 && tx < 310.0 && ty < 230.0)
471
LevelSelect_HandleNewStagePos();
472
}
473
474
if (selectedLabel != -1) {
475
LevelSelect_SetLabelHighlighted(false);
476
self->labelID = selectedLabel;
477
LevelSelect_SetLabelHighlighted(true);
478
}
479
}
480
}
481
#endif
482
else {
483
self->timer = 0;
484
}
485
486
if (ControllerInfo->keyX.press) {
487
++self->leaderCharacterID;
488
LevelSelect_ManagePlayerIcon();
489
}
490
491
if (ControllerInfo->keyY.press) {
492
++self->sidekickCharacterID;
493
LevelSelect_ManagePlayerIcon();
494
}
495
496
EntityUIPicture *zoneIcon = self->zoneIcon;
497
if (self->labelID >= self->labelCount - 1)
498
RSDK.SetSpriteAnimation(UIPicture->aniFrames, 2, &zoneIcon->animator, true, self->leaderCharacterID);
499
else
500
RSDK.SetSpriteAnimation(UIPicture->aniFrames, 1, &zoneIcon->animator, true, self->stageIDLabels[self->labelID]->data1);
501
}
502
503
void LevelSelect_State_FadeOut(void)
504
{
505
RSDK_THIS(LevelSelect);
506
507
if (self->timer >= 1024)
508
RSDK.LoadScene();
509
else
510
self->timer += 16;
511
}
512
513
void LevelSelect_ManagePlayerIcon(void)
514
{
515
RSDK_THIS(LevelSelect);
516
517
EntityUIPicture *player1 = self->player1Icon;
518
EntityUIPicture *player2 = self->player2Icon;
519
520
switch (self->leaderCharacterID) {
521
case LSELECT_PLAYER_SONIC:
522
case LSELECT_PLAYER_TAILS:
523
// Bug Details(?):
524
if (self->sidekickCharacterID == LSELECT_PLAYER_TAILS) // if leader is sonic or tails, and the sidekick is tails... change to knux...?
525
self->leaderCharacterID = LSELECT_PLAYER_KNUCKLES;
526
// playerID 3 may have been meant to be "S&T" before it was rearranged?
527
// v4 support this, with the player ids being: Sonic, Tails, Knux, Sonic & Tails
528
529
player1->animator.frameID = self->leaderCharacterID;
530
break;
531
532
case LSELECT_PLAYER_KNUCKLES: player1->animator.frameID = self->leaderCharacterID; break;
533
534
#if MANIA_USE_PLUS
535
case LSELECT_PLAYER_MIGHTY:
536
case LSELECT_PLAYER_RAY:
537
if (!API.CheckDLC(DLC_PLUS))
538
self->leaderCharacterID = LSELECT_PLAYER_SONIC;
539
540
player1->animator.frameID = self->leaderCharacterID;
541
break;
542
#endif
543
544
default:
545
self->leaderCharacterID = LSELECT_PLAYER_SONIC;
546
player1->animator.frameID = LSELECT_PLAYER_SONIC;
547
break;
548
}
549
550
switch (self->sidekickCharacterID) {
551
case LSELECT_PLAYER_TAILS:
552
player2->animator.frameID = self->sidekickCharacterID;
553
554
// if leader is sonic & sidekick is tails, show ST icon. otherwise remove sidekick
555
if (self->leaderCharacterID != LSELECT_PLAYER_SONIC) {
556
self->sidekickCharacterID = LSELECT_PLAYER_NONE;
557
player2->animator.frameID = LSELECT_PLAYER_NONE;
558
}
559
break;
560
561
default:
562
self->sidekickCharacterID = LSELECT_PLAYER_NONE;
563
player2->animator.frameID = LSELECT_PLAYER_NONE;
564
break;
565
566
// if P2 is sonic, no he's not thats tails actually
567
case LSELECT_PLAYER_SONIC:
568
self->sidekickCharacterID = LSELECT_PLAYER_TAILS;
569
player2->animator.frameID = LSELECT_PLAYER_TAILS;
570
571
// if leader is sonic & sidekick is tails, show ST icon. otherwise remove sidekick
572
if (self->leaderCharacterID != LSELECT_PLAYER_SONIC) {
573
self->sidekickCharacterID = LSELECT_PLAYER_NONE;
574
player2->animator.frameID = LSELECT_PLAYER_NONE;
575
}
576
break;
577
}
578
}
579
580
void LevelSelect_SetLabelHighlighted(bool32 highlight)
581
{
582
RSDK_THIS(LevelSelect);
583
584
EntityUIText *zoneName = self->zoneNameLabels[self->labelID];
585
if (zoneName)
586
zoneName->highlighted = highlight;
587
588
EntityUIText *stageID = self->stageIDLabels[self->labelID];
589
if (stageID)
590
stageID->highlighted = highlight;
591
}
592
593
void LevelSelect_HandleColumnChange(void)
594
{
595
RSDK_THIS(LevelSelect);
596
597
EntityUIText *curLabel = self->stageIDLabels[self->labelID];
598
if (!curLabel)
599
curLabel = self->zoneNameLabels[self->labelID];
600
601
int32 distance = 0x1000000;
602
EntityUIText *labelPtr = NULL;
603
if (curLabel->position.x < 0x1000000) {
604
foreach_active(UIText, label)
605
{
606
if (label->position.x > 0x1000000) {
607
int32 pos = abs(label->position.y - curLabel->position.y);
608
if (pos < distance) {
609
distance = pos;
610
labelPtr = label;
611
}
612
}
613
}
614
}
615
else {
616
foreach_active(UIText, label)
617
{
618
if (label->position.x < 0x1000000) {
619
int32 dist = abs(label->position.y - curLabel->position.y);
620
if (dist < distance) {
621
distance = dist;
622
labelPtr = label;
623
}
624
}
625
}
626
}
627
628
int32 labelID = self->labelID;
629
for (int32 i = 0; i < self->labelCount; ++i) {
630
if (self->stageIDLabels[i] == labelPtr || self->zoneNameLabels[i] == labelPtr) {
631
labelID = i;
632
break;
633
}
634
}
635
636
if (self->labelID != labelID) {
637
LevelSelect_SetLabelHighlighted(false);
638
639
self->labelID = labelID;
640
LevelSelect_SetLabelHighlighted(true);
641
}
642
}
643
644
void LevelSelect_HandleNewStagePos(void)
645
{
646
RSDK_THIS(LevelSelect);
647
648
EntityUIText *curLabel = self->stageIDLabels[self->labelID];
649
if (!curLabel)
650
curLabel = self->zoneNameLabels[self->labelID];
651
652
if (curLabel->selectable) {
653
char buffer[32];
654
RSDK.GetCString(buffer, &curLabel->tag);
655
RSDK.SetScene(buffer, "");
656
SceneInfo->listPos += curLabel->data0;
657
658
#if MANIA_USE_PLUS
659
if (self->labelID == self->labelCount - 4)
660
SceneInfo->listPos += self->offsetUFO;
661
else if (self->labelID == self->labelCount - 3)
662
SceneInfo->listPos += self->offsetBSS;
663
else if (globals->gameMode == MODE_ENCORE)
664
SceneInfo->listPos = Zone_GetListPos_EncoreMode();
665
#endif
666
667
int32 leaderID = 0;
668
if (self->leaderCharacterID > 0)
669
leaderID = 1 << (self->leaderCharacterID - 1);
670
671
int32 sidekickID = 0;
672
if (self->sidekickCharacterID > 0)
673
sidekickID = 1 << (self->sidekickCharacterID - 1);
674
675
globals->playerID = leaderID | (sidekickID << 8);
676
677
// MSZ1K check
678
if (CHECK_CHARACTER_ID(ID_KNUCKLES, 1) && curLabel->data0 == 15)
679
++SceneInfo->listPos;
680
681
self->timer = 0;
682
self->state = LevelSelect_State_FadeOut;
683
self->stateDraw = LevelSelect_Draw_Fade;
684
Music_FadeOut(0.1);
685
}
686
else {
687
RSDK.PlaySfx(LevelSelect->sfxFail, false, 255);
688
}
689
}
690
691
#if GAME_INCLUDE_EDITOR
692
void LevelSelect_EditorDraw(void) {}
693
694
void LevelSelect_EditorLoad(void)
695
{
696
if (UIPicture)
697
UIPicture->aniFrames = RSDK.LoadSpriteAnimation("LSelect/Icons.bin", SCOPE_STAGE);
698
699
if (UIText)
700
UIText->aniFrames = RSDK.LoadSpriteAnimation("LSelect/Text.bin", SCOPE_STAGE);
701
}
702
#endif
703
704
void LevelSelect_Serialize(void) {}
705
706