Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/Global/Camera.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: Camera Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectCamera *Camera;
11
12
void Camera_Update(void) {}
13
14
void Camera_LateUpdate(void)
15
{
16
RSDK_THIS(Camera);
17
18
self->lastPos.x = self->position.x;
19
self->lastPos.y = self->position.y;
20
21
StateMachine_Run(self->state);
22
23
self->velocity.x = self->position.x - self->lastPos.x;
24
self->velocity.y = self->position.y - self->lastPos.y;
25
26
Camera_SetCameraBounds(self);
27
28
if (self->shakePos.x) {
29
if (self->shakePos.x <= 0)
30
self->shakePos.x = -1 - self->shakePos.x;
31
else
32
self->shakePos.x = -self->shakePos.x;
33
}
34
35
if (self->shakePos.y) {
36
if (self->shakePos.y <= 0)
37
self->shakePos.y = -1 - self->shakePos.y;
38
else
39
self->shakePos.y = -self->shakePos.y;
40
}
41
42
if (!self->disableYOffset)
43
self->offset.y = MAX(self->offset.y - (self->offset.y >> 3), 0);
44
}
45
46
void Camera_StaticUpdate(void)
47
{
48
if (Camera->centerBounds.x < TO_FIXED(16))
49
Camera->centerBounds.x += 0x4000;
50
51
if (Camera->centerBounds.y < TO_FIXED(24))
52
Camera->centerBounds.y += 0x8000;
53
}
54
55
void Camera_Draw(void) {}
56
57
void Camera_Create(void *data)
58
{
59
RSDK_THIS(Camera);
60
61
int32 screen = VOID_TO_INT(data);
62
self->offset.x = TO_FIXED(8);
63
self->centerY = ScreenInfo->center.y - 16;
64
if (self->active != ACTIVE_NORMAL) {
65
self->screenID = screen;
66
RSDK.AddCamera(&self->center, TO_FIXED(ScreenInfo[screen].center.x), TO_FIXED(ScreenInfo[screen].center.y), false);
67
}
68
69
self->boundsOffset.x = 3;
70
self->boundsOffset.y = 2;
71
self->active = ACTIVE_NORMAL;
72
73
if (!Zone->setATLBounds) {
74
self->boundsL = Zone->cameraBoundsL[self->screenID];
75
self->boundsR = Zone->cameraBoundsR[self->screenID];
76
self->boundsT = Zone->cameraBoundsT[self->screenID];
77
self->boundsB = Zone->cameraBoundsB[self->screenID];
78
79
if (self->target) {
80
self->position.x = self->target->position.x;
81
self->position.y = self->target->position.y;
82
self->state = Camera_State_FollowXY;
83
}
84
else {
85
self->state = Camera_State_MapView;
86
}
87
}
88
}
89
90
void Camera_StageLoad(void)
91
{
92
// I don't think this object is in the final credits right...?
93
// Likely a holdover from the earlier credits revision
94
if (!RSDK.CheckSceneFolder("Credits")) {
95
for (int32 i = 0; i < RSDK.GetVideoSetting(VIDEOSETTING_SCREENCOUNT); ++i)
96
RSDK.ResetEntitySlot(SLOT_CAMERA1 + i, Camera->classID, INT_TO_VOID(i));
97
98
Camera->centerBounds.x = TO_FIXED(16);
99
Camera->centerBounds.y = TO_FIXED(24);
100
}
101
}
102
103
void Camera_SetCameraBounds(EntityCamera *entity)
104
{
105
RSDKScreenInfo *screen = &ScreenInfo[entity->screenID];
106
screen->position.x = FROM_FIXED(entity->position.x) + entity->lookPos.x - screen->center.x;
107
screen->position.y = FROM_FIXED(entity->position.y) + entity->lookPos.y - entity->centerY;
108
109
if (screen->position.x < entity->boundsL)
110
screen->position.x = entity->boundsL;
111
112
if (screen->size.x + screen->position.x > entity->boundsR)
113
screen->position.x = entity->boundsR - screen->size.x;
114
115
if (screen->position.y < entity->boundsT)
116
screen->position.y = entity->boundsT;
117
118
if (screen->size.y + screen->position.y > entity->boundsB)
119
screen->position.y = entity->boundsB - screen->size.y;
120
121
screen->position.x += entity->shakePos.x;
122
screen->position.y += entity->shakePos.y;
123
124
entity->center.x = screen->position.x + screen->center.x;
125
entity->center.y = screen->position.y + screen->center.y;
126
}
127
EntityCamera *Camera_SetTargetEntity(int32 screen, void *t)
128
{
129
Entity *target = (Entity *)t;
130
131
foreach_all(Camera, camera)
132
{
133
if (camera->screenID == screen) {
134
camera->target = target;
135
camera->position.x = target->position.x;
136
camera->position.y = target->position.y;
137
foreach_return camera;
138
}
139
}
140
return NULL;
141
}
142
void Camera_ShakeScreen(int32 screen, int32 shakeX, int32 shakeY)
143
{
144
foreach_all(Camera, camera)
145
{
146
if (camera->screenID == screen) {
147
camera->shakePos.x = shakeX;
148
camera->shakePos.y = shakeY;
149
foreach_break;
150
}
151
}
152
}
153
void Camera_HandleHBounds(void)
154
{
155
RSDK_THIS(Camera);
156
157
RSDKScreenInfo *screen = &ScreenInfo[self->screenID];
158
159
if (Zone->cameraBoundsL[self->screenID] > self->boundsL) {
160
if (screen->position.x > Zone->cameraBoundsL[self->screenID])
161
self->boundsL = Zone->cameraBoundsL[self->screenID];
162
else
163
self->boundsL = screen->position.x;
164
}
165
166
if (Zone->cameraBoundsL[self->screenID] < self->boundsL) {
167
if (screen->position.x <= self->boundsL) {
168
int32 off = self->boundsL - self->boundsOffset.x;
169
self->boundsL = off;
170
if (self->velocity.x < 0) {
171
self->boundsL += FROM_FIXED(self->velocity.x);
172
if (self->boundsL < Zone->cameraBoundsL[self->screenID])
173
self->boundsL = Zone->cameraBoundsL[self->screenID];
174
}
175
}
176
else {
177
self->boundsL = Zone->cameraBoundsL[self->screenID];
178
}
179
}
180
181
if (Zone->cameraBoundsR[self->screenID] < self->boundsR) {
182
if (screen->size.x + screen->position.x < Zone->cameraBoundsR[self->screenID])
183
self->boundsR = Zone->cameraBoundsR[self->screenID];
184
else
185
self->boundsR = screen->size.x + screen->position.x;
186
}
187
188
if (Zone->cameraBoundsR[self->screenID] > self->boundsR) {
189
if (screen->size.x + screen->position.x >= self->boundsR) {
190
self->boundsR += self->boundsOffset.x;
191
if (self->velocity.x > 0) {
192
self->boundsR = FROM_FIXED(self->velocity.x) + self->boundsR;
193
if (self->boundsR > Zone->cameraBoundsR[self->screenID])
194
self->boundsR = Zone->cameraBoundsR[self->screenID];
195
}
196
}
197
else {
198
self->boundsR = Zone->cameraBoundsR[self->screenID];
199
}
200
}
201
202
Zone->playerBoundsL[self->screenID] = self->boundsL << 16;
203
Zone->playerBoundsR[self->screenID] = self->boundsR << 16;
204
}
205
void Camera_HandleVBounds(void)
206
{
207
RSDK_THIS(Camera);
208
209
RSDKScreenInfo *screen = &ScreenInfo[self->screenID];
210
211
if (Zone->cameraBoundsT[self->screenID] > self->boundsT) {
212
if (screen->position.y <= self->boundsT)
213
self->boundsT = screen->position.y + self->boundsOffset.y;
214
else
215
self->boundsT = screen->position.y;
216
}
217
218
if (Zone->cameraBoundsT[self->screenID] < self->boundsT) {
219
if (screen->position.y <= self->boundsT) {
220
self->boundsT = self->boundsT - self->boundsOffset.y;
221
222
if (self->velocity.y < 0) {
223
self->boundsT += FROM_FIXED(self->velocity.y);
224
if (self->boundsT < Zone->cameraBoundsT[self->screenID])
225
self->boundsT = Zone->cameraBoundsT[self->screenID];
226
}
227
}
228
else {
229
self->boundsT = Zone->cameraBoundsT[self->screenID];
230
}
231
}
232
233
if (Zone->cameraBoundsB[self->screenID] < self->boundsB) {
234
if (screen->size.y + screen->position.y >= self->boundsB)
235
self->boundsB -= 2;
236
else
237
self->boundsB = screen->size.y + screen->position.y;
238
}
239
240
if (Zone->cameraBoundsB[self->screenID] > self->boundsB) {
241
if (screen->size.y + screen->position.y >= self->boundsB) {
242
self->boundsB += self->boundsOffset.y;
243
244
if (self->velocity.y > 0) {
245
self->boundsB += FROM_FIXED(self->velocity.y);
246
if (self->boundsB > Zone->cameraBoundsB[self->screenID])
247
self->boundsB = Zone->cameraBoundsB[self->screenID];
248
}
249
}
250
else {
251
self->boundsB = Zone->cameraBoundsB[self->screenID];
252
}
253
}
254
255
Zone->playerBoundsT[self->screenID] = self->boundsT << 16;
256
Zone->playerBoundsB[self->screenID] = self->boundsB << 16;
257
}
258
259
void Camera_SetupLerp(int32 type, int32 screen, int32 x, int32 y, int32 speed)
260
{
261
foreach_all(Camera, camera)
262
{
263
if (camera->screenID == screen) {
264
camera->startLerpPos.x = camera->position.x;
265
camera->startLerpPos.y = camera->position.y;
266
camera->endLerpPos.x = x;
267
camera->endLerpPos.y = y;
268
camera->lerpType = type;
269
camera->lerpSpeed = speed;
270
camera->state = Camera_State_HandleLerp;
271
foreach_break;
272
}
273
}
274
}
275
276
// States
277
void Camera_State_MapView(void)
278
{
279
RSDK_THIS(Camera);
280
281
int32 speed = TO_FIXED(4);
282
if (ControllerInfo[CONT_P1].keyA.down)
283
speed = TO_FIXED(16);
284
285
if (ControllerInfo[CONT_P1].keyUp.down)
286
self->position.y -= speed;
287
else if (ControllerInfo[CONT_P1].keyDown.down)
288
self->position.y += speed;
289
if (ControllerInfo[CONT_P1].keyLeft.down)
290
self->position.x -= speed;
291
else if (ControllerInfo[CONT_P1].keyRight.down)
292
self->position.x += speed;
293
294
self->position.x = FROM_FIXED(self->position.x);
295
self->position.y = FROM_FIXED(self->position.y);
296
RSDKScreenInfo *screen = &ScreenInfo[self->screenID];
297
298
if (self->position.x >= screen->center.x) {
299
if (self->position.x > Zone->cameraBoundsR[self->screenID] - screen->center.x)
300
self->position.x = Zone->cameraBoundsR[self->screenID] - screen->center.x;
301
}
302
else {
303
self->position.x = screen->center.x;
304
}
305
306
if (self->position.y >= screen->center.y) {
307
if (self->position.y > Zone->cameraBoundsB[self->screenID] - screen->center.y)
308
self->position.y = Zone->cameraBoundsB[self->screenID] - screen->center.y;
309
}
310
else {
311
self->position.y = screen->center.y;
312
}
313
314
self->position.x <<= 0x10;
315
self->position.y <<= 0x10;
316
}
317
void Camera_State_FollowXY(void)
318
{
319
RSDK_THIS(Camera);
320
321
if (self->target) {
322
Camera_HandleHBounds();
323
Camera_HandleVBounds();
324
325
Entity *target = self->target;
326
target->position.x += self->targetMoveVel.x;
327
328
if (target->position.x <= self->position.x + self->offset.x) {
329
if (target->position.x < self->position.x - self->offset.x) {
330
int32 pos = target->position.x + self->offset.x - self->position.x;
331
if (pos < -Camera->centerBounds.x)
332
pos = -Camera->centerBounds.x;
333
self->position.x += pos;
334
}
335
target->position.x -= self->targetMoveVel.x;
336
}
337
else {
338
int32 pos = target->position.x - self->position.x - self->offset.x;
339
if (pos > Camera->centerBounds.x)
340
pos = Camera->centerBounds.x;
341
self->position.x += pos;
342
343
target->position.x -= self->targetMoveVel.x;
344
}
345
346
target->position.y += self->targetMoveVel.y;
347
348
int32 adjust = target->position.y - self->adjustY;
349
if (adjust <= self->position.y + self->offset.y) {
350
if (adjust < self->position.y - self->offset.y) {
351
int32 pos = target->position.y + self->offset.y - self->position.y - self->adjustY;
352
if (pos < -Camera->centerBounds.y)
353
pos = -Camera->centerBounds.y;
354
self->position.y += pos;
355
}
356
357
target->position.y -= self->targetMoveVel.y;
358
}
359
else {
360
int32 pos = adjust - self->position.y - self->offset.y;
361
if (pos > Camera->centerBounds.y)
362
pos = Camera->centerBounds.y;
363
self->position.y += pos;
364
target->position.y -= self->targetMoveVel.y;
365
}
366
}
367
}
368
void Camera_State_FollowX(void)
369
{
370
RSDK_THIS(Camera);
371
372
if (self->target) {
373
Camera_HandleHBounds();
374
375
Entity *target = self->target;
376
target->position.x += self->targetMoveVel.x;
377
378
if (target->position.x <= self->position.x + self->offset.x) {
379
if (target->position.x < self->position.x - self->offset.x) {
380
int32 pos = target->position.x + self->offset.x - self->position.x;
381
if (pos < -Camera->centerBounds.x)
382
pos = -Camera->centerBounds.x;
383
self->position.x = self->position.x + pos;
384
}
385
target->position.x -= self->targetMoveVel.x;
386
}
387
else {
388
int32 pos = target->position.x - self->position.x - self->offset.x;
389
if (pos > Camera->centerBounds.x)
390
pos = Camera->centerBounds.x;
391
self->position.x = self->position.x + pos;
392
target->position.x -= self->targetMoveVel.x;
393
}
394
}
395
}
396
void Camera_State_FollowY(void)
397
{
398
RSDK_THIS(Camera);
399
400
if (self->target) {
401
Camera_HandleVBounds();
402
403
Entity *target = self->target;
404
target->position.y += self->targetMoveVel.y;
405
406
int32 adjust = target->position.y - self->adjustY;
407
if (adjust <= self->position.y + self->offset.y) {
408
if (adjust < self->position.y - self->offset.y) {
409
int32 pos = target->position.y + self->offset.y - self->position.y - self->adjustY;
410
if (pos < -Camera->centerBounds.y)
411
pos = -Camera->centerBounds.y;
412
self->position.y = self->position.y + pos;
413
}
414
target->position.y -= self->targetMoveVel.y;
415
}
416
else {
417
int32 pos = adjust - self->position.y - self->offset.y;
418
if (pos > Camera->centerBounds.y)
419
pos = Camera->centerBounds.y;
420
self->position.y = self->position.y + pos;
421
target->position.y -= self->targetMoveVel.y;
422
}
423
}
424
}
425
void Camera_State_HandleLerp(void)
426
{
427
RSDK_THIS(Camera);
428
429
self->lerpPercent += self->lerpSpeed;
430
431
switch (self->lerpType) {
432
default: break;
433
case CAMERA_LERP_NORMAL:
434
MathHelpers_Lerp(&self->position, self->lerpPercent, self->startLerpPos.x, self->startLerpPos.y, self->endLerpPos.x, self->endLerpPos.y);
435
break;
436
437
case CAMERA_LERP_SIN1024:
438
MathHelpers_LerpSin1024(&self->position, self->lerpPercent, self->startLerpPos.x, self->startLerpPos.y, self->endLerpPos.x,
439
self->endLerpPos.y);
440
break;
441
442
case CAMERA_LERP_SIN1024_2:
443
MathHelpers_Lerp2Sin1024(&self->position, self->lerpPercent, self->startLerpPos.x, self->startLerpPos.y, self->endLerpPos.x,
444
self->endLerpPos.y);
445
break;
446
447
case CAMERA_LERP_SIN512:
448
MathHelpers_LerpSin512(&self->position, self->lerpPercent, self->startLerpPos.x, self->startLerpPos.y, self->endLerpPos.x,
449
self->endLerpPos.y);
450
break;
451
}
452
453
if (self->lerpPercent >= 0x100) {
454
self->lerpPercent = 0;
455
self->state = StateMachine_None;
456
}
457
}
458
459
#if GAME_INCLUDE_EDITOR
460
void Camera_EditorDraw(void)
461
{
462
RSDK_THIS(Camera);
463
464
// Camera preview :)
465
if (showGizmos()) {
466
RSDK_DRAWING_OVERLAY(true);
467
DrawHelpers_DrawRectOutline(self->position.x, self->position.y, TO_FIXED(WIDE_SCR_XSIZE), TO_FIXED(SCREEN_YSIZE), 0xFF0000);
468
RSDK_DRAWING_OVERLAY(false);
469
}
470
}
471
472
void Camera_EditorLoad(void) {}
473
#endif
474
475
void Camera_Serialize(void) {}
476
477