Path: blob/master/SonicMania/Objects/Global/GameOver.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: GameOver Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectGameOver *GameOver;1011void GameOver_Update(void)12{13RSDK_THIS(GameOver);1415StateMachine_Run(self->state);16}1718void GameOver_LateUpdate(void) {}1920void GameOver_StaticUpdate(void) {}2122void GameOver_Draw(void)23{24RSDK_THIS(GameOver);2526#if MANIA_USE_PLUS27if (self->state != GameOver_State_ExitLetters && globals->gameMode == MODE_COMPETITION) {28if (SceneInfo->currentScreenID != self->playerID || RSDK.GetEntityCount(PauseMenu->classID, true) > 0) {29return;30}31}3233EntityPlayer *player = RSDK_GET_ENTITY(SceneInfo->currentScreenID + Player->playerCount, Player);34if (SceneInfo->currentScreenID == self->playerID || player->classID != GameOver->classID)35RSDK.DrawFace(self->verts, 4, 0x00, 0x00, 0x00, 0xFF, INK_NONE);3637if (globals->gameMode != MODE_COMPETITION || SceneInfo->currentScreenID == self->playerID) {38for (self->animator.frameID = 0; self->animator.frameID < GAMEOVER_LETTER_COUNT; ++self->animator.frameID) {39self->rotation = self->letterRotations[self->animator.frameID];40RSDK.DrawSprite(&self->animator, &self->letterPositions[self->animator.frameID], true);41}42}43#else44if (((1 << SceneInfo->currentScreenID) & GameOver->activeScreens) || self->state == GameOver_State_ExitLetters) {45RSDK.DrawFace(self->verts, 4, 0x00, 0x00, 0x00, 0xFF, INK_NONE);4647if (((1 << SceneInfo->currentScreenID) & GameOver->activeScreens)) {48for (self->animator.frameID = 0; self->animator.frameID < GAMEOVER_LETTER_COUNT; ++self->animator.frameID) {49self->rotation = self->letterRotations[self->animator.frameID];50RSDK.DrawSprite(&self->animator, &self->letterPositions[self->animator.frameID], true);51}52}53}54#endif55}5657void GameOver_Create(void *data)58{59RSDK_THIS(GameOver);6061if (!SceneInfo->inEditor) {62self->active = ACTIVE_ALWAYS;63self->visible = true;64self->drawFX = FX_ROTATE | FX_SCALE;65if (data)66RSDK.SetSpriteAnimation(GameOver->aniFrames, 7, &self->animator, true, 1);67else68RSDK.SetSpriteAnimation(GameOver->aniFrames, 6, &self->animator, true, 0);6970self->finalOffsets[0].x = -TO_FIXED(72);71self->finalOffsets[1].x = -TO_FIXED(55);72self->finalOffsets[2].x = -TO_FIXED(38);73self->finalOffsets[3].x = -TO_FIXED(21);74self->finalOffsets[4].x = TO_FIXED(12);75self->finalOffsets[5].x = TO_FIXED(29);76self->finalOffsets[6].x = TO_FIXED(46);77self->finalOffsets[7].x = TO_FIXED(63);7879int32 posY = -TO_FIXED(32);80for (int32 i = 0; i < GAMEOVER_LETTER_COUNT; ++i) {81self->letterPosMove[i].x = -(self->finalOffsets[i].x >> 4);82self->letterPosMove[i].y = 0x2000;8384self->finalOffsets[i].y = TO_FIXED(ScreenInfo->center.y - 4);8586self->letterPositions[i].x = 8 * ((ScreenInfo->center.x << 13) + self->finalOffsets[i].x);87self->letterPositions[i].y = posY;8889posY -= TO_FIXED(16);90}9192self->barPos.x = TO_FIXED(256);93self->barPos.y = TO_FIXED(ScreenInfo->center.y);94self->scale.x = 0x800;95self->state = GameOver_State_EnterLetters;96self->drawGroup = Zone->hudDrawGroup + 1;9798HUD_MoveOut();99100foreach_all(HUD, hud) { hud->active = ACTIVE_ALWAYS; }101}102}103104void GameOver_StageLoad(void)105{106GameOver->aniFrames = RSDK.LoadSpriteAnimation("Global/HUD.bin", SCOPE_STAGE);107108GameOver->activeScreens = 0;109}110111#if MANIA_USE_PLUS112void GameOver_SaveGameCallback(bool32 success)113{114UIWaitSpinner_FinishWait();115RSDK.LoadScene();116}117#else118void GameOver_SaveGameCallback(void)119{120UIWaitSpinner_FinishWait();121RSDK.LoadScene();122}123#endif124125void GameOver_State_EnterLetters(void)126{127RSDK_THIS(GameOver);128129if (self->barPos.x > 0)130self->barPos.x -= TO_FIXED(4);131132self->verts[0].x = self->barPos.x + TO_FIXED(ScreenInfo->center.x - 104);133self->verts[1].x = self->barPos.x + TO_FIXED(ScreenInfo->center.x + 88);134self->verts[2].x = self->barPos.x + TO_FIXED(ScreenInfo->center.x + 104);135self->verts[3].x = self->barPos.x + TO_FIXED(ScreenInfo->center.x - 88);136self->verts[0].y = self->barPos.y - TO_FIXED(8);137self->verts[1].y = self->barPos.y - TO_FIXED(8);138self->verts[2].y = self->barPos.y + TO_FIXED(8);139self->verts[3].y = self->barPos.y + TO_FIXED(8);140141for (int32 i = 0; i < GAMEOVER_LETTER_COUNT; ++i) {142self->letterPositions[i].x = TO_FIXED(ScreenInfo->center.x) + self->scale.x * (self->finalOffsets[i].x >> 9);143if (self->letterBounceCount[i] < 3) {144self->letterPosMove[i].y += 0x4000;145self->letterPositions[i].y += self->letterPosMove[i].y;146147if (self->letterPosMove[i].y > 0 && self->letterPositions[i].y > self->finalOffsets[i].y) {148self->letterPositions[i].y = self->finalOffsets[i].y;149self->letterPosMove[i].y = -(self->letterPosMove[i].y / 3);150151++self->letterBounceCount[i];152}153}154}155156if (self->scale.x <= 0x200)157self->scale.x = 0x200;158else159self->scale.x = self->scale.x - self->scale.x / 40;160self->scale.y = self->scale.x;161162if (self->timer == 0) {163#if MANIA_USE_PLUS164EntityCompetitionSession *session = CompetitionSession_GetSession();165if (globals->gameMode != MODE_COMPETITION) {166Music_TransitionTrack(TRACK_GAMEOVER, 0.025);167}168else {169if (session->playerCount <= 0) {170bool32 playMusic = false;171if (Zone->gotTimeOver)172playMusic = true;173174if (playMusic)175Music_TransitionTrack(TRACK_GAMEOVER, 0.025);176}177else {178EntityCompetition *manager = Competition->sessionManager;179int32 gameOverCount = 0;180int32 deathCount = 0;181for (int32 i = 0; i < session->playerCount; ++i) {182EntityGameOver *gameOver = RSDK_GET_ENTITY(i + Player->playerCount, GameOver);183184if (gameOver->classID == GameOver->classID) {185++gameOverCount;186++deathCount;187}188else if (manager && manager->playerFinished[i]) {189++deathCount;190}191}192193bool32 playMusic = true;194if (gameOverCount < session->playerCount - 1 && deathCount != session->playerCount) {195if (!Zone->gotTimeOver)196playMusic = false;197}198199if (playMusic)200Music_TransitionTrack(TRACK_GAMEOVER, 0.025);201}202}203#else204Music_TransitionTrack(TRACK_GAMEOVER, 0.025);205#endif206}207208if (++self->timer == 120) {209self->timer = 0;210#if MANIA_USE_PLUS211if (globals->gameMode == MODE_COMPETITION || Zone->gotTimeOver)212self->state = GameOver_State_WaitComp;213else214#endif215self->state = GameOver_State_Wait;216}217}218219#if MANIA_USE_PLUS220void GameOver_State_WaitComp(void)221{222RSDK_THIS(GameOver);223224EntityCompetition *manager = Competition->sessionManager;225EntityCompetitionSession *session = CompetitionSession_GetSession();226227int32 gameOverCount = 0;228int32 deathCount = 0;229for (int32 i = 0; i < session->playerCount; ++i) {230EntityGameOver *gameOver = RSDK_GET_ENTITY(i + Player->playerCount, GameOver);231232if (gameOver->classID == GameOver->classID) {233++gameOverCount;234++deathCount;235}236else if (manager && manager->playerFinished[i]) {237++deathCount;238}239}240241if (gameOverCount >= session->playerCount - 1 || deathCount == session->playerCount || Zone->gotTimeOver)242self->state = GameOver_State_Wait;243}244#endif245246void GameOver_State_Wait(void)247{248RSDK_THIS(GameOver);249250++self->timer;251252int32 id = globals->gameMode == MODE_COMPETITION ? (self->playerID + 1) : INPUT_NONE;253254if (ControllerInfo[id].keyA.press || ControllerInfo[id].keyB.press || ControllerInfo[id].keyC.press || ControllerInfo[id].keyX.press255|| ControllerInfo[id].keyStart.press)256self->timer = 420;257258if (self->timer == 420) {259#if MANIA_USE_PLUS260Music_ClearMusicStack();261#endif262Music_FadeOut(0.05);263264foreach_all(GameOver, gameOver)265{266int32 angle = 0x88;267for (int32 i = 0; i < GAMEOVER_LETTER_COUNT; ++i) {268gameOver->letterPosMove[i].x = RSDK.Cos256(angle) << 11;269gameOver->letterPosMove[i].y = RSDK.Sin256(angle) << 11;270gameOver->letterRotateSpeed[i] = RSDK.Rand(-8, 8);271angle += 0x10;272}273gameOver->timer = 0;274gameOver->state = GameOver_State_ExitLetters;275}276}277}278279void GameOver_State_ExitLetters(void)280{281RSDK_THIS(GameOver);282283if (self->timer < 120) {284for (int32 i = 0; i < GAMEOVER_LETTER_COUNT; ++i) {285self->letterPositions[i].x += self->letterPosMove[i].x;286self->letterPositions[i].y += self->letterPosMove[i].y;287self->letterRotations[i] += self->letterRotateSpeed[i];288}289self->verts[0].x -= TO_FIXED(16);290self->verts[0].y -= TO_FIXED(8);291self->verts[1].x += TO_FIXED(16);292self->verts[1].y -= TO_FIXED(8);293self->verts[2].x += TO_FIXED(16);294self->verts[2].y += TO_FIXED(8);295self->verts[3].x -= TO_FIXED(16);296self->verts[3].y += TO_FIXED(8);297self->scale.x += 0x20;298self->scale.y += 0x20;299++self->timer;300}301302if (self->timer == 90) {303self->timer = 0;304305EntityCompetitionSession *session = CompetitionSession_GetSession();306if (globals->gameMode == MODE_COMPETITION) {307session->completedStages[session->stageIndex] = true;308#if MANIA_USE_PLUS309session->matchID = session->prevMatchID + 1;310#else311session->matchID++;312#endif313RSDK.SetVideoSetting(VIDEOSETTING_SCREENCOUNT, 1);314RSDK.SetScene("Presentation", "Menu");315RSDK.LoadScene();316}317else if (self->animator.animationID != 6) {318StarPost->storedMS = 0;319StarPost->storedSeconds = 0;320StarPost->storedMinutes = 0;321RSDK.LoadScene();322}323else {324SaveRAM *saveRAM = SaveGame_GetSaveRAM();325if (globals->gameMode >= MODE_TIMEATTACK) {326RSDK.SetScene("Presentation", "Menu");327RSDK.LoadScene();328}329else if (globals->continues > 0) {330saveRAM->storedStageID = SceneInfo->listPos;331saveRAM->lives = 3;332saveRAM->score = 0;333saveRAM->score1UP = 0;334#if MANIA_USE_PLUS335if (globals->gameMode == MODE_ENCORE) {336globals->playerID &= 0xFF;337saveRAM->characterFlags = -1;338globals->characterFlags = 1 << HUD_CharacterIndexFromID(GET_CHARACTER_ID(1));339saveRAM->characterFlags = globals->characterFlags;340saveRAM->stock = globals->stock;341}342#endif343RSDK.SetScene("Presentation", "Continue");344RSDK.LoadScene();345}346else {347saveRAM->lives = 3;348saveRAM->score = 0;349saveRAM->score1UP = 0;350#if MANIA_USE_PLUS351if (globals->gameMode == MODE_ENCORE) {352globals->playerID &= 0xFF;353saveRAM->characterFlags = -1;354globals->characterFlags = 1 << HUD_CharacterIndexFromID(GET_CHARACTER_ID(1));355saveRAM->characterFlags = globals->characterFlags;356saveRAM->stock = globals->stock;357}358#endif359UIWaitSpinner_StartWait();360SaveGame_SaveFile(GameOver_SaveGameCallback);361RSDK.SetScene("Presentation", "Menu");362// GameOver_SaveGameCallback() loads the scene instead of doing it here363}364}365}366}367368#if GAME_INCLUDE_EDITOR369void GameOver_EditorDraw(void) {}370371void GameOver_EditorLoad(void) {}372#endif373374void GameOver_Serialize(void) {}375376377