Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/Pinball/PBL_Player.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: PBL_Player Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
#if MANIA_USE_PLUS
11
ObjectPBL_Player *PBL_Player;
12
13
void PBL_Player_Update(void)
14
{
15
RSDK_THIS(PBL_Player);
16
17
StateMachine_Run(self->stateInput);
18
StateMachine_Run(self->state);
19
20
self->angleX = ((uint16)self->angleX - (uint16)((abs(self->velocity.y) + abs(self->velocity.x)) >> 12)) & 0x3FF;
21
self->rotation = 4 * RSDK.ATan2(-self->velocity.y, self->velocity.x);
22
23
if (!(self->angleX & 0x100))
24
self->animator.animationID = PBL_Player->jumpFrames;
25
else
26
self->animator.animationID = PBL_Player->ballFrames;
27
28
RSDK.ProcessAnimation(&self->animator);
29
}
30
31
void PBL_Player_LateUpdate(void)
32
{
33
RSDK_THIS(PBL_Player);
34
35
Matrix *mat = &PBL_Camera->matWorld;
36
37
self->zdepth = mat->values[2][3] + mat->values[2][0] * FROM_FIXED(self->position.x) + mat->values[2][2] * FROM_FIXED(self->position.y)
38
+ mat->values[2][1] * FROM_FIXED(self->height);
39
}
40
41
void PBL_Player_StaticUpdate(void) {}
42
43
void PBL_Player_Draw(void)
44
{
45
RSDK_THIS(PBL_Player);
46
47
if (self->zdepth >= 0x4000) {
48
RSDK.Prepare3DScene(PBL_Player->sceneIndex);
49
50
RSDK.MatrixTranslateXYZ(&self->matTranslate, self->position.x, self->height + 0x100000, self->position.y, true);
51
RSDK.MatrixRotateX(&self->matRotate, self->angleX);
52
RSDK.MatrixRotateY(&self->matWorld, self->rotation);
53
54
RSDK.MatrixMultiply(&self->matNormal, &self->matRotate, &self->matWorld);
55
RSDK.MatrixMultiply(&self->matWorld, &self->matNormal, &self->matTranslate);
56
RSDK.MatrixMultiply(&self->matWorld, &self->matWorld, &PBL_Camera->matWorld);
57
RSDK.MatrixMultiply(&self->matNormal, &self->matNormal, &PBL_Camera->matNormalItem);
58
59
RSDK.AddModelTo3DScene(self->animator.animationID, PBL_Player->sceneIndex, S3D_SOLIDCOLOR_SHADED_BLENDED_SCREEN, &self->matWorld,
60
&self->matNormal, 0xFFFFFF);
61
62
RSDK.Draw3DScene(PBL_Player->sceneIndex);
63
}
64
}
65
66
void PBL_Player_Create(void *data)
67
{
68
RSDK_THIS(PBL_Player);
69
70
if (!SceneInfo->inEditor) {
71
self->active = ACTIVE_NORMAL;
72
self->visible = true;
73
self->updateRange.x = 0x800000;
74
self->updateRange.y = 0x800000;
75
self->drawGroup = 4;
76
77
self->stateInput = PBL_Player_Input_P1;
78
self->state = PBL_Player_State_Launcher;
79
self->controllerID = 1;
80
81
self->onGround = false;
82
self->tileCollisions = TILECOLLISION_DOWN;
83
self->collisionLayers = 1 << PBL_Setup->tableHigh;
84
85
RSDK.SetModelAnimation(PBL_Player->jumpFrames, &self->animator, 128, 0, true, 0);
86
87
foreach_all(PBL_Camera, camera) { camera->target = (Entity *)self; }
88
}
89
}
90
91
void PBL_Player_StageLoad(void)
92
{
93
if (globals->playerID == ID_NONE) {
94
globals->playerID = ID_DEFAULT_PLAYER;
95
globals->characterFlags = ID_SONIC;
96
}
97
98
switch (GET_CHARACTER_ID(1)) {
99
default:
100
case ID_SONIC:
101
PBL_Player->jumpFrames = RSDK.LoadMesh("Special/SonicJump.bin", SCOPE_STAGE);
102
PBL_Player->ballFrames = RSDK.LoadMesh("Special/SonicBall.bin", SCOPE_STAGE);
103
104
PBL_Player->outerBox.top = -12;
105
PBL_Player->outerBox.bottom = 12;
106
PBL_Player->innerBox.top = -12;
107
PBL_Player->innerBox.bottom = 12;
108
break;
109
110
case ID_TAILS:
111
PBL_Player->jumpFrames = RSDK.LoadMesh("Special/TailsJump.bin", SCOPE_STAGE);
112
PBL_Player->ballFrames = RSDK.LoadMesh("Special/TailsBall.bin", SCOPE_STAGE);
113
114
PBL_Player->outerBox.top = -10;
115
PBL_Player->outerBox.bottom = 10;
116
PBL_Player->innerBox.top = -10;
117
PBL_Player->innerBox.bottom = 10;
118
break;
119
120
case ID_KNUCKLES:
121
PBL_Player->jumpFrames = RSDK.LoadMesh("Special/KnuxJump.bin", SCOPE_STAGE);
122
PBL_Player->ballFrames = RSDK.LoadMesh("Special/KnuxBall.bin", SCOPE_STAGE);
123
124
PBL_Player->outerBox.top = -12;
125
PBL_Player->outerBox.bottom = 12;
126
PBL_Player->innerBox.top = -12;
127
PBL_Player->innerBox.bottom = 12;
128
break;
129
130
case ID_MIGHTY:
131
PBL_Player->jumpFrames = RSDK.LoadMesh("Special/MightyJump.bin", SCOPE_STAGE);
132
PBL_Player->ballFrames = RSDK.LoadMesh("Special/MightyBall.bin", SCOPE_STAGE);
133
134
PBL_Player->outerBox.top = -12;
135
PBL_Player->outerBox.bottom = 12;
136
PBL_Player->innerBox.top = -12;
137
PBL_Player->innerBox.bottom = 12;
138
break;
139
140
case ID_RAY:
141
PBL_Player->jumpFrames = RSDK.LoadMesh("Special/RayJump.bin", SCOPE_STAGE);
142
PBL_Player->ballFrames = RSDK.LoadMesh("Special/RayBall.bin", SCOPE_STAGE);
143
144
PBL_Player->outerBox.top = -10;
145
PBL_Player->outerBox.bottom = 10;
146
PBL_Player->innerBox.top = -10;
147
PBL_Player->innerBox.bottom = 10;
148
break;
149
}
150
151
PBL_Player->outerBox.left = -10;
152
PBL_Player->outerBox.right = 10;
153
PBL_Player->innerBox.left = -10;
154
PBL_Player->innerBox.right = 10;
155
156
PBL_Player->sceneIndex = RSDK.Create3DScene("View:Pinball", 4096, SCOPE_STAGE);
157
158
RSDK.SetDiffuseColor(PBL_Player->sceneIndex, 0xA0, 0xA0, 0xA0);
159
RSDK.SetDiffuseIntensity(PBL_Player->sceneIndex, 8, 8, 8);
160
RSDK.SetSpecularIntensity(PBL_Player->sceneIndex, 15, 15, 15);
161
162
PBL_Player->sfxPlunger = RSDK.GetSfx("Pinball/Plunger.wav");
163
}
164
165
void PBL_Player_Input_P1(void)
166
{
167
RSDK_THIS(PBL_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
self->up |= stick->vDelta > 0.3;
184
self->down |= stick->vDelta < -0.3;
185
self->left |= stick->hDelta < -0.3;
186
self->right |= stick->hDelta > 0.3;
187
188
if (self->left && self->right) {
189
self->left = false;
190
self->right = false;
191
}
192
193
// I don't think this is used, ever LOL
194
self->jumpPress = controller->keyA.press || controller->keyB.press || controller->keyC.press || controller->keyX.press;
195
196
if (controller->keyStart.press || Unknown_pausePress) {
197
if (SceneInfo->state == ENGINESTATE_REGULAR) {
198
EntityPauseMenu *pauseMenu = RSDK_GET_ENTITY(SLOT_PAUSEMENU, PauseMenu);
199
if (!pauseMenu->classID) {
200
RSDK.ResetEntitySlot(SLOT_PAUSEMENU, PauseMenu->classID, NULL);
201
pauseMenu->triggerPlayer = RSDK.GetEntitySlot(self);
202
pauseMenu->disableRestart = true;
203
}
204
}
205
}
206
}
207
}
208
209
void PBL_Player_State_Launcher(void)
210
{
211
RSDK_THIS(PBL_Player);
212
213
if (!self->onGround)
214
self->velocity.y += 0x3800;
215
216
RSDK.ProcessObjectMovement(self, &PBL_Player->outerBox, &PBL_Player->innerBox);
217
218
if (++self->timer == 60) {
219
self->velocity.y = -0xE0000;
220
self->timer = 0;
221
self->collisionPlane = 1;
222
self->onGround = false;
223
self->state = PBL_Player_State_Air;
224
RSDK.PlaySfx(PBL_Player->sfxPlunger, false, 255);
225
}
226
}
227
228
void PBL_Player_State_Ground(void)
229
{
230
RSDK_THIS(PBL_Player);
231
232
if (!self->angle && abs(self->groundVel) < 0x10000) {
233
self->groundVel = RSDK.Rand(-0x20000, 0x20000);
234
}
235
236
self->groundVel += 0x2800 * RSDK.Sin256(self->angle) >> 8;
237
238
if (self->collisionMode) {
239
if (self->angle >= 0x40 && self->angle <= 0xC0 && abs(self->groundVel) < 0x20000) {
240
self->velocity.x = (self->groundVel * RSDK.Cos256(self->angle)) >> 8;
241
self->velocity.y = (self->groundVel * RSDK.Sin256(self->angle)) >> 8;
242
self->onGround = false;
243
self->angle = 0;
244
self->collisionMode = CMODE_FLOOR;
245
}
246
}
247
248
if (!self->onGround)
249
self->state = PBL_Player_State_Air;
250
251
RSDK.ProcessObjectMovement(self, &PBL_Player->outerBox, &PBL_Player->innerBox);
252
}
253
254
void PBL_Player_State_Air(void)
255
{
256
RSDK_THIS(PBL_Player);
257
258
self->velocity.y += 0x2800;
259
260
if (abs(self->velocity.x) > abs(self->velocity.y)) {
261
if (RSDK.ObjectTileCollision(self, self->collisionLayers, CMODE_LWALL, self->collisionPlane, self->velocity.x + 0x100000, 0, false))
262
self->velocity.x = -(self->velocity.x >> 1);
263
264
if (RSDK.ObjectTileCollision(self, self->collisionLayers, CMODE_RWALL, self->collisionPlane, self->velocity.x - 0x100000, 0, false))
265
self->velocity.x = -(self->velocity.x >> 1);
266
}
267
268
RSDK.ProcessObjectMovement(self, &PBL_Player->outerBox, &PBL_Player->innerBox);
269
270
if (self->left)
271
self->velocity.x -= 0x800;
272
else if (self->right)
273
self->velocity.x += 0x800;
274
275
if (self->onGround) {
276
if (!self->collisionMode)
277
self->collisionPlane = 0;
278
279
self->state = PBL_Player_State_Ground;
280
}
281
}
282
283
#if GAME_INCLUDE_EDITOR
284
void PBL_Player_EditorDraw(void)
285
{
286
RSDK_THIS(PBL_Player);
287
288
RSDK.SetSpriteAnimation(PBL_Player->aniFrames, 0, &self->animator, true, 7);
289
RSDK.DrawSprite(&self->animator, NULL, false);
290
}
291
292
void PBL_Player_EditorLoad(void) { PBL_Player->aniFrames = RSDK.LoadSpriteAnimation("Editor/PlayerIcons.bin", SCOPE_STAGE); }
293
#endif
294
295
void PBL_Player_Serialize(void) {}
296
#endif
297
298