Settings: Fix double source of truth for controller names

This commit is contained in:
Stenzek
2024-04-27 13:21:11 +10:00
parent 5477f2eae2
commit 3e99084770
12 changed files with 93 additions and 128 deletions

View File

@ -873,13 +873,14 @@ static const SettingInfo s_settings[] = {
nullptr, s_invert_settings, 0.0f},
};
const Controller::ControllerInfo AnalogController::INFO = {ControllerType::AnalogController,
"AnalogController",
TRANSLATE_NOOP("ControllerType", "Analog Controller"),
ICON_PF_GAMEPAD,
s_binding_info,
s_settings,
Controller::VibrationCapabilities::LargeSmallMotors};
const Controller::ControllerInfo AnalogController::INFO = {
ControllerType::AnalogController,
"AnalogController",
TRANSLATE_NOOP("ControllerType", "Analog Controller"),
ICON_PF_GAMEPAD,
s_binding_info,
s_settings,
Controller::VibrationCapabilities::LargeSmallMotors};
void AnalogController::LoadSettings(SettingsInterface& si, const char* section)
{

View File

@ -23,9 +23,14 @@ static const Controller::ControllerInfo s_none_info = {ControllerType::None,
static const Controller::ControllerInfo* s_controller_info[] = {
&s_none_info, &DigitalController::INFO, &AnalogController::INFO, &AnalogJoystick::INFO,
&NeGcon::INFO, &NeGconRumble::INFO,&GunCon::INFO, &PlayStationMouse::INFO,
&NeGcon::INFO, &NeGconRumble::INFO, &GunCon::INFO, &PlayStationMouse::INFO,
};
const char* Controller::ControllerInfo::GetDisplayName() const
{
return Host::TranslateToCString("ControllerType", display_name);
}
Controller::Controller(u32 index) : m_index(index)
{
}
@ -100,7 +105,7 @@ std::unique_ptr<Controller> Controller::Create(ControllerType type, u32 index)
case ControllerType::NeGcon:
return NeGcon::Create(index);
case ControllerType::NeGconRumble:
return NeGconRumble::Create(index);
@ -112,8 +117,8 @@ std::unique_ptr<Controller> Controller::Create(ControllerType type, u32 index)
const char* Controller::GetDefaultPadType(u32 pad)
{
return Settings::GetControllerTypeName((pad == 0) ? Settings::DEFAULT_CONTROLLER_1_TYPE :
Settings::DEFAULT_CONTROLLER_2_TYPE);
return GetControllerInfo((pad == 0) ? Settings::DEFAULT_CONTROLLER_1_TYPE : Settings::DEFAULT_CONTROLLER_2_TYPE)
->name;
}
const Controller::ControllerInfo* Controller::GetControllerInfo(ControllerType type)
@ -127,7 +132,7 @@ const Controller::ControllerInfo* Controller::GetControllerInfo(ControllerType t
return nullptr;
}
const Controller::ControllerInfo* Controller::GetControllerInfo(const std::string_view& name)
const Controller::ControllerInfo* Controller::GetControllerInfo(std::string_view name)
{
for (const ControllerInfo* info : s_controller_info)
{

View File

@ -49,6 +49,9 @@ public:
std::span<const ControllerBindingInfo> bindings;
std::span<const SettingInfo> settings;
VibrationCapabilities vibration_caps;
/// Returns localized controller type name.
const char* GetDisplayName() const;
};
/// Default stick deadzone/sensitivity.
@ -106,7 +109,7 @@ public:
/// Returns general information for the specified controller type.
static const ControllerInfo* GetControllerInfo(ControllerType type);
static const ControllerInfo* GetControllerInfo(const std::string_view& name);
static const ControllerInfo* GetControllerInfo(std::string_view name);
/// Converts a global pad index to a multitap port and slot.
static std::tuple<u32, u32> ConvertPadToPortAndSlot(u32 index);

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#include "game_database.h"
#include "controller.h"
#include "host.h"
#include "system.h"
@ -652,15 +653,16 @@ void GameDatabase::Entry::ApplySettings(Settings& settings, bool display_osd_mes
if (!supported_controller_string.empty())
supported_controller_string.append(", ");
supported_controller_string.append(Settings::GetControllerTypeDisplayName(supported_ctype));
supported_controller_string.append(Controller::GetControllerInfo(supported_ctype)->GetDisplayName());
}
Host::AddKeyedOSDMessage(
"gamedb_controller_unsupported",
fmt::format(
TRANSLATE_FS("OSDMessage", "Controller in port {0} ({1}) is not supported for {2}.\nSupported controllers: "
"{3}\nPlease configure a supported controller from the list above."),
i + 1u, Settings::GetControllerTypeDisplayName(ctype), System::GetGameTitle(), supported_controller_string),
fmt::format(TRANSLATE_FS("OSDMessage",
"Controller in port {0} ({1}) is not supported for {2}.\nSupported controllers: "
"{3}\nPlease configure a supported controller from the list above."),
i + 1u, Controller::GetControllerInfo(ctype)->GetDisplayName(), System::GetGameTitle(),
supported_controller_string),
Host::OSD_CRITICAL_ERROR_DURATION);
}
}
@ -981,8 +983,8 @@ bool GameDatabase::ParseYamlEntry(Entry* entry, const ryml::ConstNodeRef& value)
return false;
}
std::optional<ControllerType> ctype = Settings::ParseControllerTypeName(controller_str);
if (!ctype.has_value())
const Controller::ControllerInfo* cinfo = Controller::GetControllerInfo(controller_str);
if (!cinfo)
{
Log_WarningFmt("Invalid controller type {} in {}", controller_str, entry->serial);
continue;
@ -994,7 +996,7 @@ bool GameDatabase::ParseYamlEntry(Entry* entry, const ryml::ConstNodeRef& value)
first = false;
}
entry->supported_controllers |= (1u << static_cast<u16>(ctype.value()));
entry->supported_controllers |= (1u << static_cast<u16>(cinfo->type));
}
}

