Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/SSZ/HiLoSign.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: HiLoSign Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectHiLoSign *HiLoSign;
11
12
void HiLoSign_Update(void)
13
{
14
RSDK_THIS(HiLoSign);
15
16
foreach_active(Player, player)
17
{
18
if (Player_CheckCollisionTouch(player, self, &HiLoSign->spinHitbox[self->type])) {
19
int32 velocity = (self->type & HILOSIGN_V) ? player->velocity.x : player->velocity.y;
20
21
int32 speed = abs((velocity >> 7) + (velocity >> 6));
22
if (speed > self->spinSpeed && speed >= 0xC00) {
23
self->spinSpeed = speed & 0xFFFFFF80;
24
self->active = ACTIVE_NORMAL;
25
self->state = HiLoSign_State_Spinning;
26
self->direction = velocity < 0;
27
}
28
}
29
}
30
31
StateMachine_Run(self->state);
32
}
33
34
void HiLoSign_LateUpdate(void) {}
35
36
void HiLoSign_StaticUpdate(void) {}
37
38
void HiLoSign_Draw(void)
39
{
40
RSDK_THIS(HiLoSign);
41
42
StateMachine_Run(self->stateDraw);
43
}
44
45
void HiLoSign_Create(void *data)
46
{
47
RSDK_THIS(HiLoSign);
48
49
if (!SceneInfo->inEditor) {
50
RSDK.SetSpriteAnimation(HiLoSign->aniFrames, 0, &self->faceAnimator, true, 0);
51
RSDK.SetSpriteAnimation(HiLoSign->aniFrames, 1, &self->sidesAnimator, true, 0);
52
53
self->active = ACTIVE_BOUNDS;
54
self->updateRange.x = 0x800000;
55
self->updateRange.y = 0x800000;
56
self->drawFX = FX_SCALE;
57
self->visible = true;
58
self->drawGroup = Zone->objectDrawGroup[0];
59
self->scale.x = 0x200;
60
self->scale.y = 0x200;
61
self->state = HiLoSign_State_Spinning;
62
63
switch (self->type) {
64
case HILOSIGN_H:
65
self->sidesAnimator.frameID = 1;
66
self->stateDraw = HiLoSign_Draw_Horizontal;
67
break;
68
69
case HILOSIGN_V: self->stateDraw = HiLoSign_Draw_Vertical; break;
70
}
71
}
72
}
73
74
void HiLoSign_StageLoad(void)
75
{
76
HiLoSign->aniFrames = RSDK.LoadSpriteAnimation("SSZ/HiLoSign.bin", SCOPE_STAGE);
77
78
HiLoSign->spinHitbox[HILOSIGN_H].left = -24;
79
HiLoSign->spinHitbox[HILOSIGN_H].top = -6;
80
HiLoSign->spinHitbox[HILOSIGN_H].right = 24;
81
HiLoSign->spinHitbox[HILOSIGN_H].bottom = 6;
82
83
HiLoSign->spinHitbox[HILOSIGN_V].left = -6;
84
HiLoSign->spinHitbox[HILOSIGN_V].top = -24;
85
HiLoSign->spinHitbox[HILOSIGN_V].right = 6;
86
HiLoSign->spinHitbox[HILOSIGN_V].bottom = 24;
87
88
HiLoSign->sfxSignPost = RSDK.GetSfx("Global/SignPost.wav");
89
90
DEBUGMODE_ADD_OBJ(HiLoSign);
91
}
92
93
void HiLoSign_DebugSpawn(void)
94
{
95
RSDK_THIS(DebugMode);
96
97
CREATE_ENTITY(HiLoSign, NULL, self->position.x, self->position.y);
98
}
99
100
void HiLoSign_DebugDraw(void)
101
{
102
RSDK.SetSpriteAnimation(HiLoSign->aniFrames, 0, &DebugMode->animator, true, 0);
103
RSDK.DrawSprite(&DebugMode->animator, NULL, false);
104
}
105
106
void HiLoSign_State_Spinning(void)
107
{
108
RSDK_THIS(HiLoSign);
109
110
if (self->spinSpeed) {
111
if (self->direction)
112
self->angle -= self->spinSpeed;
113
else
114
self->angle += self->spinSpeed;
115
116
self->spinSpeed -= 0x40;
117
if (self->spinSpeed < 0x100) {
118
if (self->direction) {
119
if ((self->angle & 0xFFFF) < 0x4000)
120
self->direction ^= FLIP_X;
121
}
122
else {
123
if ((self->angle & 0xFFFF) > 0xC000)
124
self->direction = FLIP_X;
125
}
126
127
self->spinSpeed = 0;
128
self->state = HiLoSign_State_FinishSpinAdjust;
129
}
130
}
131
132
self->rotation = (self->angle >> 8) & 0x1FF;
133
}
134
135
void HiLoSign_State_FinishSpinAdjust(void)
136
{
137
RSDK_THIS(HiLoSign);
138
139
uint32 prevAng = self->angle & 0xFFFF0000;
140
if (self->direction)
141
self->angle -= self->spinSpeed;
142
else
143
self->angle += self->spinSpeed;
144
145
self->spinSpeed -= 0x20;
146
if ((self->angle & 0xFFFF0000) != prevAng) {
147
self->active = ACTIVE_BOUNDS;
148
self->spinSpeed = 0;
149
self->state = HiLoSign_State_Spinning;
150
}
151
152
self->rotation = (self->angle >> 8) & 0x1FF;
153
}
154
155
void HiLoSign_Draw_Horizontal(void)
156
{
157
RSDK_THIS(HiLoSign);
158
159
Vector2 drawPos;
160
drawPos.x = self->position.x;
161
162
self->drawFX = FX_SCALE;
163
self->scale.y = abs(RSDK.Cos512(self->rotation)) + 1;
164
int32 scaleY = abs(RSDK.Sin512(self->rotation)) + 1;
165
166
switch (self->rotation >> 7) {
167
case 0:
168
case 2:
169
drawPos.y = self->position.y + (scaleY << 9);
170
RSDK.DrawSprite(&self->faceAnimator, &drawPos, false);
171
drawPos.y += -2048 * self->scale.y - (scaleY << 9);
172
break;
173
174
case 1:
175
case 3:
176
drawPos.y = self->position.y - (scaleY << 9);
177
RSDK.DrawSprite(&self->faceAnimator, &drawPos, false);
178
drawPos.y += (scaleY + 4 * (self->scale.y - 16)) << 9;
179
break;
180
181
default: break;
182
}
183
184
self->scale.y = scaleY;
185
RSDK.DrawSprite(&self->sidesAnimator, &drawPos, false);
186
}
187
188
void HiLoSign_Draw_Vertical(void)
189
{
190
RSDK_THIS(HiLoSign);
191
192
Vector2 drawPos;
193
drawPos.y = self->position.y;
194
195
self->drawFX = FX_SCALE;
196
self->scale.x = abs(RSDK.Cos512(self->rotation)) + 1;
197
int32 scaleX = abs(RSDK.Sin512(self->rotation)) + 1;
198
199
switch (self->rotation >> 7) {
200
case 0:
201
case 2:
202
drawPos.x = self->position.x + (scaleX << 9);
203
RSDK.DrawSprite(&self->faceAnimator, &drawPos, false);
204
drawPos.x += -0xF00 * self->scale.x - (scaleX << 9);
205
break;
206
207
case 1:
208
case 3:
209
drawPos.x = self->position.x - (scaleX << 9);
210
RSDK.DrawSprite(&self->faceAnimator, &drawPos, false);
211
drawPos.x += ((scaleX - 64) << 9) + 0xF00 * self->scale.x;
212
break;
213
214
default: break;
215
}
216
217
self->scale.x = scaleX;
218
RSDK.DrawSprite(&self->sidesAnimator, &drawPos, false);
219
}
220
221
#if GAME_INCLUDE_EDITOR
222
void HiLoSign_EditorDraw(void)
223
{
224
RSDK_THIS(HiLoSign);
225
226
RSDK.SetSpriteAnimation(HiLoSign->aniFrames, 0, &self->faceAnimator, true, 0);
227
228
RSDK.DrawSprite(&self->faceAnimator, NULL, false);
229
}
230
231
void HiLoSign_EditorLoad(void)
232
{
233
HiLoSign->aniFrames = RSDK.LoadSpriteAnimation("SSZ/HiLoSign.bin", SCOPE_STAGE);
234
235
RSDK_ACTIVE_VAR(HiLoSign, type);
236
RSDK_ENUM_VAR("Horizontal", HILOSIGN_H);
237
RSDK_ENUM_VAR("Vertical", HILOSIGN_V);
238
}
239
#endif
240
241
void HiLoSign_Serialize(void) { RSDK_EDITABLE_VAR(HiLoSign, VAR_UINT8, type); }
242
243