Skip to content

Commit

Permalink
Merge pull request #83 from newo-2001/animation-refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
Dextinfire committed Nov 25, 2024
2 parents ca145b6 + 7157f51 commit 53d768f
Show file tree
Hide file tree
Showing 73 changed files with 295 additions and 291 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ set(Impacto_Src
src/inputsystem.cpp
src/minilua_impl.c
src/voicetable.cpp
src/animation.cpp

src/renderer/renderer.cpp

Expand Down
47 changes: 47 additions & 0 deletions src/animation.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include "animation.h"

namespace Impacto {

void Animation::AddDelta(float dt) {
float duration =
Direction == +AnimationDirection::In ? DurationIn : DurationOut;

switch (LoopMode) {
case AnimationLoopMode::Stop: {
float endProgress = Direction == +AnimationDirection::In ? 1.0f : 0.0f;

Progress = std::clamp(Progress + Direction * dt / duration, 0.0f, 1.0f);
if (Progress == endProgress) State = AnimationState::Stopped;
return;
}
case AnimationLoopMode::Loop: {
// E.g. Progress = 1.04 => Progress = 0.04
Progress += Direction * dt / duration;
Progress -= std::floor(Progress);
return;
}
case AnimationLoopMode::ReverseDirection: {
// E.g. Progress = 1.04 => Progress = 0.96
float cycleDuration = DurationIn + DurationOut;

float time = Progress * duration;
if (Direction == +AnimationDirection::Out) {
time = cycleDuration - time;
}

time = std::fmod(time + dt, cycleDuration);

if (time < DurationIn) {
Progress = time / DurationIn;
Direction = AnimationDirection::In;
} else {
Progress = 1.0f - (time - DurationIn) / DurationOut;
Direction = AnimationDirection::Out;
}

return;
}
}
}

} // namespace Impacto
96 changes: 30 additions & 66 deletions src/animation.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,109 +2,73 @@

#include "mem.h"
#include "profile/scriptvars.h"
#include "enum.h"

namespace Impacto {

enum AnimationState { AS_Stopped, AS_Playing };
enum AnimationLoopMode { ALM_Stop, ALM_ReverseDirection, ALM_Loop };
BETTER_ENUM(AnimationState, int, Stopped, Playing)
BETTER_ENUM(AnimationLoopMode, int, Stop, ReverseDirection, Loop)
BETTER_ENUM(AnimationDirection, int, In = 1, Out = -1)

class Animation {
public:
float DurationIn = 0;
float DurationOut = 0;
// 1 = in, -1 = out
float Direction = 1;
AnimationDirection Direction = AnimationDirection::In;
// 0 = fully out, 1 = fully in
float Progress = 0;
AnimationState State = AS_Stopped;
AnimationLoopMode LoopMode = ALM_Stop;
AnimationState State = AnimationState::Stopped;
AnimationLoopMode LoopMode = AnimationLoopMode::Stop;
// Animation skips to the end when skip mode is enabled
bool SkipOnSkipMode = true;

void SetDuration(float duration) {
DurationIn = duration;
DurationOut = duration;
}

void Stop() { State = AnimationState::Stopped; }

void StartIn(bool reset = false) {
if (reset) Progress = 0;
Direction = 1;
State = AS_Playing;
Direction = AnimationDirection::In;
State = AnimationState::Playing;
StartInImpl(reset);
}

void StartOut(bool reset = false) {
if (reset) Progress = 1;
Direction = -1;
State = AS_Playing;
Direction = AnimationDirection::Out;
State = AnimationState::Playing;
StartOutImpl(reset);
}

void Update(float dt) {
if (State == AS_Stopped) return;
if (State == +AnimationState::Stopped) return;
UpdateImpl(dt);
}

virtual void Render() {}

bool IsOut() const { return Progress == 0 && State == AS_Stopped; }
bool IsIn() const { return Progress == 1 && State == AS_Stopped; }
bool IsOut() const {
return Progress == 0 && State == +AnimationState::Stopped;
}
bool IsIn() const {
return Progress == 1 && State == +AnimationState::Stopped;
}

protected:
void AddDelta(float dt);
virtual void StartInImpl(bool reset = false) {}
virtual void StartOutImpl(bool reset = false) {}
virtual void UpdateImpl(float dt) {
if (SkipOnSkipMode && GetFlag(Profile::ScriptVars::SF_MESALLSKIP) &&
State != AS_Stopped) {
Progress = Direction == 1 ? 1.0f : 0.0f;
State != +AnimationState::Stopped) {
Progress = Direction == +AnimationDirection::In ? 1.0f : 0.0f;
}
AddDelta(dt);
}

void AddDelta(float dt) {
if (Direction == 1) {
Progress += dt / DurationIn;
if (Progress >= 1) {
switch (LoopMode) {
case ALM_Stop: {
Progress = 1;
State = AS_Stopped;
break;
}
case ALM_ReverseDirection: {
// E.g. Progress = 1.04 => Progress = 0.96
Progress = 1 - (Progress - 1);
Direction = -1;
StartOutImpl();
break;
}
case ALM_Loop: {
// E.g. Progress = 1.04 => Progress = 0.04
Progress = (Progress - 1);
StartInImpl();
break;
}
}
}
} else {
Progress -= dt / DurationOut;
if (Progress <= 0) {
switch (LoopMode) {
case ALM_Stop: {
Progress = 0;
State = AS_Stopped;
break;
}
case ALM_ReverseDirection: {
// e.g. Progress = -0.04 => Progress = 0.04
Progress = 0 - Progress;
Direction = 1;
StartInImpl();
break;
}
case ALM_Loop: {
// e.g. Progress = -0.04 => Progress = 0.96
Progress = 1 + Progress;
StartOutImpl();
break;
}
}
}
}
}
};

} // namespace Impacto
4 changes: 2 additions & 2 deletions src/games/cc/dialoguebox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ using namespace Impacto::Profile::CC::DialogueBox;
void DialogueBox::Init() { Impacto::DialogueBox::Init(); }

void DialogueBox::Update(float dt) {
if (TextBoxEffect.State != AS_Playing) {
if (TextBoxEffect.State != +AnimationState::Playing) {
TextBoxEffect.DurationIn = ADVBoxEffectDuration;
TextBoxEffect.LoopMode = ALM_Loop;
TextBoxEffect.LoopMode = AnimationLoopMode::Loop;
TextBoxEffect.StartIn();
}

Expand Down
4 changes: 2 additions & 2 deletions src/games/cc/sysmesbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,8 @@ void SysMesBox::Init() {

FadeAnimation.DurationIn = FadeInDuration;
FadeAnimation.DurationOut = FadeOutDuration;
FadeAnimation.Direction = 1;
FadeAnimation.LoopMode = ALM_Stop;
FadeAnimation.Direction = AnimationDirection::In;
FadeAnimation.LoopMode = AnimationLoopMode::Stop;
}

void SysMesBox::AddMessage(uint8_t* str) {
Expand Down
2 changes: 1 addition & 1 deletion src/games/cc/titlemenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ void TitleMenu::Show() {
IsFocused = true;
UI::FocusedMenu = this;
AllowsScriptInput = true;
if (PressToStartAnimation.State == AS_Stopped) {
if (PressToStartAnimation.State == +AnimationState::Stopped) {
PressToStartAnimation.StartIn();
SmokeAnimation.StartIn();
}
Expand Down
4 changes: 2 additions & 2 deletions src/games/cclcc/clearlistmenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ using namespace Impacto::Vm::Interface;
using namespace Impacto::UI::Widgets;

ClearListMenu::ClearListMenu() {
FadeAnimation.Direction = 1;
FadeAnimation.LoopMode = ALM_Stop;
FadeAnimation.Direction = AnimationDirection::In;
FadeAnimation.LoopMode = AnimationLoopMode::Stop;
FadeAnimation.DurationIn = FadeInDuration;
FadeAnimation.DurationOut = FadeOutDuration;
}
Expand Down
4 changes: 2 additions & 2 deletions src/games/cclcc/librarymenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ LibraryMenu::LibraryMenu() {
LibraryMenuButtonOnClick(target);
};

FadeAnimation.Direction = 1;
FadeAnimation.LoopMode = ALM_Stop;
FadeAnimation.Direction = AnimationDirection::In;
FadeAnimation.LoopMode = AnimationLoopMode::Stop;
FadeAnimation.DurationIn = FadeInDuration;
FadeAnimation.DurationOut = FadeOutDuration;
}
Expand Down
14 changes: 8 additions & 6 deletions src/games/cclcc/mapsystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,8 @@ int MapSystemCCLCC::MapLoad(uint8_t* data) {
: (MapPartsDisp[i].state == Showing || MapPartsDisp[i].state == Shown)
? 1 - progress / conversionFactor
: 0;
MapPartsDisp[i].fadeAnim.Direction = inOrOut;
MapPartsDisp[i].fadeAnim.Direction =
inOrOut ? AnimationDirection::In : AnimationDirection::Out;
MapPartsDisp[i].delay = data[dataSize];
dataSize += 4;
MapPartsDisp[i].angle = data[dataSize];
Expand Down Expand Up @@ -242,7 +243,8 @@ int MapSystemCCLCC::MapLoad(uint8_t* data) {
: (MapPoolDisp[i].state == Showing || MapPoolDisp[i].state == Hidden)
? 1 - progress / conversionFactor
: 0;
MapPoolDisp[i].fadeAnim.Direction = inOrOut;
MapPoolDisp[i].fadeAnim.Direction =
inOrOut ? AnimationDirection::In : AnimationDirection::Out;
MapPoolDisp[i].delay = data[dataSize];
dataSize += 4;
MapPoolDisp[i].angle = data[dataSize];
Expand Down Expand Up @@ -1898,7 +1900,7 @@ void MapSystemCCLCC::MapFadeMain(float dt) {
if (partsDispElem.state == Showing) {
if (partsDispElem.fadeAnim.IsIn()) {
partsDispElem.state = Shown;
} else if (partsDispElem.fadeAnim.State == AS_Stopped) {
} else if (partsDispElem.fadeAnim.State == +AnimationState::Stopped) {
if (partsDispElem.type == 0 ||
(partsDispElem.type >= 8 && partsDispElem.type <= 11)) {
Audio::Channels[Audio::AC_SSE]->Play("sysse", 7, false, 0.0f);
Expand All @@ -1908,7 +1910,7 @@ void MapSystemCCLCC::MapFadeMain(float dt) {
} else if (partsDispElem.state == Hiding) {
if (partsDispElem.fadeAnim.IsOut()) {
partsDispElem.state = Hidden;
} else if (partsDispElem.fadeAnim.State == AS_Stopped) {
} else if (partsDispElem.fadeAnim.State == +AnimationState::Stopped) {
if (partsDispElem.type == 0 ||
(partsDispElem.type >= 8 && partsDispElem.type <= 11)) {
Audio::Channels[Audio::AC_SSE]->Play("sysse", 9, false, 0.0f);
Expand Down Expand Up @@ -1940,7 +1942,7 @@ void MapSystemCCLCC::MapFadeMain(float dt) {
if (poolDispElem.state == Showing) {
if (poolDispElem.fadeAnim.IsIn()) {
poolDispElem.state = Shown;
} else if (poolDispElem.fadeAnim.State == AS_Stopped) {
} else if (poolDispElem.fadeAnim.State == +AnimationState::Stopped) {
if (i % 2 == 1) {
Audio::Channels[Audio::AC_SSE]->Play("sysse", 7, false, 0.0f);
}
Expand All @@ -1950,7 +1952,7 @@ void MapSystemCCLCC::MapFadeMain(float dt) {
} else if (poolDispElem.state == Hiding) {
if (poolDispElem.fadeAnim.IsOut()) {
poolDispElem.state = Hidden;
} else if (poolDispElem.fadeAnim.State == AS_Stopped) {
} else if (poolDispElem.fadeAnim.State == +AnimationState::Stopped) {
if (i % 2 == 1) {
Audio::Channels[Audio::AC_SSE]->Play("sysse", 9, false, 0.0f);
}
Expand Down
4 changes: 2 additions & 2 deletions src/games/cclcc/optionsmenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ using namespace Impacto::Profile::ScriptVars;
using namespace Impacto::Vm::Interface;

OptionsMenu::OptionsMenu() {
FadeAnimation.Direction = 1;
FadeAnimation.LoopMode = ALM_Stop;
FadeAnimation.Direction = AnimationDirection::In;
FadeAnimation.LoopMode = AnimationLoopMode::Stop;
FadeAnimation.DurationIn = FadeInDuration;
FadeAnimation.DurationOut = FadeOutDuration;
}
Expand Down
4 changes: 2 additions & 2 deletions src/games/cclcc/savemenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ void SaveMenu::MenuButtonOnClick(Widgets::Button* target) {
}

SaveMenu::SaveMenu() {
FadeAnimation.Direction = 1;
FadeAnimation.LoopMode = ALM_Stop;
FadeAnimation.Direction = AnimationDirection::In;
FadeAnimation.LoopMode = AnimationLoopMode::Stop;
FadeAnimation.DurationIn = FadeInDuration;
FadeAnimation.DurationOut = FadeOutDuration;
}
Expand Down
12 changes: 6 additions & 6 deletions src/games/cclcc/systemmenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,18 @@ void SystemMenu::MenuButtonOnClick(Widgets::Button* target) {
}

SystemMenu::SystemMenu() {
MenuTransition.Direction = 1;
MenuTransition.LoopMode = ALM_Stop;
MenuTransition.Direction = AnimationDirection::In;
MenuTransition.LoopMode = AnimationLoopMode::Stop;
MenuTransition.DurationIn = MoveInDuration;
MenuTransition.DurationOut = MoveOutDuration;

MenuFade.Direction = 1.0f;
MenuFade.LoopMode = ALM_Stop;
MenuFade.Direction = AnimationDirection::In;
MenuFade.LoopMode = AnimationLoopMode::Stop;
MenuFade.DurationIn = FadeInDuration;
MenuFade.DurationOut = FadeOutDuration;

ItemsFade.Direction = 1.0f;
ItemsFade.LoopMode = ALM_Stop;
ItemsFade.Direction = AnimationDirection::In;
ItemsFade.LoopMode = AnimationLoopMode::Stop;
ItemsFade.DurationIn = ItemsFadeInDuration;
ItemsFade.DurationOut = ItemsFadeOutDuration;

Expand Down
6 changes: 3 additions & 3 deletions src/games/cclcc/tipsmenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ struct SortByTipName {
};

TipsMenu::TipsMenu() : TipViewItems(this) {
FadeAnimation.Direction = 1;
FadeAnimation.LoopMode = ALM_Stop;
FadeAnimation.Direction = AnimationDirection::In;
FadeAnimation.LoopMode = AnimationLoopMode::Stop;
FadeAnimation.DurationIn = FadeInDuration;
FadeAnimation.DurationOut = FadeOutDuration;
TransitionAnimation.DurationIn = TransitionInDuration;
Expand Down Expand Up @@ -306,7 +306,7 @@ void TipsMenu::Update(float dt) {
}
};

if (TransitionAnimation.State == AS_Playing) {
if (TransitionAnimation.State == +AnimationState::Playing) {
float move = glm::mix(0.0f, Profile::DesignHeight / 2,
TransitionAnimation.Progress) -
LastYPos;
Expand Down
2 changes: 1 addition & 1 deletion src/games/cclcc/tipsnotification.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ TipsNotification::TipsNotification() {
FadeAnimation.DurationOut = FadeOutDuration;

Timer.DurationIn = TimerDuration;
Timer.LoopMode = ALM_Stop;
Timer.LoopMode = AnimationLoopMode::Stop;

auto textBefore = Vm::ScriptGetTextTableStrAddress(
TextTableId, NotificationTextPart1MessageId);
Expand Down
2 changes: 1 addition & 1 deletion src/games/cclcc/titlemenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ void TitleMenu::Show() {
IsFocused = true;
UI::FocusedMenu = this;
AllowsScriptInput = true;
if (PressToStartAnimation.State == AS_Stopped) {
if (PressToStartAnimation.State == +AnimationState::Stopped) {
PressToStartAnimation.StartIn();
SmokeAnimation.StartIn();
}
Expand Down
Loading

0 comments on commit 53d768f

Please sign in to comment.