View File

@ -187,13 +187,17 @@ u32 Pad::GetMaximumRollbackFrames()
bool Pad::DoStateController(StateWrapper& sw, u32 i)
{
ControllerType controller_type = s_controllers[i] ? s_controllers[i]->GetType() : ControllerType::None;
const ControllerType controller_type = s_controllers[i] ? s_controllers[i]->GetType() : ControllerType::None;
ControllerType state_controller_type = controller_type;
sw.Do(&state_controller_type);
// Data type change...
u32 state_controller_type_value = static_cast<u32>(state_controller_type);
sw.Do(&state_controller_type_value);
state_controller_type = static_cast<ControllerType>(state_controller_type_value);
if (controller_type != state_controller_type)
{
const Controller::ControllerInfo* state_cinfo = Controller::GetControllerInfo(state_controller_type);
Assert(sw.GetMode() == StateWrapper::Mode::Read);
// UI notification portion is separated from emulation portion (intentional condition check redundancy)
@ -201,19 +205,19 @@ bool Pad::DoStateController(StateWrapper& sw, u32 i)
{
Host::AddFormattedOSDMessage(
10.0f, TRANSLATE("OSDMessage", "Save state contains controller type %s in port %u, but %s is used. Switching."),
Settings::GetControllerTypeName(state_controller_type), i + 1u,
Settings::GetControllerTypeName(controller_type));
state_cinfo ? state_cinfo->GetDisplayName() : "", i + 1u,
Controller::GetControllerInfo(controller_type)->GetDisplayName());
}
else
{
Host::AddFormattedOSDMessage(10.0f, TRANSLATE("OSDMessage", "Ignoring mismatched controller type %s in port %u."),
Settings::GetControllerTypeName(state_controller_type), i + 1u);
state_cinfo ? state_cinfo->GetDisplayName() : "", i + 1u);
}
// dev-friendly untranslated console log.
Log_DevPrintf("Controller type mismatch in slot %u: state=%s(%u) ui=%s(%u) load_from_state=%s", i + 1u,
Settings::GetControllerTypeName(state_controller_type), static_cast<unsigned>(state_controller_type),
Settings::GetControllerTypeName(controller_type), static_cast<unsigned>(controller_type),
state_cinfo ? state_cinfo->name : "", static_cast<unsigned>(state_controller_type),
Controller::GetControllerInfo(controller_type)->name, static_cast<unsigned>(controller_type),
g_settings.load_devices_from_save_states ? "yes" : "no");
if (g_settings.load_devices_from_save_states)

View File

