mirror of
https://github.com/stenzek/duckstation.git
synced 2025-06-07 12:05:52 +00:00
Qt: Fix inconsistent multitap addressing
And remove multiple copies of the same variables while we're at it.
This commit is contained in:
parent
a76b48bc7b
commit
4e880280bd
@ -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);
|
||||||
|
@ -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.
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
|
@ -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] =
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user