Qt: Fix inconsistent multitap addressing

And remove multiple copies of the same variables while we're at it.
This commit is contained in:
Stenzek 2024-09-27 20:57:35 +10:00
parent a76b48bc7b
commit 4e880280bd
No known key found for this signature in database
9 changed files with 62 additions and 77 deletions

View File

@ -32,6 +32,8 @@ static const Controller::ControllerInfo* s_controller_info[] = {
&Justifier::INFO, &Justifier::INFO,
}; };
const std::array<u32, NUM_CONTROLLER_AND_CARD_PORTS> Controller::PortDisplayOrder = {{0, 2, 3, 4, 1, 5, 6, 7}};
const char* Controller::ControllerInfo::GetDisplayName() const const char* Controller::ControllerInfo::GetDisplayName() const
{ {
return Host::TranslateToCString("ControllerType", display_name); return Host::TranslateToCString("ControllerType", display_name);
@ -211,6 +213,15 @@ bool Controller::PortAndSlotIsMultitap(u32 port, u32 slot)
return (slot != 0); return (slot != 0);
} }
const char* Controller::GetPortDisplayName(u32 port, u32 slot, bool mtap)
{
static constexpr const char* no_mtap_labels[] = {"1", "2"};
static constexpr const char* mtap_labels[][4] = {{"1A", "1B", "1C", "1D"}, {"2A", "2B", "2C", "2D"}};
DebugAssert(port < 2 && slot < 4);
return mtap ? mtap_labels[port][slot] : no_mtap_labels[port];
}
std::string Controller::GetSettingsSection(u32 pad) std::string Controller::GetSettingsSection(u32 pad)
{ {
return fmt::format("Pad{}", pad + 1u); return fmt::format("Pad{}", pad + 1u);

View File

@ -111,6 +111,15 @@ public:
static const ControllerInfo* GetControllerInfo(ControllerType type); static const ControllerInfo* GetControllerInfo(ControllerType type);
static const ControllerInfo* GetControllerInfo(std::string_view name); static const ControllerInfo* GetControllerInfo(std::string_view name);
/// Applies an analog deadzone/sensitivity.
static float ApplyAnalogDeadzoneSensitivity(float deadzone, float sensitivity, float value)
{
return (value < deadzone) ? 0.0f : ((value - deadzone) / (1.0f - deadzone) * sensitivity);
}
/// Returns true if the specified coordinates are inside a circular deadzone.
static bool InCircularDeadzone(float deadzone, float pos_x, float pos_y);
/// Converts a global pad index to a multitap port and slot. /// Converts a global pad index to a multitap port and slot.
static std::tuple<u32, u32> ConvertPadToPortAndSlot(u32 index); static std::tuple<u32, u32> ConvertPadToPortAndSlot(u32 index);
@ -124,14 +133,11 @@ public:
/// Returns the configuration section for the specified gamepad. /// Returns the configuration section for the specified gamepad.
static std::string GetSettingsSection(u32 pad); static std::string GetSettingsSection(u32 pad);
/// Applies an analog deadzone/sensitivity. /// Returns a printable label for a given port.
static float ApplyAnalogDeadzoneSensitivity(float deadzone, float sensitivity, float value) static const char* GetPortDisplayName(u32 port, u32 slot, bool mtap);
{
return (value < deadzone) ? 0.0f : ((value - deadzone) / (1.0f - deadzone) * sensitivity);
}
/// Returns true if the specified coordinates are inside a circular deadzone. /// List of controller indices in the order that they should be displayed.
static bool InCircularDeadzone(float deadzone, float pos_x, float pos_y); static const std::array<u32, NUM_CONTROLLER_AND_CARD_PORTS> PortDisplayOrder;
protected: protected:
/// Returns true if automatic analog mode can be used. /// Returns true if automatic analog mode can be used.

View File

@ -3743,28 +3743,16 @@ void FullscreenUI::DrawControllerSettingsPage()
{(mtap_mode == MultitapMode::Port1Only || mtap_mode == MultitapMode::BothPorts), {(mtap_mode == MultitapMode::Port1Only || mtap_mode == MultitapMode::BothPorts),
(mtap_mode == MultitapMode::Port2Only || mtap_mode == MultitapMode::BothPorts)}}; (mtap_mode == MultitapMode::Port2Only || mtap_mode == MultitapMode::BothPorts)}};
// we reorder things a little to make it look less silly for mtap
static constexpr const std::array<char, 4> mtap_slot_names = {{'A', 'B', 'C', 'D'}};
static constexpr const std::array<u32, NUM_CONTROLLER_AND_CARD_PORTS> mtap_port_order = {{0, 2, 3, 4, 1, 5, 6, 7}};
// create the ports // create the ports
for (u32 global_slot : mtap_port_order) for (const u32 global_slot : Controller::PortDisplayOrder)
{ {
const auto [mtap_port, mtap_slot] = Controller::ConvertPadToPortAndSlot(global_slot); const auto [mtap_port, mtap_slot] = Controller::ConvertPadToPortAndSlot(global_slot);
const bool is_mtap_port = Controller::PortAndSlotIsMultitap(mtap_port, mtap_slot); const bool is_mtap_port = Controller::PortAndSlotIsMultitap(mtap_port, mtap_slot);
if (is_mtap_port && !mtap_enabled[mtap_port]) if (is_mtap_port && !mtap_enabled[mtap_port])
continue; continue;
if (mtap_enabled[mtap_port]) MenuHeading(TinyString::from_format(fmt::runtime(FSUI_ICONSTR(ICON_FA_PLUG, "Controller Port {}")),
{ Controller::GetPortDisplayName(mtap_port, mtap_slot, mtap_enabled[mtap_port])));
MenuHeading(TinyString::from_format(fmt::runtime(FSUI_ICONSTR(ICON_FA_PLUG, "Controller Port {}{}")),
mtap_port + 1, mtap_slot_names[mtap_slot]));
}
else
{
MenuHeading(
TinyString::from_format(fmt::runtime(FSUI_ICONSTR(ICON_FA_PLUG, "Controller Port {}")), mtap_port + 1));
}
const TinyString section = TinyString::from_format("Pad{}", global_slot + 1); const TinyString section = TinyString::from_format("Pad{}", global_slot + 1);
const TinyString type = const TinyString type =
@ -3810,16 +3798,9 @@ void FullscreenUI::DrawControllerSettingsPage()
Host::TranslateToCString(ci->name, bi.display_name), bi.icon_name, true); Host::TranslateToCString(ci->name, bi.display_name), bi.icon_name, true);
} }
if (mtap_enabled[mtap_port]) MenuHeading(
{ SmallString::from_format(fmt::runtime(FSUI_ICONSTR(ICON_FA_MICROCHIP, "Controller Port {} Macros")),
MenuHeading(SmallString::from_format(fmt::runtime(FSUI_ICONSTR(ICON_FA_MICROCHIP, "Controller Port {}{} Macros")), Controller::GetPortDisplayName(mtap_port, mtap_slot, mtap_enabled[mtap_port])));
mtap_port + 1, mtap_slot_names[mtap_slot]));
}
else
{
MenuHeading(SmallString::from_format(fmt::runtime(FSUI_ICONSTR(ICON_FA_MICROCHIP, "Controller Port {} Macros")),
mtap_port + 1));
}
for (u32 macro_index = 0; macro_index < InputManager::NUM_MACRO_BUTTONS_PER_CONTROLLER; macro_index++) for (u32 macro_index = 0; macro_index < InputManager::NUM_MACRO_BUTTONS_PER_CONTROLLER; macro_index++)
{ {
@ -3962,17 +3943,9 @@ void FullscreenUI::DrawControllerSettingsPage()
if (!ci->settings.empty()) if (!ci->settings.empty())
{ {
if (mtap_enabled[mtap_port]) MenuHeading(
{ SmallString::from_format(fmt::runtime(FSUI_ICONSTR(ICON_FA_SLIDERS_H, "Controller Port {} Settings")),
MenuHeading( Controller::GetPortDisplayName(mtap_port, mtap_slot, mtap_enabled[mtap_port])));
SmallString::from_format(fmt::runtime(FSUI_ICONSTR(ICON_FA_SLIDERS_H, "Controller Port {}{} Settings")),
mtap_port + 1, mtap_slot_names[mtap_slot]));
}
else
{
MenuHeading(SmallString::from_format(
fmt::runtime(FSUI_ICONSTR(ICON_FA_SLIDERS_H, "Controller Port {} Settings")), mtap_port + 1));
}
for (const SettingInfo& si : ci->settings) for (const SettingInfo& si : ci->settings)
{ {

View File

@ -628,17 +628,20 @@ void ImGuiManager::DrawInputsOverlay()
SmallString text; SmallString text;
for (u32 port = 0; port < NUM_CONTROLLER_AND_CARD_PORTS; port++) for (const u32 pad : Controller::PortDisplayOrder)
{ {
if (g_settings.controller_types[port] == ControllerType::None) if (g_settings.controller_types[pad] == ControllerType::None)
continue; continue;
const Controller* controller = System::GetController(port); const Controller* controller = System::GetController(pad);
const Controller::ControllerInfo* cinfo = const Controller::ControllerInfo* cinfo =
controller ? Controller::GetControllerInfo(controller->GetType()) : nullptr; controller ? Controller::GetControllerInfo(controller->GetType()) : nullptr;
if (!cinfo) if (!cinfo)
continue; continue;
const auto& [port, slot] = Controller::ConvertPadToPortAndSlot(pad);
const char* port_label = Controller::GetPortDisplayName(port, slot, g_settings.IsMultitapPortEnabled(port));
float text_start_x = current_x; float text_start_x = current_x;
if (cinfo->icon_name) if (cinfo->icon_name)
{ {
@ -649,11 +652,11 @@ void ImGuiManager::DrawInputsOverlay()
dl->AddText(font, font->FontSize, ImVec2(current_x, current_y), icon_color, cinfo->icon_name, nullptr, 0.0f, dl->AddText(font, font->FontSize, ImVec2(current_x, current_y), icon_color, cinfo->icon_name, nullptr, 0.0f,
&clip_rect); &clip_rect);
text_start_x += icon_size.x; text_start_x += icon_size.x;
text.format(" {}", port + 1u); text.format(" {}", port_label);
} }
else else
{ {
text.format("{} |", port + 1u); text.format("{} |", port_label);
} }
for (const Controller::ControllerBindingInfo& bi : cinfo->bindings) for (const Controller::ControllerBindingInfo& bi : cinfo->bindings)

View File

@ -65,7 +65,8 @@ void Multitap::ResetTransferState()
bool Multitap::TransferController(u32 slot, const u8 data_in, u8* data_out) const bool Multitap::TransferController(u32 slot, const u8 data_in, u8* data_out) const
{ {
Controller* const selected_controller = Pad::GetController(m_base_index + slot); const u32 pad_port = Controller::ConvertPortAndSlotToPad(m_base_index, slot);
Controller* const selected_controller = Pad::GetController(pad_port);
if (!selected_controller) if (!selected_controller)
{ {
*data_out = 0xFF; *data_out = 0xFF;
@ -77,7 +78,8 @@ bool Multitap::TransferController(u32 slot, const u8 data_in, u8* data_out) cons
bool Multitap::TransferMemoryCard(u32 slot, const u8 data_in, u8* data_out) const bool Multitap::TransferMemoryCard(u32 slot, const u8 data_in, u8* data_out) const
{ {
MemoryCard* const selected_memcard = Pad::GetMemoryCard(m_base_index + slot); const u32 pad_port = Controller::ConvertPortAndSlotToPad(m_base_index, slot);
MemoryCard* const selected_memcard = Pad::GetMemoryCard(pad_port);
if (!selected_memcard) if (!selected_memcard)
{ {
*data_out = 0xFF; *data_out = 0xFF;

View File

@ -369,20 +369,20 @@ void Settings::Load(SettingsInterface& si, SettingsInterface& controller_si)
.value_or(DEFAULT_MULTITAP_MODE); .value_or(DEFAULT_MULTITAP_MODE);
const std::array<bool, 2> mtap_enabled = {{IsPort1MultitapEnabled(), IsPort2MultitapEnabled()}}; const std::array<bool, 2> mtap_enabled = {{IsPort1MultitapEnabled(), IsPort2MultitapEnabled()}};
for (u32 i = 0; i < NUM_CONTROLLER_AND_CARD_PORTS; i++) for (u32 pad = 0; pad < NUM_CONTROLLER_AND_CARD_PORTS; pad++)
{ {
// Ignore types when multitap not enabled // Ignore types when multitap not enabled
const auto [port, slot] = Controller::ConvertPadToPortAndSlot(i); const auto [port, slot] = Controller::ConvertPadToPortAndSlot(pad);
if (Controller::PadIsMultitapSlot(slot) && !mtap_enabled[port]) if (Controller::PadIsMultitapSlot(pad) && !mtap_enabled[port])
{ {
controller_types[i] = ControllerType::None; controller_types[pad] = ControllerType::None;
continue; continue;
} }
const ControllerType default_type = (i == 0) ? DEFAULT_CONTROLLER_1_TYPE : DEFAULT_CONTROLLER_2_TYPE; const ControllerType default_type = (pad == 0) ? DEFAULT_CONTROLLER_1_TYPE : DEFAULT_CONTROLLER_2_TYPE;
const Controller::ControllerInfo* cinfo = Controller::GetControllerInfo(controller_si.GetTinyStringValue( const Controller::ControllerInfo* cinfo = Controller::GetControllerInfo(controller_si.GetTinyStringValue(
Controller::GetSettingsSection(i).c_str(), "Type", Controller::GetControllerInfo(default_type)->name)); Controller::GetSettingsSection(pad).c_str(), "Type", Controller::GetControllerInfo(default_type)->name));
controller_types[i] = cinfo ? cinfo->type : default_type; controller_types[pad] = cinfo ? cinfo->type : default_type;
} }
memory_card_types[0] = memory_card_types[0] =

View File

@ -312,7 +312,7 @@ struct Settings
} }
ALWAYS_INLINE bool IsPort2MultitapEnabled() const ALWAYS_INLINE bool IsPort2MultitapEnabled() const
{ {
return (multitap_mode == MultitapMode::Port1Only || multitap_mode == MultitapMode::BothPorts); return (multitap_mode == MultitapMode::Port2Only || multitap_mode == MultitapMode::BothPorts);
} }
ALWAYS_INLINE bool IsMultitapPortEnabled(u32 port) const ALWAYS_INLINE bool IsMultitapPortEnabled(u32 port) const
{ {

View File

@ -489,12 +489,7 @@ void ControllerSettingsWindow::createWidgets()
// load mtap settings // load mtap settings
const std::array<bool, 2> mtap_enabled = getEnabledMultitaps(); const std::array<bool, 2> mtap_enabled = getEnabledMultitaps();
for (u32 global_slot : Controller::PortDisplayOrder)
// we reorder things a little to make it look less silly for mtap
static constexpr const std::array<u32, MAX_PORTS> mtap_port_order = {{0, 2, 3, 4, 1, 5, 6, 7}};
// create the ports
for (u32 global_slot : mtap_port_order)
{ {
const bool is_mtap_port = Controller::PadIsMultitapSlot(global_slot); const bool is_mtap_port = Controller::PadIsMultitapSlot(global_slot);
const auto [port, slot] = Controller::ConvertPadToPortAndSlot(global_slot); const auto [port, slot] = Controller::ConvertPadToPortAndSlot(global_slot);
@ -507,9 +502,9 @@ void ControllerSettingsWindow::createWidgets()
const QString display_name(QString::fromUtf8(m_port_bindings[global_slot]->getControllerInfo()->GetDisplayName())); const QString display_name(QString::fromUtf8(m_port_bindings[global_slot]->getControllerInfo()->GetDisplayName()));
QListWidgetItem* item = new QListWidgetItem(); QListWidgetItem* item = new QListWidgetItem();
item->setText(mtap_enabled[port] ? item->setText(tr("Controller Port %1\n%2")
(tr("Controller Port %1%2\n%3").arg(port + 1).arg(s_mtap_slot_names[slot]).arg(display_name)) : .arg(Controller::GetPortDisplayName(port, slot, mtap_enabled[port]))
tr("Controller Port %1\n%2").arg(port + 1).arg(display_name)); .arg(display_name));
item->setIcon(m_port_bindings[global_slot]->getIcon()); item->setIcon(m_port_bindings[global_slot]->getIcon());
item->setData(Qt::UserRole, QVariant(global_slot)); item->setData(Qt::UserRole, QVariant(global_slot));
m_ui.settingsCategory->addItem(item); m_ui.settingsCategory->addItem(item);
@ -555,9 +550,9 @@ void ControllerSettingsWindow::updateListDescription(u32 global_slot, Controller
const QString display_name = QString::fromUtf8(widget->getControllerInfo()->GetDisplayName()); const QString display_name = QString::fromUtf8(widget->getControllerInfo()->GetDisplayName());
item->setText(mtap_enabled[port] ? item->setText(tr("Controller Port %1\n%2")
(tr("Controller Port %1%2\n%3").arg(port + 1).arg(s_mtap_slot_names[slot]).arg(display_name)) : .arg(Controller::GetPortDisplayName(port, slot, mtap_enabled[port]))
tr("Controller Port %1\n%2").arg(port + 1).arg(display_name)); .arg(display_name));
item->setIcon(widget->getIcon()); item->setIcon(widget->getIcon());
break; break;
} }

View File

@ -7,7 +7,7 @@
#include "util/input_manager.h" #include "util/input_manager.h"
#include "common/types.h" #include "core/types.h"
#include <QtCore/QList> #include <QtCore/QList>
#include <QtCore/QPair> #include <QtCore/QPair>
@ -41,11 +41,6 @@ public:
Count Count
}; };
enum : u32
{
MAX_PORTS = 8
};
ControllerSettingsWindow(SettingsInterface* game_sif = nullptr, QWidget* parent = nullptr); ControllerSettingsWindow(SettingsInterface* game_sif = nullptr, QWidget* parent = nullptr);
~ControllerSettingsWindow(); ~ControllerSettingsWindow();
@ -121,7 +116,7 @@ private:
SettingsInterface* m_editing_settings_interface = nullptr; SettingsInterface* m_editing_settings_interface = nullptr;
ControllerGlobalSettingsWidget* m_global_settings = nullptr; ControllerGlobalSettingsWidget* m_global_settings = nullptr;
std::array<ControllerBindingWidget*, MAX_PORTS> m_port_bindings{}; std::array<ControllerBindingWidget*, NUM_CONTROLLER_AND_CARD_PORTS> m_port_bindings{};
HotkeySettingsWidget* m_hotkey_settings = nullptr; HotkeySettingsWidget* m_hotkey_settings = nullptr;
std::vector<std::pair<std::string, std::string>> m_device_list; std::vector<std::pair<std::string, std::string>> m_device_list;