@ -335,13 +335,8 @@ void Settings::Load(SettingsInterface& si)
si.GetStringValue("ControllerPorts", "MultitapMode", GetMultitapModeName(DEFAULT_MULTITAP_MODE)).c_str())
.value_or(DEFAULT_MULTITAP_MODE);
controller_types[0] = ParseControllerTypeName(si.GetStringValue(Controller::GetSettingsSection(0).c_str(), "Type",
GetControllerTypeName(DEFAULT_CONTROLLER_1_TYPE))
.c_str())
.value_or(DEFAULT_CONTROLLER_1_TYPE);
const std::array<bool, 2> mtap_enabled = {{IsPort1MultitapEnabled(), IsPort2MultitapEnabled()}};
for (u32 i = 1; i < NUM_CONTROLLER_AND_CARD_PORTS; i++)
for (u32 i = 0; i < NUM_CONTROLLER_AND_CARD_PORTS; i++)
{
// Ignore types when multitap not enabled
const auto [port, slot] = Controller::ConvertPadToPortAndSlot(i);
@ -351,10 +346,10 @@ void Settings::Load(SettingsInterface& si)
continue;
}
controller_types[i] = ParseControllerTypeName(si.GetStringValue(Controller::GetSettingsSection(i).c_str(), "Type",
GetControllerTypeName(DEFAULT_CONTROLLER_2_TYPE))
.c_str())
.value_or(DEFAULT_CONTROLLER_2_TYPE);
const ControllerType default_type = (i == 0) ? DEFAULT_CONTROLLER_1_TYPE : DEFAULT_CONTROLLER_2_TYPE;
const Controller::ControllerInfo* cinfo = Controller::GetControllerInfo(si.GetTinyStringValue(
Controller::GetSettingsSection(i).c_str(), "Type", Controller::GetControllerInfo(default_type)->name));
controller_types[i] = cinfo ? cinfo->type : default_type;
}
memory_card_types[0] =
@ -588,7 +583,11 @@ void Settings::Save(SettingsInterface& si, bool ignore_base) const
si.SetBoolValue("BIOS", "PatchFastBoot", bios_patch_fast_boot);
for (u32 i = 0; i < NUM_CONTROLLER_AND_CARD_PORTS; i++)
si.SetStringValue(Controller::GetSettingsSection(i).c_str(), "Type", GetControllerTypeName(controller_types[i]));
{
const Controller::ControllerInfo* cinfo = Controller::GetControllerInfo(controller_types[i]);
DebugAssert(cinfo);
si.SetStringValue(Controller::GetSettingsSection(i).c_str(), "Type", cinfo->name);
}
si.SetStringValue("MemoryCards", "Card1Type", GetMemoryCardTypeName(memory_card_types[0]));
si.SetStringValue("MemoryCards", "Card2Type", GetMemoryCardTypeName(memory_card_types[1]));
@ -1569,43 +1568,6 @@ const char* Settings::GetDisplayScreenshotFormatExtension(DisplayScreenshotForma
return s_display_screenshot_format_extensions[static_cast<size_t>(format)];
}
static constexpr const std::array s_controller_type_names = {
"None", "DigitalController", "AnalogController", "AnalogJoystick",
"GunCon", "PlayStationMouse", "NeGcon", "NeGconRumble"};
static constexpr const std::array s_controller_display_names = {
TRANSLATE_NOOP("ControllerType", "None"),
TRANSLATE_NOOP("ControllerType", "Digital Controller"),
TRANSLATE_NOOP("ControllerType", "Analog Controller (DualShock)"),
TRANSLATE_NOOP("ControllerType", "Analog Joystick"),
TRANSLATE_NOOP("ControllerType", "GunCon"),
TRANSLATE_NOOP("ControllerType", "PlayStation Mouse"),
TRANSLATE_NOOP("ControllerType", "NeGcon"),
TRANSLATE_NOOP("ControllerType", "NeGcon Rumble")};
std::optional<ControllerType> Settings::ParseControllerTypeName(std::string_view str)
{
int index = 0;
for (const char* name : s_controller_type_names)
{
if (StringUtil::EqualNoCase(str, name))
return static_cast<ControllerType>(index);
index++;
}
return std::nullopt;
}
const char* Settings::GetControllerTypeName(ControllerType type)
{
return s_controller_type_names[static_cast<int>(type)];
}
const char* Settings::GetControllerTypeDisplayName(ControllerType type)
{
return Host::TranslateToCString("ControllerType", s_controller_display_names[static_cast<int>(type)]);
}
static constexpr const std::array s_memory_card_type_names = {"None", "Shared", "PerGame",
"PerGameTitle", "PerGameFileTitle", "NonPersistent"};
static constexpr const std::array s_memory_card_type_display_names = {

View File

@ -430,10 +430,6 @@ struct Settings
static const char* GetDisplayScreenshotFormatDisplayName(DisplayScreenshotFormat mode);
static const char* GetDisplayScreenshotFormatExtension(DisplayScreenshotFormat mode);
static std::optional<ControllerType> ParseControllerTypeName(std::string_view str);
static const char* GetControllerTypeName(ControllerType type);
static const char* GetControllerTypeDisplayName(ControllerType type);
static std::optional<MemoryCardType> ParseMemoryCardTypeName(const char* str);
static const char* GetMemoryCardTypeName(MemoryCardType type);
static const char* GetMemoryCardTypeDisplayName(MemoryCardType type);

View File

@ -185,7 +185,7 @@ enum class DisplayScreenshotFormat : u8
Count
};
enum class ControllerType
enum class ControllerType : u8
{
None,
DigitalController,