mirror of
https://github.com/stenzek/duckstation.git
synced 2025-07-23 10:30:23 +00:00
GameDatabase: Warn if multitap enabled on unsupported game
Fear Effect sends a multitap read command, but doesn't know how to handle it. There's probably others. Also add a DisableMultitap trait for these games to force it off.
This commit is contained in:
parent
50fbaf90e6
commit
25ffc5a248
@ -41,7 +41,7 @@ namespace GameDatabase {
|
|||||||
enum : u32
|
enum : u32
|
||||||
{
|
{
|
||||||
GAME_DATABASE_CACHE_SIGNATURE = 0x45434C48,
|
GAME_DATABASE_CACHE_SIGNATURE = 0x45434C48,
|
||||||
GAME_DATABASE_CACHE_VERSION = 18,
|
GAME_DATABASE_CACHE_VERSION = 19,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const Entry* GetEntryForId(std::string_view code);
|
static const Entry* GetEntryForId(std::string_view code);
|
||||||
@ -85,6 +85,7 @@ static constexpr const std::array<const char*, static_cast<size_t>(Trait::MaxCou
|
|||||||
"ForceDeinterlacing",
|
"ForceDeinterlacing",
|
||||||
"ForceFullBoot",
|
"ForceFullBoot",
|
||||||
"DisableAutoAnalogMode",
|
"DisableAutoAnalogMode",
|
||||||
|
"DisableMultitap",
|
||||||
"DisableTrueColor",
|
"DisableTrueColor",
|
||||||
"DisableUpscaling",
|
"DisableUpscaling",
|
||||||
"DisableTextureFiltering",
|
"DisableTextureFiltering",
|
||||||
@ -116,6 +117,7 @@ static constexpr const std::array<const char*, static_cast<size_t>(Trait::MaxCou
|
|||||||
TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Force Deinterlacing", "GameDatabase::Trait"),
|
TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Force Deinterlacing", "GameDatabase::Trait"),
|
||||||
TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Force Full Boot", "GameDatabase::Trait"),
|
TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Force Full Boot", "GameDatabase::Trait"),
|
||||||
TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Disable Automatic Analog Mode", "GameDatabase::Trait"),
|
TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Disable Automatic Analog Mode", "GameDatabase::Trait"),
|
||||||
|
TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Disable Multitap", "GameDatabase::Trait"),
|
||||||
TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Disable True Color", "GameDatabase::Trait"),
|
TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Disable True Color", "GameDatabase::Trait"),
|
||||||
TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Disable Upscaling", "GameDatabase::Trait"),
|
TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Disable Upscaling", "GameDatabase::Trait"),
|
||||||
TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Disable Texture Filtering", "GameDatabase::Trait"),
|
TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Disable Texture Filtering", "GameDatabase::Trait"),
|
||||||
@ -437,6 +439,30 @@ void GameDatabase::Entry::ApplySettings(Settings& settings, bool display_osd_mes
|
|||||||
messages.append_format(__VA_ARGS__); \
|
messages.append_format(__VA_ARGS__); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
if (HasTrait(Trait::ForceInterpreter))
|
||||||
|
{
|
||||||
|
if (display_osd_messages && settings.cpu_execution_mode != CPUExecutionMode::Interpreter)
|
||||||
|
APPEND_MESSAGE(TRANSLATE_SV("GameDatabase", "CPU recompiler disabled."));
|
||||||
|
|
||||||
|
settings.cpu_execution_mode = CPUExecutionMode::Interpreter;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HasTrait(Trait::ForceFullBoot))
|
||||||
|
{
|
||||||
|
if (display_osd_messages && settings.bios_patch_fast_boot)
|
||||||
|
APPEND_MESSAGE(TRANSLATE_SV("GameDatabase", "Fast boot disabled."));
|
||||||
|
|
||||||
|
settings.bios_patch_fast_boot = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HasTrait(Trait::DisableMultitap))
|
||||||
|
{
|
||||||
|
if (display_osd_messages && settings.multitap_mode != MultitapMode::Disabled)
|
||||||
|
APPEND_MESSAGE(TRANSLATE_SV("GameDatabase", "Multitap disabled."));
|
||||||
|
|
||||||
|
settings.multitap_mode = MultitapMode::Disabled;
|
||||||
|
}
|
||||||
|
|
||||||
if (display_crop_mode.has_value())
|
if (display_crop_mode.has_value())
|
||||||
{
|
{
|
||||||
if (display_osd_messages && settings.display_crop_mode != display_crop_mode.value())
|
if (display_osd_messages && settings.display_crop_mode != display_crop_mode.value())
|
||||||
@ -448,14 +474,6 @@ void GameDatabase::Entry::ApplySettings(Settings& settings, bool display_osd_mes
|
|||||||
settings.display_crop_mode = display_crop_mode.value();
|
settings.display_crop_mode = display_crop_mode.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HasTrait(Trait::ForceInterpreter))
|
|
||||||
{
|
|
||||||
if (display_osd_messages && settings.cpu_execution_mode != CPUExecutionMode::Interpreter)
|
|
||||||
APPEND_MESSAGE(TRANSLATE_SV("GameDatabase", "CPU recompiler disabled."));
|
|
||||||
|
|
||||||
settings.cpu_execution_mode = CPUExecutionMode::Interpreter;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HasTrait(Trait::ForceSoftwareRenderer))
|
if (HasTrait(Trait::ForceSoftwareRenderer))
|
||||||
{
|
{
|
||||||
if (display_osd_messages && settings.gpu_renderer != GPURenderer::Software)
|
if (display_osd_messages && settings.gpu_renderer != GPURenderer::Software)
|
||||||
@ -515,14 +533,6 @@ void GameDatabase::Entry::ApplySettings(Settings& settings, bool display_osd_mes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HasTrait(Trait::ForceFullBoot))
|
|
||||||
{
|
|
||||||
if (display_osd_messages && settings.bios_patch_fast_boot)
|
|
||||||
APPEND_MESSAGE(TRANSLATE_SV("GameDatabase", "Fast boot disabled."));
|
|
||||||
|
|
||||||
settings.bios_patch_fast_boot = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HasTrait(Trait::DisableTrueColor))
|
if (HasTrait(Trait::DisableTrueColor))
|
||||||
{
|
{
|
||||||
if (display_osd_messages && settings.gpu_true_color)
|
if (display_osd_messages && settings.gpu_true_color)
|
||||||
@ -749,16 +759,25 @@ void GameDatabase::Entry::ApplySettings(Settings& settings, bool display_osd_mes
|
|||||||
supported_controller_string.append(Controller::GetControllerInfo(supported_ctype)->GetDisplayName());
|
supported_controller_string.append(Controller::GetControllerInfo(supported_ctype)->GetDisplayName());
|
||||||
}
|
}
|
||||||
|
|
||||||
Host::AddKeyedOSDMessage(
|
Host::AddIconOSDWarning(
|
||||||
"gamedb_controller_unsupported",
|
fmt::format("GameDBController{}Unsupported", i), ICON_EMOJI_WARNING,
|
||||||
fmt::format(TRANSLATE_FS("GameDatabase",
|
fmt::format(
|
||||||
"Controller in port {0} ({1}) is not supported for {2}.\nSupported controllers: "
|
TRANSLATE_FS("GameDatabase",
|
||||||
"{3}\nPlease configure a supported controller from the list above."),
|
"Controller in Port {0} ({1}) is not supported for this game.\nSupported controllers: "
|
||||||
i + 1u, Controller::GetControllerInfo(ctype)->GetDisplayName(), System::GetGameTitle(),
|
"{2}\nPlease configure a supported controller from the list above."),
|
||||||
supported_controller_string),
|
i + 1u, Controller::GetControllerInfo(ctype)->GetDisplayName(), supported_controller_string),
|
||||||
Host::OSD_CRITICAL_ERROR_DURATION);
|
Host::OSD_CRITICAL_ERROR_DURATION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (g_settings.multitap_mode != MultitapMode::Disabled && !(supported_controllers & SUPPORTS_MULTITAP_BIT))
|
||||||
|
{
|
||||||
|
Host::AddIconOSDMessage("GameDBMultitapUnsupported", ICON_EMOJI_WARNING,
|
||||||
|
TRANSLATE_STR("GameDatabase",
|
||||||
|
"This game does not support multitap, but multitap is enabled.\n"
|
||||||
|
" This may result in dropped controller inputs."),
|
||||||
|
Host::OSD_CRITICAL_ERROR_DURATION);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef BIT_FOR
|
#undef BIT_FOR
|
||||||
@ -841,6 +860,9 @@ std::string GameDatabase::Entry::GenerateCompatibilityReport() const
|
|||||||
ret.append_format(" - {}\n", Controller::GetControllerInfo(static_cast<ControllerType>(j))->GetDisplayName());
|
ret.append_format(" - {}\n", Controller::GetControllerInfo(static_cast<ControllerType>(j))->GetDisplayName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (supported_controllers & SUPPORTS_MULTITAP_BIT)
|
||||||
|
ret.append(" - Multitap\n");
|
||||||
|
|
||||||
ret.append("\n");
|
ret.append("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1303,7 +1325,7 @@ bool GameDatabase::ParseYamlEntry(Entry* entry, const ryml::ConstNodeRef& value)
|
|||||||
if (const std::optional libcrypt_val = StringUtil::FromChars<bool>(to_stringview(libcrypt.val()));
|
if (const std::optional libcrypt_val = StringUtil::FromChars<bool>(to_stringview(libcrypt.val()));
|
||||||
libcrypt_val.has_value())
|
libcrypt_val.has_value())
|
||||||
{
|
{
|
||||||
entry->traits[static_cast<size_t>(Trait::IsLibCryptProtected)] = true;
|
entry->traits[static_cast<size_t>(Trait::IsLibCryptProtected)] = libcrypt_val.value();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1311,6 +1333,20 @@ bool GameDatabase::ParseYamlEntry(Entry* entry, const ryml::ConstNodeRef& value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (const ryml::ConstNodeRef& multitap = value.find_child(to_csubstr("multitap")); multitap.valid())
|
||||||
|
{
|
||||||
|
if (const std::optional multitap_val = StringUtil::FromChars<bool>(to_stringview(multitap.val()));
|
||||||
|
multitap_val.has_value())
|
||||||
|
{
|
||||||
|
if (multitap_val.value())
|
||||||
|
entry->supported_controllers |= Entry::SUPPORTS_MULTITAP_BIT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WARNING_LOG("Invalid multitap value in {}", entry->serial);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (const ryml::ConstNodeRef settings = value.find_child(to_csubstr("settings"));
|
if (const ryml::ConstNodeRef settings = value.find_child(to_csubstr("settings"));
|
||||||
settings.valid() && settings.has_children())
|
settings.valid() && settings.has_children())
|
||||||
{
|
{
|
||||||
|
@ -41,6 +41,7 @@ enum class Trait : u32
|
|||||||
ForceDeinterlacing,
|
ForceDeinterlacing,
|
||||||
ForceFullBoot,
|
ForceFullBoot,
|
||||||
DisableAutoAnalogMode,
|
DisableAutoAnalogMode,
|
||||||
|
DisableMultitap,
|
||||||
DisableTrueColor,
|
DisableTrueColor,
|
||||||
DisableUpscaling,
|
DisableUpscaling,
|
||||||
DisableTextureFiltering,
|
DisableTextureFiltering,
|
||||||
@ -94,6 +95,8 @@ enum class Language : u8
|
|||||||
|
|
||||||
struct Entry
|
struct Entry
|
||||||
{
|
{
|
||||||
|
static constexpr u16 SUPPORTS_MULTITAP_BIT = (1u << static_cast<u8>(ControllerType::Count));
|
||||||
|
|
||||||
std::string_view serial;
|
std::string_view serial;
|
||||||
std::string_view title;
|
std::string_view title;
|
||||||
std::string_view genre;
|
std::string_view genre;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user