Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/Global/HUD.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: HUD Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectHUD *HUD;
11
12
void HUD_Update(void)
13
{
14
RSDK_THIS(HUD);
15
16
self->enableTimeFlash = false;
17
self->enableRingFlash = false;
18
19
#if MANIA_USE_PLUS
20
if (self->replayClapAnimator.animationID == 11)
21
RSDK.ProcessAnimation(&self->replayClapAnimator);
22
#endif
23
}
24
25
void HUD_LateUpdate(void)
26
{
27
RSDK_THIS(HUD);
28
29
#if MANIA_USE_PLUS
30
if (globals->gameMode == MODE_COMPETITION) {
31
for (self->screenID = 0; self->screenID < RSDK.GetVideoSetting(VIDEOSETTING_SCREENCOUNT); ++self->screenID) {
32
StateMachine_Run(self->vsStates[self->screenID]);
33
}
34
}
35
else {
36
StateMachine_Run(self->state);
37
}
38
#else
39
StateMachine_Run(self->state);
40
#endif
41
42
#if GAME_VERSION != VER_100
43
if (globals->gameMode < MODE_TIMEATTACK) {
44
EntityPlayer *player = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);
45
if (SceneInfo->timeEnabled && player->rings >= 50 && player->superState < SUPERSTATE_SUPER
46
&& SaveGame_GetSaveRAM()->collectedEmeralds >= 0b01111111) {
47
if (sku_platform == PLATFORM_PC || sku_platform == PLATFORM_SWITCH || sku_platform == PLATFORM_DEV)
48
HUD_GetActionButtonFrames();
49
50
if (self->actionPromptPos < TO_FIXED(24))
51
self->actionPromptPos += TO_FIXED(8);
52
}
53
else {
54
if (self->actionPromptPos > -TO_FIXED(32))
55
self->actionPromptPos -= TO_FIXED(8);
56
}
57
}
58
#if MANIA_USE_PLUS
59
else if (globals->gameMode == MODE_TIMEATTACK) {
60
if (HUD->showTAPrompt) {
61
if (sku_platform == PLATFORM_PC || sku_platform == PLATFORM_SWITCH || sku_platform == PLATFORM_DEV) {
62
HUD_GetButtonFrame(&self->superButtonAnimator, KEY_Y);
63
HUD_GetButtonFrame(&self->saveReplayButtonAnimator, KEY_Y);
64
HUD_GetButtonFrame(&self->thumbsUpButtonAnimator, KEY_START);
65
}
66
67
if (self->actionPromptPos < TO_FIXED(24))
68
self->actionPromptPos += TO_FIXED(8);
69
}
70
else {
71
if (self->actionPromptPos > -TO_FIXED(64))
72
self->actionPromptPos -= TO_FIXED(8);
73
}
74
}
75
#endif
76
#endif
77
}
78
79
void HUD_StaticUpdate(void) {}
80
81
void HUD_Draw(void)
82
{
83
RSDK_THIS(HUD);
84
EntityPlayer *player = RSDK_GET_ENTITY(SceneInfo->currentScreenID, Player);
85
86
Vector2 drawPos;
87
Vector2 scorePos, timePos, ringPos, lifePos;
88
89
scorePos.x = self->scorePos.x;
90
scorePos.y = self->scorePos.y;
91
timePos.x = self->timePos.x;
92
timePos.y = self->timePos.y;
93
ringPos.x = self->ringsPos.x;
94
ringPos.y = self->ringsPos.y;
95
lifePos.x = self->lifePos.x;
96
lifePos.y = self->lifePos.y;
97
if (globals->gameMode == MODE_COMPETITION) {
98
#if MANIA_USE_PLUS
99
scorePos.x = self->vsScorePos[SceneInfo->currentScreenID].x;
100
scorePos.y = self->vsScorePos[SceneInfo->currentScreenID].y;
101
timePos.x = self->vsTimePos[SceneInfo->currentScreenID].x;
102
timePos.y = self->vsTimePos[SceneInfo->currentScreenID].y;
103
ringPos.x = self->vsRingsPos[SceneInfo->currentScreenID].x;
104
ringPos.y = self->vsRingsPos[SceneInfo->currentScreenID].y;
105
lifePos.x = self->vsLifePos[SceneInfo->currentScreenID].x;
106
lifePos.y = self->vsLifePos[SceneInfo->currentScreenID].y;
107
#endif
108
109
foreach_active(Player, plr)
110
{
111
if (plr != player) {
112
self->playerIDAnimator.frameID = plr->playerID;
113
RSDK.DrawSprite(&self->playerIDAnimator, &plr->position, false);
114
}
115
}
116
}
117
#if MANIA_USE_PLUS
118
else {
119
if (HUD->swapCooldown > 0) {
120
RSDK.ProcessAnimation(&self->playerIDAnimator);
121
RSDK.DrawSprite(&self->playerIDAnimator, &player->position, false);
122
--HUD->swapCooldown;
123
}
124
}
125
#endif
126
127
self->ringFlashFrame = player->rings ? 0 : ((Zone->persistentTimer >> 3) & 1);
128
129
#if GAME_VERSION != VER_100
130
#if MANIA_USE_PLUS
131
self->timeFlashFrame = 0;
132
if ((SceneInfo->minutes == 9 && isMainGameMode() && !(globals->medalMods & MEDAL_NOTIMEOVER)) || ActClear->disableTimeBonus)
133
self->timeFlashFrame = (Zone->persistentTimer >> 3) & 1;
134
#else
135
if (SceneInfo->minutes == 9 && globals->gameMode < MODE_TIMEATTACK)
136
self->timeFlashFrame = (Zone->persistentTimer >> 3) & 1;
137
#endif
138
#endif
139
140
// Draw "Score"
141
self->hudElementsAnimator.frameID = 0;
142
RSDK.DrawSprite(&self->hudElementsAnimator, &scorePos, true);
143
144
// Draw Score
145
drawPos.x = scorePos.x + TO_FIXED(97);
146
drawPos.y = scorePos.y + TO_FIXED(14);
147
HUD_DrawNumbersBase10(&drawPos, player->score, 0);
148
149
// Draw "Time"
150
#if GAME_VERSION != VER_100
151
self->hudElementsAnimator.frameID = self->timeFlashFrame + 1;
152
#else
153
self->hudElementsAnimator.frameID = 1;
154
#endif
155
RSDK.DrawSprite(&self->hudElementsAnimator, &timePos, true);
156
157
if (!self->enableTimeFlash || Zone->persistentTimer & 8) {
158
// Draw ":"
159
drawPos.x = timePos.x + TO_FIXED(52);
160
drawPos.y = timePos.y - TO_FIXED(2);
161
self->hudElementsAnimator.frameID = 12;
162
RSDK.DrawSprite(&self->hudElementsAnimator, &drawPos, true);
163
164
// Draw Milliseconds
165
drawPos.x = timePos.x + TO_FIXED(97);
166
drawPos.y = timePos.y + TO_FIXED(14);
167
HUD_DrawNumbersBase10(&drawPos, SceneInfo->milliseconds, 2);
168
169
// Draw Seconds
170
drawPos.x -= TO_FIXED(9);
171
HUD_DrawNumbersBase10(&drawPos, SceneInfo->seconds, 2);
172
173
// Draw Minutes
174
drawPos.x -= TO_FIXED(9);
175
#if MANIA_USE_PLUS
176
if (SceneInfo->minutes > 9 && globals->medalMods & MEDAL_NOTIMEOVER)
177
HUD_DrawNumbersBase10(&drawPos, SceneInfo->minutes, 2);
178
else
179
#endif
180
HUD_DrawNumbersBase10(&drawPos, SceneInfo->minutes, 1);
181
}
182
183
// Draw "Rings"
184
self->hudElementsAnimator.frameID = self->ringFlashFrame + 3;
185
RSDK.DrawSprite(&self->hudElementsAnimator, &ringPos, true);
186
187
if (!self->enableRingFlash || Zone->persistentTimer & 8) {
188
// Draw Rings
189
drawPos.x = ringPos.x + TO_FIXED(97);
190
drawPos.y = ringPos.y + TO_FIXED(14);
191
if (player->hyperRing)
192
HUD_DrawNumbersHyperRing(&drawPos, player->rings);
193
else
194
HUD_DrawNumbersBase10(&drawPos, player->rings, 0);
195
}
196
197
if (RSDK_GET_ENTITY(SLOT_PLAYER1, Player)->classID == DebugMode->classID) {
198
if (player->camera) {
199
// Draw Camera YPos
200
drawPos.x = TO_FIXED(ScreenInfo[player->camera->screenID].size.x - 16);
201
drawPos.y = TO_FIXED(24);
202
HUD_DrawNumbersBase16(&drawPos, ScreenInfo[player->camera->screenID].position.y);
203
204
// Draw Camera XPos
205
drawPos.x -= TO_FIXED(9);
206
HUD_DrawNumbersBase16(&drawPos, ScreenInfo[player->camera->screenID].position.x);
207
208
// Draw Player YPos
209
drawPos.x = TO_FIXED(ScreenInfo[player->camera->screenID].size.x - 16);
210
drawPos.y += TO_FIXED(16);
211
HUD_DrawNumbersBase16(&drawPos, FROM_FIXED(player->position.y));
212
213
// Draw Player XPos
214
drawPos.x -= TO_FIXED(9);
215
HUD_DrawNumbersBase16(&drawPos, FROM_FIXED(player->position.x));
216
}
217
}
218
#if MANIA_USE_PLUS
219
else if (self->actionPromptPos > -TO_FIXED(64) && globals->gameMode == MODE_TIMEATTACK) {
220
drawPos.x = TO_FIXED(ScreenInfo[SceneInfo->currentScreenID].size.x) - self->actionPromptPos;
221
drawPos.y = TO_FIXED(20);
222
223
if (API.CheckDLC(DLC_PLUS)) {
224
// Draw Replay Save Icon
225
RSDK.DrawSprite(&self->replayClapAnimator, &drawPos, true);
226
227
// Draw Replay Save Button
228
drawPos.x -= TO_FIXED(28);
229
if (HUD->replaySaveEnabled) {
230
RSDK.DrawSprite(&self->saveReplayButtonAnimator, &drawPos, true);
231
}
232
else {
233
self->inkEffect = INK_BLEND;
234
RSDK.DrawSprite(&self->saveReplayButtonAnimator, &drawPos, true);
235
236
self->inkEffect = INK_NONE;
237
}
238
239
drawPos.x = TO_FIXED(ScreenInfo[SceneInfo->currentScreenID].size.x) - self->actionPromptPos;
240
drawPos.y += TO_FIXED(28);
241
}
242
// Draw Thumbs Up Icon
243
RSDK.DrawSprite(&self->thumbsUpIconAnimator, &drawPos, true);
244
245
// Draw Thumbs Up Button
246
drawPos.x -= TO_FIXED(28);
247
RSDK.DrawSprite(&self->thumbsUpButtonAnimator, &drawPos, true);
248
}
249
#endif
250
#if GAME_VERSION != VER_100
251
else if (self->actionPromptPos > -TO_FIXED(32)) {
252
// Draw Super Icon
253
drawPos.x = TO_FIXED(ScreenInfo[SceneInfo->currentScreenID].size.x) - self->actionPromptPos;
254
drawPos.y = TO_FIXED(20);
255
RSDK.DrawSprite(&self->superIconAnimator, &drawPos, true);
256
257
drawPos.x -= TO_FIXED(20);
258
bool32 canSuper = true;
259
#if MANIA_USE_PLUS
260
if (Player->canSuperCB)
261
canSuper = Player->canSuperCB(true);
262
#endif
263
// Draw Super Button
264
if (player->state == Player_State_Air && player->jumpAbilityState == 1 && canSuper) {
265
RSDK.DrawSprite(&self->superButtonAnimator, &drawPos, true);
266
}
267
else {
268
self->inkEffect = INK_BLEND;
269
RSDK.DrawSprite(&self->superButtonAnimator, &drawPos, true);
270
271
self->inkEffect = INK_NONE;
272
}
273
}
274
#endif
275
276
// Draw Life Icon (aka the Leader Icon if in encore mode)
277
drawPos.x = lifePos.x;
278
drawPos.y = lifePos.y;
279
#if MANIA_USE_PLUS
280
int32 lives = self->lives[player->playerID];
281
self->lifeIconAnimator.frameID = HUD_CharacterIndexFromID(player->characterID);
282
283
if (self->lifeIconAnimator.frameID < 0) {
284
self->lifeIconAnimator.frameID = self->lifeFrameIDs[player->playerID];
285
lives--;
286
}
287
else {
288
self->lifeFrameIDs[player->playerID] = self->lifeIconAnimator.frameID;
289
self->lives[player->playerID] = player->lives;
290
}
291
#else
292
switch (player->characterID) {
293
default:
294
case ID_SONIC: self->lifeIconAnimator.frameID = 0; break;
295
case ID_TAILS: self->lifeIconAnimator.frameID = 1; break;
296
case ID_KNUCKLES: self->lifeIconAnimator.frameID = 2; break;
297
}
298
#endif
299
RSDK.DrawSprite(&self->lifeIconAnimator, &drawPos, true);
300
301
#if MANIA_USE_PLUS
302
if (globals->gameMode == MODE_ENCORE) {
303
for (int32 p = 0; p < PLAYER_COUNT; ++p) {
304
if (HUD->stockFlashTimers[p] > 0)
305
HUD->stockFlashTimers[p]--;
306
}
307
308
drawPos.x += TO_FIXED(20);
309
EntityPlayer *sidekick = RSDK_GET_ENTITY(SLOT_PLAYER2, Player);
310
if (sidekick->classID) {
311
// Draw Buddy Icon
312
self->lifeIconAnimator.frameID = HUD_CharacterIndexFromID(sidekick->characterID);
313
if (self->lifeIconAnimator.frameID >= 0 && !(HUD->stockFlashTimers[0] & 4)) {
314
if ((sidekick->state != Player_State_Death && sidekick->state != Player_State_Drown && sidekick->state != Player_State_EncoreRespawn)
315
|| !sidekick->abilityValues[0]) {
316
RSDK.DrawSprite(&self->lifeIconAnimator, &drawPos, true);
317
}
318
}
319
320
// Draw Stock Icons
321
drawPos.x += TO_FIXED(20);
322
RSDK.SetSpriteAnimation(HUD->aniFrames, 12, &self->lifeIconAnimator, true, 0);
323
for (int32 i = 1; i < 4; ++i) {
324
self->lifeIconAnimator.frameID = HUD_CharacterIndexFromID(GET_STOCK_ID(i));
325
if (self->lifeIconAnimator.frameID >= 0 && !(HUD->stockFlashTimers[i] & 4))
326
RSDK.DrawSprite(&self->lifeIconAnimator, &drawPos, true);
327
328
drawPos.x += TO_FIXED(16);
329
}
330
331
RSDK.SetSpriteAnimation(HUD->aniFrames, 2, &self->lifeIconAnimator, true, 0);
332
}
333
}
334
else {
335
// Draw Life Icon "X"
336
self->hudElementsAnimator.frameID = 14;
337
RSDK.DrawSprite(&self->hudElementsAnimator, &drawPos, true);
338
339
// Draw Lives
340
drawPos.x += TO_FIXED(48);
341
if (player->lives < 10)
342
drawPos.x -= TO_FIXED(8);
343
HUD_DrawNumbersBase10(&drawPos, lives, 0);
344
}
345
#else
346
// Draw Life Icon "X"
347
self->hudElementsAnimator.frameID = 14;
348
RSDK.DrawSprite(&self->hudElementsAnimator, &drawPos, true);
349
350
// Draw Lives
351
drawPos.x += TO_FIXED(48);
352
if (player->lives < 10)
353
drawPos.x -= TO_FIXED(8);
354
HUD_DrawNumbersBase10(&drawPos, player->lives, 0);
355
#endif
356
357
if (globals->gameMode == MODE_COMPETITION) {
358
// Draw Competition Borders
359
#if MANIA_USE_PLUS
360
switch (HUD->screenBorderType[SceneInfo->currentScreenID]) {
361
default:
362
case VS_BORDER_NONE: break;
363
364
case VS_BORDER_BOTTOMRIGHT:
365
// Along right edge
366
RSDK.DrawRect(ScreenInfo->size.x - 1, 0, 1, ScreenInfo->size.y, 0x000000, 0xFF, INK_NONE, true);
367
// Along bottom edge
368
RSDK.DrawRect(0, ScreenInfo->size.y - 1, ScreenInfo->size.x, 1, 0x000000, 0xFF, INK_NONE, true);
369
break;
370
371
case VS_BORDER_BOTTOM:
372
// Along bottom edge
373
RSDK.DrawRect(0, ScreenInfo->size.y - 1, ScreenInfo->size.x, 1, 0x000000, 0xFF, INK_NONE, true);
374
break;
375
376
case VS_BORDER_BOTTOMLEFT:
377
// Along left edge (on screen 2)
378
RSDK.DrawRect(0, 0, 1, ScreenInfo[1].size.y, 0x000000, 0xFF, INK_NONE, true);
379
// Along bottom edge
380
RSDK.DrawRect(0, ScreenInfo->size.y - 1, ScreenInfo->size.x, 1, 0x000000, 0xFF, INK_NONE, true);
381
break;
382
383
case VS_BORDER_TOPRIGHT:
384
// Along right edge
385
RSDK.DrawRect(ScreenInfo->size.x - 1, 0, 1, ScreenInfo->size.y, 0x000000, 0xFF, INK_NONE, true);
386
// Along top edge (on screen 2 or 3)
387
RSDK.DrawRect(0, 0, ScreenInfo[1].size.x, 1, 0x000000, 0xFF, INK_NONE, true);
388
break;
389
390
case VS_BORDER_TOP:
391
// Along top edge (on screen 2)
392
RSDK.DrawRect(0, 0, ScreenInfo[1].size.x, 1, 0x000000, 0xFF, INK_NONE, true);
393
break;
394
395
case VS_BORDER_TOPLEFT:
396
// Along left edge (on screen 3 or 4)
397
RSDK.DrawRect(0, 0, 1, ScreenInfo[1].size.y, 0x000000, 0xFF, INK_NONE, true);
398
// Along top edge (on screen 3 or 4)
399
RSDK.DrawRect(0, 0, ScreenInfo[1].size.x, 1, 0x000000, 0xFF, INK_NONE, true);
400
break;
401
}
402
#else
403
switch (SceneInfo->currentScreenID) {
404
case 0:
405
// Along right edge (on screen 1)
406
RSDK.DrawRect(0, ScreenInfo->size.y - 1, ScreenInfo->size.x, 1, 0x000000, 0xFF, INK_NONE, true);
407
break;
408
409
case 1:
410
// Along left edge (on screen 2)
411
RSDK.DrawRect(0, 0, ScreenInfo[1].size.x, 1, 0x000000, 0xFF, INK_NONE, true);
412
break;
413
414
default: break;
415
}
416
#endif
417
}
418
}
419
420
void HUD_Create(void *data)
421
{
422
RSDK_THIS(HUD);
423
424
if (!SceneInfo->inEditor) {
425
#if MANIA_USE_PLUS
426
ActClear->disableTimeBonus = false;
427
#endif
428
429
self->active = ACTIVE_NORMAL;
430
self->visible = true;
431
self->drawGroup = Zone->hudDrawGroup;
432
433
self->scorePos.x = TO_FIXED(16);
434
self->scorePos.y = TO_FIXED(12);
435
self->timePos.x = TO_FIXED(16);
436
self->timePos.y = TO_FIXED(28);
437
self->ringsPos.x = TO_FIXED(16);
438
self->ringsPos.y = TO_FIXED(44);
439
self->lifePos.x = TO_FIXED(16);
440
self->lifePos.y = TO_FIXED(ScreenInfo->size.y - 12);
441
#if GAME_VERSION != VER_100
442
self->actionPromptPos = -TO_FIXED(32);
443
#endif
444
445
#if MANIA_USE_PLUS
446
for (int32 i = 0; i < SCREEN_COUNT; ++i) {
447
self->vsScorePos[i].x = self->scorePos.x;
448
self->vsScorePos[i].y = self->scorePos.y;
449
self->vsTimePos[i].x = self->timePos.x;
450
self->vsTimePos[i].y = self->timePos.y;
451
self->vsRingsPos[i].x = self->ringsPos.x;
452
self->vsRingsPos[i].y = self->ringsPos.y;
453
self->vsLifePos[i].x = self->lifePos.x;
454
self->vsLifePos[i].y = self->lifePos.y;
455
}
456
#endif
457
458
RSDK.SetSpriteAnimation(HUD->aniFrames, 0, &self->hudElementsAnimator, true, 0);
459
RSDK.SetSpriteAnimation(HUD->aniFrames, 1, &self->numbersAnimator, true, 0);
460
RSDK.SetSpriteAnimation(HUD->aniFrames, 9, &self->hyperNumbersAnimator, true, 0);
461
RSDK.SetSpriteAnimation(HUD->aniFrames, 2, &self->lifeIconAnimator, true, 0);
462
#if MANIA_USE_PLUS
463
RSDK.SetSpriteAnimation(HUD->aniFrames, globals->gameMode == MODE_ENCORE ? 13 : 8, &self->playerIDAnimator, true, 0);
464
RSDK.SetSpriteAnimation(HUD->aniFrames, 10, &self->thumbsUpIconAnimator, true, 2);
465
RSDK.SetSpriteAnimation(HUD->aniFrames, 10, &self->replayClapAnimator, true, 1);
466
#else
467
RSDK.SetSpriteAnimation(HUD->aniFrames, 8, &self->playerIDAnimator, true, 0);
468
#endif
469
470
#if GAME_VERSION != VER_100
471
RSDK.SetSpriteAnimation(HUD->superButtonFrames, 0, &self->superIconAnimator, true, 0);
472
HUD_GetActionButtonFrames();
473
#endif
474
475
#if MANIA_USE_PLUS
476
RSDK.AddViewableVariable("Show HUD", &self->visible, VIEWVAR_UINT8, false, true);
477
#endif
478
}
479
}
480
481
void HUD_StageLoad(void)
482
{
483
HUD->aniFrames = RSDK.LoadSpriteAnimation("Global/HUD.bin", SCOPE_STAGE);
484
#if GAME_VERSION != VER_100
485
HUD->superButtonFrames = RSDK.LoadSpriteAnimation("Global/SuperButtons.bin", SCOPE_STAGE);
486
#endif
487
488
#if MANIA_USE_PLUS
489
HUD->sfxClick = RSDK.GetSfx("Stage/Click.wav");
490
HUD->sfxStarpost = RSDK.GetSfx("Global/StarPost.wav");
491
492
HUD->showTAPrompt = false;
493
494
EntityCompetitionSession *session = CompetitionSession_GetSession();
495
if (globals->gameMode == MODE_COMPETITION) {
496
HUD->screenBorderType[0] = session->screenBorderType[0];
497
HUD->screenBorderType[1] = session->screenBorderType[1];
498
HUD->screenBorderType[2] = session->screenBorderType[2];
499
HUD->screenBorderType[3] = session->screenBorderType[3];
500
}
501
#endif
502
}
503
504
void HUD_DrawNumbersBase10(Vector2 *drawPos, int32 value, int32 digitCount)
505
{
506
RSDK_THIS(HUD);
507
508
if (!digitCount && value > 0) {
509
int32 v = value;
510
while (v > 0) {
511
++digitCount;
512
v /= 10;
513
}
514
}
515
else {
516
if (!digitCount && value <= 0)
517
digitCount = 1;
518
}
519
520
int32 digit = 1;
521
while (digitCount--) {
522
self->numbersAnimator.frameID = value / digit % 10;
523
RSDK.DrawSprite(&self->numbersAnimator, drawPos, true);
524
digit *= 10;
525
drawPos->x -= TO_FIXED(8);
526
}
527
}
528
529
void HUD_DrawNumbersBase16(Vector2 *drawPos, int32 value)
530
{
531
RSDK_THIS(HUD);
532
533
int32 mult = 1;
534
for (int32 i = 4; i; --i) {
535
self->numbersAnimator.frameID = value / mult & 0xF;
536
RSDK.DrawSprite(&self->numbersAnimator, drawPos, true);
537
drawPos->x -= TO_FIXED(8);
538
mult *= 16;
539
}
540
}
541
542
void HUD_DrawNumbersHyperRing(Vector2 *drawPos, int32 value)
543
{
544
RSDK_THIS(HUD);
545
546
int32 cnt = 0;
547
int32 mult = 1;
548
int32 mult2 = 1;
549
if (value <= 0) {
550
cnt = 1;
551
}
552
else {
553
int32 v = value;
554
while (v) {
555
++cnt;
556
v /= 10;
557
}
558
}
559
560
if (cnt > 0) {
561
while (cnt--) {
562
self->hyperNumbersAnimator.frameID = value / mult % 10;
563
RSDK.DrawSprite(&self->hyperNumbersAnimator, drawPos, true);
564
drawPos->x -= TO_FIXED(8);
565
mult = 10 * mult2;
566
mult2 *= 10;
567
}
568
}
569
570
self->hyperNumbersAnimator.frameID = 10;
571
drawPos->x -= TO_FIXED(4);
572
RSDK.DrawSprite(&self->hyperNumbersAnimator, drawPos, true);
573
}
574
575
#if GAME_VERSION != VER_100
576
void HUD_GetButtonFrame(Animator *animator, int32 buttonID)
577
{
578
int32 gamepadType = UIButtonPrompt_GetGamepadType();
579
if (API_GetConfirmButtonFlip() && buttonID <= 1)
580
buttonID ^= 1;
581
582
// Gamepad
583
if (gamepadType != UIBUTTONPROMPT_KEYBOARD && (gamepadType < UIBUTTONPROMPT_KEYBOARD_FR || gamepadType > UIBUTTONPROMPT_KEYBOARD_SP)) {
584
RSDK.SetSpriteAnimation(HUD->superButtonFrames, gamepadType, animator, true, buttonID);
585
}
586
else {
587
// Keyboard
588
EntityPlayer *player = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);
589
#if MANIA_USE_PLUS
590
int32 id = API_GetInputDeviceID(player->controllerID);
591
#else
592
int32 id = INPUT_NONE;
593
#endif
594
int32 contID = id == INPUT_UNASSIGNED ? CONT_P1 : player->controllerID;
595
596
int32 map = 0;
597
switch (buttonID) {
598
default: break;
599
case 0: map = ControllerInfo[contID].keyA.keyMap; break;
600
case 1: map = ControllerInfo[contID].keyB.keyMap; break;
601
case 2: map = ControllerInfo[contID].keyX.keyMap; break;
602
case 3: map = ControllerInfo[contID].keyY.keyMap; break;
603
case 4: map = ControllerInfo[contID].keyStart.keyMap; break;
604
}
605
606
int32 frame = UIButtonPrompt_MappingsToFrame(map);
607
RSDK.SetSpriteAnimation(HUD->superButtonFrames, 1, animator, true, frame);
608
}
609
}
610
void HUD_GetActionButtonFrames(void)
611
{
612
RSDK_THIS(HUD);
613
614
HUD_GetButtonFrame(&self->superButtonAnimator, KEY_Y);
615
#if MANIA_USE_PLUS
616
HUD_GetButtonFrame(&self->saveReplayButtonAnimator, KEY_Y);
617
HUD_GetButtonFrame(&self->thumbsUpButtonAnimator, KEY_START);
618
#endif
619
}
620
#endif
621
622
void HUD_State_MoveIn(void)
623
{
624
RSDK_THIS(HUD);
625
626
#if MANIA_USE_PLUS
627
StateMachine(*state) = NULL;
628
Vector2 *scorePos = NULL, *timePos = NULL, *ringsPos = NULL, *lifePos = NULL;
629
int32 *targetPos = NULL;
630
631
if (globals->gameMode == MODE_COMPETITION) {
632
state = &self->vsStates[SceneInfo->currentScreenID];
633
scorePos = &self->vsScorePos[SceneInfo->currentScreenID];
634
timePos = &self->vsTimePos[SceneInfo->currentScreenID];
635
ringsPos = &self->vsRingsPos[SceneInfo->currentScreenID];
636
lifePos = &self->vsLifePos[SceneInfo->currentScreenID];
637
targetPos = &self->vsTargetPos[SceneInfo->currentScreenID];
638
}
639
else {
640
state = &self->state;
641
scorePos = &self->scorePos;
642
timePos = &self->timePos;
643
ringsPos = &self->ringsPos;
644
lifePos = &self->lifePos;
645
targetPos = &self->targetPos;
646
}
647
648
if (scorePos->x < *targetPos)
649
scorePos->x += TO_FIXED(8);
650
651
if (timePos->x < *targetPos)
652
timePos->x += TO_FIXED(8);
653
654
if (ringsPos->x < *targetPos)
655
ringsPos->x += TO_FIXED(8);
656
657
if (lifePos->x < *targetPos)
658
lifePos->x += TO_FIXED(8);
659
else
660
*state = StateMachine_None;
661
#else
662
if (self->scorePos.x < self->targetPos)
663
self->scorePos.x += TO_FIXED(8);
664
665
if (self->timePos.x < self->targetPos)
666
self->timePos.x += TO_FIXED(8);
667
668
if (self->ringsPos.x < self->targetPos)
669
self->ringsPos.x += TO_FIXED(8);
670
671
if (self->lifePos.x < self->targetPos)
672
self->lifePos.x += TO_FIXED(8);
673
else
674
self->state = StateMachine_None;
675
#endif
676
}
677
678
void HUD_State_MoveOut(void)
679
{
680
RSDK_THIS(HUD);
681
682
#if MANIA_USE_PLUS
683
Vector2 *scorePos = NULL, *timePos = NULL, *ringsPos = NULL, *lifePos = NULL;
684
StateMachine(*state) = NULL;
685
686
if (globals->gameMode == MODE_COMPETITION) {
687
state = &self->vsStates[self->screenID];
688
scorePos = &self->vsScorePos[self->screenID];
689
timePos = &self->vsTimePos[self->screenID];
690
ringsPos = &self->vsRingsPos[self->screenID];
691
lifePos = &self->vsLifePos[self->screenID];
692
}
693
else {
694
state = &self->state;
695
scorePos = &self->scorePos;
696
timePos = &self->timePos;
697
ringsPos = &self->ringsPos;
698
lifePos = &self->lifePos;
699
}
700
701
scorePos->x -= TO_FIXED(8);
702
703
if (timePos->x - scorePos->x > TO_FIXED(16))
704
timePos->x -= TO_FIXED(8);
705
706
if (ringsPos->x - timePos->x > TO_FIXED(16))
707
ringsPos->x -= TO_FIXED(8);
708
709
if (lifePos->x - ringsPos->x > TO_FIXED(16))
710
lifePos->x -= TO_FIXED(8);
711
712
if (lifePos->x < -TO_FIXED(80)) {
713
if (globals->gameMode == MODE_COMPETITION) {
714
*state = StateMachine_None;
715
CompSession_DeriveWinner(self->screenID, FINISHTYPE_GAMEOVER);
716
EntityGameOver *gameOver = RSDK_GET_ENTITY(self->screenID + Player->playerCount, GameOver);
717
EntityCompetition *manager = Competition->sessionManager;
718
719
if (!manager || manager->timer) {
720
RSDK.ResetEntity(gameOver, GameOver->classID, INT_TO_VOID(false));
721
gameOver->playerID = self->screenID;
722
}
723
else {
724
RSDK.ResetEntity(gameOver, GameOver->classID, INT_TO_VOID(true));
725
RSDK.SetEngineState(ENGINESTATE_FROZEN);
726
SceneInfo->timeEnabled = false;
727
gameOver->playerID = self->screenID;
728
}
729
}
730
else {
731
destroyEntity(self);
732
}
733
}
734
#else
735
self->scorePos.x -= TO_FIXED(8);
736
737
if (self->timePos.x - self->scorePos.x > TO_FIXED(16))
738
self->timePos.x -= TO_FIXED(8);
739
740
if (self->ringsPos.x - self->timePos.x > TO_FIXED(16))
741
self->ringsPos.x -= TO_FIXED(8);
742
743
if (self->lifePos.x - self->ringsPos.x > TO_FIXED(16))
744
self->lifePos.x -= TO_FIXED(8);
745
746
if (self->lifePos.x < -TO_FIXED(64))
747
destroyEntity(self);
748
#endif
749
}
750
751
void HUD_MoveIn(EntityHUD *hud)
752
{
753
hud->targetPos = hud->scorePos.x;
754
hud->scorePos.x -= TO_FIXED(0x100);
755
hud->timePos.x -= TO_FIXED(0x110);
756
hud->ringsPos.x -= TO_FIXED(0x120);
757
hud->lifePos.x -= TO_FIXED(0x130);
758
hud->state = HUD_State_MoveIn;
759
}
760
761
void HUD_MoveOut(void)
762
{
763
foreach_active(HUD, hud) { hud->state = HUD_State_MoveOut; }
764
}
765
766
void HUD_EnableRingFlash(void)
767
{
768
foreach_all(HUD, hud)
769
{
770
if (hud)
771
hud->enableRingFlash = true;
772
foreach_break;
773
}
774
}
775
776
int32 HUD_CharacterIndexFromID(int32 characterID)
777
{
778
int32 id = -1;
779
for (int32 i = characterID; i > 0; ++id, i >>= 1)
780
;
781
return id;
782
}
783
784
#if GAME_INCLUDE_EDITOR
785
void HUD_EditorDraw(void)
786
{
787
RSDK_THIS(HUD);
788
RSDK.SetSpriteAnimation(HUD->aniFrames, 0, &self->hudElementsAnimator, true, 0);
789
RSDK.DrawSprite(&self->hudElementsAnimator, NULL, false);
790
}
791
792
void HUD_EditorLoad(void) { HUD->aniFrames = RSDK.LoadSpriteAnimation("Editor/EditorIcons.bin", SCOPE_STAGE); }
793
#endif
794
795
void HUD_Serialize(void) {}
796
797