diff --git a/src/engine/client/input.cpp b/src/engine/client/input.cpp index 6ffa16eac..6a0245dcc 100644 --- a/src/engine/client/input.cpp +++ b/src/engine/client/input.cpp @@ -187,14 +187,10 @@ void CInput::CloseJoysticks() m_pActiveJoystick = nullptr; } -void CInput::SelectNextJoystick() +void CInput::SetActiveJoystick(size_t Index) { - const int Num = m_vJoysticks.size(); - if(Num > 1) - { - m_pActiveJoystick = &m_vJoysticks[(m_pActiveJoystick->GetIndex() + 1) % Num]; - str_copy(g_Config.m_InpControllerGUID, m_pActiveJoystick->GetGUID()); - } + m_pActiveJoystick = &m_vJoysticks[Index]; + str_copy(g_Config.m_InpControllerGUID, m_pActiveJoystick->GetGUID()); } float CInput::CJoystick::GetAxisValue(int Axis) diff --git a/src/engine/client/input.h b/src/engine/client/input.h index d3aa18ace..9de494c20 100644 --- a/src/engine/client/input.h +++ b/src/engine/client/input.h @@ -122,8 +122,9 @@ public: bool KeyPress(int Key, bool CheckCounter) const override { return CheckCounter ? (m_aInputCount[Key] == m_InputCounter) : m_aInputCount[Key]; } size_t NumJoysticks() const override { return m_vJoysticks.size(); } + CJoystick *GetJoystick(size_t Index) override { return &m_vJoysticks[Index]; } CJoystick *GetActiveJoystick() override { return m_pActiveJoystick; } - void SelectNextJoystick() override; + void SetActiveJoystick(size_t Index) override; bool MouseRelative(float *pX, float *pY) override; void MouseModeAbsolute() override; diff --git a/src/engine/input.h b/src/engine/input.h index 95760c558..5227f1218 100644 --- a/src/engine/input.h +++ b/src/engine/input.h @@ -98,8 +98,9 @@ public: virtual bool Absolute(float *pX, float *pY) = 0; }; virtual size_t NumJoysticks() const = 0; + virtual IJoystick *GetJoystick(size_t Index) = 0; virtual IJoystick *GetActiveJoystick() = 0; - virtual void SelectNextJoystick() = 0; + virtual void SetActiveJoystick(size_t Index) = 0; // mouse virtual void NativeMousePos(int *pX, int *pY) const = 0; diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp index 96db41dc3..43066ebdb 100644 --- a/src/game/client/components/menus_settings.cpp +++ b/src/game/client/components/menus_settings.cpp @@ -1078,20 +1078,39 @@ float CMenus::RenderSettingsControlsJoystick(CUIRect View) { // show joystick device selection if more than one available or just the joystick name if there is only one { + CUIRect JoystickDropDown; View.HSplitTop(Spacing, nullptr, &View); - View.HSplitTop(ButtonHeight, &Button, &View); - char aBuf[96]; - str_format(aBuf, sizeof(aBuf), Localize("Controller %d: %s"), Input()->GetActiveJoystick()->GetIndex(), Input()->GetActiveJoystick()->GetName()); + View.HSplitTop(ButtonHeight, &JoystickDropDown, &View); if(NumJoysticks > 1) { - static CButtonContainer s_ButtonJoystickId; - if(DoButton_Menu(&s_ButtonJoystickId, aBuf, 0, &Button)) - Input()->SelectNextJoystick(); - GameClient()->m_Tooltips.DoToolTip(&s_ButtonJoystickId, &Button, Localize("Click to cycle through all available controllers.")); + static std::vector s_vJoystickNames; + static std::vector s_vpJoystickNames; + s_vJoystickNames.resize(NumJoysticks); + s_vpJoystickNames.resize(NumJoysticks); + + for(int i = 0; i < NumJoysticks; ++i) + { + char aBuf[256]; + str_format(aBuf, sizeof(aBuf), "%s %d: %s", Localize("Controller"), i, Input()->GetJoystick(i)->GetName()); + s_vJoystickNames[i] = aBuf; + s_vpJoystickNames[i] = s_vJoystickNames[i].c_str(); + } + + static CUI::SDropDownState s_JoystickDropDownState; + static CScrollRegion s_JoystickDropDownScrollRegion; + s_JoystickDropDownState.m_SelectionPopupContext.m_pScrollRegion = &s_JoystickDropDownScrollRegion; + const int CurrentJoystick = Input()->GetActiveJoystick()->GetIndex(); + const int NewJoystick = UI()->DoDropDown(&JoystickDropDown, CurrentJoystick, s_vpJoystickNames.data(), s_vpJoystickNames.size(), s_JoystickDropDownState); + if(NewJoystick != CurrentJoystick) + { + Input()->SetActiveJoystick(NewJoystick); + } } else { - UI()->DoLabel(&Button, aBuf, 13.0f, TEXTALIGN_ML); + char aBuf[256]; + str_format(aBuf, sizeof(aBuf), "%s 0: %s", Localize("Controller"), Input()->GetJoystick(0)->GetName()); + UI()->DoLabel(&JoystickDropDown, aBuf, 13.0f, TEXTALIGN_ML); } }