Path: blob/master/SonicMania/Objects/HCZ/HCZSetup.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: HCZSetup Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectHCZSetup *HCZSetup;1011void HCZSetup_Update(void) {}1213void HCZSetup_LateUpdate(void) {}1415void HCZSetup_StaticUpdate(void)16{17if (!(Zone->timer & 3)) {18++HCZSetup->background2Layer->deformationOffsetW;1920// Handle Animating the BG candle & waterline tiles21if (!(Zone->timer & 3)) {22HCZSetup->bgCandlesAniTileFrame += 0x10;23HCZSetup->bgCandlesAniTileFrame &= 0x3F;24RSDK.DrawAniTiles(HCZSetup->bgCandlesAniTiles, 386, 0, HCZSetup->bgCandlesAniTileFrame, 64, 16);2526HCZSetup->waterlineAniTileFrame += 0x20;27HCZSetup->waterlineAniTileFrame &= 0x1FF;28RSDK.DrawAniTiles(HCZSetup->waterlineAniTiles, 820, HCZSetup->waterlineAniTileFrame, 0, 32, 96);29RSDK.DrawAniTiles(HCZSetup->waterlineAniTiles, 857, HCZSetup->waterlineAniTileFrame, 96, 32, 128);30RSDK.RotatePalette(0, 176, 182, true);31}32}3334// Handle Animating the pendulum tiles35int32 *durations = HCZSetup->pendulumAniTileDurations;36int32 duration1 = 0;37int32 duration2 = 0;3839for (int32 i = 0; i < 7; ++i) {40duration1 += durations[0];41duration2 += durations[1];42durations += 2;43}4445int32 pendulumTimer = Zone->timer % (duration2 + duration1);46int32 pendulumAniTileFrame = 0;4748while (pendulumTimer >= HCZSetup->pendulumAniTileDurations[pendulumAniTileFrame]) {49pendulumTimer -= HCZSetup->pendulumAniTileDurations[pendulumAniTileFrame++];50}5152if (!pendulumTimer)53RSDK.DrawAniTiles(HCZSetup->pendulumAniTiles, 874, 0, 16 * pendulumAniTileFrame, 32, 16);5455if (!(Zone->timer & 1)) {56for (int32 layerID = Zone->fgLayer[0]; layerID <= Zone->fgLayer[1]; ++layerID) RSDK.GetTileLayer(layerID)->deformationOffsetW++;57}5859#if MANIA_USE_PLUS60if (HCZSetup->waterslidingPlayerCount) {61if (HCZSetup->playingWaterfallLoop) {62if (!(HCZSetup->waterfallLoopTimer & 0x1F)) {63RSDK.StopSfx(HCZSetup->sfxWaterfall);64RSDK.PlaySfx(HCZSetup->sfxWaterfallLoop, false, 0xFF);65}66}67else {68HCZSetup->waterfallLoopTimer = 0;69HCZSetup->playingWaterfallLoop = true;70RSDK.PlaySfx(HCZSetup->sfxWaterfall, false, 0xFF);71}72++HCZSetup->waterfallLoopTimer;73}74else {75HCZSetup->playingWaterfallLoop = false;76}7778HCZSetup->waterslidingPlayerCount = 0;79foreach_active(Player, player)80{81RSDK.GetEntitySlot(player);82if (player->state != Player_State_Static) {83Hitbox *hitbox = Player_GetHitbox(player);84uint16 tile =85RSDK.GetTile(Zone->fgLayer[1], player->position.x >> 20, ((hitbox->bottom << 16) + player->position.y - 0x10000) >> 20) & 0x3FF;8687if (((tile >= 226 && tile <= 244) || (tile >= 880 && tile <= 888)) && player->collisionPlane == 1) {88if (player->state != Player_State_BubbleBounce && player->state != Player_State_MightyHammerDrop) {89if (player->onGround) {90if (player->state != Player_State_WaterSlide) {91player->interaction = true;92player->tileCollisions = TILECOLLISION_DOWN;93player->position.y += player->jumpOffset;94player->nextGroundState = StateMachine_None;95player->state = Player_State_WaterSlide;96}9798if (player->onGround)99++HCZSetup->waterslidingPlayerCount;100}101else if (player->animator.animationID == ANI_FLUME)102++HCZSetup->waterslidingPlayerCount;103}104}105}106}107#endif108}109110void HCZSetup_Draw(void) {}111112void HCZSetup_Create(void *data) {}113114void HCZSetup_StageLoad(void)115{116HCZSetup->bgCandlesAniTiles = RSDK.LoadSpriteSheet("HCZ/AniTiles.gif", SCOPE_STAGE);117HCZSetup->waterlineAniTiles = RSDK.LoadSpriteSheet("HCZ/AniTiles2.gif", SCOPE_STAGE);118HCZSetup->pendulumAniTiles = RSDK.LoadSpriteSheet("HCZ/AniTiles3.gif", SCOPE_STAGE);119120HCZSetup->background2Layer = RSDK.GetTileLayer(1);121// Add some deformations to background 2122for (int32 i = 0; i < 0x200; i += 0x10) {123int32 deformation = RSDK.Rand(0, 4);124125int32 *deformDataW = &HCZSetup->background2Layer->deformationDataW[CLAMP(i, 0, 0x200)];126127int32 angle = 0;128for (int32 d = 0; d < 0x10; ++d) {129*deformDataW = deformation * RSDK.Sin1024(angle) >> 10;130angle += 0x40;131}132133memcpy(&HCZSetup->background2Layer->deformationDataW[0x200], &HCZSetup->background2Layer->deformationDataW[0], 0x200 * sizeof(int32));134}135136// if Act 2, Setup the waterline effect137if (Zone->actID == 1)138HCZSetup->background2Layer->scanlineCallback = HCZSetup_Scanline_WaterLine;139140// All Layers between FG Low & FG High get foreground water deformation applied141for (int32 layerID = Zone->fgLayer[0]; layerID <= Zone->fgLayer[1]; ++layerID) {142TileLayer *layer = RSDK.GetTileLayer(layerID);143int32 *deformDataW = layer->deformationDataW;144145// HCZ FG underwater deformation values146for (int32 i = 0; i < 4; ++i) {147deformDataW[0] = 1;148deformDataW[1] = 1;149deformDataW[2] = 2;150deformDataW[3] = 2;151deformDataW[4] = 3;152deformDataW[5] = 3;153deformDataW[6] = 3;154deformDataW[7] = 3;155deformDataW[8] = 2;156deformDataW[9] = 2;157deformDataW[10] = 1;158deformDataW[11] = 1;159160deformDataW[128] = 1;161deformDataW[129] = 1;162deformDataW[130] = 2;163deformDataW[131] = 2;164deformDataW[132] = 3;165deformDataW[133] = 3;166deformDataW[134] = 3;167deformDataW[135] = 3;168deformDataW[136] = 2;169deformDataW[137] = 2;170deformDataW[138] = 1;171deformDataW[139] = 1;172173deformDataW[160] = -1;174deformDataW[161] = -1;175deformDataW[162] = -2;176deformDataW[163] = -2;177deformDataW[164] = -3;178deformDataW[165] = -3;179deformDataW[166] = -3;180deformDataW[167] = -3;181deformDataW[168] = -2;182deformDataW[169] = -2;183deformDataW[170] = -1;184deformDataW[171] = -1;185186deformDataW += 0x100;187}188}189190Animals->animalTypes[0] = ANIMAL_POCKY;191Animals->animalTypes[1] = ANIMAL_ROCKY;192193RSDK.SetDrawGroupProperties(0, false, Water_DrawHook_ApplyWaterPalette);194RSDK.SetDrawGroupProperties(Zone->hudDrawGroup, false, Water_DrawHook_RemoveWaterPalette);195196Water->waterPalette = 1;197198if (Zone->actID) {199if (!CutsceneRules_CheckStageReload())200CutsceneRules_CheckPlayerPos(TO_FIXED(176), TO_FIXED(1424), TO_FIXED(608), TO_FIXED(1664));201202Zone->cameraBoundsL[0] = 168;203Zone->cameraBoundsL[1] = 168;204Zone->cameraBoundsL[2] = 168;205Zone->cameraBoundsL[3] = 168;206207if (isMainGameMode() && globals->atlEnabled && !CutsceneRules_CheckStageReload())208Zone_ReloadStoredEntities(TO_FIXED(388), TO_FIXED(1696), true);209210Zone->stageFinishCallback = HCZSetup_StageFinish_EndAct2;211}212else if (isMainGameMode() && CutsceneRules_IsAct1()) {213Zone->shouldRecoverPlayers = true;214Zone->stageFinishCallback = HCZSetup_StageFinish_EndAct1;215}216217#if MANIA_USE_PLUS218if (SceneInfo->filter & FILTER_ENCORE) {219RSDK.LoadPalette(0, "EncoreHCZ.act", 0b0000000011111111);220RSDK.LoadPalette(1, "EncoreHCZw.act", 0b0000000011111111);221}222223HCZSetup->sfxWaterfall = RSDK.GetSfx("Stage/Waterfall.wav");224HCZSetup->sfxWaterfallLoop = RSDK.GetSfx("Stage/Waterfall2.wav");225#endif226}227228void HCZSetup_Scanline_WaterLine(ScanlineInfo *scanlines)229{230RSDK.ProcessParallax(HCZSetup->background2Layer);231232RSDKScreenInfo *screen = &ScreenInfo[SceneInfo->currentScreenID];233int32 screenY = 0x210 - (screen->position.y >> 2);234int32 waterLevel = FROM_FIXED(Water->waterLevel) - screen->position.y;235236int32 scanlineHeight = MAX(0x10000, 0x640000 / MAX(1, abs(screenY - waterLevel)));237238screenY = CLAMP(screenY, 0, screen->size.y);239waterLevel = CLAMP(waterLevel, 0, screen->size.y);240241ScanlineInfo *scanlinePtr = &scanlines[screenY];242243// scanlinePtr->position.x handles the horizontal scroll that gives water the parallax effect244// scanlinePtr->position.y handles the cool "water line" effect245246// if above OR below, if it's equal, the water covers it all anyways247if (screenY > waterLevel) { // below the waterline248int32 scanlineY = 1232 << 16; // bottom most tile of the water tiles249for (int32 i = 0; i < screenY - waterLevel; ++i) {250// 852 = (top most tile of the below water tiles)251scanlinePtr->position.x = ((((852 << 16) - 0xC000 * (scanlineY >> 16)) / 100 + 0x10000) * screen->position.x) & 0x1FFFFFF;252scanlinePtr->position.y = scanlineY;253scanlineY -= scanlineHeight;254--scanlinePtr;255}256}257else if (screenY < waterLevel) { // above the waterline258int32 scanlineY = 1036 << 16; // top most tile of the water tiles259for (int32 i = 0; i < waterLevel - screenY; ++i) {260// 1132 = bottom most tile of the above water tiles261int32 distance = 1132 - (scanlineY >> 16);262scanlinePtr->position.x = (((-0xC000 * distance) / 100 + 0x10000) * screen->position.x) & 0x1FFFFFF;263scanlinePtr->position.y = scanlineY;264scanlineY += scanlineHeight;265++scanlinePtr;266}267}268}269270void HCZSetup_StageFinish_EndAct1(void)271{272Zone_StoreEntities((Zone->cameraBoundsL[0] + ScreenInfo->center.x) << 16, Zone->cameraBoundsB[0] << 16);273RSDK.LoadScene();274}275276void HCZSetup_StageFinish_EndAct2(void)277{278if (globals->gameMode == MODE_MANIA && CHECK_CHARACTER_ID(ID_KNUCKLES, 1))279RSDK.SetScene("Cutscenes", "Mirage Saloon K Intro");280281Zone_StartFadeOut(10, 0x000000);282}283284#if GAME_INCLUDE_EDITOR285void HCZSetup_EditorDraw(void) {}286287void HCZSetup_EditorLoad(void) {}288#endif289290void HCZSetup_Serialize(void) {}291292293