Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/Global/ImageTrail.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: ImageTrail Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectImageTrail *ImageTrail;
11
12
void ImageTrail_Update(void) {}
13
14
void ImageTrail_LateUpdate(void)
15
{
16
RSDK_THIS(ImageTrail);
17
18
EntityPlayer *player = self->player;
19
20
if (!player || (player->classID != self->playerClassID && player->classID != DebugMode->classID)) {
21
destroyEntity(self);
22
}
23
else {
24
// Check for fadeouts/destroy triggers
25
if (player->superState == SUPERSTATE_SUPER) {
26
self->baseAlpha = 0x100;
27
}
28
#if MANIA_USE_PLUS
29
else if (player->speedShoesTimer < 16 && player->state == Player_State_MightyHammerDrop) {
30
self->fadeoutTimer = 16;
31
}
32
#endif
33
else if (self->fadeoutTimer <= 0 && player->speedShoesTimer < 32) {
34
self->baseAlpha = 8 * player->speedShoesTimer;
35
if (!self->baseAlpha)
36
destroyEntity(self);
37
}
38
else if (self->fadeoutTimer > 0) {
39
self->fadeoutTimer--;
40
self->baseAlpha = 16 * self->fadeoutTimer;
41
if (!self->baseAlpha)
42
destroyEntity(self);
43
}
44
}
45
46
// if we destroyed this entity, skip any more logic
47
if (!self->classID)
48
return;
49
50
// Update recordings
51
for (int32 i = IMAGETRAIL_TRACK_COUNT - 1; i > 0; --i) {
52
self->statePos[i].x = self->statePos[i - 1].x;
53
self->statePos[i].y = self->statePos[i - 1].y;
54
self->stateRotation[i] = self->stateRotation[i - 1];
55
self->stateScale[i] = self->stateScale[i - 1];
56
self->stateDirection[i] = self->stateDirection[i - 1];
57
self->stateVisible[i] = self->stateVisible[i - 1];
58
memcpy(&self->stateAnimator[i], &self->stateAnimator[i - 1], sizeof(Animator));
59
}
60
61
self->statePos[0].x = self->currentPos.x;
62
self->statePos[0].y = self->currentPos.y;
63
self->stateRotation[0] = self->currentRotation;
64
self->stateDirection[0] = self->currentDirection;
65
self->stateScale[0] = self->currentScale;
66
self->stateVisible[0] = self->currentVisible;
67
memcpy(&self->stateAnimator[0], &self->currentAnimator, sizeof(Animator));
68
69
// Record Player
70
self->drawGroup = player->drawGroup - 1;
71
self->currentPos.x = player->position.x;
72
self->currentPos.y = player->position.y;
73
self->currentRotation = player->rotation;
74
self->currentDirection = player->direction;
75
memcpy(&self->currentAnimator, &player->animator, sizeof(Animator));
76
if (player->isChibi || !(player->drawFX & FX_SCALE))
77
self->currentScale = 0x200;
78
else
79
self->currentScale = player->scale.x;
80
81
// Check if we have enough speed to be visible
82
if (abs(player->velocity.x) >= TO_FIXED(1) || abs(player->velocity.y) >= TO_FIXED(1))
83
self->currentVisible = player->visible;
84
else
85
self->currentVisible = false;
86
}
87
88
void ImageTrail_StaticUpdate(void) {}
89
90
void ImageTrail_Draw(void)
91
{
92
RSDK_THIS(ImageTrail);
93
94
// int32 alpha[3] = { 0xA0 * self->baseAlpha >> 8, self->baseAlpha >> 1, 0x60 * self->baseAlpha >> 8 };
95
int32 alpha = 0x60 * self->baseAlpha >> 8;
96
int32 inc = 0x40 / (IMAGETRAIL_TRACK_COUNT / 3);
97
98
for (int32 i = (IMAGETRAIL_TRACK_COUNT / 3); i >= 0; --i) {
99
int32 id = (i * 3) - (i - 1);
100
if (self->stateVisible[id]) {
101
if (self->stateScale[id] != 0x200) {
102
self->drawFX |= FX_SCALE;
103
self->scale.x = self->stateScale[id];
104
self->scale.y = self->stateScale[id];
105
}
106
self->alpha = alpha;
107
alpha += inc;
108
self->rotation = self->stateRotation[id];
109
self->direction = self->stateDirection[id];
110
RSDK.DrawSprite(&self->stateAnimator[id], &self->statePos[id], false);
111
self->drawFX &= ~FX_SCALE;
112
}
113
}
114
}
115
116
void ImageTrail_Create(void *data)
117
{
118
RSDK_THIS(ImageTrail);
119
120
if (!SceneInfo->inEditor) {
121
EntityPlayer *player = (EntityPlayer *)data;
122
self->active = ACTIVE_ALWAYS;
123
self->visible = true;
124
self->player = player;
125
self->playerClassID = player->classID; // dunno what this is for, maybe a v4 leftover where frames were per-object?
126
self->baseAlpha = 0x100;
127
self->drawFX = FX_FLIP | FX_SCALE | FX_ROTATE;
128
self->inkEffect = INK_ALPHA;
129
130
for (int32 i = IMAGETRAIL_TRACK_COUNT - 1; i >= 0; --i) {
131
self->statePos[i].x = player->position.x;
132
self->statePos[i].y = player->position.y;
133
self->stateRotation[i] = player->rotation;
134
self->stateDirection[i] = player->direction;
135
self->stateVisible[i] = false;
136
}
137
}
138
}
139
140
void ImageTrail_StageLoad(void) {}
141
142
#if GAME_INCLUDE_EDITOR
143
void ImageTrail_EditorDraw(void) {}
144
145
void ImageTrail_EditorLoad(void) {}
146
#endif
147
148
void ImageTrail_Serialize(void) {}
149
150