diff --git a/CMakeLists.txt b/CMakeLists.txt index c151eed..2fea9b8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -173,6 +173,7 @@ set (SOURCES ${CMAKE_SOURCE_DIR}/src/ui/ui_config_page_controls.cpp ${CMAKE_SOURCE_DIR}/src/ui/ui_config_page_controls_element.cpp ${CMAKE_SOURCE_DIR}/src/ui/ui_prompt.cpp + ${CMAKE_SOURCE_DIR}/src/ui/ui_player_card.cpp ${CMAKE_SOURCE_DIR}/src/ui/ui_config_sub_menu.cpp ${CMAKE_SOURCE_DIR}/src/ui/ui_color_hack.cpp ${CMAKE_SOURCE_DIR}/src/ui/ui_rml_hacks.cpp diff --git a/include/recomp_input.h b/include/recomp_input.h index 7ceb044..a0f654f 100644 --- a/include/recomp_input.h +++ b/include/recomp_input.h @@ -273,6 +273,8 @@ namespace recompinput { PlayerAssignmentState() : is_assigning(false), player_index(0), temp_assigned_players{} {}; }; + AssignedPlayer& get_assigned_player(int player_index, bool temp_player = false); + bool get_player_is_assigned(int player_index); void start_player_assignment(void); void stop_player_assignment(void); diff --git a/src/game/input.cpp b/src/game/input.cpp index 108ece5..29ac8aa 100644 --- a/src/game/input.cpp +++ b/src/game/input.cpp @@ -80,6 +80,14 @@ int recompinput::get_num_players() { return static_cast(InputState.assigned_controllers.size()); } +recompinput::AssignedPlayer& recompinput::get_assigned_player(int player_index, bool temp_player) { + if (temp_player) { + return player_assignment_state.temp_assigned_players[player_index]; + } else { + return InputState.assigned_controllers[player_index]; + } +} + bool recompinput::get_player_is_assigned(int player_index) { if (player_index < 0 || player_index >= recompinput::get_num_players()) { return false; diff --git a/src/ui/ui_assign_players_modal.cpp b/src/ui/ui_assign_players_modal.cpp index cee45d7..694c4df 100644 --- a/src/ui/ui_assign_players_modal.cpp +++ b/src/ui/ui_assign_players_modal.cpp @@ -7,67 +7,6 @@ namespace recompui { recompui::ContextId assign_players_modal_context; -static constexpr float assign_player_card_size = 128.0f; -static constexpr float assign_player_card_icon_size = 64.0f; -AssignPlayerCard::AssignPlayerCard(Element *parent) : Element(parent, 0, "div", false) { - set_display(Display::Flex); - set_flex_direction(FlexDirection::Column); - set_align_items(AlignItems::Center); - set_justify_content(JustifyContent::Center); - set_width(assign_player_card_size); - set_height(assign_player_card_size); - set_border_color(theme::color::BorderSoft); - set_border_width(theme::border::width, Unit::Dp); - set_border_radius(theme::border::radius_sm, Unit::Dp); - set_background_color(theme::color::Transparent); - - recompui::ContextId context = get_current_context(); - icon = context.create_element(this, "assets/icons/RecordBorder.svg"); - icon->set_width(assign_player_card_icon_size, Unit::Dp); - icon->set_height(assign_player_card_icon_size, Unit::Dp); - icon->set_color(theme::color::TextDim); -} - -AssignPlayerCard::~AssignPlayerCard() { -} - -void AssignPlayerCard::update_player_card(int player_index) { - static const float scale_anim_duration = 0.25f; - bool is_assigned = recompinput::get_player_is_assigned(player_index); - if (!is_assigned) { - icon->set_scale_2D(1.0f, 1.0f); - set_background_color(theme::color::Transparent); - icon->set_color(theme::color::TextDim); - icon->set_src("assets/icons/RecordBorder.svg"); - return; - } - - set_background_color(theme::color::PrimaryA20); - - bool has_controller =recompinput::does_player_have_controller(player_index); - - std::chrono::steady_clock::duration time_since_last_button_press = recompinput::get_player_time_since_last_button_press(player_index); - auto millis = static_cast(std::chrono::duration_cast(time_since_last_button_press).count()); - float seconds = millis / 1000.0f; - - if (seconds > 0 && seconds < scale_anim_duration) { - float t = 1.0f - (seconds / scale_anim_duration); - float scale = 1.0f + t * 0.15f; - icon->set_scale_2D(scale, scale); - icon->set_color(theme::color::Text, 200 + static_cast(t * 55.0f)); - } else { - icon->set_scale_2D(1.0f, 1.0f); - icon->set_color(theme::color::Text, 200); - } - - if (has_controller) { - icon->set_src("assets/icons/Cont.svg"); - } else { - icon->set_src("assets/icons/Keyboard.svg"); - } - -} - static const float assignPlayersHFPaddingVert = 20.0f; static const float assignPlayersHFPaddingHorz = 20.0f; @@ -179,7 +118,7 @@ void AssignPlayersModal::process_event(const Event &e) { } for (int i = 0; i < recompinput::get_num_players(); i++) { - player_elements[i]->update_player_card(i); + player_elements[i]->update_assignment_player_card(); } if (!recompinput::is_player_assignment_active()) { @@ -215,7 +154,7 @@ void AssignPlayersModal::create_player_elements() { recompui::ContextId context = get_current_context(); for (int i = 0; i < recompinput::get_num_players(); i++) { - AssignPlayerCard* player_element = context.create_element(player_elements_wrapper); + PlayerCard* player_element = context.create_element(player_elements_wrapper, i, true); player_elements.push_back(player_element); } } diff --git a/src/ui/ui_assign_players_modal.h b/src/ui/ui_assign_players_modal.h index c712710..14f99b1 100644 --- a/src/ui/ui_assign_players_modal.h +++ b/src/ui/ui_assign_players_modal.h @@ -4,28 +4,17 @@ #include "elements/ui_element.h" #include "elements/ui_svg.h" #include "elements/ui_button.h" +#include "ui_player_card.h" namespace recompui { -class AssignPlayerCard : public Element { -protected: - bool is_open = false; - Svg* icon = nullptr; - - std::string_view get_type_name() override { return "AssignPlayerCard"; } -public: - AssignPlayerCard(Element *parent); - virtual ~AssignPlayerCard(); - void update_player_card(int player_index); -}; - class AssignPlayersModal : public Element { protected: bool is_open = false; bool was_assigning = false; Element* player_elements_wrapper = nullptr; Element* fake_focus_button = nullptr; - std::vector player_elements = {}; + std::vector player_elements = {}; Button* close_button = nullptr; Button* retry_button = nullptr; diff --git a/src/ui/ui_player_card.cpp b/src/ui/ui_player_card.cpp new file mode 100644 index 0000000..70ffdd2 --- /dev/null +++ b/src/ui/ui_player_card.cpp @@ -0,0 +1,99 @@ +#include "ui_player_card.h" + +namespace recompui { + +static constexpr float assign_player_card_size = 128.0f; +static constexpr float assign_player_card_icon_size = 64.0f; + +static constexpr float static_player_card_size = 256.0f; +static constexpr float static_player_card_icon_size = 128.0f; + +PlayerCard::PlayerCard( + Element *parent, + int player_index, + bool is_assignment_card +) : Element(parent, 0, "div", false), + player_index(player_index), + is_assignment_card(is_assignment_card) +{ + const float size = is_assignment_card ? assign_player_card_size : static_player_card_size; + const float icon_size = is_assignment_card ? assign_player_card_icon_size : static_player_card_icon_size; + + set_display(Display::Flex); + set_flex_direction(FlexDirection::Column); + set_align_items(AlignItems::Center); + set_justify_content(JustifyContent::Center); + set_width(size); + set_height(size); + set_border_color(theme::color::BorderSoft); + set_border_width(theme::border::width, Unit::Dp); + set_border_radius(theme::border::radius_sm, Unit::Dp); + set_background_color(theme::color::Transparent); + + recompui::ContextId context = get_current_context(); + icon = context.create_element(this, "assets/icons/RecordBorder.svg"); + icon->set_width(icon_size, Unit::Dp); + icon->set_height(icon_size, Unit::Dp); + icon->set_color(theme::color::TextDim); + icon->set_display(Display::None); + + if (!is_assignment_card) { + update_player_card_icon(); + } +} + +PlayerCard::~PlayerCard() { +} + +void PlayerCard::update_player_card_icon() { + recompinput::AssignedPlayer& assigned_player = recompinput::get_assigned_player(player_index, is_assignment_card); + if (assigned_player.is_assigned) { + if (assigned_player.controller != nullptr) { + icon->set_display(Display::Block); + icon->set_src("assets/icons/Cont.svg"); + } else { + icon->set_display(Display::Block); + icon->set_src("assets/icons/Keyboard.svg"); + } + } else { + if (is_assignment_card) { + icon->set_display(Display::Block); + icon->set_src("assets/icons/RecordBorder.svg"); + } else { + icon->set_display(Display::None); + } + } +} + +void PlayerCard::update_assignment_player_card() { + static const float scale_anim_duration = 0.25f; + + update_player_card_icon(); + + if (!recompinput::get_player_is_assigned(player_index)) { + icon->set_scale_2D(1.0f, 1.0f); + set_background_color(theme::color::Transparent); + icon->set_color(theme::color::TextDim); + return; + } + + set_background_color(theme::color::PrimaryA20); + + bool has_controller =recompinput::does_player_have_controller(player_index); + + std::chrono::steady_clock::duration time_since_last_button_press = recompinput::get_player_time_since_last_button_press(player_index); + auto millis = static_cast(std::chrono::duration_cast(time_since_last_button_press).count()); + float seconds = millis / 1000.0f; + + if (seconds > 0 && seconds < scale_anim_duration) { + float t = 1.0f - (seconds / scale_anim_duration); + float scale = 1.0f + t * 0.15f; + icon->set_scale_2D(scale, scale); + icon->set_color(theme::color::Text, 200 + static_cast(t * 55.0f)); + } else { + icon->set_scale_2D(1.0f, 1.0f); + icon->set_color(theme::color::Text, 200); + } +} + +} // namespace recompui diff --git a/src/ui/ui_player_card.h b/src/ui/ui_player_card.h new file mode 100644 index 0000000..d2d866f --- /dev/null +++ b/src/ui/ui_player_card.h @@ -0,0 +1,25 @@ +#pragma once + +#include "recomp_input.h" +#include "elements/ui_element.h" +#include "elements/ui_svg.h" +#include "elements/ui_button.h" + +namespace recompui { + +class PlayerCard : public Element { +protected: + bool is_open = false; + Svg* icon = nullptr; + int player_index = -1; + bool is_assignment_card = false; + + std::string_view get_type_name() override { return "PlayerCard"; } +public: + PlayerCard(Element *parent, int player_index, bool is_assignment_card = false); + virtual ~PlayerCard(); + void update_assignment_player_card(); + void update_player_card_icon(); +}; + +} // namespace recompui