Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/Menu/UIControl.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: UIControl Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectUIControl *UIControl;
11
12
void UIControl_Update(void)
13
{
14
RSDK_THIS(UIControl);
15
16
if (self->buttonID >= 0 && self->buttonID != self->lastButtonID)
17
self->lastButtonID = self->buttonID;
18
19
if (!UIControl->hasTouchInput && self->buttonID == -1)
20
self->buttonID = self->lastButtonID;
21
22
StateMachine_Run(self->state);
23
24
if (self->backoutTimer > 0)
25
self->backoutTimer--;
26
27
StateMachine_Run(self->menuUpdateCB);
28
}
29
30
void UIControl_LateUpdate(void) {}
31
32
void UIControl_StaticUpdate(void)
33
{
34
if (UIControl->lockInput) {
35
UIControl->lockInput = false;
36
UIControl->inputLocked = true;
37
}
38
else {
39
UIControl->inputLocked = false;
40
}
41
42
UIControl->forceBackPress = false;
43
44
++UIControl->timer;
45
UIControl->timer &= 0x7FFF;
46
}
47
48
void UIControl_Draw(void)
49
{
50
RSDK_THIS(UIControl);
51
52
ScreenInfo->position.x = FROM_FIXED(self->position.x) - ScreenInfo->center.x;
53
ScreenInfo->position.y = FROM_FIXED(self->position.y) - ScreenInfo->center.y;
54
}
55
56
void UIControl_Create(void *data)
57
{
58
RSDK_THIS(UIControl);
59
60
if (!SceneInfo->inEditor) {
61
if (data) {
62
Vector2 *size = (Vector2 *)data;
63
self->size.x = size->x;
64
self->size.y = size->y;
65
}
66
67
self->updateRange.x = self->size.x >> 1;
68
self->updateRange.y = self->size.y >> 1;
69
#if MANIA_USE_PLUS
70
self->promptCount = 0;
71
#endif
72
73
if (self->rowCount <= 1)
74
self->rowCount = 1;
75
76
if (self->columnCount <= 1)
77
self->columnCount = 1;
78
79
if (!self->hasStoredButton)
80
self->buttonID = self->startingID;
81
else
82
self->buttonID = self->storedButtonID;
83
84
self->position.x += self->cameraOffset.x;
85
self->position.y += self->cameraOffset.y;
86
self->startPos.x = self->position.x;
87
self->startPos.y = self->position.y;
88
89
#if MANIA_USE_PLUS
90
int32 slotID = RSDK.GetEntitySlot(self);
91
if (UIButtonPrompt && slotID != SLOT_DIALOG_UICONTROL) {
92
foreach_all(UIButtonPrompt, prompt)
93
{
94
if (self->promptCount < UICONTROL_PROMPT_COUNT && UIControl_ContainsPos(self, &prompt->position)) {
95
prompt->parent = (Entity *)self;
96
self->prompts[self->promptCount++] = prompt;
97
}
98
}
99
}
100
#endif
101
102
AnalogStickInfoL[1].deadzone = 0.75f;
103
AnalogStickInfoL[2].deadzone = 0.75f;
104
AnalogStickInfoL[3].deadzone = 0.75f;
105
AnalogStickInfoL[4].deadzone = 0.75f;
106
107
UIControl_SetupButtons();
108
109
if (self->noWidgets) {
110
self->active = ACTIVE_NORMAL;
111
self->visible = true;
112
}
113
else {
114
#if MANIA_USE_PLUS
115
self->menuWasSetup = false;
116
#endif
117
118
if (self->activeOnLoad)
119
UIControl_SetActiveMenu(self);
120
else
121
self->active = ACTIVE_NEVER;
122
}
123
}
124
}
125
126
void UIControl_StageLoad(void)
127
{
128
UIControl->inputLocked = false;
129
UIControl->lockInput = false;
130
UIControl->active = ACTIVE_ALWAYS;
131
UIControl->isProcessingInput = false;
132
}
133
134
EntityUIControl *UIControl_GetUIControl(void)
135
{
136
foreach_all(UIControl, control)
137
{
138
if (control->active == ACTIVE_ALWAYS) {
139
foreach_return control;
140
}
141
}
142
143
return NULL;
144
}
145
146
void UIControl_ClearInputs(uint8 buttonID)
147
{
148
for (int32 i = 0; i < PLAYER_COUNT; ++i) {
149
UIControl->upPress[i] = false;
150
UIControl->downPress[i] = false;
151
UIControl->leftPress[i] = false;
152
UIControl->rightPress[i] = false;
153
UIControl->yPress[i] = false;
154
UIControl->xPress[i] = false;
155
UIControl->backPress[i] = false;
156
UIControl->confirmPress[i] = false;
157
#if MANIA_USE_PLUS
158
UIControl->startPress[i] = false;
159
#endif
160
}
161
162
UIControl->anyUpPress = false;
163
UIControl->anyDownPress = false;
164
UIControl->anyLeftPress = false;
165
UIControl->anyRightPress = false;
166
UIControl->anyYPress = buttonID == UIBUTTONPROMPT_BUTTON_Y;
167
UIControl->anyXPress = buttonID == UIBUTTONPROMPT_BUTTON_X;
168
#if MANIA_USE_PLUS
169
UIControl->anyStartPress = buttonID == UIBUTTONPROMPT_BUTTON_SELECT;
170
#endif
171
172
if (API_GetConfirmButtonFlip()) {
173
UIControl->anyConfirmPress = buttonID == UIBUTTONPROMPT_BUTTON_B;
174
UIControl->anyBackPress = buttonID == UIBUTTONPROMPT_BUTTON_A;
175
UIControl->forceBackPress = buttonID == UIBUTTONPROMPT_BUTTON_A;
176
}
177
else {
178
UIControl->anyConfirmPress = buttonID == UIBUTTONPROMPT_BUTTON_A;
179
UIControl->anyBackPress = buttonID == UIBUTTONPROMPT_BUTTON_B;
180
UIControl->forceBackPress = buttonID == UIBUTTONPROMPT_BUTTON_B;
181
}
182
183
UIControl->lockInput = true;
184
UIControl->inputLocked = true;
185
}
186
187
void UIControl_ProcessInputs(void)
188
{
189
RSDK_THIS(UIControl);
190
191
UIControl_HandlePosition();
192
193
if (!UIControl->inputLocked) {
194
for (int32 i = 0; i < PLAYER_COUNT; ++i) {
195
UIControl->upPress[i] = ControllerInfo[CONT_P1 + i].keyUp.press || AnalogStickInfoL[CONT_P1 + i].keyUp.press;
196
UIControl->downPress[i] = ControllerInfo[CONT_P1 + i].keyDown.press || AnalogStickInfoL[CONT_P1 + i].keyDown.press;
197
UIControl->leftPress[i] = ControllerInfo[CONT_P1 + i].keyLeft.press || AnalogStickInfoL[CONT_P1 + i].keyLeft.press;
198
UIControl->rightPress[i] = ControllerInfo[CONT_P1 + i].keyRight.press || AnalogStickInfoL[CONT_P1 + i].keyRight.press;
199
200
if (UIControl->upPress[i] && UIControl->downPress[i]) {
201
UIControl->upPress[i] = false;
202
UIControl->downPress[i] = false;
203
}
204
205
if (UIControl->leftPress[i] && UIControl->rightPress[i]) {
206
UIControl->leftPress[i] = false;
207
UIControl->rightPress[i] = false;
208
}
209
210
UIControl->yPress[i] = ControllerInfo[CONT_P1 + i].keyY.press;
211
UIControl->xPress[i] = ControllerInfo[CONT_P1 + i].keyX.press;
212
#if MANIA_USE_PLUS
213
UIControl->startPress[i] = ControllerInfo[CONT_P1 + i].keyStart.press;
214
#endif
215
216
UIControl->confirmPress[i] = ControllerInfo[CONT_P1 + i].keyStart.press;
217
if (API_GetConfirmButtonFlip()) {
218
UIControl->confirmPress[i] |= ControllerInfo[CONT_P1 + i].keyB.press;
219
UIControl->backPress[i] = ControllerInfo[CONT_P1 + i].keyA.press;
220
}
221
else {
222
UIControl->confirmPress[i] |= ControllerInfo[CONT_P1 + i].keyA.press;
223
UIControl->backPress[i] = ControllerInfo[CONT_P1 + i].keyB.press;
224
}
225
}
226
227
UIControl->anyUpPress = ControllerInfo->keyUp.press || AnalogStickInfoL->keyUp.press;
228
UIControl->anyDownPress = ControllerInfo->keyDown.press || AnalogStickInfoL->keyDown.press;
229
UIControl->anyLeftPress = ControllerInfo->keyLeft.press || AnalogStickInfoL->keyLeft.press;
230
UIControl->anyRightPress = ControllerInfo->keyRight.press || AnalogStickInfoL->keyRight.press;
231
UIControl->anyYPress = ControllerInfo->keyY.press;
232
UIControl->anyXPress = ControllerInfo->keyX.press;
233
#if MANIA_USE_PLUS
234
UIControl->anyStartPress = ControllerInfo->keyStart.press;
235
#endif
236
237
UIControl->anyConfirmPress = ControllerInfo->keyStart.press;
238
if (API_GetConfirmButtonFlip()) {
239
UIControl->anyConfirmPress |= ControllerInfo->keyB.press;
240
UIControl->anyBackPress = ControllerInfo->keyA.press;
241
}
242
else {
243
UIControl->anyConfirmPress |= ControllerInfo->keyA.press;
244
UIControl->anyBackPress = ControllerInfo->keyB.press;
245
}
246
247
UIControl->anyBackPress |= Unknown_pausePress;
248
UIControl->anyBackPress |= UIControl->forceBackPress;
249
250
if (UIControl->anyBackPress) {
251
UIControl->anyConfirmPress = false;
252
UIControl->anyYPress = false;
253
}
254
255
if (UIControl->anyConfirmPress) {
256
UIControl->anyYPress = false;
257
}
258
259
UIControl->inputLocked = true;
260
}
261
262
if (!self->selectionDisabled) {
263
bool32 backPressed = false;
264
265
if (UIControl->anyBackPress) {
266
if (!self->childHasFocus && !self->dialogHasFocus
267
#if MANIA_USE_PLUS
268
&& !self->popoverHasFocus
269
#endif
270
&& self->backoutTimer <= 0) {
271
if (self->backPressCB) {
272
backPressed = self->backPressCB();
273
274
if (!backPressed) {
275
UIControl->anyBackPress = false;
276
}
277
else {
278
if (self->buttons[self->buttonID])
279
self->buttons[self->buttonID]->isSelected = false;
280
}
281
}
282
else {
283
if (self->parentTag.length <= 0) {
284
UIControl->anyBackPress = false;
285
}
286
else {
287
self->selectionDisabled = true;
288
UITransition_StartTransition(UIControl_ReturnToParentMenu, 0);
289
backPressed = false;
290
291
if (self->buttons[self->buttonID])
292
self->buttons[self->buttonID]->isSelected = false;
293
}
294
}
295
296
if (backPressed)
297
return;
298
}
299
#if MANIA_USE_PLUS
300
else {
301
LogHelpers_Print("Backout prevented");
302
LogHelpers_Print("childHasFocus = %d", self->childHasFocus);
303
LogHelpers_Print("dialogHasFocus = %d", self->dialogHasFocus);
304
LogHelpers_Print("popoverHasFocus = %d", self->popoverHasFocus);
305
LogHelpers_Print("backoutTimer = %d", self->backoutTimer);
306
}
307
#endif
308
}
309
310
if (self->processButtonInputCB) {
311
StateMachine_Run(self->processButtonInputCB);
312
}
313
else
314
UIControl_ProcessButtonInput();
315
316
if (!self->selectionDisabled) {
317
if (UIControl->anyYPress) {
318
if (!self->childHasFocus && !self->dialogHasFocus
319
#if MANIA_USE_PLUS
320
&& !self->popoverHasFocus
321
#endif
322
&& self->backoutTimer <= 0) {
323
StateMachine_Run(self->yPressCB);
324
}
325
326
UIControl->anyYPress = false;
327
}
328
329
if (UIControl->anyXPress) {
330
if (!self->childHasFocus && !self->dialogHasFocus
331
#if MANIA_USE_PLUS
332
&& !self->popoverHasFocus
333
#endif
334
&& self->backoutTimer <= 0) {
335
StateMachine_Run(self->xPressCB);
336
}
337
338
UIControl->anyXPress = false;
339
}
340
}
341
}
342
}
343
344
int32 UIControl_GetButtonID(EntityUIControl *control, EntityUIButton *entity)
345
{
346
for (int32 i = 0; i < control->buttonCount; ++i) {
347
if (entity == control->buttons[i])
348
return i;
349
}
350
351
return -1;
352
}
353
354
void UIControl_MenuChangeButtonInit(EntityUIControl *control)
355
{
356
Entity *storeEntity = SceneInfo->entity;
357
for (int32 i = 0; i < SCENEENTITY_COUNT; ++i) {
358
EntityUIButton *entity = RSDK_GET_ENTITY(i, UIButton);
359
360
if (entity) {
361
int32 left = MIN(-ScreenInfo->size.x >> 1, ScreenInfo->size.x >> 1) << 16;
362
int32 right = MAX(-ScreenInfo->size.x >> 1, ScreenInfo->size.x >> 1) << 16;
363
int32 top = MIN(-ScreenInfo->size.y >> 1, ScreenInfo->size.y >> 1) << 16;
364
int32 bottom = MAX(-ScreenInfo->size.y >> 1, ScreenInfo->size.y >> 1) << 16;
365
366
if (entity->position.x >= control->position.x + left && entity->position.x <= control->position.x + right) {
367
if (entity->position.y >= control->position.y + top && entity->position.y <= control->position.y + bottom) {
368
int32 slot = RSDK.GetEntitySlot(entity);
369
370
SceneInfo->entity = (Entity *)entity;
371
if (UIButton && entity->classID == UIButton->classID) {
372
UIButton_ManageChoices(entity);
373
UIButton_Update();
374
}
375
else if (UIChoice && entity->classID == UIChoice->classID) {
376
UIChoice_Update();
377
}
378
else if (UITAZoneModule && entity->classID == UITAZoneModule->classID) {
379
UITAZoneModule_Update();
380
}
381
#if MANIA_USE_PLUS
382
else if (UIReplayCarousel && entity->classID == UIReplayCarousel->classID) {
383
UIReplayCarousel_Update();
384
}
385
#endif
386
else if (UIModeButton && entity->classID == UIModeButton->classID) {
387
#if MANIA_USE_PLUS
388
UIModeButton_Update();
389
#else
390
EntityUIModeButton *modeButton = (EntityUIModeButton *)SceneInfo->entity;
391
modeButton->touchPosSizeS.x = 0xB80000;
392
modeButton->touchPosSizeS.y = 0x3E0000;
393
modeButton->touchPosOffsetS.x = 0;
394
modeButton->touchPosOffsetS.y = -0x120000;
395
if (modeButton->textFrames != UIWidgets->textFrames || modeButton->wasDisabled != modeButton->disabled) {
396
UIModeButton_SetupSprites();
397
modeButton->textFrames = UIWidgets->textFrames;
398
modeButton->wasDisabled = modeButton->disabled;
399
}
400
#endif
401
}
402
else if (UIVsZoneButton && entity->classID == UIVsZoneButton->classID) {
403
UIVsZoneButton_Update();
404
}
405
else if (UIHeading && entity->classID == UIHeading->classID) {
406
UIHeading_Update();
407
}
408
409
if (entity->visible)
410
RSDK.AddDrawListRef(entity->drawGroup, slot);
411
412
SceneInfo->entity = storeEntity;
413
}
414
}
415
}
416
}
417
}
418
419
#if MANIA_USE_PLUS
420
void UIControl_SetActiveMenuButtonPrompts(EntityUIControl *entity)
421
{
422
for (int32 i = 0; i < entity->promptCount; ++i) entity->prompts[i]->active = ACTIVE_NORMAL;
423
}
424
#endif
425
426
void UIControl_SetActiveMenu(EntityUIControl *entity)
427
{
428
#if MANIA_USE_PLUS
429
LogHelpers_PrintString(&entity->tag);
430
#endif
431
432
entity->active = ACTIVE_ALWAYS;
433
entity->visible = true;
434
435
if (entity->hasStoredButton) {
436
entity->buttonID = entity->storedButtonID;
437
entity->storedButtonID = 0;
438
entity->hasStoredButton = false;
439
}
440
else if (entity->resetSelection) {
441
entity->buttonID = entity->startingID;
442
}
443
444
RSDK.ClearCameras();
445
RSDK.AddCamera(&entity->position, ScreenInfo->size.x << 16, ScreenInfo->size.y << 16, true);
446
447
UIControl_MenuChangeButtonInit(entity);
448
449
#if MANIA_USE_PLUS
450
if (!entity->childHasFocus && (entity->resetSelection || !entity->menuWasSetup)) {
451
#else
452
if (!entity->childHasFocus) {
453
#endif
454
entity->position.x = entity->startPos.x;
455
entity->position.y = entity->startPos.y;
456
entity->targetPos.x = entity->startPos.x;
457
entity->targetPos.y = entity->startPos.y;
458
}
459
460
entity->state = UIControl_ProcessInputs;
461
entity->childHasFocus = false;
462
463
#if MANIA_USE_PLUS
464
entity->menuWasSetup = true;
465
466
for (int32 p = 0; p < entity->promptCount; ++p) entity->prompts[p]->active = ACTIVE_NORMAL;
467
#endif
468
469
if (entity->menuSetupCB) {
470
Entity *storeEntity = SceneInfo->entity;
471
SceneInfo->entity = (Entity *)entity;
472
#if RETRO_USE_MOD_LOADER
473
StateMachine_Run(entity->menuSetupCB);
474
#else
475
entity->menuSetupCB();
476
#endif
477
SceneInfo->entity = storeEntity;
478
}
479
}
480
481
void UIControl_SetMenuLostFocus(EntityUIControl *entity)
482
{
483
entity->active = ACTIVE_ALWAYS;
484
entity->visible = true;
485
486
if (!entity->dialogHasFocus && !entity->childHasFocus
487
#if MANIA_USE_PLUS
488
&& !entity->popoverHasFocus
489
#endif
490
) {
491
if (entity->hasStoredButton) {
492
entity->buttonID = entity->storedButtonID;
493
entity->storedButtonID = 0;
494
entity->hasStoredButton = false;
495
}
496
else if (entity->resetSelection) {
497
entity->buttonID = entity->startingID;
498
#if !MANIA_USE_PLUS
499
entity->position.x = entity->startPos.x;
500
entity->position.y = entity->startPos.y;
501
entity->targetPos.x = entity->startPos.x;
502
entity->targetPos.y = entity->startPos.y;
503
entity->state = UIControl_ProcessInputs;
504
#endif
505
}
506
507
#if MANIA_USE_PLUS
508
if (entity->resetSelection || !entity->menuWasSetup) {
509
entity->position.x = entity->startPos.x;
510
entity->position.y = entity->startPos.y;
511
entity->targetPos.x = entity->startPos.x;
512
entity->targetPos.y = entity->startPos.y;
513
}
514
515
entity->menuWasSetup = true;
516
UIControl_SetActiveMenuButtonPrompts(entity);
517
#endif
518
entity->state = UIControl_ProcessInputs;
519
}
520
}
521
522
void UIControl_SetInactiveMenu(EntityUIControl *control)
523
{
524
UIControl->hasTouchInput = false;
525
control->active = ACTIVE_NEVER;
526
control->visible = false;
527
control->state = StateMachine_None;
528
529
#if MANIA_USE_PLUS
530
RSDK_THIS(UIControl);
531
532
if (self->promptCount) {
533
for (int32 p = 0; p < control->promptCount; ++p) control->prompts[p]->active = ACTIVE_BOUNDS;
534
}
535
#endif
536
}
537
538
void UIControl_SetupButtons(void)
539
{
540
RSDK_THIS(UIControl);
541
542
int32 slotID = RSDK.GetEntitySlot(self);
543
544
if (UIHeading && slotID != SLOT_DIALOG_UICONTROL) {
545
foreach_all(UIHeading, heading)
546
{
547
if (UIControl_ContainsPos(self, &heading->position))
548
self->heading = heading;
549
}
550
}
551
552
#if MANIA_USE_PLUS
553
if (UIShifter && slotID != SLOT_DIALOG_UICONTROL) {
554
foreach_all(UIShifter, shifter)
555
{
556
if (UIControl_ContainsPos(self, &shifter->position)) {
557
self->shifter = shifter;
558
shifter->parent = self;
559
}
560
}
561
}
562
563
if (UICarousel && slotID != SLOT_DIALOG_UICONTROL) {
564
foreach_all(UICarousel, carousel)
565
{
566
if (UIControl_ContainsPos(self, &carousel->position)) {
567
self->carousel = carousel;
568
carousel->parent = self;
569
}
570
}
571
}
572
#endif
573
574
for (int32 i = 0; i < SCENEENTITY_COUNT; ++i) {
575
EntityUIButton *button = RSDK_GET_ENTITY(i, UIButton);
576
577
if (button) {
578
int32 classID = button->classID;
579
if (classID != UIButton->classID && (!UIModeButton || classID != UIModeButton->classID) && (!UISaveSlot || classID != UISaveSlot->classID)
580
&& (!UICharButton || classID != UICharButton->classID) && (!UITAZoneModule || classID != UITAZoneModule->classID)
581
#if MANIA_USE_PLUS
582
&& (!UIRankButton || classID != UIRankButton->classID) && (!UIReplayCarousel || classID != UIReplayCarousel->classID)
583
#endif
584
&& (!UILeaderboard || classID != UILeaderboard->classID) && (!UIVsCharSelector || classID != UIVsCharSelector->classID)
585
&& (!UIVsZoneButton || classID != UIVsZoneButton->classID) && (!UIVsResults || classID != UIVsResults->classID)
586
&& (!UISlider || classID != UISlider->classID) && (!UIKeyBinder || classID != UIKeyBinder->classID)) {
587
}
588
else {
589
if (self->buttonCount < UICONTROL_BUTTON_COUNT && UIControl_ContainsPos(self, &button->position)) {
590
if (!button->parent)
591
button->parent = (Entity *)self;
592
593
self->buttons[self->buttonCount++] = button;
594
}
595
}
596
}
597
}
598
}
599
600
bool32 UIControl_isMoving(EntityUIControl *entity)
601
{
602
if (entity->scrollSpeed.x && entity->scrollSpeed.y) {
603
return entity->position.x != entity->targetPos.x || entity->position.y != entity->targetPos.y;
604
}
605
else {
606
if (entity->scrollSpeed.x) {
607
return entity->position.x != entity->targetPos.x;
608
}
609
else if (entity->scrollSpeed.y) {
610
return entity->position.y != entity->targetPos.y;
611
}
612
}
613
614
return false;
615
}
616
617
void UIControl_MatchMenuTag(const char *text)
618
{
619
String string;
620
INIT_STRING(string);
621
622
RSDK.SetString(&string, text);
623
foreach_all(UIControl, entity)
624
{
625
if (entity->active == ACTIVE_ALWAYS || !RSDK.CompareStrings(&string, &entity->tag, false))
626
UIControl_SetInactiveMenu(entity);
627
else
628
UIControl_SetActiveMenu(entity);
629
}
630
}
631
632
void UIControl_HandleMenuChange(String *newMenuTag)
633
{
634
if (newMenuTag->length) {
635
foreach_all(UIControl, entity)
636
{
637
if (entity->active == ACTIVE_ALWAYS || !RSDK.CompareStrings(newMenuTag, &entity->tag, false))
638
UIControl_SetInactiveMenu(entity);
639
else
640
UIControl_SetActiveMenu(entity);
641
}
642
}
643
}
644
645
void UIControl_HandleMenuLoseFocus(EntityUIControl *parent)
646
{
647
foreach_all(UIControl, entity)
648
{
649
if (entity->active == ACTIVE_ALWAYS || entity != parent)
650
UIControl_SetInactiveMenu(entity);
651
else
652
UIControl_SetMenuLostFocus(entity);
653
}
654
}
655
656
void UIControl_ReturnToParentMenu(void)
657
{
658
EntityUIControl *entity = UIControl_GetUIControl();
659
entity->selectionDisabled = false;
660
661
UIControl_HandleMenuChange(&entity->parentTag);
662
}
663
664
#if MANIA_USE_PLUS
665
void UIControl_SetTargetPos(EntityUIControl *entity, int32 x, int32 y)
666
{
667
int32 targetX = x;
668
if (!x) {
669
targetX = entity->position.x;
670
x = entity->position.x;
671
}
672
673
int32 targetY = y;
674
if (!y) {
675
targetY = entity->position.y;
676
y = entity->position.y;
677
}
678
679
if (!entity->noClamp) {
680
int32 startX = entity->startPos.x - entity->cameraOffset.x;
681
int32 startY = entity->startPos.y - entity->cameraOffset.y;
682
int32 x1 = startX + (ScreenInfo->size.x << 15) - (entity->size.x >> 1);
683
int32 x2 = startX + (entity->size.x >> 1) - (ScreenInfo->size.x << 15);
684
int32 y1 = startY + (ScreenInfo->size.y << 15) - (entity->size.y >> 1);
685
int32 y2 = startY + (entity->size.y >> 1) - (ScreenInfo->size.y << 15);
686
687
if (x < x2)
688
x2 = x;
689
targetX = x2;
690
691
if (x1 > x2)
692
targetX = x1;
693
694
if (y < y2)
695
y2 = y;
696
targetY = y2;
697
698
if (y1 > y2)
699
targetY = y1;
700
}
701
702
entity->targetPos.x = targetX;
703
entity->targetPos.y = targetY;
704
}
705
#endif
706
707
void UIControl_HandlePosition(void)
708
{
709
RSDK_THIS(UIControl);
710
711
if (self->position.x < self->targetPos.x) {
712
self->position.x += self->scrollSpeed.x;
713
if (self->position.x > self->targetPos.x)
714
self->position.x = self->targetPos.x;
715
}
716
else if (self->position.x > self->targetPos.x) {
717
self->position.x -= self->scrollSpeed.x;
718
if (self->position.x < self->targetPos.x)
719
self->position.x = self->targetPos.x;
720
}
721
722
if (self->position.y < self->targetPos.y) {
723
self->position.y += self->scrollSpeed.y;
724
if (self->position.y > self->targetPos.y)
725
self->position.y = self->targetPos.y;
726
}
727
else if (self->position.y > self->targetPos.y) {
728
self->position.y -= self->scrollSpeed.y;
729
if (self->position.y < self->targetPos.y)
730
self->position.y = self->targetPos.y;
731
}
732
733
if (self->heading)
734
self->heading->position.x = self->position.x;
735
}
736
737
void UIControl_ProcessButtonInput(void)
738
{
739
RSDK_THIS(UIControl);
740
741
bool32 allowAction = false;
742
if (TouchInfo->count || UIControl->hasTouchInput) {
743
EntityUIButton *activeButton = 0;
744
UIControl->hasTouchInput = TouchInfo->count != 0;
745
UIControl->isProcessingInput = true;
746
747
for (int32 i = 0; i < self->buttonCount; ++i) {
748
if (self->buttons[i]) {
749
EntityUIButton *button = self->buttons[i];
750
751
Entity *storeEntity = SceneInfo->entity;
752
SceneInfo->entity = (Entity *)button;
753
if (button->touchCB && !self->dialogHasFocus
754
#if MANIA_USE_PLUS
755
&& !self->popoverHasFocus
756
#endif
757
) {
758
if (!button->checkSelectedCB || !button->checkSelectedCB()) {
759
bool32 wasTouched = button->touchCB();
760
if (allowAction || wasTouched) {
761
allowAction = true;
762
if (button->touchCB && !activeButton)
763
activeButton = button;
764
}
765
else {
766
allowAction = false;
767
}
768
}
769
}
770
771
SceneInfo->entity = storeEntity;
772
}
773
}
774
775
if (TouchInfo->count) {
776
if (allowAction) {
777
int32 id = -1;
778
779
for (int32 i = 0; i < self->buttonCount; ++i) {
780
if (activeButton == self->buttons[i]) {
781
id = i;
782
break;
783
}
784
}
785
786
self->buttonID = id;
787
if (activeButton->isSelected) {
788
Entity *storeEntity = SceneInfo->entity;
789
SceneInfo->entity = (Entity *)activeButton;
790
activeButton->isSelected = true;
791
StateMachine_Run(activeButton->buttonEnterCB);
792
SceneInfo->entity = storeEntity;
793
}
794
}
795
else {
796
self->buttonID = -1;
797
}
798
}
799
800
UIControl->isProcessingInput = false;
801
}
802
803
if (self->buttonID >= 0) {
804
if (self->buttonID < self->buttonCount) {
805
EntityUIButton *button = self->buttons[self->buttonID];
806
807
if (button) {
808
Entity *storeEntity = SceneInfo->entity;
809
SceneInfo->entity = (Entity *)button;
810
if (button->processButtonCB) {
811
if (!button->checkSelectedCB || !button->checkSelectedCB()) {
812
#if RETRO_USE_MOD_LOADER
813
StateMachine_Run(button->processButtonCB);
814
#else
815
button->processButtonCB();
816
#endif
817
}
818
}
819
SceneInfo->entity = storeEntity;
820
}
821
}
822
}
823
}
824
825
bool32 UIControl_ContainsPos(EntityUIControl *control, Vector2 *pos) {
826
int32 x = control->startPos.x - control->cameraOffset.x;
827
int32 y = control->startPos.y - control->cameraOffset.y;
828
829
Hitbox hitbox;
830
hitbox.top = -(control->size.y >> 17);
831
hitbox.left = -(control->size.x >> 17);
832
hitbox.right = control->size.x >> 17;
833
hitbox.bottom = control->size.y >> 17;
834
835
if (MathHelpers_PointInHitbox(x, y, pos->x, pos->y, FLIP_NONE, &hitbox))
836
return true;
837
838
return false;
839
}
840
841
#if GAME_INCLUDE_EDITOR
842
void UIControl_EditorDraw(void)
843
{
844
RSDK_THIS(UIControl);
845
846
self->updateRange.x = self->size.x >> 1;
847
self->updateRange.y = self->size.y >> 1;
848
849
DrawHelpers_DrawRectOutline(self->position.x, self->position.y, self->size.x, self->size.y, 0xFFFF00);
850
851
Animator animator;
852
RSDK.SetSpriteAnimation(UIControl->aniFrames, 0, &animator, false, 7);
853
RSDK.DrawSprite(&animator, NULL, false);
854
}
855
856
void UIControl_EditorLoad(void) { UIControl->aniFrames = RSDK.LoadSpriteAnimation("Editor/EditorIcons.bin", SCOPE_STAGE); }
857
#endif
858
859
void UIControl_Serialize(void)
860
{
861
RSDK_EDITABLE_VAR(UIControl, VAR_STRING, tag);
862
RSDK_EDITABLE_VAR(UIControl, VAR_STRING, parentTag);
863
RSDK_EDITABLE_VAR(UIControl, VAR_BOOL, activeOnLoad);
864
RSDK_EDITABLE_VAR(UIControl, VAR_BOOL, noWidgets);
865
RSDK_EDITABLE_VAR(UIControl, VAR_BOOL, resetSelection);
866
RSDK_EDITABLE_VAR(UIControl, VAR_UINT8, rowCount);
867
RSDK_EDITABLE_VAR(UIControl, VAR_UINT8, columnCount);
868
RSDK_EDITABLE_VAR(UIControl, VAR_UINT8, startingID);
869
RSDK_EDITABLE_VAR(UIControl, VAR_VECTOR2, size);
870
RSDK_EDITABLE_VAR(UIControl, VAR_VECTOR2, cameraOffset);
871
RSDK_EDITABLE_VAR(UIControl, VAR_VECTOR2, scrollSpeed);
872
#if MANIA_USE_PLUS
873
RSDK_EDITABLE_VAR(UIControl, VAR_BOOL, noClamp);
874
RSDK_EDITABLE_VAR(UIControl, VAR_BOOL, noWrap);
875
#endif
876
}
877
878