Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/BSS/BSS_Player.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: BSS_Player Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectBSS_Player *BSS_Player;
11
12
void BSS_Player_Update(void)
13
{
14
RSDK_THIS(BSS_Player);
15
16
EntityBSS_Setup *setup = RSDK_GET_ENTITY(SLOT_BSS_SETUP, BSS_Setup);
17
18
StateMachine_Run(self->stateInput);
19
20
if (self->onGround) {
21
if (self->jumpPress) {
22
self->velocity.y = -TO_FIXED(16);
23
self->onGround = false;
24
RSDK.SetSpriteAnimation(self->aniFrames, 2, &self->animator, false, 0);
25
RSDK.PlaySfx(BSS_Player->sfxJump, false, 255);
26
}
27
}
28
else {
29
self->gravityStrength += self->velocity.y;
30
31
int32 speed = !setup->speedupLevel ? 16 : setup->speedupLevel;
32
self->velocity.y += (speed << 12);
33
if (self->gravityStrength >= 0) {
34
self->gravityStrength = 0;
35
self->onGround = true;
36
37
if (!self->sidekick) {
38
if (self->animator.animationID == 3)
39
setup->globeSpeed >>= 1;
40
41
setup->globeSpeedInc = 2;
42
}
43
44
if (setup->speedupLevel)
45
RSDK.SetSpriteAnimation(self->aniFrames, 1, &self->animator, false, 0);
46
else
47
RSDK.SetSpriteAnimation(self->aniFrames, 0, &self->animator, false, 0);
48
}
49
}
50
51
self->position.y = (self->gravityStrength >> 1) - (self->gravityStrength >> 4);
52
self->position.y += SceneInfo->entitySlot ? TO_FIXED(186) : TO_FIXED(170);
53
54
if (self->animator.animationID == 1) {
55
self->animator.timer += abs(setup->globeSpeed);
56
self->animator.speed = abs(setup->globeSpeed);
57
58
if (self->animator.timer > 0x1F) {
59
self->animator.timer &= 0x1F;
60
61
if (setup->globeSpeed <= 0) {
62
if (--self->animator.frameID < 0)
63
self->animator.frameID = 11;
64
}
65
else if (++self->animator.frameID > 11) {
66
self->animator.frameID = 0;
67
}
68
}
69
}
70
else if (self->animator.animationID >= 2) {
71
self->animator.speed = MAX(abs(setup->speedupLevel), 0x10);
72
RSDK.ProcessAnimation(&self->animator);
73
}
74
75
self->tailAnimator.speed = abs(setup->speedupLevel) + 40;
76
RSDK.ProcessAnimation(&self->tailAnimator);
77
}
78
79
void BSS_Player_LateUpdate(void) {}
80
81
void BSS_Player_StaticUpdate(void) {}
82
83
void BSS_Player_Draw(void)
84
{
85
RSDK_THIS(BSS_Player);
86
87
Vector2 drawPos;
88
drawPos.x = TO_FIXED(ScreenInfo->center.x);
89
drawPos.y = self->position.y;
90
RSDK.DrawSprite(&self->animator, &drawPos, true);
91
92
// if we're tails, draw his tail
93
if (CHECK_CHARACTER_ID(ID_TAILS, 1))
94
RSDK.DrawSprite(&self->tailAnimator, &drawPos, true);
95
#if MANIA_USE_PLUS
96
// if we're ray, draw his tail
97
else if (CHECK_CHARACTER_ID(ID_RAY, 1) && self->animator.animationID == 1)
98
RSDK.DrawSprite(&self->tailAnimator, &drawPos, true);
99
#endif
100
}
101
102
void BSS_Player_Create(void *data)
103
{
104
RSDK_THIS(BSS_Player);
105
106
if (!SceneInfo->inEditor) {
107
self->active = ACTIVE_NORMAL;
108
self->visible = true;
109
self->drawGroup = 4;
110
self->updateRange.x = TO_FIXED(128);
111
self->updateRange.y = TO_FIXED(128);
112
113
switch (GET_CHARACTER_ID(1)) {
114
default:
115
case ID_SONIC: self->aniFrames = BSS_Player->sonicFrames; break;
116
117
case ID_TAILS:
118
self->aniFrames = BSS_Player->tailsFrames;
119
RSDK.SetSpriteAnimation(self->aniFrames, 4, &self->tailAnimator, true, 0);
120
break;
121
122
case ID_KNUCKLES: self->aniFrames = BSS_Player->knuxFrames; break;
123
124
#if MANIA_USE_PLUS
125
case ID_MIGHTY: self->aniFrames = BSS_Player->mightyFrames; break;
126
127
case ID_RAY:
128
self->aniFrames = BSS_Player->rayFrames;
129
RSDK.SetSpriteAnimation(self->aniFrames, 4, &self->tailAnimator, true, 0);
130
break;
131
#endif
132
}
133
134
// The BSS Player gets reset into P1 slot, no other player entities ever get set, so sidekick BSS player behaviour goes unused...
135
if (SceneInfo->entitySlot) {
136
self->stateInput = BSS_Player_Input_P2;
137
self->sidekick = true;
138
}
139
else {
140
self->stateInput = BSS_Player_Input_P1;
141
self->controllerID = CONT_P1;
142
self->sidekick = false;
143
}
144
145
RSDK.SetSpriteAnimation(self->aniFrames, 0, &self->animator, true, 0);
146
}
147
}
148
149
void BSS_Player_StageLoad(void)
150
{
151
BSS_Player->sonicFrames = RSDK.LoadSpriteAnimation("SpecialBS/Sonic.bin", SCOPE_STAGE);
152
BSS_Player->tailsFrames = RSDK.LoadSpriteAnimation("SpecialBS/Tails.bin", SCOPE_STAGE);
153
BSS_Player->knuxFrames = RSDK.LoadSpriteAnimation("SpecialBS/Knuckles.bin", SCOPE_STAGE);
154
BSS_Player->mightyFrames = RSDK.LoadSpriteAnimation("SpecialBS/Mighty.bin", SCOPE_STAGE);
155
BSS_Player->rayFrames = RSDK.LoadSpriteAnimation("SpecialBS/Ray.bin", SCOPE_STAGE);
156
157
if (globals->playerID == ID_NONE)
158
globals->playerID = ID_DEFAULT_PLAYER;
159
160
RSDK.ResetEntitySlot(SLOT_PLAYER1, BSS_Player->classID, NULL);
161
162
BSS_Player->sfxJump = RSDK.GetSfx("Global/Jump.wav");
163
}
164
165
void BSS_Player_Input_P1(void)
166
{
167
RSDK_THIS(BSS_Player);
168
169
if (self->controllerID < PLAYER_COUNT) {
170
RSDKControllerState *controller = &ControllerInfo[self->controllerID];
171
RSDKAnalogState *stick = &AnalogStickInfoL[self->controllerID];
172
173
self->up = controller->keyUp.down;
174
self->down = controller->keyDown.down;
175
self->left = controller->keyLeft.down;
176
self->right = controller->keyRight.down;
177
178
self->up |= stick->keyUp.down;
179
self->down |= stick->keyDown.down;
180
self->left |= stick->keyLeft.down;
181
self->right |= stick->keyRight.down;
182
183
#if MANIA_USE_PLUS
184
self->up |= stick->vDelta > 0.3;
185
self->down |= stick->vDelta < -0.3;
186
self->left |= stick->hDelta < -0.3;
187
self->right |= stick->hDelta > 0.3;
188
#else
189
self->up |= stick->vDeltaL > 0.3;
190
self->down |= stick->vDeltaL < -0.3;
191
self->left |= stick->hDeltaL < -0.3;
192
self->right |= stick->hDeltaL > 0.3;
193
#endif
194
195
if (self->left && self->right) {
196
self->left = false;
197
self->right = false;
198
}
199
self->jumpPress = controller->keyA.press || controller->keyB.press || controller->keyC.press || controller->keyX.press;
200
201
if (controller->keyStart.press || Unknown_pausePress) {
202
if (SceneInfo->state == ENGINESTATE_REGULAR) {
203
EntityPauseMenu *pauseMenu = RSDK_GET_ENTITY(SLOT_PAUSEMENU, PauseMenu);
204
if (!pauseMenu->classID) {
205
RSDK.ResetEntitySlot(SLOT_PAUSEMENU, PauseMenu->classID, NULL);
206
pauseMenu->triggerPlayer = RSDK.GetEntitySlot(self);
207
pauseMenu->disableRestart = true;
208
}
209
}
210
}
211
}
212
}
213
214
void BSS_Player_Input_P2(void)
215
{
216
RSDK_THIS(BSS_Player);
217
218
// Bug Details:
219
// this uses "self->jumpPress" for the state rather than "player1->jumpPress" as intended
220
// this results in P2 never actually jumping
221
// Fix:
222
// replace "BSS_Player->jumpPressState |= self->jumpPress;" with "BSS_Player->jumpPressState |= player1->jumpPress;"
223
224
// EntityBSS_Player *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, BSS_Player);
225
BSS_Player->jumpPressState <<= 1;
226
BSS_Player->jumpPressState |= self->jumpPress;
227
BSS_Player->jumpPressState &= 0xFFFF;
228
229
self->jumpPress = BSS_Player->jumpPressState >> 15;
230
}
231
232
#if GAME_INCLUDE_EDITOR
233
void BSS_Player_EditorDraw(void)
234
{
235
RSDK_THIS(BSS_Player);
236
237
RSDK.SetSpriteAnimation(BSS_Player->sonicFrames, 0, &self->animator, false, 0);
238
239
RSDK.DrawSprite(&self->animator, NULL, true);
240
}
241
242
void BSS_Player_EditorLoad(void) { BSS_Player->sonicFrames = RSDK.LoadSpriteAnimation("SpecialBS/Sonic.bin", SCOPE_STAGE); }
243
#endif
244
245
void BSS_Player_Serialize(void) {}
246
247