Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/Common/ParallaxSprite.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: ParallaxSprite Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectParallaxSprite *ParallaxSprite;
11
12
void ParallaxSprite_Update(void)
13
{
14
RSDK_THIS(ParallaxSprite);
15
16
StateMachine_Run(self->state);
17
}
18
19
void ParallaxSprite_LateUpdate(void) {}
20
21
void ParallaxSprite_StaticUpdate(void) {}
22
23
void ParallaxSprite_Draw(void)
24
{
25
RSDK_THIS(ParallaxSprite);
26
27
RSDKScreenInfo *screen = &ScreenInfo[SceneInfo->currentScreenID];
28
Vector2 drawPos;
29
30
int32 scrollPosX = ((self->scrollPos.x + self->parallaxFactor.x * screen->position.x) & 0x7FFF0000) % self->loopPoint.x;
31
drawPos.x = self->position.x - scrollPosX;
32
33
int32 scrollPosY = ((self->scrollPos.y + self->parallaxFactor.y * screen->position.y) & 0x7FFF0000) % self->loopPoint.y;
34
drawPos.y = self->position.y - scrollPosY;
35
36
int32 loopX = -self->loopPoint.x >> 2;
37
if (drawPos.x < loopX)
38
drawPos.x += self->loopPoint.x;
39
40
int32 loopY = -self->loopPoint.y >> 2;
41
if (drawPos.y < loopY)
42
drawPos.y += self->loopPoint.y;
43
44
if (self->attribute == PARALLAXSPRITE_ATTR_COLORS) {
45
int32 x = FROM_FIXED(drawPos.x) - 56;
46
int32 y = FROM_FIXED(drawPos.y) - 32;
47
RSDK.DrawRect(x, y, 112, 64, self->color1, 255, INK_NONE, true);
48
49
for (int32 i = 0; i < 0xE0; i += 0x20) {
50
int32 height = MIN((RSDK.Sin256(i + Zone->timer) >> 3) + 48, 64);
51
RSDK.DrawRect(x, y - height + 64, 16, height, self->color2, 255, INK_NONE, true);
52
x += 16;
53
}
54
}
55
else if (self->attribute == PARALLAXSPRITE_ATTR_SHIFT) {
56
RSDK.GetFrame(ParallaxSprite->aniFrames, self->aniID, 0)->sprX = self->sprX + ((self->xSpeed + (Zone->timer << self->timerSpeed)) & 0x7F);
57
}
58
59
RSDK.DrawSprite(&self->animator, &drawPos, true);
60
}
61
62
void ParallaxSprite_Create(void *data)
63
{
64
RSDK_THIS(ParallaxSprite);
65
66
self->active = ACTIVE_NORMAL;
67
self->drawGroup = Zone->fgDrawGroup[0] + 1;
68
69
if (data)
70
self->attribute = VOID_TO_INT(data);
71
72
switch (self->attribute) {
73
default:
74
case PARALLAXSPRITE_ATTR_STANDARD:
75
case PARALLAXSPRITE_ATTR_WINDMILL:
76
self->parallaxFactor.x >>= 8;
77
self->parallaxFactor.y >>= 8;
78
self->drawFX = FX_ROTATE;
79
self->visible = !self->hiddenAtStart;
80
self->state = ParallaxSprite_State_Normal;
81
break;
82
83
case PARALLAXSPRITE_ATTR_COLORS:
84
#if MANIA_USE_PLUS
85
if (SceneInfo->filter & FILTER_ENCORE) {
86
self->color1 = 0x189098;
87
self->color2 = 0x00D098;
88
}
89
else {
90
#endif
91
self->color1 = 0x885820;
92
self->color2 = 0xE89850;
93
#if MANIA_USE_PLUS
94
}
95
#endif
96
self->parallaxFactor.x >>= 8;
97
self->parallaxFactor.y >>= 8;
98
self->drawFX = FX_ROTATE;
99
self->visible = !self->hiddenAtStart;
100
self->state = ParallaxSprite_State_Normal;
101
break;
102
103
case PARALLAXSPRITE_ATTR_EMITTER:
104
self->parallaxFactor.x >>= 8;
105
self->parallaxFactor.y >>= 8;
106
self->state = ParallaxSprite_State_Emitter;
107
break;
108
109
case PARALLAXSPRITE_ATTR_PARTICLE:
110
self->inkEffect = INK_ALPHA;
111
self->visible = true;
112
self->alpha = 0x100;
113
self->state = ParallaxSprite_State_Particle;
114
break;
115
116
case PARALLAXSPRITE_ATTR_BLENDHIGH:
117
self->parallaxFactor.x >>= 8;
118
self->parallaxFactor.y >>= 8;
119
self->visible = true;
120
self->inkEffect = INK_BLEND;
121
self->drawGroup = Zone->objectDrawGroup[1] + 1;
122
self->state = ParallaxSprite_State_Normal;
123
break;
124
125
case PARALLAXSPRITE_ATTR_SHIFT:
126
self->parallaxFactor.x >>= 8;
127
self->parallaxFactor.y >>= 8;
128
self->sprX = RSDK.GetFrame(ParallaxSprite->aniFrames, self->aniID, 1)->sprX;
129
self->timerSpeed = ZONE_RAND(0, 2);
130
self->xSpeed = ZONE_RAND(0, 128);
131
self->inkEffect = INK_MASKED;
132
self->visible = true;
133
self->state = NULL;
134
break;
135
}
136
137
RSDK.SetSpriteAnimation(ParallaxSprite->aniFrames, self->aniID, &self->animator, true, 0);
138
}
139
140
void ParallaxSprite_StageLoad(void)
141
{
142
if (RSDK.CheckSceneFolder("AIZ"))
143
ParallaxSprite->aniFrames = RSDK.LoadSpriteAnimation("AIZ/Decoration.bin", SCOPE_STAGE);
144
else if (RSDK.CheckSceneFolder("CPZ"))
145
ParallaxSprite->aniFrames = RSDK.LoadSpriteAnimation("CPZ/CPZParallax.bin", SCOPE_STAGE);
146
else if (RSDK.CheckSceneFolder("SPZ1"))
147
ParallaxSprite->aniFrames = RSDK.LoadSpriteAnimation("SPZ1/SPZParallax.bin", SCOPE_STAGE);
148
else if (RSDK.CheckSceneFolder("FBZ"))
149
ParallaxSprite->aniFrames = RSDK.LoadSpriteAnimation("FBZ/FBZParallax.bin", SCOPE_STAGE);
150
else if (RSDK.CheckSceneFolder("MSZ") || RSDK.CheckSceneFolder("MSZCutscene"))
151
ParallaxSprite->aniFrames = RSDK.LoadSpriteAnimation("MSZ/MSZParallax.bin", SCOPE_STAGE);
152
else if (RSDK.CheckSceneFolder("OOZ2"))
153
ParallaxSprite->aniFrames = RSDK.LoadSpriteAnimation("OOZ/OOZParallax.bin", SCOPE_STAGE);
154
else if (RSDK.CheckSceneFolder("LRZ2") || RSDK.CheckSceneFolder("LRZ3"))
155
ParallaxSprite->aniFrames = RSDK.LoadSpriteAnimation("LRZ2/LRZParallax.bin", SCOPE_STAGE);
156
}
157
158
void ParallaxSprite_State_Normal(void)
159
{
160
RSDK_THIS(ParallaxSprite);
161
162
RSDK.ProcessAnimation(&self->animator);
163
164
self->rotation = (self->rotation + 2) & 0x1FF;
165
166
self->scrollPos.x += self->scrollSpeed.x;
167
self->scrollPos.y += self->scrollSpeed.y;
168
}
169
170
void ParallaxSprite_State_Emitter(void)
171
{
172
RSDK_THIS(ParallaxSprite);
173
174
if (!(Zone->timer & 3)) {
175
EntityParallaxSprite *sprite = CREATE_ENTITY(ParallaxSprite, INT_TO_VOID(PARALLAXSPRITE_ATTR_PARTICLE), self->position.x, self->position.y);
176
sprite->parallaxFactor.x = self->parallaxFactor.x;
177
sprite->parallaxFactor.y = self->parallaxFactor.y;
178
sprite->loopPoint.x = self->loopPoint.x;
179
sprite->loopPoint.y = self->loopPoint.y;
180
sprite->scrollSpeed.y = RSDK.Rand(0x8000, 0x20000);
181
sprite->acceleration.x = RSDK.Rand(-0x100, 0x100);
182
}
183
}
184
185
void ParallaxSprite_State_Particle(void)
186
{
187
RSDK_THIS(ParallaxSprite);
188
189
RSDK.ProcessAnimation(&self->animator);
190
191
self->scrollSpeed.x += self->acceleration.x;
192
self->scrollSpeed.y += self->acceleration.y;
193
self->scrollPos.x += self->scrollSpeed.x;
194
self->scrollPos.y += self->scrollSpeed.y;
195
196
self->alpha -= 2;
197
if (!self->alpha)
198
destroyEntity(self);
199
}
200
201
void ParallaxSprite_State_FadeIntoHalf(void)
202
{
203
RSDK_THIS(ParallaxSprite);
204
205
RSDK.ProcessAnimation(&self->animator);
206
207
self->scrollPos.x += self->scrollSpeed.x;
208
self->scrollPos.y += self->scrollSpeed.y;
209
210
if (self->alpha >= 0x80) {
211
self->inkEffect = INK_BLEND;
212
self->visible = true;
213
self->state = ParallaxSprite_State_Normal;
214
}
215
else {
216
self->inkEffect = INK_ALPHA;
217
self->alpha += 4;
218
}
219
}
220
221
void ParallaxSprite_State_FadeOut(void)
222
{
223
RSDK_THIS(ParallaxSprite);
224
225
RSDK.ProcessAnimation(&self->animator);
226
227
self->scrollPos.x += self->scrollSpeed.x;
228
self->scrollPos.y += self->scrollSpeed.y;
229
230
if (self->alpha <= 0) {
231
self->visible = false;
232
self->state = ParallaxSprite_State_Normal;
233
}
234
else {
235
self->inkEffect = INK_ALPHA;
236
self->alpha -= 4;
237
}
238
}
239
240
#if GAME_INCLUDE_EDITOR
241
void ParallaxSprite_EditorDraw(void)
242
{
243
RSDK_THIS(ParallaxSprite);
244
245
RSDK.SetSpriteAnimation(ParallaxSprite->aniFrames, self->aniID, &self->animator, true, 0);
246
247
Vector2 drawPos = self->position;
248
249
if (self->attribute == PARALLAXSPRITE_ATTR_COLORS) {
250
int32 x = FROM_FIXED(drawPos.x) - 56;
251
int32 y = FROM_FIXED(drawPos.y) - 32;
252
RSDK.DrawRect(x << 16, y << 16, 112 << 16, 64 << 16, self->color1, 255, 0, false);
253
254
for (int32 i = 0; i < 0xE0; i += 0x20) {
255
int32 height = MIN((RSDK.Sin256(i + Zone->timer) >> 3) + 48, 64);
256
RSDK.DrawRect(x << 16, (y - height + 64) << 16, 16 << 16, height << 16, self->color2, 255, 0, false);
257
x += 16;
258
}
259
}
260
else if (self->attribute == PARALLAXSPRITE_ATTR_SHIFT) {
261
RSDK.GetFrame(ParallaxSprite->aniFrames, self->aniID, 0)->sprX = self->sprX + ((self->xSpeed + (Zone->timer << self->timerSpeed)) & 0x7F);
262
}
263
264
RSDK.DrawSprite(&self->animator, &drawPos, false);
265
}
266
267
void ParallaxSprite_EditorLoad(void)
268
{
269
if (RSDK.CheckSceneFolder("AIZ"))
270
ParallaxSprite->aniFrames = RSDK.LoadSpriteAnimation("AIZ/Decoration.bin", SCOPE_STAGE);
271
else if (RSDK.CheckSceneFolder("CPZ"))
272
ParallaxSprite->aniFrames = RSDK.LoadSpriteAnimation("CPZ/CPZParallax.bin", SCOPE_STAGE);
273
else if (RSDK.CheckSceneFolder("SPZ1"))
274
ParallaxSprite->aniFrames = RSDK.LoadSpriteAnimation("SPZ1/SPZParallax.bin", SCOPE_STAGE);
275
else if (RSDK.CheckSceneFolder("FBZ"))
276
ParallaxSprite->aniFrames = RSDK.LoadSpriteAnimation("FBZ/FBZParallax.bin", SCOPE_STAGE);
277
else if (RSDK.CheckSceneFolder("MSZ") || RSDK.CheckSceneFolder("MSZCutscene"))
278
ParallaxSprite->aniFrames = RSDK.LoadSpriteAnimation("MSZ/MSZParallax.bin", SCOPE_STAGE);
279
else if (RSDK.CheckSceneFolder("OOZ2"))
280
ParallaxSprite->aniFrames = RSDK.LoadSpriteAnimation("OOZ/OOZParallax.bin", SCOPE_STAGE);
281
else if (RSDK.CheckSceneFolder("LRZ2") || RSDK.CheckSceneFolder("LRZ3"))
282
ParallaxSprite->aniFrames = RSDK.LoadSpriteAnimation("LRZ2/LRZParallax.bin", SCOPE_STAGE);
283
284
RSDK_ACTIVE_VAR(ParallaxSprite, attribute);
285
RSDK_ENUM_VAR("Standard", PARALLAXSPRITE_ATTR_STANDARD);
286
RSDK_ENUM_VAR("Windmill (Unused)", PARALLAXSPRITE_ATTR_WINDMILL);
287
RSDK_ENUM_VAR("Colors (SPZ Billboard)", PARALLAXSPRITE_ATTR_COLORS);
288
RSDK_ENUM_VAR("Emitter", PARALLAXSPRITE_ATTR_EMITTER);
289
RSDK_ENUM_VAR("Particle", PARALLAXSPRITE_ATTR_PARTICLE);
290
RSDK_ENUM_VAR("Blend", PARALLAXSPRITE_ATTR_BLENDHIGH);
291
}
292
#endif
293
294
void ParallaxSprite_Serialize(void)
295
{
296
RSDK_EDITABLE_VAR(ParallaxSprite, VAR_UINT8, aniID);
297
RSDK_EDITABLE_VAR(ParallaxSprite, VAR_UINT8, attribute);
298
RSDK_EDITABLE_VAR(ParallaxSprite, VAR_VECTOR2, parallaxFactor);
299
RSDK_EDITABLE_VAR(ParallaxSprite, VAR_VECTOR2, scrollSpeed);
300
RSDK_EDITABLE_VAR(ParallaxSprite, VAR_VECTOR2, loopPoint);
301
RSDK_EDITABLE_VAR(ParallaxSprite, VAR_BOOL, hiddenAtStart);
302
}
303
304