Path: blob/master/SonicMania/Objects/Common/ParallaxSprite.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: ParallaxSprite Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectParallaxSprite *ParallaxSprite;1011void ParallaxSprite_Update(void)12{13RSDK_THIS(ParallaxSprite);1415StateMachine_Run(self->state);16}1718void ParallaxSprite_LateUpdate(void) {}1920void ParallaxSprite_StaticUpdate(void) {}2122void ParallaxSprite_Draw(void)23{24RSDK_THIS(ParallaxSprite);2526RSDKScreenInfo *screen = &ScreenInfo[SceneInfo->currentScreenID];27Vector2 drawPos;2829int32 scrollPosX = ((self->scrollPos.x + self->parallaxFactor.x * screen->position.x) & 0x7FFF0000) % self->loopPoint.x;30drawPos.x = self->position.x - scrollPosX;3132int32 scrollPosY = ((self->scrollPos.y + self->parallaxFactor.y * screen->position.y) & 0x7FFF0000) % self->loopPoint.y;33drawPos.y = self->position.y - scrollPosY;3435int32 loopX = -self->loopPoint.x >> 2;36if (drawPos.x < loopX)37drawPos.x += self->loopPoint.x;3839int32 loopY = -self->loopPoint.y >> 2;40if (drawPos.y < loopY)41drawPos.y += self->loopPoint.y;4243if (self->attribute == PARALLAXSPRITE_ATTR_COLORS) {44int32 x = FROM_FIXED(drawPos.x) - 56;45int32 y = FROM_FIXED(drawPos.y) - 32;46RSDK.DrawRect(x, y, 112, 64, self->color1, 255, INK_NONE, true);4748for (int32 i = 0; i < 0xE0; i += 0x20) {49int32 height = MIN((RSDK.Sin256(i + Zone->timer) >> 3) + 48, 64);50RSDK.DrawRect(x, y - height + 64, 16, height, self->color2, 255, INK_NONE, true);51x += 16;52}53}54else if (self->attribute == PARALLAXSPRITE_ATTR_SHIFT) {55RSDK.GetFrame(ParallaxSprite->aniFrames, self->aniID, 0)->sprX = self->sprX + ((self->xSpeed + (Zone->timer << self->timerSpeed)) & 0x7F);56}5758RSDK.DrawSprite(&self->animator, &drawPos, true);59}6061void ParallaxSprite_Create(void *data)62{63RSDK_THIS(ParallaxSprite);6465self->active = ACTIVE_NORMAL;66self->drawGroup = Zone->fgDrawGroup[0] + 1;6768if (data)69self->attribute = VOID_TO_INT(data);7071switch (self->attribute) {72default:73case PARALLAXSPRITE_ATTR_STANDARD:74case PARALLAXSPRITE_ATTR_WINDMILL:75self->parallaxFactor.x >>= 8;76self->parallaxFactor.y >>= 8;77self->drawFX = FX_ROTATE;78self->visible = !self->hiddenAtStart;79self->state = ParallaxSprite_State_Normal;80break;8182case PARALLAXSPRITE_ATTR_COLORS:83#if MANIA_USE_PLUS84if (SceneInfo->filter & FILTER_ENCORE) {85self->color1 = 0x189098;86self->color2 = 0x00D098;87}88else {89#endif90self->color1 = 0x885820;91self->color2 = 0xE89850;92#if MANIA_USE_PLUS93}94#endif95self->parallaxFactor.x >>= 8;96self->parallaxFactor.y >>= 8;97self->drawFX = FX_ROTATE;98self->visible = !self->hiddenAtStart;99self->state = ParallaxSprite_State_Normal;100break;101102case PARALLAXSPRITE_ATTR_EMITTER:103self->parallaxFactor.x >>= 8;104self->parallaxFactor.y >>= 8;105self->state = ParallaxSprite_State_Emitter;106break;107108case PARALLAXSPRITE_ATTR_PARTICLE:109self->inkEffect = INK_ALPHA;110self->visible = true;111self->alpha = 0x100;112self->state = ParallaxSprite_State_Particle;113break;114115case PARALLAXSPRITE_ATTR_BLENDHIGH:116self->parallaxFactor.x >>= 8;117self->parallaxFactor.y >>= 8;118self->visible = true;119self->inkEffect = INK_BLEND;120self->drawGroup = Zone->objectDrawGroup[1] + 1;121self->state = ParallaxSprite_State_Normal;122break;123124case PARALLAXSPRITE_ATTR_SHIFT:125self->parallaxFactor.x >>= 8;126self->parallaxFactor.y >>= 8;127self->sprX = RSDK.GetFrame(ParallaxSprite->aniFrames, self->aniID, 1)->sprX;128self->timerSpeed = ZONE_RAND(0, 2);129self->xSpeed = ZONE_RAND(0, 128);130self->inkEffect = INK_MASKED;131self->visible = true;132self->state = NULL;133break;134}135136RSDK.SetSpriteAnimation(ParallaxSprite->aniFrames, self->aniID, &self->animator, true, 0);137}138139void ParallaxSprite_StageLoad(void)140{141if (RSDK.CheckSceneFolder("AIZ"))142ParallaxSprite->aniFrames = RSDK.LoadSpriteAnimation("AIZ/Decoration.bin", SCOPE_STAGE);143else if (RSDK.CheckSceneFolder("CPZ"))144ParallaxSprite->aniFrames = RSDK.LoadSpriteAnimation("CPZ/CPZParallax.bin", SCOPE_STAGE);145else if (RSDK.CheckSceneFolder("SPZ1"))146ParallaxSprite->aniFrames = RSDK.LoadSpriteAnimation("SPZ1/SPZParallax.bin", SCOPE_STAGE);147else if (RSDK.CheckSceneFolder("FBZ"))148ParallaxSprite->aniFrames = RSDK.LoadSpriteAnimation("FBZ/FBZParallax.bin", SCOPE_STAGE);149else if (RSDK.CheckSceneFolder("MSZ") || RSDK.CheckSceneFolder("MSZCutscene"))150ParallaxSprite->aniFrames = RSDK.LoadSpriteAnimation("MSZ/MSZParallax.bin", SCOPE_STAGE);151else if (RSDK.CheckSceneFolder("OOZ2"))152ParallaxSprite->aniFrames = RSDK.LoadSpriteAnimation("OOZ/OOZParallax.bin", SCOPE_STAGE);153else if (RSDK.CheckSceneFolder("LRZ2") || RSDK.CheckSceneFolder("LRZ3"))154ParallaxSprite->aniFrames = RSDK.LoadSpriteAnimation("LRZ2/LRZParallax.bin", SCOPE_STAGE);155}156157void ParallaxSprite_State_Normal(void)158{159RSDK_THIS(ParallaxSprite);160161RSDK.ProcessAnimation(&self->animator);162163self->rotation = (self->rotation + 2) & 0x1FF;164165self->scrollPos.x += self->scrollSpeed.x;166self->scrollPos.y += self->scrollSpeed.y;167}168169void ParallaxSprite_State_Emitter(void)170{171RSDK_THIS(ParallaxSprite);172173if (!(Zone->timer & 3)) {174EntityParallaxSprite *sprite = CREATE_ENTITY(ParallaxSprite, INT_TO_VOID(PARALLAXSPRITE_ATTR_PARTICLE), self->position.x, self->position.y);175sprite->parallaxFactor.x = self->parallaxFactor.x;176sprite->parallaxFactor.y = self->parallaxFactor.y;177sprite->loopPoint.x = self->loopPoint.x;178sprite->loopPoint.y = self->loopPoint.y;179sprite->scrollSpeed.y = RSDK.Rand(0x8000, 0x20000);180sprite->acceleration.x = RSDK.Rand(-0x100, 0x100);181}182}183184void ParallaxSprite_State_Particle(void)185{186RSDK_THIS(ParallaxSprite);187188RSDK.ProcessAnimation(&self->animator);189190self->scrollSpeed.x += self->acceleration.x;191self->scrollSpeed.y += self->acceleration.y;192self->scrollPos.x += self->scrollSpeed.x;193self->scrollPos.y += self->scrollSpeed.y;194195self->alpha -= 2;196if (!self->alpha)197destroyEntity(self);198}199200void ParallaxSprite_State_FadeIntoHalf(void)201{202RSDK_THIS(ParallaxSprite);203204RSDK.ProcessAnimation(&self->animator);205206self->scrollPos.x += self->scrollSpeed.x;207self->scrollPos.y += self->scrollSpeed.y;208209if (self->alpha >= 0x80) {210self->inkEffect = INK_BLEND;211self->visible = true;212self->state = ParallaxSprite_State_Normal;213}214else {215self->inkEffect = INK_ALPHA;216self->alpha += 4;217}218}219220void ParallaxSprite_State_FadeOut(void)221{222RSDK_THIS(ParallaxSprite);223224RSDK.ProcessAnimation(&self->animator);225226self->scrollPos.x += self->scrollSpeed.x;227self->scrollPos.y += self->scrollSpeed.y;228229if (self->alpha <= 0) {230self->visible = false;231self->state = ParallaxSprite_State_Normal;232}233else {234self->inkEffect = INK_ALPHA;235self->alpha -= 4;236}237}238239#if GAME_INCLUDE_EDITOR240void ParallaxSprite_EditorDraw(void)241{242RSDK_THIS(ParallaxSprite);243244RSDK.SetSpriteAnimation(ParallaxSprite->aniFrames, self->aniID, &self->animator, true, 0);245246Vector2 drawPos = self->position;247248if (self->attribute == PARALLAXSPRITE_ATTR_COLORS) {249int32 x = FROM_FIXED(drawPos.x) - 56;250int32 y = FROM_FIXED(drawPos.y) - 32;251RSDK.DrawRect(x << 16, y << 16, 112 << 16, 64 << 16, self->color1, 255, 0, false);252253for (int32 i = 0; i < 0xE0; i += 0x20) {254int32 height = MIN((RSDK.Sin256(i + Zone->timer) >> 3) + 48, 64);255RSDK.DrawRect(x << 16, (y - height + 64) << 16, 16 << 16, height << 16, self->color2, 255, 0, false);256x += 16;257}258}259else if (self->attribute == PARALLAXSPRITE_ATTR_SHIFT) {260RSDK.GetFrame(ParallaxSprite->aniFrames, self->aniID, 0)->sprX = self->sprX + ((self->xSpeed + (Zone->timer << self->timerSpeed)) & 0x7F);261}262263RSDK.DrawSprite(&self->animator, &drawPos, false);264}265266void ParallaxSprite_EditorLoad(void)267{268if (RSDK.CheckSceneFolder("AIZ"))269ParallaxSprite->aniFrames = RSDK.LoadSpriteAnimation("AIZ/Decoration.bin", SCOPE_STAGE);270else if (RSDK.CheckSceneFolder("CPZ"))271ParallaxSprite->aniFrames = RSDK.LoadSpriteAnimation("CPZ/CPZParallax.bin", SCOPE_STAGE);272else if (RSDK.CheckSceneFolder("SPZ1"))273ParallaxSprite->aniFrames = RSDK.LoadSpriteAnimation("SPZ1/SPZParallax.bin", SCOPE_STAGE);274else if (RSDK.CheckSceneFolder("FBZ"))275ParallaxSprite->aniFrames = RSDK.LoadSpriteAnimation("FBZ/FBZParallax.bin", SCOPE_STAGE);276else if (RSDK.CheckSceneFolder("MSZ") || RSDK.CheckSceneFolder("MSZCutscene"))277ParallaxSprite->aniFrames = RSDK.LoadSpriteAnimation("MSZ/MSZParallax.bin", SCOPE_STAGE);278else if (RSDK.CheckSceneFolder("OOZ2"))279ParallaxSprite->aniFrames = RSDK.LoadSpriteAnimation("OOZ/OOZParallax.bin", SCOPE_STAGE);280else if (RSDK.CheckSceneFolder("LRZ2") || RSDK.CheckSceneFolder("LRZ3"))281ParallaxSprite->aniFrames = RSDK.LoadSpriteAnimation("LRZ2/LRZParallax.bin", SCOPE_STAGE);282283RSDK_ACTIVE_VAR(ParallaxSprite, attribute);284RSDK_ENUM_VAR("Standard", PARALLAXSPRITE_ATTR_STANDARD);285RSDK_ENUM_VAR("Windmill (Unused)", PARALLAXSPRITE_ATTR_WINDMILL);286RSDK_ENUM_VAR("Colors (SPZ Billboard)", PARALLAXSPRITE_ATTR_COLORS);287RSDK_ENUM_VAR("Emitter", PARALLAXSPRITE_ATTR_EMITTER);288RSDK_ENUM_VAR("Particle", PARALLAXSPRITE_ATTR_PARTICLE);289RSDK_ENUM_VAR("Blend", PARALLAXSPRITE_ATTR_BLENDHIGH);290}291#endif292293void ParallaxSprite_Serialize(void)294{295RSDK_EDITABLE_VAR(ParallaxSprite, VAR_UINT8, aniID);296RSDK_EDITABLE_VAR(ParallaxSprite, VAR_UINT8, attribute);297RSDK_EDITABLE_VAR(ParallaxSprite, VAR_VECTOR2, parallaxFactor);298RSDK_EDITABLE_VAR(ParallaxSprite, VAR_VECTOR2, scrollSpeed);299RSDK_EDITABLE_VAR(ParallaxSprite, VAR_VECTOR2, loopPoint);300RSDK_EDITABLE_VAR(ParallaxSprite, VAR_BOOL, hiddenAtStart);301}302303304