Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/Cutscene/FXRuby.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: FXRuby Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectFXRuby *FXRuby;
11
12
void FXRuby_Update(void)
13
{
14
RSDK_THIS(FXRuby);
15
16
StateMachine_Run(self->state);
17
}
18
19
void FXRuby_LateUpdate(void) {}
20
21
void FXRuby_StaticUpdate(void)
22
{
23
if (Zone) {
24
foreach_active(FXRuby, fxRuby)
25
{
26
RSDK.AddDrawListRef(Zone->hudDrawGroup + 1, RSDK.GetEntitySlot(fxRuby));
27
foreach_break;
28
}
29
}
30
}
31
32
void FXRuby_Draw(void)
33
{
34
RSDK_THIS(FXRuby);
35
36
#if MANIA_USE_PLUS
37
RSDK.SetTintLookupTable(FXRuby->tintLookupTable);
38
#endif
39
40
if (self->fadeWhite >= 512 || self->fadeBlack >= 512 || SceneInfo->currentDrawGroup != self->drawGroup) {
41
if (self->fadeWhite > 0)
42
RSDK.FillScreen(0xFFF0F0, self->fadeWhite, self->fadeWhite - 256, self->fadeWhite - 256);
43
44
if (self->fadeBlack > 0)
45
RSDK.FillScreen(0x000000, self->fadeBlack, self->fadeBlack - 128, self->fadeBlack - 256);
46
}
47
else {
48
if (self->outerRadius <= ScreenInfo->size.x) {
49
if (self->innerRadius)
50
RSDK.DrawCircleOutline(self->position.x, self->position.y, self->innerRadius, self->outerRadius, 0x000000, 0xFF, INK_TINT, false);
51
else
52
RSDK.DrawCircle(self->position.x, self->position.y, self->outerRadius, 0x000000, 0xFF, INK_TINT, false);
53
}
54
else {
55
RSDK.DrawRect(0, 0, ScreenInfo->size.x, ScreenInfo->size.y, 0x000000, 0xFF, INK_TINT, true);
56
}
57
}
58
}
59
60
void FXRuby_Create(void *data)
61
{
62
RSDK_THIS(FXRuby);
63
64
if (!SceneInfo->inEditor) {
65
self->visible = true;
66
self->active = ACTIVE_NORMAL;
67
self->drawGroup = Zone ? Zone->objectDrawGroup[1] : (DRAWGROUP_COUNT - 1);
68
69
self->radiusSpeed = 4;
70
71
if (data)
72
self->state = (Type_StateMachine)data;
73
else if (!self->waitForTrigger)
74
self->state = FXRuby_State_Expanding;
75
76
#if !MANIA_USE_PLUS
77
uint16 *tintLookupTable = RSDK.GetTintLookupTable();
78
for (int32 c = 0; c < 0x10000; ++c) tintLookupTable[0xFFFF - c] = c;
79
#endif
80
}
81
}
82
83
void FXRuby_StageLoad(void)
84
{
85
FXRuby->fgLow = RSDK.GetTileLayer(RSDK.GetTileLayerID("FG Low"));
86
FXRuby->fgHigh = RSDK.GetTileLayer(RSDK.GetTileLayerID("FG High"));
87
88
for (int32 d = 0; d < 0x200; ++d) FXRuby->deformation[d] = RSDK.Rand(-64, 64);
89
90
#if MANIA_USE_PLUS
91
for (int32 c = 0; c < 0x10000; ++c) FXRuby->tintLookupTable[0xFFFF - c] = c;
92
#endif
93
}
94
95
void FXRuby_SetupLayerDeformation(void)
96
{
97
for (int32 l = 0; l < LAYER_COUNT; ++l) {
98
TileLayer *layer = RSDK.GetTileLayer(l);
99
100
if (layer->width && layer->drawGroup[0] != DRAWGROUP_COUNT) {
101
for (int32 s = 0; s < layer->scrollInfoCount; ++s) layer->scrollInfo[s].deform = true;
102
}
103
}
104
}
105
106
void FXRuby_HandleLayerDeform(void)
107
{
108
RSDK_THIS(FXRuby);
109
110
int32 timer = Zone ? Zone->timer : UIWidgets->timer;
111
112
int32 *deformationData = NULL;
113
for (int32 l = 0; l < LAYER_COUNT; ++l) {
114
TileLayer *layer = RSDK.GetTileLayer(l);
115
if (layer->width && layer->drawGroup[0] != DRAWGROUP_COUNT) {
116
layer->deformationOffset += 3;
117
118
if (deformationData) {
119
for (int32 s = 0; s < 0x200; ++s) {
120
layer->deformationData[s] = deformationData[s];
121
layer->deformationData[s + 0x200] = deformationData[s + 0x200];
122
}
123
}
124
else {
125
int32 cnt = 8 * timer;
126
for (int32 s = 0; s < 0x200; ++s) {
127
int32 angle = RSDK.Sin256(4 * s);
128
layer->deformationData[s] = ((self->timer * FXRuby->deformation[cnt-- & 0x1FF]) >> 7) + ((self->timer * angle) >> 7);
129
layer->deformationData[s + 0x200] = layer->deformationData[s];
130
}
131
deformationData = layer->deformationData;
132
}
133
}
134
}
135
}
136
137
void FXRuby_State_Expanding(void)
138
{
139
RSDK_THIS(FXRuby);
140
141
self->outerRadius += self->radiusSpeed;
142
143
if (self->outerRadius > ScreenInfo->size.x) {
144
self->fullyExpanded = true;
145
self->state = FXRuby_State_Idle;
146
}
147
}
148
void FXRuby_State_Shrinking(void)
149
{
150
RSDK_THIS(FXRuby);
151
152
self->outerRadius -= self->radiusSpeed;
153
154
if (self->outerRadius <= 0) {
155
self->fullyExpanded = false;
156
self->state = FXRuby_State_Idle;
157
}
158
}
159
160
void FXRuby_State_Idle(void)
161
{
162
// do nothin, just chill
163
}
164
165
void FXRuby_State_IncreaseStageDeform(void)
166
{
167
RSDK_THIS(FXRuby);
168
169
FXRuby_HandleLayerDeform();
170
171
if (++self->timer >= self->delay)
172
self->state = FXRuby_State_DecreaseStageDeform;
173
}
174
void FXRuby_State_DecreaseStageDeform(void)
175
{
176
RSDK_THIS(FXRuby);
177
178
FXRuby_HandleLayerDeform();
179
180
if (self->timer > 0)
181
self->timer--;
182
}
183
void FXRuby_State_ShrinkAndDestroy(void)
184
{
185
RSDK_THIS(FXRuby);
186
187
self->radiusSpeed -= 0x3800;
188
self->radius += self->radiusSpeed;
189
self->innerRadius = 0;
190
self->outerRadius = self->radius >> 16;
191
192
if (self->radius <= 0)
193
destroyEntity(self);
194
}
195
196
#if GAME_INCLUDE_EDITOR
197
void FXRuby_EditorDraw(void) {}
198
199
void FXRuby_EditorLoad(void) {}
200
#endif
201
202
void FXRuby_Serialize(void)
203
{
204
RSDK_EDITABLE_VAR(FXRuby, VAR_ENUM, outerRadius);
205
RSDK_EDITABLE_VAR(FXRuby, VAR_ENUM, fadeWhite);
206
RSDK_EDITABLE_VAR(FXRuby, VAR_ENUM, fadeBlack);
207
RSDK_EDITABLE_VAR(FXRuby, VAR_BOOL, waitForTrigger);
208
}
209
210