Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/Menu/UICharButton.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: UICharButton Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectUICharButton *UICharButton;
11
12
void UICharButton_Update(void)
13
{
14
RSDK_THIS(UICharButton);
15
16
self->touchPosSizeS.x = 0x600000;
17
self->touchPosSizeS.y = 0x600000;
18
self->touchPosOffsetS.x = 0;
19
self->touchPosOffsetS.y = 0;
20
21
StateMachine_Run(self->state);
22
23
if (self->isSelected) {
24
self->triBounceVelocity -= 0x600;
25
self->triBounceOffset += self->triBounceVelocity;
26
27
if (self->triBounceOffset <= 0x10000 && self->triBounceVelocity < 0) {
28
self->triBounceOffset = 0x10000;
29
self->triBounceVelocity = 0;
30
}
31
32
self->playerBounceVelocity -= 0x1800;
33
self->playerBounceOffset += self->playerBounceVelocity;
34
35
if (self->playerBounceOffset <= 0x8000 && self->playerBounceVelocity < 0) {
36
self->playerBounceOffset = 0x8000;
37
self->playerBounceVelocity = 0;
38
}
39
}
40
else if (self->state != UICharButton_State_Selected) {
41
if (self->triBounceOffset > 0) {
42
self->triBounceOffset -= 0x2000;
43
44
if (self->triBounceOffset < 0)
45
self->triBounceOffset = 0;
46
}
47
48
if (self->playerBounceOffset > 0) {
49
self->playerBounceOffset -= 0x2000;
50
51
if (self->playerBounceOffset < 0)
52
self->playerBounceOffset = 0;
53
}
54
}
55
56
EntityUIControl *parent = (EntityUIControl *)self->parent;
57
int32 id = -1;
58
for (int32 i = 0; i < parent->buttonCount; ++i) {
59
if (self == (EntityUICharButton *)parent->buttons[i]) {
60
id = i;
61
break;
62
}
63
}
64
65
if (self->isSelected && (parent->state != UIControl_ProcessInputs || parent->buttonID != id)) {
66
self->isSelected = false;
67
self->state = UICharButton_State_HandleButtonLeave;
68
}
69
}
70
71
void UICharButton_LateUpdate(void) {}
72
73
void UICharButton_StaticUpdate(void) {}
74
75
void UICharButton_Draw(void)
76
{
77
RSDK_THIS(UICharButton);
78
79
RSDK.DrawRect(self->position.x - 0x2D0000, self->position.y - 0x2D0000, 0x600000, 0x600000, 0xFFFFFF, 0x7F, INK_BLEND, false);
80
81
UICharButton_DrawBG();
82
UICharButton_DrawOutlines();
83
UICharButton_DrawPlayers();
84
}
85
86
void UICharButton_Create(void *data)
87
{
88
RSDK_THIS(UICharButton);
89
90
self->active = ACTIVE_BOUNDS;
91
self->drawGroup = 2;
92
self->visible = true;
93
self->drawFX = FX_FLIP;
94
self->updateRange.x = 0x800000;
95
self->updateRange.y = 0x300000;
96
97
self->processButtonCB = UIButton_ProcessButtonCB_Scroll;
98
self->touchCB = UIButton_ProcessTouchCB_Single;
99
self->selectedCB = UICharButton_SelectedCB;
100
self->failCB = StateMachine_None;
101
self->buttonEnterCB = UICharButton_ButtonEnterCB;
102
self->buttonLeaveCB = UICharButton_ButtonLeaveCB;
103
self->checkButtonEnterCB = UICharButton_CheckButtonEnterCB;
104
self->checkSelectedCB = UICharButton_CheckSelectedCB;
105
self->state = UICharButton_State_HandleButtonLeave;
106
}
107
108
void UICharButton_StageLoad(void) { UICharButton->aniFrames = RSDK.LoadSpriteAnimation("UI/SaveSelect.bin", SCOPE_STAGE); }
109
110
void UICharButton_DrawOutlines(void)
111
{
112
RSDK_THIS(UICharButton);
113
114
if (!SceneInfo->inEditor)
115
UIWidgets_DrawRectOutline_Blended(self->position.x + 0x30000, self->position.y + 0x30000, 96, 96);
116
117
if (self->isSelected)
118
UIWidgets_DrawRectOutline_Flash(self->position.x, self->position.y, 96, 96);
119
else
120
UIWidgets_DrawRectOutline_Black(self->position.x, self->position.y, 96, 96);
121
}
122
123
void UICharButton_DrawBG(void)
124
{
125
RSDK_THIS(UICharButton);
126
127
UIWidgets_DrawRightTriangle(self->position.x - 0x2D0000, self->position.y - 0x2D0000, (self->triBounceOffset >> 11), 232, 40, 88);
128
UIWidgets_DrawRightTriangle(self->position.x + 0x2D0000, self->position.y + 0x2C0000, (-64 * self->triBounceOffset) >> 16, 96, 160, 176);
129
UIWidgets_DrawRightTriangle(self->position.x + 0x2D0000, self->position.y + 0x2C0000, (-44 * self->triBounceOffset) >> 16, 88, 112, 224);
130
}
131
132
void UICharButton_DrawPlayers(void)
133
{
134
RSDK_THIS(UICharButton);
135
136
Vector2 drawPos;
137
drawPos = self->position;
138
drawPos.x -= 0x2D0000;
139
drawPos.y += 0x180000;
140
RSDK.DrawRect(drawPos.x, drawPos.y, 0x5A0000, 0x100000, 0, 255, INK_NONE, false);
141
142
if (self->state != UICharButton_State_Selected || !(self->timer & 2)) {
143
int32 frame = self->characterID;
144
#if MANIA_USE_PLUS
145
if (self->characterID >= UICHARBUTTON_MIGHTY)
146
frame = self->characterID + 1;
147
#endif
148
RSDK.SetSpriteAnimation(UICharButton->aniFrames, 1, &self->playerAnimator, true, frame);
149
RSDK.SetSpriteAnimation(UICharButton->aniFrames, 2, &self->shadowAnimator, true, frame);
150
drawPos.x = self->position.x;
151
drawPos.y = self->position.y - 0x80000;
152
drawPos.x += 4 * self->playerBounceOffset;
153
drawPos.y += 4 * self->playerBounceOffset;
154
RSDK.DrawSprite(&self->shadowAnimator, &drawPos, false);
155
156
drawPos.x -= 8 * self->playerBounceOffset;
157
drawPos.y -= 8 * self->playerBounceOffset;
158
RSDK.DrawSprite(&self->playerAnimator, &drawPos, false);
159
160
RSDK.SetSpriteAnimation(UIWidgets->textFrames, 8, &self->nameAnimator, true, self->characterID);
161
drawPos.x = self->position.x;
162
drawPos.y = self->position.y + 0x200000;
163
RSDK.DrawSprite(&self->nameAnimator, &drawPos, false);
164
}
165
}
166
167
void UICharButton_SelectedCB(void)
168
{
169
RSDK_THIS(UICharButton);
170
171
self->timer = 0;
172
self->state = UICharButton_State_Selected;
173
self->processButtonCB = StateMachine_None;
174
175
UITransition_StartTransition(self->actionCB, 30);
176
177
if (UIControl_GetUIControl())
178
UIControl_GetUIControl()->selectionDisabled = true;
179
180
((EntityUIControl *)self->parent)->backoutTimer = 30;
181
182
RSDK.PlaySfx(UIWidgets->sfxAccept, false, 255);
183
}
184
185
bool32 UICharButton_CheckButtonEnterCB(void)
186
{
187
RSDK_THIS(UICharButton);
188
189
return self->state == UICharButton_State_HandleButtonEnter;
190
}
191
192
bool32 UICharButton_CheckSelectedCB(void)
193
{
194
RSDK_THIS(UICharButton);
195
196
return self->state == UICharButton_State_Selected;
197
}
198
199
void UICharButton_ButtonEnterCB(void)
200
{
201
RSDK_THIS(UICharButton);
202
203
if (!self->isSelected) {
204
self->triBounceOffset = 0;
205
self->triBounceVelocity = 0x4000;
206
self->playerBounceOffset = 0;
207
self->playerBounceVelocity = 0x8000;
208
209
self->isSelected = true;
210
self->state = UICharButton_State_HandleButtonEnter;
211
}
212
}
213
214
void UICharButton_ButtonLeaveCB(void)
215
{
216
RSDK_THIS(UICharButton);
217
218
self->isSelected = false;
219
self->state = UICharButton_State_HandleButtonLeave;
220
}
221
222
void UICharButton_State_HandleButtonLeave(void) {}
223
224
void UICharButton_State_HandleButtonEnter(void) {}
225
226
void UICharButton_State_Selected(void)
227
{
228
RSDK_THIS(UICharButton);
229
230
if (self->timer >= 30) {
231
self->isSelected = false;
232
self->timer = 0;
233
self->state = UICharButton_State_HandleButtonLeave;
234
self->processButtonCB = UIButton_ProcessButtonCB_Scroll;
235
}
236
else {
237
if (self->timer == 2) {
238
switch (self->characterID) {
239
case UICHARBUTTON_SONIC: RSDK.PlaySfx(Announcer->sfxSonic, false, 255); break;
240
case UICHARBUTTON_TAILS: RSDK.PlaySfx(Announcer->sfxTails, false, 255); break;
241
case UICHARBUTTON_KNUX: RSDK.PlaySfx(Announcer->sfxKnuckles, false, 255); break;
242
#if MANIA_USE_PLUS
243
case UICHARBUTTON_MIGHTY: RSDK.PlaySfx(Announcer->sfxMighty, false, 255); break;
244
case UICHARBUTTON_RAY: RSDK.PlaySfx(Announcer->sfxRay, false, 255); break;
245
#endif
246
default: break;
247
}
248
}
249
250
++self->timer;
251
}
252
}
253
254
#if GAME_INCLUDE_EDITOR
255
void UICharButton_EditorDraw(void)
256
{
257
RSDK_THIS(UICharButton);
258
259
self->inkEffect = self->disabled ? INK_BLEND : INK_NONE;
260
261
UICharButton_Draw();
262
}
263
264
void UICharButton_EditorLoad(void)
265
{
266
UICharButton->aniFrames = RSDK.LoadSpriteAnimation("UI/SaveSelect.bin", SCOPE_STAGE);
267
268
RSDK_ACTIVE_VAR(UICharButton, characterID);
269
RSDK_ENUM_VAR("Sonic", UICHARBUTTON_SONIC);
270
RSDK_ENUM_VAR("Tails", UICHARBUTTON_TAILS);
271
RSDK_ENUM_VAR("Knuckles", UICHARBUTTON_KNUX);
272
#if MANIA_USE_PLUS
273
RSDK_ENUM_VAR("Mighty", UICHARBUTTON_MIGHTY);
274
RSDK_ENUM_VAR("Ray", UICHARBUTTON_RAY);
275
#endif
276
}
277
#endif
278
279
void UICharButton_Serialize(void)
280
{
281
RSDK_EDITABLE_VAR(UICharButton, VAR_BOOL, disabled);
282
RSDK_EDITABLE_VAR(UICharButton, VAR_UINT8, characterID);
283
}
284
285