Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/Menu/UIDialog.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: UIDialog Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectUIDialog *UIDialog;
11
12
void UIDialog_Update(void)
13
{
14
RSDK_THIS(UIDialog);
15
16
StateMachine_Run(self->state);
17
18
UIDialog_HandleButtonPositions();
19
20
if (self->closeDelay > 0) {
21
if (!--self->closeDelay)
22
UIDialog_HandleAutoClose();
23
}
24
}
25
26
void UIDialog_LateUpdate(void) {}
27
28
void UIDialog_StaticUpdate(void) {}
29
30
void UIDialog_Draw(void)
31
{
32
RSDK_THIS(UIDialog);
33
34
UIDialog_DrawBGShapes();
35
36
Vector2 drawPos;
37
switch (self->lineCount) {
38
case 0:
39
case 1:
40
drawPos.x = (self->position.x + 0x100000) + 0x100000;
41
drawPos.y = self->position.y - 0x200000;
42
break;
43
44
case 2:
45
drawPos.x = (self->position.x + 0x100000) + 0x180000;
46
drawPos.y = self->position.y - 0x280000;
47
break;
48
49
case 3:
50
drawPos.x = (self->position.x + 0x100000) + 0x200000;
51
drawPos.y = self->position.y - 0x300000;
52
break;
53
54
default: break;
55
}
56
57
drawPos.x += self->dialogPos.x;
58
drawPos.y += self->dialogPos.y;
59
60
int32 w = 0;
61
int32 count = self->lineCount + 1;
62
if (count > 0) {
63
for (int32 i = 0; i < count; ++i) {
64
int32 start = !i ? 0 : self->lineLength[i - 1] + 1;
65
int32 len = i >= self->lineCount ? self->textInfo.length : self->lineLength[i];
66
67
int32 width = RSDK.GetStringWidth(UIWidgets->fontFrames, 0, &self->textInfo, start, len, 0);
68
if (width > w)
69
w = width;
70
}
71
}
72
73
for (int32 i = 0; i < count; ++i) {
74
int32 offset = -0x8000 * w;
75
76
int32 start = !i ? 0 : self->lineLength[i - 1] + 1;
77
int32 len = i >= self->lineCount ? self->textInfo.length : self->lineLength[i];
78
79
RSDK.GetStringWidth(UIWidgets->fontFrames, 0, &self->textInfo, start, len, 0);
80
81
drawPos.x += offset;
82
RSDK.DrawText(&self->animator, &drawPos, &self->textInfo, start, len, 0, 0, NULL, NULL, false);
83
84
drawPos.y += 0x120000;
85
drawPos.x = drawPos.x - offset - 0x120000;
86
}
87
}
88
89
void UIDialog_Create(void *data)
90
{
91
RSDK_THIS(UIDialog);
92
93
self->active = ACTIVE_ALWAYS;
94
self->drawGroup = 15;
95
self->visible = true;
96
97
if (data)
98
UIDialog_SetupText(self, data);
99
100
self->buttonCount = 0;
101
}
102
103
void UIDialog_StageLoad(void)
104
{
105
UIDialog->controlStore = NULL;
106
UIDialog->activeDialog = NULL;
107
}
108
109
EntityUIDialog *UIDialog_CreateActiveDialog(String *msg)
110
{
111
if (UIDialog->activeDialog) {
112
LogHelpers_Print("EXCEPTION: Called CreateDialog when an activeDialog already existed.");
113
}
114
else {
115
int32 id = RSDK_GET_ENTITY(SLOT_DIALOG, UIDialog)->classID;
116
117
if (id) {
118
LogHelpers_Print("Can't create UIDialog (%d), entity already exists in slot (class ID: %d)", UIDialog->classID, id);
119
}
120
else {
121
RSDK.ResetEntitySlot(SLOT_DIALOG, UIDialog->classID, msg);
122
123
EntityUIDialog *dialog = RSDK_GET_ENTITY(SLOT_DIALOG, UIDialog);
124
dialog->position.x = (ScreenInfo->position.x + ScreenInfo->center.x) << 16;
125
dialog->position.y = (ScreenInfo->position.y + ScreenInfo->center.y) << 16;
126
UIDialog->activeDialog = dialog;
127
128
return dialog;
129
}
130
}
131
132
return NULL;
133
}
134
135
void UIDialog_SetupText(EntityUIDialog *dialog, String *text)
136
{
137
if (text) {
138
dialog->lineCount = 0;
139
int32 charPos = 0;
140
141
for (int32 i = 0; i < text->length; ++i) {
142
if (text->chars[charPos] == '\n' && dialog->lineCount < 3) {
143
dialog->lineLength[dialog->lineCount] = charPos;
144
++dialog->lineCount;
145
}
146
147
++charPos;
148
}
149
150
RSDK.CopyString(&dialog->textInfo, text);
151
RSDK.SetSpriteAnimation(UIWidgets->fontFrames, 0, &dialog->animator, true, 0);
152
RSDK.SetSpriteString(UIWidgets->fontFrames, 0, &dialog->textInfo);
153
}
154
}
155
156
void UIDialog_AddButton(uint8 frame, EntityUIDialog *dialog, void (*callback)(void), bool32 closeOnSelect)
157
{
158
int32 id = dialog->buttonCount;
159
160
if (dialog->buttonCount < UIDIALOG_OPTION_COUNT) {
161
dialog->buttonFrames[dialog->buttonCount] = frame;
162
dialog->callbacks[dialog->buttonCount] = callback;
163
dialog->closeOnSelect[dialog->buttonCount] = closeOnSelect;
164
165
RSDK.ResetEntitySlot(SLOT_DIALOG_BUTTONS + dialog->buttonCount, UIButton->classID, NULL);
166
167
EntityUIButton *button = RSDK_GET_ENTITY(SLOT_DIALOG_BUTTONS + dialog->buttonCount, UIButton);
168
button->position.x = (ScreenInfo->position.x + ScreenInfo->center.x) << 16;
169
button->position.y = (ScreenInfo->position.y + ScreenInfo->center.y) << 16;
170
RSDK.SetSpriteAnimation(UIWidgets->textFrames, 9, &button->animator, true, frame);
171
button->textFrames = UIWidgets->textFrames;
172
173
if (frame == DIALOG_CONTINUE)
174
button->size.x = 0x640000;
175
else
176
button->size.x = 0x320000;
177
button->size.y = 0x180000;
178
button->actionCB = UIDialog_ButtonActionCB;
179
button->bgEdgeSize = 24;
180
button->align = UIBUTTON_ALIGN_CENTER;
181
button->active = ACTIVE_ALWAYS;
182
button->drawGroup = dialog->drawGroup;
183
dialog->buttons[dialog->buttonCount++] = button;
184
185
EntityUIControl *parent = dialog->parent;
186
if (parent) {
187
button->parent = (Entity *)parent;
188
parent->buttons[id] = button;
189
parent->buttonCount = dialog->buttonCount;
190
}
191
}
192
}
193
194
void UIDialog_Setup(EntityUIDialog *dialog)
195
{
196
if (dialog) {
197
bool32 tookFocus = false;
198
199
Vector2 size;
200
size.x = ScreenInfo->size.x << 16;
201
size.y = ScreenInfo->size.y << 16;
202
foreach_all(UIControl, control)
203
{
204
if (control->active == ACTIVE_ALWAYS) {
205
tookFocus = true;
206
control->dialogHasFocus = true;
207
UIDialog->controlStore = control;
208
UIDialog->controlStateStore = control->state;
209
foreach_break;
210
}
211
}
212
213
control = NULL;
214
RSDK.ResetEntitySlot(SLOT_DIALOG_UICONTROL, UIControl->classID, &size);
215
216
control = RSDK_GET_ENTITY(SLOT_DIALOG_UICONTROL, UIControl);
217
#if MANIA_USE_PLUS
218
control->menuWasSetup = true;
219
#endif
220
control->position.x = (ScreenInfo->position.x + ScreenInfo->center.x) << 16;
221
control->position.y = (ScreenInfo->position.y + ScreenInfo->center.y) << 16;
222
control->rowCount = 1;
223
control->columnCount = dialog->buttonCount;
224
control->buttonID = 0;
225
control->backPressCB = UIDialog_HandleAutoClose;
226
control->selectionDisabled = true;
227
228
dialog->parent = control;
229
if (!tookFocus) {
230
UIDialog->controlStore = NULL;
231
UIDialog->controlStateStore = StateMachine_None;
232
}
233
234
int32 i = 0;
235
for (; i < UIDIALOG_OPTION_COUNT; ++i) {
236
if (!dialog->buttons[i])
237
break;
238
239
dialog->buttons[i]->parent = (Entity *)control;
240
control->buttons[i] = dialog->buttons[i];
241
}
242
243
control->buttonCount = i;
244
dialog->timer = 0;
245
dialog->state = UIDialog_State_Appear;
246
}
247
}
248
249
void UIDialog_CloseOnSel_HandleSelection(EntityUIDialog *dialog, void (*callback)(void))
250
{
251
if (dialog && dialog->state != UIDialog_State_Close) {
252
dialog->parent->selectionDisabled = true;
253
dialog->timer = 0;
254
dialog->state = UIDialog_State_Close;
255
dialog->closeCB = callback;
256
}
257
}
258
259
void UIDialog_DrawBGShapes(void)
260
{
261
RSDK_THIS(UIDialog);
262
263
RSDK.DrawRect(((ScreenInfo->position.x + ScreenInfo->center.x) << 16) - (self->bgRectSize.x >> 1),
264
((ScreenInfo->position.y + ScreenInfo->center.y) << 16) - (self->bgRectSize.y >> 1), self->bgRectSize.x, self->bgRectSize.y,
265
self->useAltColor ? 0x282028 : 0x000000, 0xFF, INK_NONE, false);
266
267
UIWidgets_DrawParallelogram(self->dialogPos.x + ((ScreenInfo->position.x + ScreenInfo->center.x) << 16),
268
self->dialogPos.y + ((ScreenInfo->position.y + ScreenInfo->center.y) << 16), 0xC8, 0x8F, 0x8F, 0x30, 0xA0, 0xF0);
269
}
270
271
void UIDialog_HandleButtonPositions(void)
272
{
273
RSDK_THIS(UIDialog);
274
275
int32 offsets[] = { 0, 0, 0x80, 0x70 };
276
277
int32 offset = offsets[self->buttonCount] << 16;
278
int32 x = self->position.x - 0x240000 + self->dialogPos.x - ((offset * MAX(self->buttonCount - 1, 0)) >> 1);
279
int32 y = self->position.y + 0x2C0000 + self->dialogPos.y;
280
281
for (int32 i = 0; i < UIDIALOG_OPTION_COUNT; ++i) {
282
if (!self->buttons[i])
283
break;
284
285
EntityUIButton *button = self->buttons[i];
286
button->startPos.x = x;
287
button->startPos.y = y;
288
button->position.x = x;
289
button->position.y = y;
290
291
x += offset;
292
}
293
}
294
295
void UIDialog_Close(void)
296
{
297
RSDK_THIS(UIDialog);
298
299
EntityUIControl *control = self->parent;
300
301
if (control) {
302
UIControl_SetInactiveMenu(control);
303
destroyEntity(control);
304
}
305
306
for (int32 i = 0; i < UIDIALOG_OPTION_COUNT; ++i) {
307
if (self->buttons[i])
308
destroyEntity(self->buttons[i]);
309
}
310
311
EntityUIControl *storedControl = UIDialog->controlStore;
312
if (storedControl) {
313
UIControl_SetMenuLostFocus(UIDialog->controlStore);
314
storedControl->state = UIDialog->controlStateStore;
315
storedControl->dialogHasFocus = false;
316
}
317
318
UIDialog->controlStore = NULL;
319
UIDialog->controlStateStore = StateMachine_None;
320
UIDialog->activeDialog = NULL;
321
322
StateMachine_Run(self->closeCB);
323
destroyEntity(self);
324
}
325
326
bool32 UIDialog_HandleAutoClose(void)
327
{
328
EntityUIDialog *entity = UIDialog->activeDialog;
329
EntityUIControl *control = entity->parent;
330
331
for (int32 i = 0; i < control->buttonCount; ++i) {
332
int32 frame = entity->buttonFrames[i];
333
if (frame == DIALOG_NO || frame == DIALOG_CANCEL) {
334
if (entity->closeOnSelect[i]) {
335
UIDialog_CloseOnSel_HandleSelection(entity, entity->callbacks[i]);
336
}
337
else {
338
StateMachine_Run(entity->callbacks[i]);
339
}
340
341
return true;
342
}
343
}
344
345
return false;
346
}
347
348
void UIDialog_ButtonActionCB(void)
349
{
350
EntityUIDialog *entity = UIDialog->activeDialog;
351
352
if (entity->parent) {
353
int32 id = entity->parent->buttonID;
354
355
if (id >= 0 && id < entity->parent->buttonCount) {
356
if (entity->closeOnSelect[id]) {
357
UIDialog_CloseOnSel_HandleSelection(entity, entity->callbacks[id]);
358
}
359
else {
360
StateMachine_Run(entity->callbacks[id]);
361
}
362
}
363
}
364
}
365
366
void UIDialog_State_Appear(void)
367
{
368
RSDK_THIS(UIDialog);
369
370
Vector2 pos;
371
pos.x = 0;
372
pos.y = 0;
373
374
if (self->timer == 1) {
375
RSDK.PlaySfx(UIWidgets->sfxWoosh, false, 255);
376
UIControl_HandleMenuLoseFocus(self->parent);
377
}
378
379
if (self->timer >= 8) {
380
if (self->timer >= 16) {
381
if (self->timer >= 26) {
382
self->parent->selectionDisabled = false;
383
self->timer = 0;
384
self->state = UIDialog_State_Idle;
385
}
386
else {
387
self->bgRectSize.x = ScreenInfo->size.x << 16;
388
self->bgRectSize.y = 0x900000;
389
MathHelpers_Lerp2Sin1024(&pos, MAX(((self->timer - 16) << 8) / 10, 0), -0x400000 - (ScreenInfo->size.x << 16), 0, 0, 0);
390
self->dialogPos = pos;
391
392
if (self->timer - 16 == 1 && self->playEventSfx)
393
RSDK.PlaySfx(UIWidgets->sfxEvent, false, 255);
394
395
++self->timer;
396
}
397
}
398
else {
399
self->dialogPos.x = -0x400000 - (ScreenInfo->size.x << 16);
400
self->dialogPos.y = 0;
401
MathHelpers_Lerp(&pos, MAX(((self->timer - 8) << 8) / 8, 0), ScreenInfo->size.x << 16, 0x10000, ScreenInfo->size.x << 16, 0x900000);
402
self->bgRectSize = pos;
403
404
self->timer++;
405
}
406
}
407
else {
408
self->dialogPos.x = -0x400000 - (ScreenInfo->size.x << 16);
409
self->dialogPos.y = 0;
410
MathHelpers_Lerp2Sin1024(&pos, MAX((self->timer << 8) / 8, 0), 0, 0x10000, ScreenInfo->size.x << 16, 0x10000);
411
self->bgRectSize = pos;
412
413
++self->timer;
414
}
415
}
416
417
void UIDialog_State_Idle(void)
418
{
419
RSDK_THIS(UIDialog);
420
421
self->bgRectSize.x = ScreenInfo->size.x << 16;
422
self->bgRectSize.y = 0x900000;
423
self->dialogPos.x = 0;
424
self->dialogPos.y = 0;
425
}
426
427
void UIDialog_State_Close(void)
428
{
429
RSDK_THIS(UIDialog);
430
431
if (self->timer >= 8) {
432
if (self->timer >= 16) {
433
UIDialog_Close();
434
}
435
else {
436
self->dialogPos.x = (ScreenInfo->size.x + 64) << 16;
437
self->dialogPos.y = 0;
438
MathHelpers_Lerp2Sin1024(&self->bgRectSize, MAX(((self->timer - 8) << 8) / 8, 0), ScreenInfo->size.x << 16, 0x900000,
439
ScreenInfo->size.x << 16, 0);
440
441
++self->timer;
442
}
443
}
444
else {
445
self->bgRectSize.x = ScreenInfo->size.x << 16;
446
self->bgRectSize.y = 0x900000;
447
MathHelpers_LerpSin1024(&self->dialogPos, MAX((self->timer << 8) / 8, 0), 0, 0, (ScreenInfo->size.x + 64) << 16, 0);
448
449
++self->timer;
450
}
451
}
452
453
EntityUIDialog *UIDialog_CreateDialogOk(String *text, void (*callback)(void), bool32 closeOnSelect)
454
{
455
EntityUIDialog *dialog = UIDialog_CreateActiveDialog(text);
456
457
if (dialog) {
458
UIDialog_AddButton(DIALOG_OK, dialog, callback, closeOnSelect);
459
UIDialog_Setup(dialog);
460
}
461
462
return dialog;
463
}
464
EntityUIDialog *UIDialog_CreateDialogYesNo(String *text, void (*callbackYes)(void), void (*callbackNo)(void), bool32 closeOnSelect_Yes,
465
bool32 closeOnSelect_No)
466
{
467
EntityUIDialog *dialog = UIDialog_CreateActiveDialog(text);
468
469
if (dialog) {
470
UIDialog_AddButton(DIALOG_NO, dialog, callbackNo, closeOnSelect_No);
471
UIDialog_AddButton(DIALOG_YES, dialog, callbackYes, closeOnSelect_Yes);
472
UIDialog_Setup(dialog);
473
}
474
475
return dialog;
476
}
477
EntityUIDialog *UIDialog_CreateDialogOkCancel(String *text, void (*callbackOk)(void), void (*callbackCancel)(void), bool32 closeOnSelect_Ok,
478
bool32 closeOnSelect_Cancel)
479
{
480
EntityUIDialog *dialog = UIDialog_CreateActiveDialog(text);
481
482
if (dialog) {
483
UIDialog_AddButton(DIALOG_OK, dialog, callbackOk, closeOnSelect_Ok);
484
UIDialog_AddButton(DIALOG_CANCEL, dialog, callbackCancel, closeOnSelect_Cancel);
485
UIDialog_Setup(dialog);
486
}
487
488
return dialog;
489
}
490
491
#if GAME_INCLUDE_EDITOR
492
void UIDialog_EditorDraw(void) {}
493
494
void UIDialog_EditorLoad(void) {}
495
#endif
496
497
void UIDialog_Serialize(void) {}
498
499