Compare commits

...

5 Commits

Author SHA1 Message Date
TheLastRar
42c576cf99 FSUI: More formatting 2025-03-13 10:56:09 +01:00
PCSX2 Bot
1fd26c919b [ci skip] Qt: Update Base Translation. 2025-03-12 20:40:15 -04:00
TheLastRar
c957b558e0 FSUI: Automatic "Swap OK/Cancel" will now swap with switch controllers 2025-03-12 17:22:32 -04:00
JordanTheToaster
ec047c5972 GS: Change GetValidSize warning to DevCon 2025-03-12 17:21:52 -04:00
JordanTheToaster
08388d12d1 Config: Default to higher compression 2025-03-12 17:21:52 -04:00
19 changed files with 2318 additions and 1705 deletions

View File

@@ -100,7 +100,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
sif, m_ui.screenshotSize, "EmuCore/GS", "ScreenshotSize", static_cast<int>(GSScreenshotSize::WindowResolution));
SettingWidgetBinder::BindWidgetToIntSetting(
sif, m_ui.screenshotFormat, "EmuCore/GS", "ScreenshotFormat", static_cast<int>(GSScreenshotFormat::PNG));
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.screenshotQuality, "EmuCore/GS", "ScreenshotQuality", 50);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.screenshotQuality, "EmuCore/GS", "ScreenshotQuality", 90);
SettingWidgetBinder::BindWidgetToFloatSetting(sif, m_ui.stretchY, "EmuCore/GS", "StretchY", 100.0f);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.cropLeft, "EmuCore/GS", "CropLeft", 0);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.cropTop, "EmuCore/GS", "CropTop", 0);
@@ -515,8 +515,8 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
dialog->registerWidgetHelp(m_ui.screenshotFormat, tr("Screenshot Format"), tr("PNG"),
tr("Selects the format which will be used to save screenshots. JPEG produces smaller files, but loses detail."));
dialog->registerWidgetHelp(m_ui.screenshotQuality, tr("Screenshot Quality"), tr("50%"),
tr("Selects the quality at which screenshots will be compressed. Higher values preserve more detail for JPEG, and reduce file "
dialog->registerWidgetHelp(m_ui.screenshotQuality, tr("Screenshot Quality"), tr("90%"),
tr("Selects the quality at which screenshots will be compressed. Higher values preserve more detail for JPEG and WebP, and reduce file "
"size for PNG."));
dialog->registerWidgetHelp(m_ui.stretchY, tr("Vertical Stretch"), tr("100%"),

File diff suppressed because it is too large Load Diff

View File

@@ -833,7 +833,7 @@ struct Pcsx2Config
s8 ExclusiveFullscreenControl = -1;
GSScreenshotSize ScreenshotSize = GSScreenshotSize::WindowResolution;
GSScreenshotFormat ScreenshotFormat = GSScreenshotFormat::PNG;
int ScreenshotQuality = 50;
int ScreenshotQuality = 90;
std::string CaptureContainer = DEFAULT_CAPTURE_CONTAINER;
std::string VideoCaptureCodec;

View File

@@ -1034,7 +1034,7 @@ GSVector2i GSRendererHW::GetValidSize(const GSTextureCache::Source* tex)
constexpr int valid_max_size = 2047;
if ((width > valid_max_size) || (height > valid_max_size))
{
Console.Warning("Warning: GetValidSize out of bounds, X:%d Y:%d", width, height);
DevCon.Warning("Warning: GetValidSize out of bounds, X:%d Y:%d", width, height);
width = std::min(width, valid_max_size);
height = std::min(height, valid_max_size);
}

View File

@@ -628,6 +628,14 @@ void FullscreenUI::ApplyConfirmSetting(const SettingsInterface* bsi)
}
}
// Check gamepad
const InputLayout layout = ImGuiFullscreen::GetGamepadLayout();
if (layout == InputLayout::Nintendo)
{
io.ConfigNavSwapGamepadButtons = true;
return;
}
// X is confirm
io.ConfigNavSwapGamepadButtons = false;
return;
@@ -642,6 +650,11 @@ void FullscreenUI::LocaleChanged()
ApplyConfirmSetting();
}
void FullscreenUI::GamepadLayoutChanged()
{
ApplyConfirmSetting();
}
//////////////////////////////////////////////////////////////////////////
// Main
//////////////////////////////////////////////////////////////////////////
@@ -2302,11 +2315,30 @@ void FullscreenUI::DrawIntRectSetting(SettingsInterface* bsi, const char* title,
bool is_open = true;
if (ImGui::BeginPopupModal(title, &is_open, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove))
{
static constexpr const char* labels[4] = {FSUI_NSTR("Left: "), FSUI_NSTR("Top: "), FSUI_NSTR("Right: "), FSUI_NSTR("Bottom: ")};
const char* keys[4] = {left_key, top_key, right_key, bottom_key};
int defaults[4] = {default_left, default_top, default_right, default_bottom};
s32 values[4] = {static_cast<s32>(left_value.value_or(default_left)), static_cast<s32>(top_value.value_or(default_top)),
static_cast<s32>(right_value.value_or(default_right)), static_cast<s32>(bottom_value.value_or(default_bottom))};
static constexpr const char* labels[4] = {
FSUI_NSTR("Left: "),
FSUI_NSTR("Top: "),
FSUI_NSTR("Right: "),
FSUI_NSTR("Bottom: "),
};
const char* keys[4] = {
left_key,
top_key,
right_key,
bottom_key,
};
int defaults[4] = {
default_left,
default_top,
default_right,
default_bottom,
};
s32 values[4] = {
static_cast<s32>(left_value.value_or(default_left)),
static_cast<s32>(top_value.value_or(default_top)),
static_cast<s32>(right_value.value_or(default_right)),
static_cast<s32>(bottom_value.value_or(default_bottom)),
};
BeginMenuButtons();
@@ -2929,21 +2961,69 @@ void FullscreenUI::DrawSettingsWindow()
{
static constexpr float ITEM_WIDTH = 25.0f;
static constexpr const char* global_icons[] = {ICON_FA_TV, ICON_PF_MICROCHIP, ICON_PF_GEARS_OPTIONS_SETTINGS, ICON_PF_PICTURE,
ICON_PF_SOUND, ICON_PF_MEMORY_CARD, ICON_PF_GAMEPAD_ALT, ICON_PF_KEYBOARD_ALT, ICON_FA_TROPHY, ICON_FA_FOLDER_OPEN, ICON_FA_EXCLAMATION_TRIANGLE};
static constexpr const char* per_game_icons[] = {ICON_FA_INFO, ICON_PF_GEARS_OPTIONS_SETTINGS, ICON_FA_BAND_AID, ICON_PF_INFINITY,
ICON_PF_PICTURE, ICON_PF_SOUND, ICON_PF_MEMORY_CARD, ICON_FA_EXCLAMATION_TRIANGLE};
static constexpr SettingsPage global_pages[] = {SettingsPage::Interface, SettingsPage::BIOS, SettingsPage::Emulation,
SettingsPage::Graphics, SettingsPage::Audio, SettingsPage::MemoryCard, SettingsPage::Controller, SettingsPage::Hotkey,
SettingsPage::Achievements, SettingsPage::Folders, SettingsPage::Advanced};
static constexpr SettingsPage per_game_pages[] = {SettingsPage::Summary, SettingsPage::Emulation, SettingsPage::Patches,
SettingsPage::Cheats, SettingsPage::Graphics, SettingsPage::Audio, SettingsPage::MemoryCard,
SettingsPage::GameFixes};
static constexpr const char* titles[] = {FSUI_NSTR("Summary"), FSUI_NSTR("Interface Settings"), FSUI_NSTR("BIOS Settings"),
FSUI_NSTR("Emulation Settings"), FSUI_NSTR("Graphics Settings"), FSUI_NSTR("Audio Settings"), FSUI_NSTR("Memory Card Settings"),
FSUI_NSTR("Controller Settings"), FSUI_NSTR("Hotkey Settings"), FSUI_NSTR("Achievements Settings"),
FSUI_NSTR("Folder Settings"), FSUI_NSTR("Advanced Settings"), FSUI_NSTR("Patches"), FSUI_NSTR("Cheats"),
FSUI_NSTR("Game Fixes")};
static constexpr const char* global_icons[] = {
ICON_FA_TV,
ICON_PF_MICROCHIP,
ICON_PF_GEARS_OPTIONS_SETTINGS,
ICON_PF_PICTURE,
ICON_PF_SOUND,
ICON_PF_MEMORY_CARD,
ICON_PF_GAMEPAD_ALT,
ICON_PF_KEYBOARD_ALT,
ICON_FA_TROPHY,
ICON_FA_FOLDER_OPEN,
ICON_FA_EXCLAMATION_TRIANGLE,
};
static constexpr const char* per_game_icons[] = {
ICON_FA_INFO,
ICON_PF_GEARS_OPTIONS_SETTINGS,
ICON_FA_BAND_AID,
ICON_PF_INFINITY,
ICON_PF_PICTURE,
ICON_PF_SOUND,
ICON_PF_MEMORY_CARD,
ICON_FA_EXCLAMATION_TRIANGLE,
};
static constexpr SettingsPage global_pages[] = {
SettingsPage::Interface,
SettingsPage::BIOS,
SettingsPage::Emulation,
SettingsPage::Graphics,
SettingsPage::Audio,
SettingsPage::MemoryCard,
SettingsPage::Controller,
SettingsPage::Hotkey,
SettingsPage::Achievements,
SettingsPage::Folders,
SettingsPage::Advanced,
};
static constexpr SettingsPage per_game_pages[] = {
SettingsPage::Summary,
SettingsPage::Emulation,
SettingsPage::Patches,
SettingsPage::Cheats,
SettingsPage::Graphics,
SettingsPage::Audio,
SettingsPage::MemoryCard,
SettingsPage::GameFixes,
};
static constexpr const char* titles[] = {
FSUI_NSTR("Summary"),
FSUI_NSTR("Interface Settings"),
FSUI_NSTR("BIOS Settings"),
FSUI_NSTR("Emulation Settings"),
FSUI_NSTR("Graphics Settings"),
FSUI_NSTR("Audio Settings"),
FSUI_NSTR("Memory Card Settings"),
FSUI_NSTR("Controller Settings"),
FSUI_NSTR("Hotkey Settings"),
FSUI_NSTR("Achievements Settings"),
FSUI_NSTR("Folder Settings"),
FSUI_NSTR("Advanced Settings"),
FSUI_NSTR("Patches"),
FSUI_NSTR("Cheats"),
FSUI_NSTR("Game Fixes"),
};
const u32 count = game_settings ? (show_advanced_settings ? std::size(per_game_pages) : (std::size(per_game_pages) - 1)) : std::size(global_pages);
const char* const* icons = game_settings ? per_game_icons : global_icons;
@@ -3809,7 +3889,13 @@ void FullscreenUI::DrawGraphicsSettingsPage(SettingsInterface* bsi, bool show_ad
FSUI_NSTR("8x"),
FSUI_NSTR("16x"),
};
static constexpr const char* s_anisotropic_filtering_values[] = {"0", "2", "4", "8", "16"};
static constexpr const char* s_anisotropic_filtering_values[] = {
"0",
"2",
"4",
"8",
"16",
};
static constexpr const char* s_preloading_options[] = {
FSUI_NSTR("None"),
FSUI_NSTR("Partial"),
@@ -3873,7 +3959,7 @@ void FullscreenUI::DrawGraphicsSettingsPage(SettingsInterface* bsi, bool show_ad
"EmuCore/GS", "ScreenshotFormat", static_cast<int>(GSScreenshotFormat::PNG), s_screenshot_formats, std::size(s_screenshot_formats),
true);
DrawIntRangeSetting(bsi, FSUI_CSTR("Screenshot Quality"), FSUI_CSTR("Selects the quality at which screenshots will be compressed."),
"EmuCore/GS", "ScreenshotQuality", 50, 1, 100, FSUI_CSTR("%d%%"));
"EmuCore/GS", "ScreenshotQuality", 90, 1, 100, FSUI_CSTR("%d%%"));
DrawIntRangeSetting(bsi, FSUI_CSTR("Vertical Stretch"), FSUI_CSTR("Increases or decreases the virtual picture size vertically."),
"EmuCore/GS", "StretchY", 100, 10, 300, FSUI_CSTR("%d%%"));
DrawIntRectSetting(bsi, FSUI_CSTR("Crop"), FSUI_CSTR("Crops the image, while respecting aspect ratio."), "EmuCore/GS", "CropLeft", 0,
@@ -4140,9 +4226,16 @@ void FullscreenUI::DrawGraphicsSettingsPage(SettingsInterface* bsi, bool show_ad
DrawIntRangeSetting(bsi, FSUI_CSTR("Shade Boost Saturation"), FSUI_CSTR("Adjusts saturation. 50 is normal."), "EmuCore/GS",
"ShadeBoost_Saturation", 50, 1, 100, "%d", shadeboost_active);
static constexpr const char* s_tv_shaders[] = {FSUI_NSTR("None (Default)"), FSUI_NSTR("Scanline Filter"),
FSUI_NSTR("Diagonal Filter"), FSUI_NSTR("Triangular Filter"), FSUI_NSTR("Wave Filter"), FSUI_NSTR("Lottes CRT"),
FSUI_NSTR("4xRGSS"), FSUI_NSTR("NxAGSS")};
static constexpr const char* s_tv_shaders[] = {
FSUI_NSTR("None (Default)"),
FSUI_NSTR("Scanline Filter"),
FSUI_NSTR("Diagonal Filter"),
FSUI_NSTR("Triangular Filter"),
FSUI_NSTR("Wave Filter"),
FSUI_NSTR("Lottes CRT"),
FSUI_NSTR("4xRGSS"),
FSUI_NSTR("NxAGSS"),
};
DrawIntListSetting(bsi, FSUI_CSTR("TV Shaders"), FSUI_CSTR("Applies a shader which replicates the visual effects of different styles of television set."), "EmuCore/GS", "TVShader", 0,
s_tv_shaders, std::size(s_tv_shaders), true);
}
@@ -4900,7 +4993,12 @@ void FullscreenUI::DrawFoldersSettingsPage()
void FullscreenUI::DrawAdvancedSettingsPage()
{
static constexpr const char* ee_rounding_mode_settings[] = {FSUI_NSTR("Nearest"), FSUI_NSTR("Negative"), FSUI_NSTR("Positive"), FSUI_NSTR("Chop/Zero (Default)")};
static constexpr const char* ee_rounding_mode_settings[] = {
FSUI_NSTR("Nearest"),
FSUI_NSTR("Negative"),
FSUI_NSTR("Positive"),
FSUI_NSTR("Chop/Zero (Default)"),
};
SettingsInterface* bsi = GetEditingSettingsInterface();

View File

@@ -33,6 +33,7 @@ namespace FullscreenUI
void ReturnToMainWindow();
void SetStandardSelectionFooterText(bool back_instead_of_cancel);
void LocaleChanged();
void GamepadLayoutChanged();
void Shutdown(bool clear_state);
void Render();

View File

@@ -7,9 +7,11 @@
#include "Host.h"
#include "GS/Renderers/Common/GSDevice.h"
#include "GS/Renderers/Common/GSTexture.h"
#include "ImGui/FullscreenUI.h"
#include "ImGui/ImGuiAnimated.h"
#include "ImGui/ImGuiFullscreen.h"
#include "ImGui/ImGuiManager.h"
#include "Input/InputManager.h"
#include "common/Assertions.h"
#include "common/Console.h"
@@ -192,6 +194,8 @@ namespace ImGuiFullscreen
static std::vector<BackgroundProgressDialogData> s_background_progress_dialogs;
static std::mutex s_background_progress_lock;
static InputLayout s_gamepad_layout = InputLayout::Unknown;
} // namespace ImGuiFullscreen
void ImGuiFullscreen::SetFonts(ImFont* standard_font, ImFont* medium_font, ImFont* large_font)
@@ -738,6 +742,20 @@ bool ImGuiFullscreen::IsGamepadInputSource()
return (ImGui::GetCurrentContext()->NavInputSource == ImGuiInputSource_Gamepad);
}
void ImGuiFullscreen::ReportGamepadLayout(InputLayout layout)
{
if (s_gamepad_layout == layout)
return;
s_gamepad_layout = layout;
FullscreenUI::GamepadLayoutChanged();
}
InputLayout ImGuiFullscreen::GetGamepadLayout()
{
return s_gamepad_layout;
}
void ImGuiFullscreen::CreateFooterTextString(SmallStringBase& dest,
std::span<const std::pair<const char*, std::string_view>> items)
{

View File

@@ -18,6 +18,7 @@
#include <vector>
class GSTexture;
enum class InputLayout : u8;
namespace ImGuiFullscreen
{
@@ -149,6 +150,8 @@ namespace ImGuiFullscreen
void EndFullscreenWindow();
bool IsGamepadInputSource();
void ReportGamepadLayout(InputLayout layout);
InputLayout GetGamepadLayout();
void CreateFooterTextString(SmallStringBase& dest, std::span<const std::pair<const char*, std::string_view>> items);
void SetFullscreenFooterText(std::string_view text);
void SetFullscreenFooterText(std::span<const std::pair<const char*, std::string_view>> items);

View File

@@ -921,7 +921,7 @@ bool ImGuiManager::ProcessHostKeyEvent(InputBindingKey key, float value)
return s_imgui_wants_keyboard.load(std::memory_order_acquire);
}
bool ImGuiManager::ProcessGenericInputEvent(GenericInputBinding key, float value)
bool ImGuiManager::ProcessGenericInputEvent(GenericInputBinding key, InputLayout layout, float value)
{
static constexpr ImGuiKey key_map[] = {
ImGuiKey_None, // Unknown,
@@ -959,7 +959,10 @@ bool ImGuiManager::ProcessGenericInputEvent(GenericInputBinding key, float value
return false;
MTGS::RunOnGSThread(
[key = key_map[static_cast<u32>(key)], value]() { ImGui::GetIO().AddKeyAnalogEvent(key, (value > 0.0f), value); });
[key = key_map[static_cast<u32>(key)], value, layout]() {
ImGuiFullscreen::ReportGamepadLayout(layout);
ImGui::GetIO().AddKeyAnalogEvent(key, (value > 0.0f), value);
});
return s_imgui_wants_keyboard.load(std::memory_order_acquire);
}

View File

@@ -12,6 +12,7 @@ struct ImFont;
union InputBindingKey;
enum class GenericInputBinding : u8;
enum class InputLayout : u8;
namespace ImGuiManager
{
@@ -94,7 +95,7 @@ namespace ImGuiManager
bool ProcessHostKeyEvent(InputBindingKey key, float value);
/// Called on the CPU thread when any input event fires. Allows imgui to take over controller navigation.
bool ProcessGenericInputEvent(GenericInputBinding key, float value);
bool ProcessGenericInputEvent(GenericInputBinding key, InputLayout layout, float value);
/// Sets an image and scale for a software cursor. Software cursors can be used for things like crosshairs.
void SetSoftwareCursor(u32 index, std::string image_path, float image_scale, u32 multiply_color = 0xFFFFFF);

View File

@@ -315,6 +315,11 @@ bool DInputSource::GetGenericBindingMapping(const std::string_view device, Input
return {};
}
InputLayout DInputSource::GetControllerLayout(u32 index)
{
return InputLayout::Unknown;
}
void DInputSource::UpdateMotorState(InputBindingKey key, float intensity)
{
// not supported

View File

@@ -44,6 +44,7 @@ public:
std::vector<std::pair<std::string, std::string>> EnumerateDevices() override;
std::vector<InputBindingKey> EnumerateMotors() override;
bool GetGenericBindingMapping(const std::string_view device, InputManager::GenericInputBindingMapping* mapping) override;
InputLayout GetControllerLayout(u32 index) override;
void UpdateMotorState(InputBindingKey key, float intensity) override;
void UpdateMotorState(InputBindingKey large_key, InputBindingKey small_key, float large_intensity, float small_intensity) override;

View File

@@ -1263,7 +1263,8 @@ bool InputManager::PreprocessEvent(InputBindingKey key, float value, GenericInpu
}
else if (generic_key != GenericInputBinding::Unknown)
{
if (ImGuiManager::ProcessGenericInputEvent(generic_key, value) && value != 0.0f)
InputLayout layout = s_input_sources[static_cast<u32>(InputSourceType::SDL)]->GetControllerLayout(key.source_index);
if (ImGuiManager::ProcessGenericInputEvent(generic_key, layout, value) && value != 0.0f)
return true;
}

View File

@@ -46,6 +46,15 @@ enum class InputSubclass : u32
ControllerHaptic = 4,
};
/// Layout of the source controller
enum class InputLayout : u8
{
Unknown,
Xbox,
Playstation,
Nintendo
};
enum class InputModifier : u32
{
None = 0,

View File

@@ -43,6 +43,9 @@ public:
/// Returns false if it's not one of our devices.
virtual bool GetGenericBindingMapping(const std::string_view device, InputManager::GenericInputBindingMapping* mapping) = 0;
/// Gets the layout of the controller connected at index.
virtual InputLayout GetControllerLayout(u32 index) = 0;
/// Informs the source of a new vibration motor state. Changes may not take effect until the next PollEvents() call.
virtual void UpdateMotorState(InputBindingKey key, float intensity) = 0;

View File

@@ -1519,6 +1519,25 @@ bool SDLInputSource::GetGenericBindingMapping(const std::string_view device, Inp
}
}
InputLayout SDLInputSource::GetControllerLayout(u32 index)
{
auto it = GetControllerDataForPlayerId(index);
if (it == m_controllers.end())
return InputLayout::Unknown;
// Infer layout based on face button label to avoid having
// to maintain a long switch statement of gamepad types
// clang-format off
switch (SDL_GetGamepadButtonLabel(it->gamepad, SDL_GAMEPAD_BUTTON_EAST))
{
case SDL_GAMEPAD_BUTTON_LABEL_B: return InputLayout::Xbox;
case SDL_GAMEPAD_BUTTON_LABEL_A: return InputLayout::Nintendo;
case SDL_GAMEPAD_BUTTON_LABEL_CIRCLE: return InputLayout::Playstation;
default: return InputLayout::Unknown;
}
// clang-format on
}
void SDLInputSource::UpdateMotorState(InputBindingKey key, float intensity)
{
if (key.source_subtype != InputSubclass::ControllerMotor && key.source_subtype != InputSubclass::ControllerHaptic)

View File

@@ -32,6 +32,7 @@ public:
std::vector<std::pair<std::string, std::string>> EnumerateDevices() override;
std::vector<InputBindingKey> EnumerateMotors() override;
bool GetGenericBindingMapping(const std::string_view device, InputManager::GenericInputBindingMapping* mapping) override;
InputLayout GetControllerLayout(u32 index) override;
void UpdateMotorState(InputBindingKey key, float intensity) override;
void UpdateMotorState(InputBindingKey large_key, InputBindingKey small_key, float large_intensity, float small_intensity) override;

View File

@@ -466,6 +466,11 @@ bool XInputSource::GetGenericBindingMapping(const std::string_view device, Input
return true;
}
InputLayout XInputSource::GetControllerLayout(u32 index)
{
return InputLayout::Xbox;
}
void XInputSource::HandleControllerConnection(u32 index)
{
INFO_LOG("XInput controller {} connected.", index);

View File

@@ -81,6 +81,7 @@ public:
std::vector<std::pair<std::string, std::string>> EnumerateDevices() override;
std::vector<InputBindingKey> EnumerateMotors() override;
bool GetGenericBindingMapping(const std::string_view device, InputManager::GenericInputBindingMapping* mapping) override;
InputLayout GetControllerLayout(u32 index) override;
void UpdateMotorState(InputBindingKey key, float intensity) override;
void UpdateMotorState(InputBindingKey large_key, InputBindingKey small_key, float large_intensity, float small_intensity) override;