From 1429654c4f1dc0815e108a443743f6f8a991a0aa Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Wed, 13 Nov 2024 01:01:09 +0100 Subject: [PATCH] Added character voice page --- CMakeLists.txt | 2 + profiles/cclcc/hud/optionsmenu.lua | 4 +- src/games/cclcc/optionsmenu.cpp | 46 ++++++++++++++++++-- src/ui/widgets/cclcc/optionsslider.h | 2 +- src/ui/widgets/cclcc/optionsvoiceslider.cpp | 48 +++++++++++++++++++++ src/ui/widgets/cclcc/optionsvoiceslider.h | 29 +++++++++++++ 6 files changed, 124 insertions(+), 7 deletions(-) create mode 100644 src/ui/widgets/cclcc/optionsvoiceslider.cpp create mode 100644 src/ui/widgets/cclcc/optionsvoiceslider.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f94df5a..d37d6d4f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -246,6 +246,7 @@ set(Impacto_Src src/ui/widgets/cclcc/optionsentry.cpp src/ui/widgets/cclcc/optionsbinarybutton.cpp src/ui/widgets/cclcc/optionsslider.cpp + src/ui/widgets/cclcc/optionsvoiceslider.cpp src/ui/widgets/cclcc/saveentrybutton.cpp src/ui/widgets/cclcc/sysmenubutton.cpp src/ui/widgets/cclcc/tipsentrybutton.cpp @@ -560,6 +561,7 @@ set(Impacto_Header src/ui/widgets/cclcc/optionsentry.h src/ui/widgets/cclcc/optionsbinarybutton.h src/ui/widgets/cclcc/optionsslider.h + src/ui/widgets/cclcc/optionsvoiceslider.h src/renderer/3d/camera.h src/renderer/3d/model.h diff --git a/profiles/cclcc/hud/optionsmenu.lua b/profiles/cclcc/hud/optionsmenu.lua index 884e949c..0987145b 100644 --- a/profiles/cclcc/hud/optionsmenu.lua +++ b/profiles/cclcc/hud/optionsmenu.lua @@ -26,7 +26,7 @@ root.OptionsMenu = { SliderTrackSprite = "OptionsSliderTrack", SliderTrackOffset = { X = 664, Y = 2 }, VoiceSliderTrackSprite = "OptionsVoiceSliderTrack", - VoiceSliderOffset = { X = 111, Y = 56 }, + VoiceSliderOffset = { X = 110, Y = 55 }, BinaryBoxSprite = "OptionsBinaryBox", BinaryBoxOffset = { X = 812, Y = 2 }, SliderSpeed = 1.0, @@ -207,7 +207,7 @@ for i = 0, 25 do root.Sprites["OptionsPortrait" .. i] = { Sheet = "ConfigEx", Bounds = { - X = 768 + (width + 1) * i, + X = 768 + (width + 1) * (i // 2), Y = ((i % 2 == 0) and {2256} or {2357})[1], Width = width, Height = width diff --git a/src/games/cclcc/optionsmenu.cpp b/src/games/cclcc/optionsmenu.cpp index 8b0c5a5b..f06a4b9f 100644 --- a/src/games/cclcc/optionsmenu.cpp +++ b/src/games/cclcc/optionsmenu.cpp @@ -6,6 +6,7 @@ #include "../../vm/interface/input.h" #include "../../ui/widgets/cclcc/optionsbinarybutton.h" #include "../../ui/widgets/cclcc/optionsslider.h" +#include "../../ui/widgets/cclcc/optionsvoiceslider.h" namespace Impacto { namespace UI { @@ -70,12 +71,47 @@ OptionsMenu::OptionsMenu() { Pages.push_back(SoundPage); VoicePage = new Group(this); - for (int i = 0; i < 12; i++) { + constexpr int columns = 3; + constexpr int entries = 12; + for (int i = 0; i < entries; i++) { glm::vec2 pos = VoicePosition; - pos += VoiceEntriesOffset * glm::vec2(i % 3, i / 3); + pos += VoiceEntriesOffset * glm::vec2(i % columns, i / columns); - VoicePage->Add(new Label(NametagSprites[i], pos), FDIR_RIGHT); + Widget* widget = new OptionsVoiceSlider( + VoiceSliderTrackSprite, NametagSprites[i], PortraitSprites[2 * i], + PortraitSprites[2 * i + 1], pos, highlightTint, SliderSpeed); + VoicePage->Add(widget, FDIR_RIGHT); } + + // Loop separately to overwrite the direction set at initial adding + // First entry won't set anything; skip + for (int i = 1; i < entries; i++) { + Widget* const widget = VoicePage->Children.at(i); + + if (i % columns != 0) { // Not on first column + Widget* const leftWidget = VoicePage->Children.at(i - 1); + widget->SetFocus(leftWidget, FDIR_LEFT); + leftWidget->SetFocus(widget, FDIR_RIGHT); + + if (i % columns == columns - 1) { // On last column + Widget* const rowStart = VoicePage->Children.at(i - columns + 1); + widget->SetFocus(rowStart, FDIR_RIGHT); + rowStart->SetFocus(widget, FDIR_LEFT); + } + } + if (i >= columns) { // Not on first row + Widget* const upWidget = VoicePage->Children.at(i - columns); + widget->SetFocus(upWidget, FDIR_UP); + upWidget->SetFocus(widget, FDIR_DOWN); + + if (i >= entries - columns) { // On last layer + Widget* const columnStart = VoicePage->Children.at(i % columns); + widget->SetFocus(columnStart, FDIR_DOWN); + columnStart->SetFocus(widget, FDIR_UP); + } + } + } + Pages.push_back(VoicePage); CurrentPage = 0; @@ -163,7 +199,9 @@ void OptionsMenu::Render() { Renderer->DrawSprite(PoleAnimation.CurrentSprite(), PagePanelPosition, col); - Renderer->DrawSprite(GuideSprite, GuidePosition, col); + const Sprite& guideSprite = + CurrentPage == 3 ? VoiceGuideSprite : GuideSprite; + Renderer->DrawSprite(guideSprite, GuidePosition, col); } } diff --git a/src/ui/widgets/cclcc/optionsslider.h b/src/ui/widgets/cclcc/optionsslider.h index 9333d216..627734fb 100644 --- a/src/ui/widgets/cclcc/optionsslider.h +++ b/src/ui/widgets/cclcc/optionsslider.h @@ -16,7 +16,7 @@ class OptionsSlider : public OptionsEntry { void Render() override; void Update(float dt) override; - private: + protected: const Sprite& BoxSprite; float Progress = 0.0f; diff --git a/src/ui/widgets/cclcc/optionsvoiceslider.cpp b/src/ui/widgets/cclcc/optionsvoiceslider.cpp new file mode 100644 index 00000000..a7c75f18 --- /dev/null +++ b/src/ui/widgets/cclcc/optionsvoiceslider.cpp @@ -0,0 +1,48 @@ +#include "optionsvoiceslider.h" + +#include "../../../profile/games/cclcc/optionsmenu.h" +#include "../../../renderer/renderer.h" +#include "../../../vm/interface/input.h" + +using namespace Impacto::Profile::CCLCC::OptionsMenu; +using namespace Impacto::Vm::Interface; + +namespace Impacto { +namespace UI { +namespace Widgets { +namespace CCLCC { + +OptionsVoiceSlider::OptionsVoiceSlider(const Sprite& box, const Sprite& label, + const Sprite& portrait, + const Sprite& mutedPortrait, + glm::vec2 pos, glm::vec4 highlightTint, + float sliderSpeed) + : OptionsSlider(box, label, pos, highlightTint, sliderSpeed), + Portrait(portrait), + MutedPortrait(mutedPortrait) {} + +void OptionsVoiceSlider::Render() { + HighlightTint.a = Tint.a; + + Renderer->DrawSprite(Muted ? MutedPortrait : Portrait, Bounds.GetPos(), Tint); + Renderer->DrawSprite(LabelSprite, Bounds.GetPos() + NametagOffset, + Selected ? Tint : glm::vec4(0.0f, 0.0f, 0.0f, Tint.a)); + + RectF highlightBounds( + Bounds.X + VoiceSliderOffset.x, Bounds.Y + VoiceSliderOffset.y, + Progress * BoxSprite.ScaledWidth(), BoxSprite.ScaledHeight()); + Renderer->DrawRect(highlightBounds, HighlightTint); + Renderer->DrawSprite(BoxSprite, Bounds.GetPos() + VoiceSliderOffset, Tint); +} + +void OptionsVoiceSlider::UpdateInput() { + OptionsEntry::UpdateInput(); + if (!Selected) return; + + Muted ^= (bool)(PADinputButtonWentDown & PAD1Y); +} + +} // namespace CCLCC +} // namespace Widgets +} // namespace UI +} // namespace Impacto \ No newline at end of file diff --git a/src/ui/widgets/cclcc/optionsvoiceslider.h b/src/ui/widgets/cclcc/optionsvoiceslider.h new file mode 100644 index 00000000..a49543c4 --- /dev/null +++ b/src/ui/widgets/cclcc/optionsvoiceslider.h @@ -0,0 +1,29 @@ +#pragma once + +#include "./optionsslider.h" +#include "../../../spritesheet.h" + +namespace Impacto { +namespace UI { +namespace Widgets { +namespace CCLCC { + +class OptionsVoiceSlider : public OptionsSlider { + public: + OptionsVoiceSlider(const Sprite& box, const Sprite& label, + const Sprite& portrait, const Sprite& mutedPortrait, + glm::vec2 pos, glm::vec4 highlightTint, float sliderSpeed); + void Render() override; + void UpdateInput() override; + + private: + const Sprite& Portrait; + const Sprite& MutedPortrait; + + bool Muted = false; +}; + +} // namespace CCLCC +} // namespace Widgets +} // namespace UI +} // namespace Impacto \ No newline at end of file