Path: blob/master/SonicMania/Objects/Global/Camera.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: Camera Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectCamera *Camera;1011void Camera_Update(void) {}1213void Camera_LateUpdate(void)14{15RSDK_THIS(Camera);1617self->lastPos.x = self->position.x;18self->lastPos.y = self->position.y;1920StateMachine_Run(self->state);2122self->velocity.x = self->position.x - self->lastPos.x;23self->velocity.y = self->position.y - self->lastPos.y;2425Camera_SetCameraBounds(self);2627if (self->shakePos.x) {28if (self->shakePos.x <= 0)29self->shakePos.x = -1 - self->shakePos.x;30else31self->shakePos.x = -self->shakePos.x;32}3334if (self->shakePos.y) {35if (self->shakePos.y <= 0)36self->shakePos.y = -1 - self->shakePos.y;37else38self->shakePos.y = -self->shakePos.y;39}4041if (!self->disableYOffset)42self->offset.y = MAX(self->offset.y - (self->offset.y >> 3), 0);43}4445void Camera_StaticUpdate(void)46{47if (Camera->centerBounds.x < TO_FIXED(16))48Camera->centerBounds.x += 0x4000;4950if (Camera->centerBounds.y < TO_FIXED(24))51Camera->centerBounds.y += 0x8000;52}5354void Camera_Draw(void) {}5556void Camera_Create(void *data)57{58RSDK_THIS(Camera);5960int32 screen = VOID_TO_INT(data);61self->offset.x = TO_FIXED(8);62self->centerY = ScreenInfo->center.y - 16;63if (self->active != ACTIVE_NORMAL) {64self->screenID = screen;65RSDK.AddCamera(&self->center, TO_FIXED(ScreenInfo[screen].center.x), TO_FIXED(ScreenInfo[screen].center.y), false);66}6768self->boundsOffset.x = 3;69self->boundsOffset.y = 2;70self->active = ACTIVE_NORMAL;7172if (!Zone->setATLBounds) {73self->boundsL = Zone->cameraBoundsL[self->screenID];74self->boundsR = Zone->cameraBoundsR[self->screenID];75self->boundsT = Zone->cameraBoundsT[self->screenID];76self->boundsB = Zone->cameraBoundsB[self->screenID];7778if (self->target) {79self->position.x = self->target->position.x;80self->position.y = self->target->position.y;81self->state = Camera_State_FollowXY;82}83else {84self->state = Camera_State_MapView;85}86}87}8889void Camera_StageLoad(void)90{91// I don't think this object is in the final credits right...?92// Likely a holdover from the earlier credits revision93if (!RSDK.CheckSceneFolder("Credits")) {94for (int32 i = 0; i < RSDK.GetVideoSetting(VIDEOSETTING_SCREENCOUNT); ++i)95RSDK.ResetEntitySlot(SLOT_CAMERA1 + i, Camera->classID, INT_TO_VOID(i));9697Camera->centerBounds.x = TO_FIXED(16);98Camera->centerBounds.y = TO_FIXED(24);99}100}101102void Camera_SetCameraBounds(EntityCamera *entity)103{104RSDKScreenInfo *screen = &ScreenInfo[entity->screenID];105screen->position.x = FROM_FIXED(entity->position.x) + entity->lookPos.x - screen->center.x;106screen->position.y = FROM_FIXED(entity->position.y) + entity->lookPos.y - entity->centerY;107108if (screen->position.x < entity->boundsL)109screen->position.x = entity->boundsL;110111if (screen->size.x + screen->position.x > entity->boundsR)112screen->position.x = entity->boundsR - screen->size.x;113114if (screen->position.y < entity->boundsT)115screen->position.y = entity->boundsT;116117if (screen->size.y + screen->position.y > entity->boundsB)118screen->position.y = entity->boundsB - screen->size.y;119120screen->position.x += entity->shakePos.x;121screen->position.y += entity->shakePos.y;122123entity->center.x = screen->position.x + screen->center.x;124entity->center.y = screen->position.y + screen->center.y;125}126EntityCamera *Camera_SetTargetEntity(int32 screen, void *t)127{128Entity *target = (Entity *)t;129130foreach_all(Camera, camera)131{132if (camera->screenID == screen) {133camera->target = target;134camera->position.x = target->position.x;135camera->position.y = target->position.y;136foreach_return camera;137}138}139return NULL;140}141void Camera_ShakeScreen(int32 screen, int32 shakeX, int32 shakeY)142{143foreach_all(Camera, camera)144{145if (camera->screenID == screen) {146camera->shakePos.x = shakeX;147camera->shakePos.y = shakeY;148foreach_break;149}150}151}152void Camera_HandleHBounds(void)153{154RSDK_THIS(Camera);155156RSDKScreenInfo *screen = &ScreenInfo[self->screenID];157158if (Zone->cameraBoundsL[self->screenID] > self->boundsL) {159if (screen->position.x > Zone->cameraBoundsL[self->screenID])160self->boundsL = Zone->cameraBoundsL[self->screenID];161else162self->boundsL = screen->position.x;163}164165if (Zone->cameraBoundsL[self->screenID] < self->boundsL) {166if (screen->position.x <= self->boundsL) {167int32 off = self->boundsL - self->boundsOffset.x;168self->boundsL = off;169if (self->velocity.x < 0) {170self->boundsL += FROM_FIXED(self->velocity.x);171if (self->boundsL < Zone->cameraBoundsL[self->screenID])172self->boundsL = Zone->cameraBoundsL[self->screenID];173}174}175else {176self->boundsL = Zone->cameraBoundsL[self->screenID];177}178}179180if (Zone->cameraBoundsR[self->screenID] < self->boundsR) {181if (screen->size.x + screen->position.x < Zone->cameraBoundsR[self->screenID])182self->boundsR = Zone->cameraBoundsR[self->screenID];183else184self->boundsR = screen->size.x + screen->position.x;185}186187if (Zone->cameraBoundsR[self->screenID] > self->boundsR) {188if (screen->size.x + screen->position.x >= self->boundsR) {189self->boundsR += self->boundsOffset.x;190if (self->velocity.x > 0) {191self->boundsR = FROM_FIXED(self->velocity.x) + self->boundsR;192if (self->boundsR > Zone->cameraBoundsR[self->screenID])193self->boundsR = Zone->cameraBoundsR[self->screenID];194}195}196else {197self->boundsR = Zone->cameraBoundsR[self->screenID];198}199}200201Zone->playerBoundsL[self->screenID] = self->boundsL << 16;202Zone->playerBoundsR[self->screenID] = self->boundsR << 16;203}204void Camera_HandleVBounds(void)205{206RSDK_THIS(Camera);207208RSDKScreenInfo *screen = &ScreenInfo[self->screenID];209210if (Zone->cameraBoundsT[self->screenID] > self->boundsT) {211if (screen->position.y <= self->boundsT)212self->boundsT = screen->position.y + self->boundsOffset.y;213else214self->boundsT = screen->position.y;215}216217if (Zone->cameraBoundsT[self->screenID] < self->boundsT) {218if (screen->position.y <= self->boundsT) {219self->boundsT = self->boundsT - self->boundsOffset.y;220221if (self->velocity.y < 0) {222self->boundsT += FROM_FIXED(self->velocity.y);223if (self->boundsT < Zone->cameraBoundsT[self->screenID])224self->boundsT = Zone->cameraBoundsT[self->screenID];225}226}227else {228self->boundsT = Zone->cameraBoundsT[self->screenID];229}230}231232if (Zone->cameraBoundsB[self->screenID] < self->boundsB) {233if (screen->size.y + screen->position.y >= self->boundsB)234self->boundsB -= 2;235else236self->boundsB = screen->size.y + screen->position.y;237}238239if (Zone->cameraBoundsB[self->screenID] > self->boundsB) {240if (screen->size.y + screen->position.y >= self->boundsB) {241self->boundsB += self->boundsOffset.y;242243if (self->velocity.y > 0) {244self->boundsB += FROM_FIXED(self->velocity.y);245if (self->boundsB > Zone->cameraBoundsB[self->screenID])246self->boundsB = Zone->cameraBoundsB[self->screenID];247}248}249else {250self->boundsB = Zone->cameraBoundsB[self->screenID];251}252}253254Zone->playerBoundsT[self->screenID] = self->boundsT << 16;255Zone->playerBoundsB[self->screenID] = self->boundsB << 16;256}257258void Camera_SetupLerp(int32 type, int32 screen, int32 x, int32 y, int32 speed)259{260foreach_all(Camera, camera)261{262if (camera->screenID == screen) {263camera->startLerpPos.x = camera->position.x;264camera->startLerpPos.y = camera->position.y;265camera->endLerpPos.x = x;266camera->endLerpPos.y = y;267camera->lerpType = type;268camera->lerpSpeed = speed;269camera->state = Camera_State_HandleLerp;270foreach_break;271}272}273}274275// States276void Camera_State_MapView(void)277{278RSDK_THIS(Camera);279280int32 speed = TO_FIXED(4);281if (ControllerInfo[CONT_P1].keyA.down)282speed = TO_FIXED(16);283284if (ControllerInfo[CONT_P1].keyUp.down)285self->position.y -= speed;286else if (ControllerInfo[CONT_P1].keyDown.down)287self->position.y += speed;288if (ControllerInfo[CONT_P1].keyLeft.down)289self->position.x -= speed;290else if (ControllerInfo[CONT_P1].keyRight.down)291self->position.x += speed;292293self->position.x = FROM_FIXED(self->position.x);294self->position.y = FROM_FIXED(self->position.y);295RSDKScreenInfo *screen = &ScreenInfo[self->screenID];296297if (self->position.x >= screen->center.x) {298if (self->position.x > Zone->cameraBoundsR[self->screenID] - screen->center.x)299self->position.x = Zone->cameraBoundsR[self->screenID] - screen->center.x;300}301else {302self->position.x = screen->center.x;303}304305if (self->position.y >= screen->center.y) {306if (self->position.y > Zone->cameraBoundsB[self->screenID] - screen->center.y)307self->position.y = Zone->cameraBoundsB[self->screenID] - screen->center.y;308}309else {310self->position.y = screen->center.y;311}312313self->position.x <<= 0x10;314self->position.y <<= 0x10;315}316void Camera_State_FollowXY(void)317{318RSDK_THIS(Camera);319320if (self->target) {321Camera_HandleHBounds();322Camera_HandleVBounds();323324Entity *target = self->target;325target->position.x += self->targetMoveVel.x;326327if (target->position.x <= self->position.x + self->offset.x) {328if (target->position.x < self->position.x - self->offset.x) {329int32 pos = target->position.x + self->offset.x - self->position.x;330if (pos < -Camera->centerBounds.x)331pos = -Camera->centerBounds.x;332self->position.x += pos;333}334target->position.x -= self->targetMoveVel.x;335}336else {337int32 pos = target->position.x - self->position.x - self->offset.x;338if (pos > Camera->centerBounds.x)339pos = Camera->centerBounds.x;340self->position.x += pos;341342target->position.x -= self->targetMoveVel.x;343}344345target->position.y += self->targetMoveVel.y;346347int32 adjust = target->position.y - self->adjustY;348if (adjust <= self->position.y + self->offset.y) {349if (adjust < self->position.y - self->offset.y) {350int32 pos = target->position.y + self->offset.y - self->position.y - self->adjustY;351if (pos < -Camera->centerBounds.y)352pos = -Camera->centerBounds.y;353self->position.y += pos;354}355356target->position.y -= self->targetMoveVel.y;357}358else {359int32 pos = adjust - self->position.y - self->offset.y;360if (pos > Camera->centerBounds.y)361pos = Camera->centerBounds.y;362self->position.y += pos;363target->position.y -= self->targetMoveVel.y;364}365}366}367void Camera_State_FollowX(void)368{369RSDK_THIS(Camera);370371if (self->target) {372Camera_HandleHBounds();373374Entity *target = self->target;375target->position.x += self->targetMoveVel.x;376377if (target->position.x <= self->position.x + self->offset.x) {378if (target->position.x < self->position.x - self->offset.x) {379int32 pos = target->position.x + self->offset.x - self->position.x;380if (pos < -Camera->centerBounds.x)381pos = -Camera->centerBounds.x;382self->position.x = self->position.x + pos;383}384target->position.x -= self->targetMoveVel.x;385}386else {387int32 pos = target->position.x - self->position.x - self->offset.x;388if (pos > Camera->centerBounds.x)389pos = Camera->centerBounds.x;390self->position.x = self->position.x + pos;391target->position.x -= self->targetMoveVel.x;392}393}394}395void Camera_State_FollowY(void)396{397RSDK_THIS(Camera);398399if (self->target) {400Camera_HandleVBounds();401402Entity *target = self->target;403target->position.y += self->targetMoveVel.y;404405int32 adjust = target->position.y - self->adjustY;406if (adjust <= self->position.y + self->offset.y) {407if (adjust < self->position.y - self->offset.y) {408int32 pos = target->position.y + self->offset.y - self->position.y - self->adjustY;409if (pos < -Camera->centerBounds.y)410pos = -Camera->centerBounds.y;411self->position.y = self->position.y + pos;412}413target->position.y -= self->targetMoveVel.y;414}415else {416int32 pos = adjust - self->position.y - self->offset.y;417if (pos > Camera->centerBounds.y)418pos = Camera->centerBounds.y;419self->position.y = self->position.y + pos;420target->position.y -= self->targetMoveVel.y;421}422}423}424void Camera_State_HandleLerp(void)425{426RSDK_THIS(Camera);427428self->lerpPercent += self->lerpSpeed;429430switch (self->lerpType) {431default: break;432case CAMERA_LERP_NORMAL:433MathHelpers_Lerp(&self->position, self->lerpPercent, self->startLerpPos.x, self->startLerpPos.y, self->endLerpPos.x, self->endLerpPos.y);434break;435436case CAMERA_LERP_SIN1024:437MathHelpers_LerpSin1024(&self->position, self->lerpPercent, self->startLerpPos.x, self->startLerpPos.y, self->endLerpPos.x,438self->endLerpPos.y);439break;440441case CAMERA_LERP_SIN1024_2:442MathHelpers_Lerp2Sin1024(&self->position, self->lerpPercent, self->startLerpPos.x, self->startLerpPos.y, self->endLerpPos.x,443self->endLerpPos.y);444break;445446case CAMERA_LERP_SIN512:447MathHelpers_LerpSin512(&self->position, self->lerpPercent, self->startLerpPos.x, self->startLerpPos.y, self->endLerpPos.x,448self->endLerpPos.y);449break;450}451452if (self->lerpPercent >= 0x100) {453self->lerpPercent = 0;454self->state = StateMachine_None;455}456}457458#if GAME_INCLUDE_EDITOR459void Camera_EditorDraw(void)460{461RSDK_THIS(Camera);462463// Camera preview :)464if (showGizmos()) {465RSDK_DRAWING_OVERLAY(true);466DrawHelpers_DrawRectOutline(self->position.x, self->position.y, TO_FIXED(WIDE_SCR_XSIZE), TO_FIXED(SCREEN_YSIZE), 0xFF0000);467RSDK_DRAWING_OVERLAY(false);468}469}470471void Camera_EditorLoad(void) {}472#endif473474void Camera_Serialize(void) {}475476477