Skip to content

Commit

Permalink
The perfect title menu
Browse files Browse the repository at this point in the history
  • Loading branch information
Dextinfire committed Sep 22, 2024
1 parent 069ca6f commit 4ef9890
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 25 deletions.
4 changes: 2 additions & 2 deletions profiles/cclcc/hud/titlemenu.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ root.TitleMenu = {
PressToStartAnimDurationOut = 0.6,
PrimaryFadeInDuration = 0.7,
PrimaryFadeOutDuration = 0.7,
SecondaryFadeInDuration = 0.512,
SecondaryFadeOutDuration = 0.512,
SecondaryFadeInDuration = 0.4,
SecondaryFadeOutDuration = 0.4,
SlideItemsAnimationDurationIn = 0.5,
SlideItemsAnimationDurationOut = 0.5,
PressToStartSprite = "TitleMenuPressToStart",
Expand Down
83 changes: 64 additions & 19 deletions src/games/cclcc/titlemenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ TitleMenu::TitleMenu() {

// Start menu items offscreen
MainItems->Move({-Profile::DesignWidth / 2, 0.0f});
ContinueItems->Move({-Profile::DesignWidth / 4, 0.0f});
ExtraItems->Move({-Profile::DesignWidth / 4, 0.0f});

PressToStartAnimation.DurationIn = PressToStartAnimDurationIn;
PressToStartAnimation.DurationOut = PressToStartAnimDurationOut;
Expand Down Expand Up @@ -193,23 +195,54 @@ void TitleMenu::Hide() {
}

void TitleMenu::UpdateInput() {
Menu::UpdateInput();
if (CurrentSubMenu) {
if (IsFocused && MainItems->HasFocus) {
TitleButton* currentFocus =
static_cast<TitleButton*>(CurrentlyFocusedElement);

auto changeInput = [&](int buttonMask, UI::FocusDirection dir) {
if (PADinputButtonWentDown & buttonMask) {
LastFocusedButton = static_cast<TitleButton*>(CurrentlyFocusedElement);
LastFocusedButton->HighlightAnimation.StartOut(true);
AdvanceFocus(dir);
currentFocus = static_cast<TitleButton*>(CurrentlyFocusedElement);
currentFocus->HighlightAnimation.StartIn(true);
}
};
if (CurrentSubMenu ||
currentFocus && currentFocus->HighlightAnimation.State == AS_Stopped) {
changeInput(PAD1DOWN, FDIR_DOWN);
changeInput(PAD1UP, FDIR_UP);
changeInput(PAD1RIGHT, FDIR_RIGHT);
changeInput(PAD1LEFT, FDIR_LEFT);
}
}

if (CurrentSubMenu && SecondaryFadeAnimation.IsIn()) {
if ((PADinputButtonWentDown & PAD1B || PADinputMouseWentDown & PAD1B) &&
CurrentSubMenu->IsShown && CurrentSubMenu->HasFocus) {
if (CurrentSubMenu == ContinueItems) {
HideContinueItems();
SecondaryFadeAnimation.StartOut();
ContinueItems->Move(glm::vec2(-Profile::DesignWidth / 4, 0.0f),
SecondaryFadeAnimation.DurationOut);
}
if (CurrentSubMenu == ExtraItems) {
HideExtraItems();
SecondaryFadeAnimation.StartOut();
ExtraItems->Move(glm::vec2(-Profile::DesignWidth / 4, 0.0f),
SecondaryFadeAnimation.DurationOut);
}
}
}
}

void TitleMenu::Update(float dt) {
UpdateInput();

if (CurrentlyFocusedElement) {
static_cast<TitleButton*>(CurrentlyFocusedElement)
->HighlightAnimation.Update(dt);
}
if (LastFocusedButton && LastFocusedButton != CurrentlyFocusedElement) {
LastFocusedButton->HighlightAnimation.Update(dt);
}
PressToStartAnimation.Update(dt);
PrimaryFadeAnimation.Update(dt);
SecondaryFadeAnimation.Update(dt);
Expand Down Expand Up @@ -257,11 +290,6 @@ void TitleMenu::Update(float dt) {
<< 16;
} break;
case 3: { // Main Menu Fade In
MainItems->HasFocus = true;
if (CurrentSubMenu) {
CurrentSubMenu->HasFocus = true;
}

MainItems->Tint.a =
glm::smoothstep(0.0f, 1.0f, PrimaryFadeAnimation.Progress);
ContinueItems->Tint.a =
Expand All @@ -280,8 +308,12 @@ void TitleMenu::Update(float dt) {
if (PrimaryFadeAnimation.IsOut()) {
PrimaryFadeAnimation.StartIn();
}
if (CurrentSubMenu && SecondaryFadeAnimation.IsOut()) {
SecondaryFadeAnimation.StartIn();

if (CurrentSubMenu) {
if (SlideItemsAnimation.IsIn() && SecondaryFadeAnimation.IsIn())
CurrentSubMenu->HasFocus = true;
} else if (PrimaryFadeAnimation.IsIn() && SlideItemsAnimation.IsIn()) {
MainItems->HasFocus = true;
}

if (CurrentSubMenu && !CurrentSubMenu->IsShown) {
Expand All @@ -296,8 +328,18 @@ void TitleMenu::Update(float dt) {
MainItems->Show();
MainItems->Tint.a = 0.0f;
CurrentlyFocusedElement = NewGame;
static_cast<TitleButton*>(CurrentlyFocusedElement)
->HighlightAnimation.StartIn(true);
NewGame->HasFocus = true;
}

if (SecondaryFadeAnimation.IsOut() && CurrentSubMenu) {
if (CurrentSubMenu == ContinueItems) {
HideContinueItems();
} else if (CurrentSubMenu == ExtraItems) {
HideExtraItems();
}
}
} break;
case 4: {
} break;
Expand Down Expand Up @@ -335,6 +377,7 @@ void TitleMenu::Update(float dt) {
SlideItemsAnimation.StartIn();
PrimaryFadeAnimation.StartIn();
SecondaryFadeAnimation.StartIn();
AllowsScriptInput = false;
MainItems->Move({Profile::DesignWidth / 2, 0.0f},
SlideItemsAnimation.DurationIn);
CurrentSubMenu->Move({Profile::DesignWidth / 2, 0.0f},
Expand Down Expand Up @@ -471,16 +514,17 @@ void TitleMenu::ShowContinueItems() {
Extra->Move(glm::vec2(0.0f, ItemPadding));
Config->Move(glm::vec2(0.0f, ItemPadding));
Help->Move(glm::vec2(0.0f, ItemPadding));
ContinueItems->Move(glm::vec2(Profile::DesignWidth / 4, 0.0f),
SecondaryFadeAnimation.DurationOut);
}

void TitleMenu::HideContinueItems() {
ContinueItems->Hide();
MainItems->HasFocus = true;
CurrentlyFocusedElement = Continue;
CurrentSubMenu = 0;
ContinueItems->HasFocus = true;
SecondaryFadeAnimation.StartOut();

CurrentSubMenu = nullptr;
AllowsScriptInput = true;
Extra->Move(glm::vec2(0.0f, -ItemPadding));
Config->Move(glm::vec2(0.0f, -ItemPadding));
Help->Move(glm::vec2(0.0f, -ItemPadding));
Expand All @@ -497,16 +541,17 @@ void TitleMenu::ShowExtraItems() {

Config->Move(glm::vec2(0, ItemPadding));
Help->Move(glm::vec2(0, ItemPadding));
ExtraItems->Move({Profile::DesignWidth / 4, 0.0f},
SecondaryFadeAnimation.DurationIn);
}

void TitleMenu::HideExtraItems() {
ExtraItems->Hide();
MainItems->HasFocus = true;
CurrentlyFocusedElement = Extra;
CurrentSubMenu = 0;
ExtraItems->HasFocus = true;
SecondaryFadeAnimation.StartOut();

CurrentlyFocusedElement->HasFocus = true;
CurrentSubMenu = nullptr;
AllowsScriptInput = true;
Config->Move(glm::vec2(0, -ItemPadding));
Help->Move(glm::vec2(0, -ItemPadding));
}
Expand Down
3 changes: 3 additions & 0 deletions src/games/cclcc/titlemenu.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ class TitleMenu : public Menu {
Widgets::Group* ContinueItems;
Widgets::CCLCC::TitleButton* Load;
Widgets::CCLCC::TitleButton* QuickLoad;

Widgets::CCLCC::TitleButton* LastFocusedButton = nullptr;

void ShowContinueItems();
void HideContinueItems();

Expand Down
19 changes: 16 additions & 3 deletions src/ui/widgets/cclcc/titlebutton.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,29 @@ namespace CCLCC {

using namespace Impacto::Profile::CCLCC::TitleMenu;

void TitleButton::UpdateInput() {
if (IsSubButton || HighlightAnimation.State == AS_Stopped) {
Button::UpdateInput();
}
}

void TitleButton::Render() {
if (HasFocus) {
if (HasFocus || HighlightAnimation.State == AS_Playing) {
if (!IsSubButton) { // Main buttons
Renderer->DrawSprite(HighlightSprite,
Sprite newHighlightSprite = HighlightSprite;
float smoothProgress =
HighlightAnimation.State == AS_Playing
? glm::smoothstep(0.0f, 1.0f, HighlightAnimation.Progress)
: 1.0f;
newHighlightSprite.Bounds.Width *= smoothProgress;
Renderer->DrawSprite(newHighlightSprite,
glm::vec2(Bounds.X - ItemHighlightOffsetX,
Bounds.Y - ItemHighlightOffsetY),
Tint);
glm::vec4 pointerTint = glm::vec4(1.0f, 1.0f, 1.0f, smoothProgress);
Renderer->DrawSprite(
ItemHighlightPointerSprite,
glm::vec2(Bounds.X - ItemHighlightPointerY, Bounds.Y), Tint);
glm::vec2(Bounds.X - ItemHighlightPointerY, Bounds.Y), pointerTint);
Renderer->DrawSprite(FocusedSprite, glm::vec2(Bounds.X, Bounds.Y), Tint);
} else { // Sub buttons
Renderer->DrawSprite(HighlightSprite, glm::vec2(Bounds.X, Bounds.Y),
Expand Down
7 changes: 6 additions & 1 deletion src/ui/widgets/cclcc/titlebutton.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,14 @@ class TitleButton : public Widgets::Button {
public:
TitleButton(int id, Sprite const& norm, Sprite const& focused,
Sprite const& highlight, glm::vec2 pos)
: Widgets::Button(id, norm, focused, highlight, pos) {}
: Widgets::Button(id, norm, focused, highlight, pos) {
HighlightAnimation.DurationIn = 0.3f;
HighlightAnimation.DurationOut = 0.3f;
}
void Render() override;
void UpdateInput() override;
bool IsSubButton = false;
Animation HighlightAnimation;
};

} // namespace CCLCC
Expand Down

0 comments on commit 4ef9890

Please sign in to comment.