Compare commits

...

17 Commits

Author SHA1 Message Date
lightningterror
ff87bc5889 GS: Use inclusive req factor of 1 for sw renderer.
Workaround until the issue can be properly fixed.
2025-04-14 23:02:43 +02:00
Rares-Alexandru Fodor
42cd80c172 UI: Fix vertical alignment of achievement progress text 2025-04-14 23:02:19 +02:00
TheLastRar
123cd3a092 Qt: Centre region flags in game list 2025-04-14 18:11:48 +02:00
TheLastRar
cbc3c4e6eb Qt: Fix broken icon styling in Win11 theme 2025-04-14 18:11:48 +02:00
PCSX2 Bot
b50e39e5cb [ci skip] PAD: Update to latest controller database. 2025-04-14 18:11:21 +02:00
PCSX2 Bot
bbe5ef451a [ci skip] Qt: Update Base Translation. 2025-04-12 20:54:51 -04:00
chaoticgd
c359c0e747 Debugger: Add setting to change UI refresh interval 2025-04-12 12:26:32 -04:00
TheLastRar
99ecb0b60f SDLInput: Set BPM legacy Nintendo layout when migrating non-Xbox layout binds 2025-04-12 12:25:19 -04:00
TheLastRar
cfc7e45020 FSUI: Add option to use legacy SDL2 Nintendo layout 2025-04-12 12:25:19 -04:00
TheLastRar
0307d064ad MSBuild: Update QtUi includes 2025-04-12 12:24:18 -04:00
TheLastRar
89cd824c70 MSBuild: Improve QtMoc tasks 2025-04-12 12:24:18 -04:00
TheLastRar
1066e8a5e9 MSBuild: Adjust how MSBuild handles Qt ui files 2025-04-12 12:24:18 -04:00
JordanTheToaster
d2c31df106 GS/HW: Mask 16bit colours when blending is disabled 2025-04-12 01:50:37 +02:00
PCSX2 Bot
a56ffee8f7 [ci skip] Qt: Update Base Translation. 2025-04-11 02:10:28 +02:00
JordanTheToaster
7c798126e3 GameDB: Fix broken FMVs in Clock Tower 3 2025-04-10 18:47:28 -04:00
KamFretoZ
a755131488 Qt: Enable Savestate Selector UI by default
This should've been enabled by default but I've missed the part that actually enables it.
2025-04-10 19:00:46 +02:00
KamFretoZ
648ff65a76 Rcheevos: Add customizable sound effects 2025-04-10 19:00:46 +02:00
30 changed files with 2363 additions and 1750 deletions

View File

@@ -17537,6 +17537,8 @@ SLES-51619:
name: "Clock Tower 3"
region: "PAL-M5"
compat: 5
gameFixes:
- SoftwareRendererFMVHack # Fixes brightness and striped lines in FMVs.
SLES-51620:
name: "Black and Bruised"
region: "PAL-M5"
@@ -30036,6 +30038,8 @@ SLKA-25051:
name: "Clock Tower 3"
region: "NTSC-K"
compat: 5
gameFixes:
- SoftwareRendererFMVHack # Fixes brightness and striped lines in FMVs.
SLKA-25052:
name: "Air Ranger 2 - Rescue Helicopter"
region: "NTSC-K"
@@ -40428,6 +40432,8 @@ SLPM-65221:
name-en: "Clock Tower 3"
region: "NTSC-J"
compat: 5
gameFixes:
- SoftwareRendererFMVHack # Fixes brightness and striped lines in FMVs.
SLPM-65222:
name: "遊戯王真デュエルモンスターズⅡ 継承されし記憶 [コナミ殿堂セレクション]"
name-sort: "ゆうぎおうしんでゅえるもんすたーず2 けいしょうされしきおく [こなみでんどうせれくしょん]"
@@ -52313,6 +52319,8 @@ SLPM-74416:
name-sort: "くろっくたわー3 [PlayStation2 the Best]"
name-en: "Clock Tower 3 [PlayStation2 the Best]"
region: "NTSC-J"
gameFixes:
- SoftwareRendererFMVHack # Fixes brightness and striped lines in FMVs.
SLPM-74420:
name: "頭文字D Special Stage [PlayStation2 the Best]"
name-sort: "いにしゃるD すぺしゃる すてーじ [PlayStation2 the Best]"
@@ -64595,6 +64603,8 @@ SLUS-20633:
name: "Clock Tower 3"
region: "NTSC-U"
compat: 5
gameFixes:
- SoftwareRendererFMVHack # Fixes brightness and striped lines in FMVs.
SLUS-20634:
name: "Summer Heat Beach Volleyball"
region: "NTSC-U"

View File

@@ -1590,6 +1590,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000009b2800003200000001010000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
030000009b2800006000000001010000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
030000009b2800008000000020020000,Raphnet Wii Classic Adapter,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Linux,
030000009b2800008000000001010000,Raphnet Wii Classic Adapter V3,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Linux,
03000000f8270000bf0b000011010000,Razer Kishi,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
030000008916000001fd000024010000,Razer Onza Classic Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000321500000204000011010000,Razer Panthera PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,

View File

@@ -852,6 +852,8 @@ void ps_color_clamp_wrap(inout float3 C)
else if (PS_COLCLIP == 1 || PS_HDR == 1)
C = (float3)((int3)C & (int3)0xFF);
}
else if (PS_DST_FMT == FMT_16 && PS_DITHER != 3 && PS_BLEND_MIX == 0 && PS_BLEND_HW == 0)
C = (float3)((int3)C & (int3)0xF8);
}
void ps_blend(inout float4 Color, inout float4 As_rgba, float2 pos_xy)

View File

@@ -775,6 +775,8 @@ void ps_color_clamp_wrap(inout vec3 C)
C = vec3(ivec3(C) & ivec3(0xFF));
#endif
#elif PS_DST_FMT == FMT_16 && PS_DITHER != 3 && PS_BLEND_MIX == 0 && PS_BLEND_HW == 0
C = vec3(ivec3(C) & ivec3(0xF8));
#endif
}

View File

@@ -1045,6 +1045,8 @@ void ps_color_clamp_wrap(inout vec3 C)
C = vec3(ivec3(C) & ivec3(0xFF));
#endif
#elif PS_DST_FMT == FMT_16 && PS_DITHER != 3 && PS_BLEND_MIX == 0 && PS_BLEND_HW == 0
C = vec3(ivec3(C) & ivec3(0xF8));
#endif
}

View File

@@ -59,23 +59,37 @@
<Delete Files="@(ResFiles->'$(QtToolOutDir)qrc_%(Filename).cpp')" />
</Target>
<!--Passes all .ui files to uic and puts output in the build directory-->
<ItemGroup>
<UiFiles Include="$(MSBuildProjectDirectory)\**\*.ui" />
</ItemGroup>
<!--Passes .ui files to uic and puts output in the build directory-->
<!--We need to create tlogs so that VS knows the ui files are used-->
<!--See https://learn.microsoft.com/en-us/visualstudio/extensibility/visual-cpp-project-extensibility?view=vs-2022#tlog-files-->
<Target Name="QtUi"
BeforeTargets="ClCompile"
Inputs="@(UiFiles)"
Condition="'@(QtUi)'!=''"
Outputs="@(UiFiles->'$(QtToolOutDir)ui_%(Filename).h')">
<Message Text="uic %(UiFiles.Filename)" Importance="High" />
Condition="'@(QtUi)'!=''">
<Error Condition="!$(QtDirValid)" Text="Qt directory non-existent (download/extract the zip)" />
<MakeDir Directories="$(QtToolOutDir)" />
<Exec Command="&quot;$(QtHostBinDir)uic.exe&quot; &quot;%(UiFiles.FullPath)&quot; -o &quot;$(QtToolOutDir)ui_%(UiFiles.Filename).h&quot;" />
</Target>
<!--Setup metadata for following tasks-->
<ItemGroup>
<QtUi>
<Message>uic %(Filename)</Message>
<Command>
"$(QtHostBinDir)uic.exe" "%(FullPath)" -o "$(QtToolOutDir)ui_%(Filename).h"
</Command>
<Outputs>$(QtToolOutDir)ui_%(Filename).h</Outputs>
</QtUi>
</ItemGroup>
<Target Name="QtUiClean">
<Delete Files="@(UiFiles->'$(QtToolOutDir)ui_%(Filename).h')" />
<!--Helper for dealing with tlogs-->
<!--https://learn.microsoft.com/en-us/visualstudio/msbuild/getoutofdateitems-task?view=vs-2022-->
<GetOutOfDateItems Sources="@(QtUi)"
OutputsMetadataName="Outputs"
CommandMetadataName="Command"
TLogDirectory="$(TLogLocation)"
TLogNamePrefix="QtUi">
<Output TaskParameter="OutOfDateSources" ItemName="OutOfDateQtUi"/>
</GetOutOfDateItems>
<CustomBuild Condition="'@(OutOfDateQtUi)'!=''"
Sources="@(OutOfDateQtUi)" />
</Target>
<!--Compile files needed to MOC and output in the build directory-->
@@ -88,7 +102,7 @@
<Target Name="QtMoc"
BeforeTargets="ClCompile"
Condition="'@(QtMoc)'!=''"
Inputs="%(QtMoc.Identity);%(QtMoc.AdditionalDependencies);$(MSBuildProjectFile)"
Inputs="%(QtMoc.Identity);$(QtHostBinDir)moc.exe"
Outputs="$(QtToolOutDir)%(QtMoc.RelativeDir)moc_%(QtMoc.Filename).cpp">
<Message Text="moc %(QtMoc.Filename) $(QtToolOutDir)%(QtMoc.RelativeDir)moc_%(QtMoc.Filename).cpp" Importance="High" />
<Error Condition="!$(QtDirValid)" Text="Qt directory non-existent (download/extract the zip)" />
@@ -97,7 +111,7 @@
</Target>
<ItemGroup>
<MocOutputs Include="$(QtToolOutDir)moc_*.cpp" />
<MocOutputs Include="$(QtToolOutDir)**/moc_*.cpp" />
</ItemGroup>
<Target Name="QtMocClean">
<Delete Files="@(MocOutputs)" />

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<CleanDependsOn>QtResourceClean;QtUiClean;QtMocClean;QtTsClean;$(CleanDependsOn)</CleanDependsOn>
<CleanDependsOn>QtResourceClean;QtMocClean;QtTsClean;$(CleanDependsOn)</CleanDependsOn>
<!--
<ComputeLinkInputsTargets>$(ComputeLinkInputsTargets);QtComputeMocOutput;</ComputeLinkInputsTargets>
<ComputeLibInputsTargets>$(ComputeLibInputsTargets);QtComputeMocOutput;</ComputeLibInputsTargets>

View File

@@ -4,10 +4,10 @@
<ItemType Name="QtUi" DisplayName="Qt User Interface File" />
<ItemType Name="QtMoc" DisplayName="Qt Meta Object File" />
<ItemType Name="QtTs" DisplayName="Qt Translation File" />
<ContentType Name="QtUi" DisplayName="Qt User Interface Compiler" />
<ContentType Name="QtResource" DisplayName="Qt Resource Compiler" />
<ContentType Name="QtMoc" DisplayName="Qt Meta Object Compiler" />
<ContentType Name="QtTs" DisplayName="Qt Translation Compiler" />
<ContentType Name="QtResource" DisplayName="Qt Resource Compiler" ItemType="QtResource" />
<ContentType Name="QtUi" DisplayName="Qt User Interface Compiler" ItemType = "QtUi"/>
<ContentType Name="QtMoc" DisplayName="Qt Meta Object Compiler" ItemType="QtMoc" />
<ContentType Name="QtTs" DisplayName="Qt Translation Compiler" ItemType="QtTs" />
<FileExtension Name="*.qrc" ContentType="QtResource" />
<FileExtension Name="*.ui" ContentType="QtUi" />
<FileExtension Name="*.ts" ContentType="QtTs" />

View File

@@ -120,11 +120,7 @@ DebuggerWindow::DebuggerWindow(QWidget* parent)
R5900SymbolImporter.OnDebuggerOpened();
});
QTimer* refresh_timer = new QTimer(this);
connect(refresh_timer, &QTimer::timeout, this, []() {
DebuggerWidget::broadcastEvent(DebuggerEvents::Refresh());
});
refresh_timer->start(1000);
updateFromSettings();
}
DebuggerWindow* DebuggerWindow::getInstance()
@@ -285,6 +281,25 @@ bool DebuggerWindow::shouldSaveWindowGeometry()
return Host::GetBaseBoolSettingValue("Debugger/UserInterface", "SaveWindowGeometry", true);
}
void DebuggerWindow::updateFromSettings()
{
const int refresh_interval = Host::GetBaseIntSettingValue("Debugger/UserInterface", "RefreshInterval", 1000);
const int effective_refresh_interval = std::clamp(refresh_interval, 10, 100000);
if (!m_refresh_timer)
{
m_refresh_timer = new QTimer(this);
connect(m_refresh_timer, &QTimer::timeout, this, []() {
DebuggerWidget::broadcastEvent(DebuggerEvents::Refresh());
});
m_refresh_timer->start(effective_refresh_interval);
}
else
{
m_refresh_timer->setInterval(effective_refresh_interval);
}
}
void DebuggerWindow::onVMStarting()
{
m_ui.actionRun->setEnabled(true);

View File

@@ -8,6 +8,7 @@
#include "DebugTools/DebugInterface.h"
#include <kddockwidgets/MainWindow.h>
#include <QtCore/QTimer>
class DockManager;
@@ -37,6 +38,8 @@ public:
void restoreWindowGeometry();
bool shouldSaveWindowGeometry();
void updateFromSettings();
public slots:
void onVMStarting();
void onVMPaused();
@@ -67,6 +70,7 @@ private:
DockManager* m_dock_manager;
QByteArray m_default_toolbar_state;
QTimer* m_refresh_timer = nullptr;
int m_font_size;
static const constexpr int DEFAULT_FONT_SIZE = 10;

View File

@@ -19,6 +19,7 @@
#include <QtCore/QSortFilterProxyModel>
#include <QtGui/QPainter>
#include <QtGui/QPixmap>
#include <QtGui/QPixmapCache>
#include <QtGui/QWheelEvent>
#include <QtWidgets/QApplication>
#include <QtWidgets/QHeaderView>
@@ -113,20 +114,51 @@ namespace
// https://stackoverflow.com/questions/32216568/how-to-set-icon-center-in-qtableview
Q_ASSERT(index.isValid());
// draw default item
// Draw the base item, with a blank icon
QStyleOptionViewItem opt = option;
initStyleOption(&opt, index);
opt.type = QStyleOption::SO_Default;
QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &opt, painter, 0);
opt.icon = QIcon();
// Based on QStyledItemDelegate::paint()
const QStyle* style = option.widget ? option.widget->style() : QApplication::style();
style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, option.widget);
// Fetch icon pixmap
const QRect r = option.rect;
const QPixmap pix = qvariant_cast<QPixmap>(index.data(Qt::DecorationRole));
const int pix_width = static_cast<int>(pix.width() / pix.devicePixelRatio());
const int pix_height = static_cast<int>(pix.width() / pix.devicePixelRatio());
const int pix_height = static_cast<int>(pix.height() / pix.devicePixelRatio());
// draw pixmap at center of item
// Draw the icon, using code derived from QItemDelegate::drawDecoration()
const bool enabled = option.state & QStyle::State_Enabled;
const QPoint p = QPoint((r.width() - pix_width) / 2, (r.height() - pix_height) / 2);
painter->drawPixmap(r.topLeft() + p, pix);
if (option.state & QStyle::State_Selected)
{
// See QItemDelegate::selectedPixmap()
QString key = QString::fromStdString(fmt::format("{:016X}-{:d}", pix.cacheKey(), enabled));
QPixmap pm;
if (!QPixmapCache::find(key, &pm))
{
QImage img = pix.toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied);
QColor color = option.palette.color(enabled ? QPalette::Normal : QPalette::Disabled,
QPalette::Highlight);
color.setAlphaF(0.3f);
QPainter tinted_painter(&img);
tinted_painter.setCompositionMode(QPainter::CompositionMode_SourceAtop);
tinted_painter.fillRect(0, 0, img.width(), img.height(), color);
tinted_painter.end();
pm = QPixmap(QPixmap::fromImage(img));
QPixmapCache::insert(key, pm);
}
painter->drawPixmap(r.topLeft() + p, pm);
}
else
{
painter->drawPixmap(r.topLeft() + p, pix);
}
}
};
} // namespace
@@ -190,6 +222,7 @@ void GameListWidget::initialize()
m_table_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
m_table_view->setVerticalScrollMode(QAbstractItemView::ScrollMode::ScrollPerPixel);
m_table_view->setItemDelegateForColumn(0, new GameListIconStyleDelegate(this));
m_table_view->setItemDelegateForColumn(8, new GameListIconStyleDelegate(this));
loadTableViewColumnVisibilitySettings();
loadTableViewColumnSortSettings();

View File

@@ -1261,6 +1261,102 @@ namespace SettingWidgetBinder
widget->connect(widget, &QLineEdit::editingFinished, widget, std::move(value_changed));
}
static inline void BindWidgetToFileSetting(SettingsInterface* sif, QLineEdit* widget, QAbstractButton* browse_button,
QAbstractButton* open_button, QAbstractButton* reset_button, std::string section, std::string key, std::string default_value,
const char* filter, bool allow_pergame = false, bool use_relative = true)
{
using Accessor = SettingAccessor<QLineEdit>;
std::string current_path(Host::GetBaseStringSettingValue(section.c_str(), key.c_str(), default_value.c_str()));
if (current_path.empty())
current_path = default_value;
else if (use_relative && !Path::IsAbsolute(current_path))
current_path = Path::Canonicalize(Path::Combine(EmuFolders::DataRoot, current_path));
const QString value(QString::fromStdString(current_path));
Accessor::setStringValue(widget, value);
if (!allow_pergame)
{
widget->setEnabled(false);
if (browse_button)
browse_button->setEnabled(false);
if (reset_button)
reset_button->setEnabled(false);
return;
}
auto value_changed = [widget, section = std::move(section), key = std::move(key), default_value, use_relative]() {
const std::string new_value(widget->text().toStdString());
if (!new_value.empty())
{
if (use_relative)
{
const std::string relative_path(Path::MakeRelative(new_value, EmuFolders::DataRoot));
Host::SetBaseStringSettingValue(section.c_str(), key.c_str(), relative_path.c_str());
}
else
{
Host::SetBaseStringSettingValue(section.c_str(), key.c_str(), new_value.c_str());
}
if (!FileSystem::FileExists(new_value.c_str()))
{
QMessageBox::critical(QtUtils::GetRootWidget(widget), qApp->translate("SettingWidgetBinder", "Error"),
qApp->translate("SettingWidgetBinder", "File cannot be found."));
}
Host::CommitBaseSettingChanges();
return;
}
else
{
QMessageBox::critical(QtUtils::GetRootWidget(widget), qApp->translate("SettingWidgetBinder", "Error"),
qApp->translate("SettingWidgetBinder", "File path cannot be empty."));
}
// reset to old value
std::string current_path(Host::GetBaseStringSettingValue(section.c_str(), key.c_str(), default_value.c_str()));
if (current_path.empty())
current_path = default_value;
else if (use_relative && !Path::IsAbsolute(current_path))
current_path = Path::Canonicalize(Path::Combine(EmuFolders::DataRoot, current_path));
widget->setText(QString::fromStdString(current_path));
};
if (browse_button)
{
QObject::connect(browse_button, &QAbstractButton::clicked, browse_button, [widget, key, value_changed, filter]() {
const QString path(QDir::toNativeSeparators(QFileDialog::getOpenFileName(QtUtils::GetRootWidget(widget),
qApp->translate("SettingWidgetBinder", "Select File"), QString(), filter)));
if (path.isEmpty())
return;
widget->setText(path);
value_changed();
});
}
if (open_button)
{
QObject::connect(open_button, &QAbstractButton::clicked, open_button, [widget]() {
QString path(Accessor::getStringValue(widget));
if (!path.isEmpty())
QtUtils::OpenURL(QtUtils::GetRootWidget(widget), QUrl::fromLocalFile(path));
});
}
if (reset_button)
{
QObject::connect(
reset_button, &QAbstractButton::clicked, reset_button, [widget, default_value = std::move(default_value), value_changed]() {
widget->setText(QString::fromStdString(default_value));
value_changed();
});
}
widget->connect(widget, &QLineEdit::editingFinished, widget, std::move(value_changed));
}
// No need to pass a section or key since this is only used once and has six keys associated with it
static inline void BindWidgetToDateTimeSetting(SettingsInterface* sif, QDateTimeEdit* widget, std::string section)
{

View File

@@ -16,6 +16,8 @@
#include <QtCore/QDateTime>
#include <QtWidgets/QMessageBox>
const char* AUDIO_FILE_FILTER = QT_TRANSLATE_NOOP("MainWindow", "Audio Files (*.wav)");
AchievementSettingsWidget::AchievementSettingsWidget(SettingsWindow* dialog, QWidget* parent)
: QWidget(parent)
, m_dialog(dialog)
@@ -29,6 +31,9 @@ AchievementSettingsWidget::AchievementSettingsWidget(SettingsWindow* dialog, QWi
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.achievementNotifications, "Achievements", "Notifications", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.leaderboardNotifications, "Achievements", "LeaderboardNotifications", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.soundEffects, "Achievements", "SoundEffects", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.notificationSound, "Achievements", "InfoSound", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.unlockSound, "Achievements", "UnlockSound", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.lbSound, "Achievements", "LBSubmitSound", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.overlays, "Achievements", "Overlays", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.encoreMode, "Achievements", "EncoreMode", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.spectatorMode, "Achievements", "SpectatorMode", false);
@@ -36,11 +41,16 @@ AchievementSettingsWidget::AchievementSettingsWidget(SettingsWindow* dialog, QWi
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.achievementNotificationsDuration, "Achievements", "NotificationsDuration", Pcsx2Config::AchievementsOptions::DEFAULT_NOTIFICATION_DURATION);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.leaderboardNotificationsDuration, "Achievements", "LeaderboardsDuration", Pcsx2Config::AchievementsOptions::DEFAULT_LEADERBOARD_DURATION);
SettingWidgetBinder::BindWidgetToFileSetting(sif, m_ui.notificationSoundPath, m_ui.notificationSoundBrowse, m_ui.notificationSoundOpen, m_ui.notificationSoundReset, "Achievements", "InfoSoundName", Path::Combine(EmuFolders::Resources, EmuConfig.Achievements.DEFAULT_INFO_SOUND_NAME), AUDIO_FILE_FILTER, true, false);
SettingWidgetBinder::BindWidgetToFileSetting(sif, m_ui.unlockSoundPath, m_ui.unlockSoundBrowse, m_ui.unlockSoundOpen, m_ui.unlockSoundReset, "Achievements", "UnlockSoundName", Path::Combine(EmuFolders::Resources, EmuConfig.Achievements.DEFAULT_UNLOCK_SOUND_NAME), AUDIO_FILE_FILTER, true, false);
SettingWidgetBinder::BindWidgetToFileSetting(sif, m_ui.lbSoundPath, m_ui.lbSoundBrowse, m_ui.lbSoundOpen, m_ui.lbSoundReset, "Achievements", "LBSubmitSoundName", Path::Combine(EmuFolders::Resources, EmuConfig.Achievements.DEFAULT_LBSUBMIT_SOUND_NAME), AUDIO_FILE_FILTER, true, false);
dialog->registerWidgetHelp(m_ui.enable, tr("Enable Achievements"), tr("Unchecked"), tr("When enabled and logged in, PCSX2 will scan for achievements on startup."));
dialog->registerWidgetHelp(m_ui.hardcoreMode, tr("Enable Hardcore Mode"), tr("Unchecked"), tr("\"Challenge\" mode for achievements, including leaderboard tracking. Disables save state, cheats, and slowdown functions."));
dialog->registerWidgetHelp(m_ui.achievementNotifications, tr("Show Achievement Notifications"), tr("Checked"), tr("Displays popup messages on events such as achievement unlocks and game completion."));
dialog->registerWidgetHelp(m_ui.leaderboardNotifications, tr("Show Leaderboard Notifications"), tr("Checked"), tr("Displays popup messages when starting, submitting, or failing a leaderboard challenge."));
dialog->registerWidgetHelp(m_ui.soundEffects, tr("Enable Sound Effects"), tr("Checked"), tr("Plays sound effects for events such as achievement unlocks and leaderboard submissions."));
dialog->registerWidgetHelp(m_ui.soundEffectsBox, tr("Custom Sound Effect"), tr("Any"), tr("Customize the sound effect that are played whenever you received a notification, earned an achievement or submitted an entry to the leaderboard."));
dialog->registerWidgetHelp(m_ui.overlays, tr("Enable In-Game Overlays"), tr("Checked"), tr("Shows icons in the lower-right corner of the screen when a challenge/primed achievement is active."));
dialog->registerWidgetHelp(m_ui.encoreMode, tr("Enable Encore Mode"), tr("Unchecked"),tr("When enabled, each session will behave as if no achievements have been unlocked."));
dialog->registerWidgetHelp(m_ui.spectatorMode, tr("Enable Spectator Mode"), tr("Unchecked"), tr("When enabled, PCSX2 will assume all achievements are locked and not send any unlock notifications to the server."));
@@ -51,6 +61,10 @@ AchievementSettingsWidget::AchievementSettingsWidget(SettingsWindow* dialog, QWi
connect(m_ui.hardcoreMode, &QCheckBox::checkStateChanged, this, &AchievementSettingsWidget::onHardcoreModeStateChanged);
connect(m_ui.achievementNotifications, &QCheckBox::checkStateChanged, this, &AchievementSettingsWidget::updateEnableState);
connect(m_ui.leaderboardNotifications, &QCheckBox::checkStateChanged, this, &AchievementSettingsWidget::updateEnableState);
connect(m_ui.soundEffects, &QCheckBox::checkStateChanged, this, &AchievementSettingsWidget::updateEnableState);
connect(m_ui.notificationSound, &QCheckBox::checkStateChanged, this, &AchievementSettingsWidget::updateEnableState);
connect(m_ui.unlockSound, &QCheckBox::checkStateChanged, this, &AchievementSettingsWidget::updateEnableState);
connect(m_ui.lbSound, &QCheckBox::checkStateChanged, this, &AchievementSettingsWidget::updateEnableState);
connect(m_ui.achievementNotificationsDuration, &QSlider::valueChanged, this, &AchievementSettingsWidget::onAchievementsNotificationDurationSliderChanged);
connect(m_ui.leaderboardNotificationsDuration, &QSlider::valueChanged, this, &AchievementSettingsWidget::onLeaderboardsNotificationDurationSliderChanged);
@@ -73,6 +87,11 @@ AchievementSettingsWidget::AchievementSettingsWidget(SettingsWindow* dialog, QWi
m_ui.verticalLayout->removeWidget(m_ui.loginBox);
m_ui.loginBox->deleteLater();
m_ui.loginBox = nullptr;
// sound effects
m_ui.verticalLayout->removeWidget(m_ui.soundEffectsBox);
m_ui.soundEffectsBox->deleteLater();
m_ui.soundEffectsBox = nullptr;
}
updateEnableState();
@@ -87,6 +106,10 @@ void AchievementSettingsWidget::updateEnableState()
const bool enabled = m_dialog->getEffectiveBoolValue("Achievements", "Enabled", false);
const bool notifications = enabled && m_dialog->getEffectiveBoolValue("Achievements", "Notifications", true);
const bool lb_notifications = enabled && m_dialog->getEffectiveBoolValue("Achievements", "LeaderboardNotifications", true);
const bool sound = m_dialog->getEffectiveBoolValue("Achievements", "SoundEffects", true);
const bool info = enabled && sound && m_dialog->getEffectiveBoolValue("Achievements", "InfoSound", true);
const bool unlock = enabled && sound && m_dialog->getEffectiveBoolValue("Achievements", "UnlockSound", true);
const bool lbsound = enabled && sound && m_dialog->getEffectiveBoolValue("Achievements", "LBSubmitSound", true);
m_ui.hardcoreMode->setEnabled(enabled);
m_ui.achievementNotifications->setEnabled(enabled);
m_ui.leaderboardNotifications->setEnabled(enabled);
@@ -94,6 +117,21 @@ void AchievementSettingsWidget::updateEnableState()
m_ui.achievementNotificationsDurationLabel->setEnabled(notifications);
m_ui.leaderboardNotificationsDuration->setEnabled(lb_notifications);
m_ui.leaderboardNotificationsDurationLabel->setEnabled(lb_notifications);
m_ui.notificationSoundPath->setEnabled(info);
m_ui.notificationSoundBrowse->setEnabled(info);
m_ui.notificationSoundOpen->setEnabled(info);
m_ui.notificationSoundReset->setEnabled(info);
m_ui.notificationSound->setEnabled(enabled);
m_ui.unlockSoundPath->setEnabled(unlock);
m_ui.unlockSoundBrowse->setEnabled(unlock);
m_ui.unlockSoundOpen->setEnabled(unlock);
m_ui.unlockSoundReset->setEnabled(unlock);
m_ui.unlockSound->setEnabled(enabled);
m_ui.lbSoundPath->setEnabled(lbsound);
m_ui.lbSoundOpen->setEnabled(lbsound);
m_ui.lbSoundBrowse->setEnabled(lbsound);
m_ui.lbSoundReset->setEnabled(lbsound);
m_ui.lbSound->setEnabled(enabled);
m_ui.soundEffects->setEnabled(enabled);
m_ui.overlays->setEnabled(enabled);
m_ui.encoreMode->setEnabled(enabled);

View File

@@ -24,256 +24,364 @@
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Settings</string>
<widget class="QScrollArea" name="scrollArea">
<property name="widgetResizable">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="1">
<widget class="QCheckBox" name="spectatorMode">
<property name="text">
<string>Enable Spectator Mode</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="enable">
<property name="text">
<string>Enable Achievements</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="unofficialAchievements">
<property name="text">
<string>Test Unofficial Achievements</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="encoreMode">
<property name="text">
<string>Enable Encore Mode</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="hardcoreMode">
<property name="text">
<string>Enable Hardcore Mode</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="notificationBox">
<property name="title">
<string>Notifications</string>
</property>
<layout class="QGridLayout" name="gridLayout_2" columnstretch="1,1">
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3" stretch="1,0">
<item>
<widget class="QSlider" name="achievementNotificationsDuration">
<property name="minimum">
<number>3</number>
</property>
<property name="maximum">
<number>30</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>5</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="invertedAppearance">
<bool>false</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>1</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="achievementNotificationsDurationLabel">
<property name="text">
<string>5 seconds</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="achievementNotifications">
<property name="text">
<string>Show Achievement Notifications</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,0">
<item>
<widget class="QSlider" name="leaderboardNotificationsDuration">
<property name="minimum">
<number>3</number>
</property>
<property name="maximum">
<number>30</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>5</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="invertedAppearance">
<bool>false</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>1</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="leaderboardNotificationsDurationLabel">
<property name="text">
<string>5 seconds</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="leaderboardNotifications">
<property name="text">
<string>Show Leaderboard Notifications</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="soundEffects">
<property name="text">
<string>Enable Sound Effects</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="overlays">
<property name="text">
<string>Enable In-Game Overlays</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="loginBox">
<property name="title">
<string>Account</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0">
<item>
<widget class="QLabel" name="loginStatus">
<property name="text">
<string>Username:
<widget class="QWidget" name="scrollAreaAchievements">
<property name="geometry">
<rect>
<x>0</x>
<y>-2</y>
<width>655</width>
<height>739</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="settingsBox">
<property name="title">
<string>Settings</string>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<item row="2" column="0">
<widget class="QCheckBox" name="unofficialAchievements">
<property name="text">
<string>Test Unofficial Achievements</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="hardcoreMode">
<property name="text">
<string>Enable Hardcore Mode</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="enable">
<property name="text">
<string>Enable Achievements</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="spectatorMode">
<property name="text">
<string>Enable Spectator Mode</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="encoreMode">
<property name="text">
<string>Enable Encore Mode</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="notificationBox">
<property name="title">
<string>Notifications</string>
</property>
<layout class="QGridLayout" name="gridLayout_2" columnstretch="1,0">
<item row="0" column="1">
<layout class="QHBoxLayout" name="achievementNotificationsDurationSliderContainer" stretch="1,0">
<item>
<widget class="QSlider" name="achievementNotificationsDuration">
<property name="minimum">
<number>3</number>
</property>
<property name="maximum">
<number>30</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>5</number>
</property>
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="invertedAppearance">
<bool>false</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TickPosition::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>1</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="achievementNotificationsDurationLabel">
<property name="text">
<string>5 seconds</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="achievementNotifications">
<property name="text">
<string>Show Achievement Notifications</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="leaderboardNotificationsDurationSliderContainer" stretch="1,0">
<item>
<widget class="QSlider" name="leaderboardNotificationsDuration">
<property name="minimum">
<number>3</number>
</property>
<property name="maximum">
<number>30</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>5</number>
</property>
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="invertedAppearance">
<bool>false</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TickPosition::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>1</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="leaderboardNotificationsDurationLabel">
<property name="text">
<string>5 seconds</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="leaderboardNotifications">
<property name="text">
<string>Show Leaderboard Notifications</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="soundEffects">
<property name="text">
<string>Enable Sound Effects</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="overlays">
<property name="text">
<string>Enable In-Game Overlays</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="soundEffectsBox">
<property name="title">
<string>Sound Effects</string>
</property>
<layout class="QGridLayout" name="gridLayout_6">
<item row="5" column="0">
<widget class="QLineEdit" name="lbSoundPath"/>
</item>
<item row="1" column="0">
<widget class="QLineEdit" name="notificationSoundPath"/>
</item>
<item row="3" column="1">
<widget class="QPushButton" name="unlockSoundBrowse">
<property name="text">
<string>Browse...</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QPushButton" name="notificationSoundReset">
<property name="text">
<string>Reset</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="unlockSound">
<property name="text">
<string>Achievement Unlock Sound</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="notificationSoundBrowse">
<property name="text">
<string>Browse...</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLineEdit" name="unlockSoundPath"/>
</item>
<item row="5" column="1">
<widget class="QPushButton" name="lbSoundBrowse">
<property name="text">
<string>Browse...</string>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QPushButton" name="unlockSoundOpen">
<property name="text">
<string>Preview</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="notificationSoundOpen">
<property name="text">
<string>Preview</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="notificationSound">
<property name="text">
<string>Notification Sound</string>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QPushButton" name="lbSoundOpen">
<property name="text">
<string>Preview</string>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QPushButton" name="unlockSoundReset">
<property name="text">
<string>Reset</string>
</property>
</widget>
</item>
<item row="5" column="3">
<widget class="QPushButton" name="lbSoundReset">
<property name="text">
<string>Reset</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="lbSound">
<property name="text">
<string>Leaderboard Submit Sound</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="loginBox">
<property name="title">
<string>Account</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0">
<item>
<widget class="QLabel" name="loginStatus">
<property name="text">
<string>Username:
Login token generated at:</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QPushButton" name="viewProfile">
<property name="text">
<string>View Profile...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="loginButton">
<property name="text">
<string>Login...</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="achievementButtons">
<item>
<widget class="QPushButton" name="viewProfile">
<property name="text">
<string>View Profile...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="loginButton">
<property name="text">
<string>Login...</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="gameInfoBox">
<property name="minimumSize">
<size>
<width>0</width>
<height>75</height>
</size>
</property>
<property name="title">
<string>Game Info</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="gameInfo">
<property name="alignment">
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="rcheevosDisclaimer">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;PCSX2 uses RetroAchievements as an achievement database and for tracking progress. To use achievements, please sign up for an account at &lt;a href=&quot;https://retroachievements.org/&quot;&gt;retroachievements.org&lt;/a&gt;.&lt;/p&gt;&lt;p align=&quot;justify&quot;&gt;To view the achievement list in-game, press the hotkey for &lt;span style=&quot; font-weight:600;&quot;&gt;Open Pause Menu&lt;/span&gt; and select &lt;span style=&quot; font-weight:600;&quot;&gt;Achievements&lt;/span&gt; from the menu.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::TextFormat::RichText</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="margin">
<number>8</number>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QGroupBox" name="gameInfoBox">
<property name="minimumSize">
<size>
<width>0</width>
<height>75</height>
</size>
</property>
<property name="title">
<string>Game Info</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="gameInfo">
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;PCSX2 uses RetroAchievements as an achievement database and for tracking progress. To use achievements, please sign up for an account at &lt;a href=&quot;https://retroachievements.org/&quot;&gt;retroachievements.org&lt;/a&gt;.&lt;/p&gt;&lt;p align=&quot;justify&quot;&gt;To view the achievement list in-game, press the hotkey for &lt;span style=&quot; font-weight:600;&quot;&gt;Open Pause Menu&lt;/span&gt; and select &lt;span style=&quot; font-weight:600;&quot;&gt;Achievements&lt;/span&gt; from the menu.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="margin">
<number>8</number>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources>

View File

@@ -32,9 +32,9 @@
<property name="geometry">
<rect>
<x>0</x>
<y>-447</y>
<y>-449</y>
<width>790</width>
<height>1049</height>
<height>1051</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">

View File

@@ -4,6 +4,7 @@
#include "DebugUserInterfaceSettingsWidget.h"
#include "SettingWidgetBinder.h"
#include "Debugger/DebuggerWindow.h"
static const char* s_drop_indicators[] = {
QT_TRANSLATE_NOOP("DebugUserInterfaceSettingsWidget", "Classic"),
@@ -19,32 +20,40 @@ DebugUserInterfaceSettingsWidget::DebugUserInterfaceSettingsWidget(SettingsWindo
m_ui.setupUi(this);
SettingWidgetBinder::BindWidgetToBoolSetting(
sif, m_ui.showOnStartupCheckBox, "Debugger/UserInterface", "ShowOnStartup", false);
SettingWidgetBinder::BindWidgetToIntSetting(
sif, m_ui.refreshInterval, "Debugger/UserInterface", "RefreshInterval", 1000);
connect(m_ui.refreshInterval, &QSpinBox::valueChanged, this, []() {
if (g_debugger_window)
g_debugger_window->updateFromSettings();
});
dialog->registerWidgetHelp(
m_ui.showOnStartupCheckBox, tr("Show On Startup"), tr("Unchecked"),
m_ui.refreshInterval, tr("Refresh Interval"), tr("1000ms"),
tr("The amount of time to wait between subsequent attempts to update the user interface to reflect the state "
"of the virtual machine."));
SettingWidgetBinder::BindWidgetToBoolSetting(
sif, m_ui.showOnStartup, "Debugger/UserInterface", "ShowOnStartup", false);
dialog->registerWidgetHelp(
m_ui.showOnStartup, tr("Show On Startup"), tr("Unchecked"),
tr("Open the debugger window automatically when PCSX2 starts."));
SettingWidgetBinder::BindWidgetToBoolSetting(
sif, m_ui.saveWindowGeometryCheckBox, "Debugger/UserInterface", "SaveWindowGeometry", true);
sif, m_ui.saveWindowGeometry, "Debugger/UserInterface", "SaveWindowGeometry", true);
dialog->registerWidgetHelp(
m_ui.saveWindowGeometryCheckBox, tr("Save Window Geometry"), tr("Checked"),
m_ui.saveWindowGeometry, tr("Save Window Geometry"), tr("Checked"),
tr("Save the position and size of the debugger window when it is closed so that it can be restored later."));
SettingWidgetBinder::BindWidgetToEnumSetting(
sif,
m_ui.dropIndicatorCombo,
m_ui.dropIndicator,
"Debugger/UserInterface",
"DropIndicatorStyle",
s_drop_indicators,
s_drop_indicators,
s_drop_indicators[0],
"DebugUserInterfaceSettingsWidget");
dialog->registerWidgetHelp(
m_ui.dropIndicatorCombo, tr("Drop Indicator Style"), tr("Classic"),
m_ui.dropIndicator, tr("Drop Indicator Style"), tr("Classic"),
tr("Choose how the drop indicators that appear when you drag dock windows in the debugger are styled. "
"You will have to restart the debugger for this option to take effect."));
}

View File

@@ -38,15 +38,8 @@
<string>Debugger Window</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="1">
<widget class="QCheckBox" name="saveWindowGeometryCheckBox">
<property name="text">
<string>Save Window Geometry</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="showOnStartupCheckBox">
<item row="1" column="0">
<widget class="QCheckBox" name="showOnStartup">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
@@ -58,6 +51,36 @@
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="saveWindowGeometry">
<property name="text">
<string>Save Window Geometry</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="refreshIntervalLabel">
<property name="text">
<string>Refresh Interval:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="refreshInterval">
<property name="suffix">
<string>ms</string>
</property>
<property name="minimum">
<number>10</number>
</property>
<property name="maximum">
<number>100000</number>
</property>
<property name="value">
<number>1000</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@@ -76,12 +99,12 @@
<item row="0" column="0">
<widget class="QLabel" name="dropIndicatorLabel">
<property name="text">
<string>Drop Indicator Style</string>
<string>Drop Indicator Style:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="dropIndicatorCombo"/>
<widget class="QComboBox" name="dropIndicator"/>
</item>
</layout>
</widget>

File diff suppressed because it is too large Load Diff

View File

@@ -351,208 +351,85 @@
</ClCompile>
</ItemGroup>
<ItemGroup>
<QtUi Include="MainWindow.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="GameList\EmptyGameListWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="GameList\GameListWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\SettingsWindow.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\GameListSettingsWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\BIOSSettingsWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\EmulationSettingsWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\GraphicsSettingsWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\InterfaceSettingsWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\AdvancedSettingsWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\GameFixSettingsWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\InputBindingDialog.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\ControllerSettingsWindow.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\ControllerBindingWidget_DualShock2.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\ControllerBindingWidget_Guitar.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\ControllerBindingWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\ControllerGlobalSettingsWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\MemoryCardCreateDialog.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\AudioSettingsWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\MemoryCardConvertDialog.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\MemoryCardSettingsWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\DEV9DnsHostDialog.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\DEV9SettingsWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\GameSummaryWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="AutoUpdaterDialog.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="CoverDownloadDialog.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Tools\InputRecording\NewInputRecordingDlg.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\AchievementLoginDialog.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\AchievementSettingsWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Tools\InputRecording\InputRecordingViewer.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Debugger\AnalysisOptionsDialog.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Debugger\DebuggerWindow.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Debugger\DisassemblyWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Debugger\RegisterWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Debugger\Breakpoints\BreakpointDialog.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Debugger\Breakpoints\BreakpointWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Debugger\Docking\LayoutEditorDialog.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Debugger\Docking\NoLayoutsWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Debugger\Memory\MemorySearchWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Debugger\Memory\MemoryViewWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Debugger\Memory\SavedAddressesWidget.ui">
<FileType>Document</FileType>
</QtUi>
</ItemGroup>
<ItemGroup>
<QtUi Include="SetupWizardDialog.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="AboutDialog.ui" />
<QtUi Include="AutoUpdaterDialog.ui" />
<QtUi Include="CoverDownloadDialog.ui" />
<QtUi Include="Debugger\AnalysisOptionsDialog.ui" />
<QtUi Include="Debugger\Breakpoints\BreakpointDialog.ui" />
<QtUi Include="Debugger\Breakpoints\BreakpointWidget.ui" />
<QtUi Include="Debugger\DebuggerWindow.ui" />
<QtUi Include="Debugger\DisassemblyWidget.ui" />
<QtUi Include="Debugger\Docking\LayoutEditorDialog.ui" />
<QtUi Include="Debugger\Docking\NoLayoutsWidget.ui" />
<QtUi Include="Debugger\Memory\MemorySearchWidget.ui" />
<QtUi Include="Debugger\Memory\MemoryViewWidget.ui" />
<QtUi Include="Debugger\Memory\SavedAddressesWidget.ui" />
<QtUi Include="Debugger\RegisterWidget.ui" />
<QtUi Include="Debugger\StackWidget.ui" />
<QtUi Include="Debugger\SymbolTree\NewSymbolDialog.ui" />
<QtUi Include="Debugger\SymbolTree\SymbolTreeWidget.ui" />
<QtUi Include="Debugger\ThreadWidget.ui" />
<QtUi Include="GameList\EmptyGameListWidget.ui" />
<QtUi Include="GameList\GameListWidget.ui" />
<QtUi Include="MainWindow.ui" />
<QtUi Include="Settings\AchievementLoginDialog.ui" />
<QtUi Include="Settings\AchievementSettingsWidget.ui" />
<QtUi Include="Settings\AdvancedSettingsWidget.ui" />
<QtUi Include="Settings\AudioExpansionSettingsDialog.ui" />
<QtUi Include="Settings\AudioSettingsWidget.ui" />
<QtUi Include="Settings\AudioStretchSettingsDialog.ui" />
<QtUi Include="Settings\BIOSSettingsWidget.ui" />
<QtUi Include="Settings\ControllerBindingWidget.ui" />
<QtUi Include="Settings\ControllerBindingWidget_DualShock2.ui" />
<QtUi Include="Settings\ControllerBindingWidget_Guitar.ui" />
<QtUi Include="Settings\ControllerBindingWidget_Jogcon.ui" />
<QtUi Include="Settings\ControllerBindingWidget_Negcon.ui" />
<QtUi Include="Settings\ControllerBindingWidget_Popn.ui" />
<QtUi Include="Settings\ControllerGlobalSettingsWidget.ui" />
<QtUi Include="Settings\ControllerLEDSettingsDialog.ui" />
<QtUi Include="Settings\ControllerMacroEditWidget.ui" />
<QtUi Include="Settings\ControllerMacroWidget.ui" />
<QtUi Include="Settings\ControllerMappingSettingsDialog.ui" />
<QtUi Include="Settings\ControllerMouseSettingsDialog.ui" />
<QtUi Include="Settings\ControllerSettingsWindow.ui" />
<QtUi Include="Settings\DebugAnalysisSettingsWidget.ui" />
<QtUi Include="Settings\DebugSettingsWidget.ui" />
<QtUi Include="Settings\DebugUserInterfaceSettingsWidget.ui" />
<QtUi Include="Settings\DEV9DnsHostDialog.ui" />
<QtUi Include="Settings\DEV9SettingsWidget.ui" />
<QtUi Include="Settings\EmulationSettingsWidget.ui" />
<QtUi Include="Settings\FolderSettingsWidget.ui" />
<QtUi Include="Settings\GameCheatSettingsWidget.ui" />
<QtUi Include="Settings\GameFixSettingsWidget.ui" />
<QtUi Include="Settings\GameListSettingsWidget.ui" />
<QtUi Include="Settings\GamePatchDetailsWidget.ui" />
<QtUi Include="Settings\GamePatchSettingsWidget.ui" />
<QtUi Include="Settings\GameSummaryWidget.ui" />
<QtUi Include="Settings\GraphicsSettingsWidget.ui" />
<QtUi Include="Settings\InputBindingDialog.ui" />
<QtUi Include="Settings\InterfaceSettingsWidget.ui" />
<QtUi Include="Settings\MemoryCardConvertDialog.ui" />
<QtUi Include="Settings\MemoryCardCreateDialog.ui" />
<QtUi Include="Settings\MemoryCardSettingsWidget.ui" />
<QtUi Include="Settings\PatchDetailsWidget.ui" />
<QtUi Include="Settings\SettingsWindow.ui" />
<QtUi Include="Settings\USBBindingWidget_Buzz.ui" />
<QtUi Include="Settings\USBBindingWidget_DenshaCon.ui" />
<QtUi Include="Settings\USBBindingWidget_DrivingForce.ui" />
<QtUi Include="Settings\USBBindingWidget_Gametrak.ui" />
<QtUi Include="Settings\USBBindingWidget_GTForce.ui" />
<QtUi Include="Settings\USBBindingWidget_GunCon2.ui" />
<QtUi Include="Settings\USBBindingWidget_RealPlay.ui" />
<QtUi Include="Settings\USBBindingWidget_RyojouhenCon.ui" />
<QtUi Include="Settings\USBBindingWidget_ShinkansenCon.ui" />
<QtUi Include="Settings\USBBindingWidget_TranceVibrator.ui" />
<QtUi Include="Settings\USBDeviceWidget.ui" />
<QtTs Include="Translations\pcsx2-qt_en.ts">
<FileType>Document</FileType>
</QtTs>
<QtUi Include="Settings\DebugAnalysisSettingsWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\DebugUserInterfaceSettingsWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\DebugSettingsWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\ControllerLEDSettingsDialog.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\ControllerMouseSettingsDialog.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\GameCheatSettingsWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\GamePatchSettingsWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\USBBindingWidget_Buzz.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\USBBindingWidget_DenshaCon.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\USBBindingWidget_DrivingForce.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\USBBindingWidget_Gametrak.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\USBBindingWidget_GTForce.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\USBBindingWidget_GunCon2.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\USBBindingWidget_RealPlay.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\USBBindingWidget_RyojouhenCon.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\USBBindingWidget_ShinkansenCon.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\USBBindingWidget_TranceVibrator.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\USBDeviceWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\ControllerMacroEditWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\ControllerMacroWidget.ui">
<FileType>Document</FileType>
</QtUi>
<None Include="Debugger\SymbolTree\NewSymbolDialog.ui" />
<None Include="Debugger\SymbolTree\SymbolTreeWidget.ui" />
<QtUi Include="Settings\AudioExpansionSettingsDialog.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\AudioStretchSettingsDialog.ui">
<FileType>Document</FileType>
</QtUi>
<None Include="Settings\ControllerBindingWidget_Popn.ui" />
<None Include="Settings\ControllerMappingSettingsDialog.ui" />
<None Include="Settings\FolderSettingsWidget.ui" />
<QtUi Include="SetupWizardDialog.ui" />
<QtUi Include="Tools\InputRecording\InputRecordingViewer.ui" />
<QtUi Include="Tools\InputRecording\NewInputRecordingDlg.ui" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Import Project="$(SolutionDir)common\vsprops\QtCompile.targets" />

View File

@@ -735,107 +735,32 @@
</QtResource>
</ItemGroup>
<ItemGroup>
<QtUi Include="mainwindow.ui" />
<QtUi Include="Settings\BIOSSettingsWidget.ui">
<Filter>Settings</Filter>
<QtUi Include="Debugger\Breakpoints\BreakpointDialog.ui">
<Filter>Debugger\Breakpoints</Filter>
</QtUi>
<QtUi Include="Settings\EmulationSettingsWidget.ui">
<Filter>Settings</Filter>
<QtUi Include="Debugger\Breakpoints\BreakpointWidget.ui">
<Filter>Debugger\Breakpoints</Filter>
</QtUi>
<QtUi Include="Settings\GameListSettingsWidget.ui">
<Filter>Settings</Filter>
<QtUi Include="Debugger\Docking\LayoutEditorDialog.ui">
<Filter>Debugger\Docking</Filter>
</QtUi>
<QtUi Include="Settings\GraphicsSettingsWidget.ui">
<Filter>Settings</Filter>
<QtUi Include="Debugger\Docking\NoLayoutsWidget.ui">
<Filter>Debugger\Docking</Filter>
</QtUi>
<QtUi Include="Settings\InterfaceSettingsWidget.ui">
<Filter>Settings</Filter>
<QtUi Include="Debugger\Memory\MemorySearchWidget.ui">
<Filter>Debugger\Memory</Filter>
</QtUi>
<QtUi Include="Settings\SettingsWindow.ui">
<Filter>Settings</Filter>
<QtUi Include="Debugger\Memory\MemoryViewWidget.ui">
<Filter>Debugger\Memory</Filter>
</QtUi>
<QtUi Include="Settings\AdvancedSettingsWidget.ui">
<Filter>Settings</Filter>
<QtUi Include="Debugger\Memory\SavedAddressesWidget.ui">
<Filter>Debugger\Memory</Filter>
</QtUi>
<QtUi Include="Settings\GameFixSettingsWidget.ui">
<Filter>Settings</Filter>
<QtUi Include="Debugger\SymbolTree\NewSymbolDialog.ui">
<Filter>Debugger\SymbolTree</Filter>
</QtUi>
<QtUi Include="Settings\InputBindingDialog.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\ControllerSettingsWindow.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\ControllerBindingWidget_DualShock2.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\ControllerBindingWidget_Guitar.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\ControllerBindingWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\ControllerGlobalSettingsWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\GameSummaryWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\MemoryCardConvertDialog.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\MemoryCardSettingsWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\AudioSettingsWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\MemoryCardCreateDialog.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\DEV9DnsHostDialog.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\DEV9SettingsWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="GameList\EmptyGameListWidget.ui">
<Filter>GameList</Filter>
</QtUi>
<QtUi Include="GameList\GameListWidget.ui">
<Filter>GameList</Filter>
</QtUi>
<QtUi Include="AutoUpdaterDialog.ui" />
<QtUi Include="Tools\InputRecording\NewInputRecordingDlg.ui">
<Filter>Tools\Input Recording</Filter>
</QtUi>
<QtUi Include="Settings\ControllerMacroWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\ControllerMacroEditWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\AchievementSettingsWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\AchievementLoginDialog.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="CoverDownloadDialog.ui" />
<QtUi Include="Tools\InputRecording\InputRecordingViewer.ui">
<Filter>Tools\Input Recording</Filter>
</QtUi>
<QtUi Include="Settings\USBDeviceWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\DebugAnalysisSettingsWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\DebugUserInterfaceSettingsWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\DebugSettingsWidget.ui">
<Filter>Settings</Filter>
<QtUi Include="Debugger\SymbolTree\SymbolTreeWidget.ui">
<Filter>Debugger\SymbolTree</Filter>
</QtUi>
<QtUi Include="Debugger\AnalysisOptionsDialog.ui">
<Filter>Debugger</Filter>
@@ -849,19 +774,141 @@
<QtUi Include="Debugger\RegisterWidget.ui">
<Filter>Debugger</Filter>
</QtUi>
<QtUi Include="Debugger\StackWidget.ui">
<Filter>Debugger</Filter>
</QtUi>
<QtUi Include="Debugger\ThreadWidget.ui">
<Filter>Debugger</Filter>
</QtUi>
<QtUi Include="GameList\EmptyGameListWidget.ui">
<Filter>GameList</Filter>
</QtUi>
<QtUi Include="GameList\GameListWidget.ui">
<Filter>GameList</Filter>
</QtUi>
<QtUi Include="Settings\AchievementLoginDialog.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\AchievementSettingsWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\AdvancedSettingsWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\AudioExpansionSettingsDialog.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\AudioSettingsWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\AudioStretchSettingsDialog.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\BIOSSettingsWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\ControllerBindingWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\ControllerBindingWidget_DualShock2.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\ControllerBindingWidget_Guitar.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\ControllerBindingWidget_Jogcon.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\ControllerBindingWidget_Negcon.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\ControllerBindingWidget_Popn.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\ControllerGlobalSettingsWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\ControllerLEDSettingsDialog.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\ControllerMacroEditWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\ControllerMacroWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\ControllerMappingSettingsDialog.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\ControllerMouseSettingsDialog.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\ControllerSettingsWindow.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\DebugAnalysisSettingsWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\DebugSettingsWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\DebugUserInterfaceSettingsWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\DEV9DnsHostDialog.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\DEV9SettingsWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\EmulationSettingsWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\FolderSettingsWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\GameCheatSettingsWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\GameFixSettingsWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\GameListSettingsWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\GamePatchDetailsWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\GamePatchSettingsWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="SetupWizardDialog.ui" />
<QtUi Include="Settings\GameSummaryWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\GraphicsSettingsWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\InputBindingDialog.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\InterfaceSettingsWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\MemoryCardConvertDialog.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\MemoryCardCreateDialog.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\MemoryCardSettingsWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\PatchDetailsWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\SettingsWindow.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\USBBindingWidget_Buzz.ui">
<Filter>Settings</Filter>
</QtUi>
@@ -892,50 +939,20 @@
<QtUi Include="Settings\USBBindingWidget_TranceVibrator.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\AudioExpansionSettingsDialog.ui">
<QtUi Include="Settings\USBDeviceWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\AudioStretchSettingsDialog.ui">
<Filter>Settings</Filter>
<QtUi Include="Tools\InputRecording\InputRecordingViewer.ui">
<Filter>Tools\Input Recording</Filter>
</QtUi>
<QtUi Include="Debugger\Breakpoints\BreakpointDialog.ui">
<Filter>Debugger\Breakpoints</Filter>
<QtUi Include="Tools\InputRecording\NewInputRecordingDlg.ui">
<Filter>Tools\Input Recording</Filter>
</QtUi>
<QtUi Include="Debugger\Breakpoints\BreakpointWidget.ui">
<Filter>Debugger\Breakpoints</Filter>
</QtUi>
<QtUi Include="Debugger\Memory\SavedAddressesWidget.ui">
<Filter>Debugger\Memory</Filter>
</QtUi>
<QtUi Include="Debugger\Memory\MemoryViewWidget.ui">
<Filter>Debugger\Memory</Filter>
</QtUi>
<QtUi Include="Debugger\Memory\MemorySearchWidget.ui">
<Filter>Debugger\Memory</Filter>
</QtUi>
<QtUi Include="Debugger\Docking\LayoutEditorDialog.ui">
<Filter>Debugger\Docking</Filter>
</QtUi>
<QtUi Include="Debugger\Docking\NoLayoutsWidget.ui">
<Filter>Debugger\Docking</Filter>
</QtUi>
</ItemGroup>
<ItemGroup>
<None Include="Settings\FolderSettingsWidget.ui">
<Filter>Settings</Filter>
</None>
<None Include="Settings\ControllerBindingWidget_Popn.ui">
<Filter>Settings</Filter>
</None>
<None Include="Settings\ControllerMappingSettingsDialog.ui">
<Filter>Settings</Filter>
</None>
<None Include="Debugger\SymbolTree\NewSymbolDialog.ui">
<Filter>Debugger\SymbolTree</Filter>
</None>
<None Include="Debugger\SymbolTree\SymbolTreeWidget.ui">
<Filter>Debugger\SymbolTree</Filter>
</None>
<QtUi Include="AboutDialog.ui" />
<QtUi Include="AutoUpdaterDialog.ui" />
<QtUi Include="CoverDownloadDialog.ui" />
<QtUi Include="MainWindow.ui" />
<QtUi Include="SetupWizardDialog.ui" />
</ItemGroup>
<ItemGroup>
<QtTs Include="Translations\pcsx2-qt_en.ts">

View File

@@ -74,10 +74,6 @@ namespace Achievements
// Chrome uses 10 server calls per domain, seems reasonable.
static constexpr u32 MAX_CONCURRENT_SERVER_CALLS = 10;
static constexpr const char* INFO_SOUND_NAME = "sounds/achievements/message.wav";
static constexpr const char* UNLOCK_SOUND_NAME = "sounds/achievements/unlock.wav";
static constexpr const char* LBSUBMIT_SOUND_NAME = "sounds/achievements/lbsubmit.wav";
namespace
{
struct LoginWithPasswordParameters
@@ -1050,9 +1046,8 @@ void Achievements::DisplayAchievementSummary()
});
}
// Technically not going through the resource API, but since we're passing this to something else, we can't.
if (EmuConfig.Achievements.SoundEffects)
Common::PlaySoundAsync(EmuFolders::GetOverridableResourcePath(INFO_SOUND_NAME).c_str());
if (EmuConfig.Achievements.SoundEffects && EmuConfig.Achievements.InfoSound)
Common::PlaySoundAsync(EmuConfig.Achievements.InfoSoundName.c_str());
}
void Achievements::DisplayHardcoreDeferredMessage()
@@ -1103,8 +1098,8 @@ void Achievements::HandleUnlockEvent(const rc_client_event_t* event)
});
}
if (EmuConfig.Achievements.SoundEffects)
Common::PlaySoundAsync(EmuFolders::GetOverridableResourcePath(UNLOCK_SOUND_NAME).c_str());
if (EmuConfig.Achievements.SoundEffects && EmuConfig.Achievements.UnlockSound)
Common::PlaySoundAsync(EmuConfig.Achievements.UnlockSoundName.c_str());
}
void Achievements::HandleGameCompleteEvent(const rc_client_event_t* event)
@@ -1197,8 +1192,8 @@ void Achievements::HandleLeaderboardSubmittedEvent(const rc_client_event_t* even
});
}
if (EmuConfig.Achievements.SoundEffects)
Common::PlaySoundAsync(EmuFolders::GetOverridableResourcePath(LBSUBMIT_SOUND_NAME).c_str());
if (EmuConfig.Achievements.SoundEffects && EmuConfig.Achievements.LBSubmitSound)
Common::PlaySoundAsync(EmuConfig.Achievements.LBSubmitSoundName.c_str());
}
void Achievements::HandleLeaderboardScoreboardEvent(const rc_client_event_t* event)
@@ -2271,7 +2266,9 @@ void Achievements::DrawAchievementsWindow()
ImGui::GetColorU32(ImGuiFullscreen::UISecondaryColor));
text.format("{}%", static_cast<int>(std::round(fraction * 100.0f)));
ImGui::PushFont(g_medium_font);
text_size = ImGui::CalcTextSize(text.c_str(), text.end_ptr());
ImGui::PopFont();
const ImVec2 text_pos(progress_bb.Min.x + ((progress_bb.Max.x - progress_bb.Min.x) / 2.0f) - (text_size.x / 2.0f),
progress_bb.Min.y + ((progress_bb.Max.y - progress_bb.Min.y) / 2.0f) - (text_size.y / 2.0f));
dl->AddText(g_medium_font, g_medium_font->FontSize, text_pos, ImGui::GetColorU32(ImGuiFullscreen::UIPrimaryTextColor),

View File

@@ -1209,6 +1209,9 @@ struct Pcsx2Config
static constexpr u32 MAXIMUM_NOTIFICATION_DURATION = 30;
static constexpr u32 DEFAULT_NOTIFICATION_DURATION = 5;
static constexpr u32 DEFAULT_LEADERBOARD_DURATION = 10;
static constexpr const char* DEFAULT_INFO_SOUND_NAME = "sounds/achievements/message.wav";
static constexpr const char* DEFAULT_UNLOCK_SOUND_NAME = "sounds/achievements/unlock.wav";
static constexpr const char* DEFAULT_LBSUBMIT_SOUND_NAME = "sounds/achievements/lbsubmit.wav";
BITFIELD32()
bool
@@ -1220,12 +1223,19 @@ struct Pcsx2Config
Notifications : 1,
LeaderboardNotifications : 1,
SoundEffects : 1,
InfoSound : 1,
UnlockSound : 1,
LBSubmitSound : 1,
Overlays : 1;
BITFIELD_END
u32 NotificationsDuration = DEFAULT_NOTIFICATION_DURATION;
u32 LeaderboardsDuration = DEFAULT_LEADERBOARD_DURATION;
std::string InfoSoundName;
std::string UnlockSoundName;
std::string LBSubmitSoundName;
AchievementsOptions();
void LoadSave(SettingsWrapper& wrap);

View File

@@ -3929,8 +3929,9 @@ GSState::TextureMinMaxResult GSState::GetTextureMinMax(GIFRegTEX0 TEX0, GIFRegCL
// Need to make sure we don't oversample, this can cause trouble in grabbing textures.
// This may be inaccurate depending on the draw, but adding 1 all the time is wrong too.
const int inclusive_x_req = ((m_vt.m_primclass < GS_TRIANGLE_CLASS) || (grad.x < 1.0f || (grad.x == 1.0f && m_vt.m_max.p.x != floor(m_vt.m_max.p.x)))) ? 1 : 0;
const int inclusive_y_req = ((m_vt.m_primclass < GS_TRIANGLE_CLASS) || (grad.y < 1.0f || (grad.y == 1.0f && m_vt.m_max.p.y != floor(m_vt.m_max.p.y)))) ? 1 : 0;
// FIXME: It breaks sw renderer so let's still use 1 for SW mode for now.
const int inclusive_x_req = GSIsHardwareRenderer() ? (((m_vt.m_primclass < GS_TRIANGLE_CLASS) || (grad.x < 1.0f || (grad.x == 1.0f && m_vt.m_max.p.x != floor(m_vt.m_max.p.x)))) ? 1 : 0) : 1;
const int inclusive_y_req = GSIsHardwareRenderer() ? (((m_vt.m_primclass < GS_TRIANGLE_CLASS) || (grad.y < 1.0f || (grad.y == 1.0f && m_vt.m_max.p.y != floor(m_vt.m_max.p.y)))) ? 1 : 0) : 1;
// Roughly cut out the min/max of the read (Clamp)
switch (wms)

View File

@@ -890,28 +890,31 @@ struct PSMain
void ps_color_clamp_wrap(thread float4& C)
{
// When dithering the bottom 3 bits become meaningless and cause lines in the picture so we need to limit the color depth on dithered items
if (!SW_BLEND && !(PS_DITHER > 0 && PS_DITHER < 3) && !PS_FBMASK)
return;
// When dithering the bottom 3 bits become meaningless and cause lines in the picture
// so we need to limit the color depth on dithered items
if (SW_BLEND || (PS_DITHER > 0 && PS_DITHER < 3) || PS_FBMASK)
{
if (PS_DST_FMT == FMT_16 && PS_BLEND_MIX == 0 && PS_ROUND_INV)
C.rgb += 7.f; // Need to round up, not down since the shader will invert
if (PS_DST_FMT == FMT_16 && PS_BLEND_MIX == 0 && PS_ROUND_INV)
C.rgb += 7.f; // Need to round up, not down since the shader will invert
// Correct the Color value based on the output format
if (PS_COLCLIP == 0 && PS_HDR == 0)
C.rgb = clamp(C.rgb, 0.f, 255.f); // Standard Clamp
// Correct the Color value based on the output format
if (!PS_COLCLIP && !PS_HDR)
C.rgb = clamp(C.rgb, 0.f, 255.f); // Standard Clamp
// FIXME rouding of negative float?
// compiler uses trunc but it might need floor
// FIXME rouding of negative float?
// compiler uses trunc but it might need floor
// Warning: normally blending equation is mult(A, B) = A * B >> 7. GPU have the full accuracy
// GS: Color = 1, Alpha = 255 => output 1
// GPU: Color = 1/255, Alpha = 255/255 * 255/128 => output 1.9921875
if (PS_DST_FMT == FMT_16 && PS_DITHER < 3 && (PS_BLEND_MIX == 0 || PS_DITHER))
// Warning: normally blending equation is mult(A, B) = A * B >> 7. GPU have the full accuracy
// GS: Color = 1, Alpha = 255 => output 1
// GPU: Color = 1/255, Alpha = 255/255 * 255/128 => output 1.9921875
// In 16 bits format, only 5 bits of colors are used. It impacts shadows computation of Castlevania
if (PS_DST_FMT == FMT_16 && PS_DITHER != 3 && (PS_BLEND_MIX == 0 || PS_DITHER))
C.rgb = float3(short3(C.rgb) & 0xF8);
else if (PS_COLCLIP == 1 || PS_HDR == 1)
C.rgb = float3(short3(C.rgb) & 0xFF);
}
else if (PS_DST_FMT == FMT_16 && PS_DITHER != 3 && PS_BLEND_MIX == 0 && PS_BLEND_HW == 0)
C.rgb = float3(short3(C.rgb) & 0xF8);
else if (PS_COLCLIP || PS_HDR)
C.rgb = float3(short3(C.rgb) & 0xFF);
}
template <typename T>

View File

@@ -237,7 +237,7 @@ namespace FullscreenUI
static void DrawAboutWindow();
static void OpenAboutWindow();
static void GetStandardSelectionFooterText(SmallStringBase& dest, bool back_instead_of_cancel);
static void ApplyConfirmSetting(const SettingsInterface* bsi = nullptr);
static void ApplyLayoutSettings(const SettingsInterface* bsi = nullptr);
static MainWindowType s_current_main_window = MainWindowType::None;
static PauseSubMenu s_current_pause_submenu = PauseSubMenu::None;
@@ -272,6 +272,7 @@ namespace FullscreenUI
static void SwitchToLanding();
static ImGuiFullscreen::FileSelectorFilters GetOpenFileFilters();
static ImGuiFullscreen::FileSelectorFilters GetDiscImageFilters();
static ImGuiFullscreen::FileSelectorFilters GetAudioFileFilters();
static void DoStartPath(
const std::string& path, std::optional<s32> state_index = std::nullopt, std::optional<bool> fast_boot = std::nullopt);
static void DoStartFile();
@@ -542,10 +543,11 @@ void ImGuiFullscreen::GetFileSelectorHelpText(SmallStringBase& dest)
if (IsGamepadInputSource())
{
const bool circleOK = ImGui::GetIO().ConfigNavSwapGamepadButtons;
const bool swapNorthWest = ImGuiManager::IsGamepadNorthWestSwapped();
ImGuiFullscreen::CreateFooterTextString(
dest, std::array{
std::make_pair(ICON_PF_DPAD_UP_DOWN, FSUI_VSTR("Change Selection")),
std::make_pair(ICON_PF_BUTTON_TRIANGLE, FSUI_VSTR("Parent Directory")),
std::make_pair(swapNorthWest ? ICON_PF_BUTTON_SQUARE : ICON_PF_BUTTON_TRIANGLE, FSUI_VSTR("Parent Directory")),
std::make_pair(circleOK ? ICON_PF_BUTTON_CIRCLE : ICON_PF_BUTTON_CROSS, FSUI_VSTR("Select")),
std::make_pair(circleOK ? ICON_PF_BUTTON_CROSS : ICON_PF_BUTTON_CIRCLE, FSUI_VSTR("Cancel")),
});
@@ -584,7 +586,7 @@ void ImGuiFullscreen::GetInputDialogHelpText(SmallStringBase& dest)
}
}
void FullscreenUI::ApplyConfirmSetting(const SettingsInterface* bsi)
void FullscreenUI::ApplyLayoutSettings(const SettingsInterface* bsi)
{
ImGuiIO& io = ImGui::GetIO();
SmallString swap_mode;
@@ -593,12 +595,43 @@ void FullscreenUI::ApplyConfirmSetting(const SettingsInterface* bsi)
else
swap_mode = Host::GetBaseSmallStringSettingValue("UI", "SwapOKFullscreenUI", "auto");
// Check Nintendo Setting
SmallString sdl2_nintendo_mode;
if (bsi)
sdl2_nintendo_mode = bsi->GetSmallStringValue("UI", "SDL2NintendoLayout", "false");
else
sdl2_nintendo_mode = Host::GetBaseSmallStringSettingValue("UI", "SDL2NintendoLayout", "false");
const InputLayout layout = ImGuiFullscreen::GetGamepadLayout();
if (sdl2_nintendo_mode == "true" || (sdl2_nintendo_mode == "auto") && layout == InputLayout::Nintendo)
{
// Apply
ImGuiManager::SwapGamepadNorthWest(true);
// Check swap_mode if A/B should also be swapped
if (swap_mode == "auto")
{
io.ConfigNavSwapGamepadButtons = true;
return;
}
}
else
ImGuiManager::SwapGamepadNorthWest(false);
if (swap_mode == "true")
io.ConfigNavSwapGamepadButtons = true;
else if (swap_mode == "false")
io.ConfigNavSwapGamepadButtons = false;
else if (swap_mode == "auto")
{
// Check gamepad
if (layout == InputLayout::Nintendo)
{
io.ConfigNavSwapGamepadButtons = true;
return;
}
// Check language
if (Host::LocaleCircleConfirm())
{
@@ -628,14 +661,6 @@ 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;
@@ -647,12 +672,12 @@ void FullscreenUI::ApplyConfirmSetting(const SettingsInterface* bsi)
void FullscreenUI::LocaleChanged()
{
ApplyConfirmSetting();
ApplyLayoutSettings();
}
void FullscreenUI::GamepadLayoutChanged()
{
ApplyConfirmSetting();
ApplyLayoutSettings();
}
//////////////////////////////////////////////////////////////////////////
@@ -669,7 +694,7 @@ bool FullscreenUI::Initialize()
ImGuiFullscreen::SetTheme(Host::GetBaseStringSettingValue("UI", "FullscreenUITheme", "Dark"));
ImGuiFullscreen::UpdateLayoutScale();
ApplyConfirmSetting();
ApplyLayoutSettings();
if (!ImGuiManager::AddFullscreenFontsIfMissing() || !ImGuiFullscreen::Initialize("fullscreenui/placeholder.png") || !LoadResources())
{
@@ -740,7 +765,7 @@ void FullscreenUI::CheckForConfigChanges(const Pcsx2Config& old_config)
if (old_config.FullpathToBios() != EmuConfig.FullpathToBios())
{
MTGS::RunOnGSThread([]() {
ApplyConfirmSetting();
ApplyLayoutSettings();
});
}
}
@@ -1059,6 +1084,11 @@ ImGuiFullscreen::FileSelectorFilters FullscreenUI::GetDiscImageFilters()
return {"*.bin", "*.iso", "*.cue", "*.mdf", "*.chd", "*.cso", "*.zso", "*.gz"};
}
ImGuiFullscreen::FileSelectorFilters FullscreenUI::GetAudioFileFilters()
{
return {"*.wav"};
}
void FullscreenUI::DoStartPath(const std::string& path, std::optional<s32> state_index, std::optional<bool> fast_boot)
{
VMBootParameters params;
@@ -1405,11 +1435,12 @@ void FullscreenUI::DrawLandingWindow()
if (IsGamepadInputSource())
{
const bool circleOK = ImGui::GetIO().ConfigNavSwapGamepadButtons;
const bool swapNorthWest = ImGuiManager::IsGamepadNorthWestSwapped();
SetFullscreenFooterText(std::array{
std::make_pair(ICON_PF_SELECT_SHARE, FSUI_VSTR("About")),
std::make_pair(ICON_PF_DPAD_LEFT_RIGHT, FSUI_VSTR("Navigate")),
std::make_pair(ICON_PF_BUTTON_TRIANGLE, FSUI_VSTR("Game List")),
std::make_pair(ICON_PF_BUTTON_SQUARE, FSUI_VSTR("Toggle Fullscreen")),
std::make_pair(swapNorthWest ? ICON_PF_BUTTON_SQUARE : ICON_PF_BUTTON_TRIANGLE, FSUI_VSTR("Game List")),
std::make_pair(swapNorthWest ? ICON_PF_BUTTON_TRIANGLE : ICON_PF_BUTTON_SQUARE, FSUI_VSTR("Toggle Fullscreen")),
std::make_pair(circleOK ? ICON_PF_BUTTON_CIRCLE : ICON_PF_BUTTON_CROSS, FSUI_VSTR("Select")),
std::make_pair(circleOK ? ICON_PF_BUTTON_CROSS : ICON_PF_BUTTON_CIRCLE, FSUI_VSTR("Exit")),
});
@@ -1478,9 +1509,10 @@ void FullscreenUI::DrawStartGameWindow()
if (IsGamepadInputSource())
{
const bool circleOK = ImGui::GetIO().ConfigNavSwapGamepadButtons;
const bool swapNorthWest = ImGuiManager::IsGamepadNorthWestSwapped();
SetFullscreenFooterText(std::array{
std::make_pair(ICON_PF_DPAD_LEFT_RIGHT, FSUI_VSTR("Navigate")),
std::make_pair(ICON_PF_BUTTON_SQUARE, FSUI_VSTR("Load Global State")),
std::make_pair(swapNorthWest ? ICON_PF_BUTTON_TRIANGLE : ICON_PF_BUTTON_SQUARE, FSUI_VSTR("Load Global State")),
std::make_pair(circleOK ? ICON_PF_BUTTON_CIRCLE : ICON_PF_BUTTON_CROSS, FSUI_VSTR("Select")),
std::make_pair(circleOK ? ICON_PF_BUTTON_CROSS : ICON_PF_BUTTON_CIRCLE, FSUI_VSTR("Back")),
});
@@ -3418,7 +3450,40 @@ void FullscreenUI::DrawInterfaceSettingsPage()
SettingsInterface* bsi = GetEditingSettingsInterface(false);
bsi->SetStringValue("UI", "SwapOKFullscreenUI", swap_values[index]);
SetSettingsChanged(bsi);
ApplyConfirmSetting(bsi);
ApplyLayoutSettings(bsi);
}
CloseChoiceDialog();
});
}
const SmallString nintendo_mode = bsi->GetSmallStringValue("UI", "SDL2NintendoLayout", "false");
size_t nintendo_index = std::size(swap_values);
for (size_t i = 0; i < std::size(swap_values); i++)
{
if (nintendo_mode == swap_values[i])
{
nintendo_index = i;
break;
}
}
swap_summery.format(FSUI_FSTR("Swaps both {}/{} (When Swap OK/Cancel is set to automatic) and {}/{} buttons"), ICON_PF_BUTTON_CROSS, ICON_PF_BUTTON_CIRCLE, ICON_PF_BUTTON_SQUARE, ICON_PF_BUTTON_TRIANGLE);
if (MenuButtonWithValue(FSUI_ICONSTR(ICON_FA_GAMEPAD, "Use Legacy Nintendo Layout in Big Picture Mode"), swap_summery.c_str(),
(nintendo_index < std::size(swap_values)) ? Host::TranslateToCString(TR_CONTEXT, swap_names[nintendo_index]) : FSUI_CSTR("Unknown")))
{
ImGuiFullscreen::ChoiceDialogOptions cd_options;
cd_options.reserve(std::size(swap_values));
for (size_t i = 0; i < std::size(swap_values); i++)
cd_options.emplace_back(Host::TranslateToString(TR_CONTEXT, swap_names[i]), i == static_cast<size_t>(nintendo_index));
OpenChoiceDialog(FSUI_ICONSTR(ICON_FA_GAMEPAD, "Use Legacy Nintendo Layout in Big Picture Mode"), false, std::move(cd_options), [](s32 index, const std::string& title, bool checked) {
if (index >= 0)
{
auto lock = Host::GetSettingsLock();
SettingsInterface* bsi = GetEditingSettingsInterface(false);
bsi->SetStringValue("UI", "SDL2NintendoLayout", swap_values[index]);
SetSettingsChanged(bsi);
ApplyLayoutSettings(bsi);
}
CloseChoiceDialog();
@@ -3542,7 +3607,7 @@ void FullscreenUI::DrawBIOSSettingsPage()
SettingsInterface* bsi = GetEditingSettingsInterface(game_settings);
bsi->SetStringValue("Filenames", "BIOS", values[index].c_str());
SetSettingsChanged(bsi);
ApplyConfirmSetting(bsi);
ApplyLayoutSettings(bsi);
CloseChoiceDialog();
});
}
@@ -5971,9 +6036,10 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading)
if (IsGamepadInputSource())
{
const bool circleOK = ImGui::GetIO().ConfigNavSwapGamepadButtons;
const bool swapNorthWest = ImGuiManager::IsGamepadNorthWestSwapped();
SetFullscreenFooterText(std::array{
std::make_pair(ICON_PF_DPAD, FSUI_VSTR("Select State")),
std::make_pair(ICON_PF_BUTTON_SQUARE, FSUI_VSTR("Options")),
std::make_pair(swapNorthWest ? ICON_PF_BUTTON_TRIANGLE : ICON_PF_BUTTON_SQUARE, FSUI_VSTR("Options")),
std::make_pair(circleOK ? ICON_PF_BUTTON_CIRCLE : ICON_PF_BUTTON_CROSS, FSUI_VSTR("Load/Save State")),
std::make_pair(circleOK ? ICON_PF_BUTTON_CROSS : ICON_PF_BUTTON_CIRCLE, FSUI_VSTR("Cancel")),
});
@@ -6270,11 +6336,12 @@ void FullscreenUI::DrawGameListWindow()
if (IsGamepadInputSource())
{
const bool circleOK = ImGui::GetIO().ConfigNavSwapGamepadButtons;
const bool swapNorthWest = ImGuiManager::IsGamepadNorthWestSwapped();
SetFullscreenFooterText(std::array{
std::make_pair(ICON_PF_DPAD, FSUI_VSTR("Select Game")),
std::make_pair(ICON_PF_START, FSUI_VSTR("Settings")),
std::make_pair(ICON_PF_BUTTON_TRIANGLE, FSUI_VSTR("Change View")),
std::make_pair(ICON_PF_BUTTON_SQUARE, FSUI_VSTR("Launch Options")),
std::make_pair(swapNorthWest ? ICON_PF_BUTTON_SQUARE : ICON_PF_BUTTON_TRIANGLE, FSUI_VSTR("Change View")),
std::make_pair(swapNorthWest ? ICON_PF_BUTTON_TRIANGLE : ICON_PF_BUTTON_SQUARE, FSUI_VSTR("Launch Options")),
std::make_pair(circleOK ? ICON_PF_BUTTON_CIRCLE : ICON_PF_BUTTON_CROSS, FSUI_VSTR("Start Game")),
std::make_pair(circleOK ? ICON_PF_BUTTON_CROSS : ICON_PF_BUTTON_CIRCLE, FSUI_VSTR("Back")),
});
@@ -7129,6 +7196,46 @@ void FullscreenUI::DrawAchievementsSettingsPage(std::unique_lock<std::mutex>& se
if (!IsEditingGameSettings(bsi))
{
MenuHeading(FSUI_CSTR("Sound Effects"));
if (MenuButton(FSUI_ICONSTR(ICON_FA_MUSIC, "Notification Sound"), bsi->GetTinyStringValue("Achievements", "InfoSoundName")))
{
auto callback = [bsi](const std::string& path) {
if (!path.empty())
{
bsi->SetStringValue("Achievements", "InfoSoundName", path.c_str());
SetSettingsChanged(bsi);
}
CloseFileSelector();
};
OpenFileSelector(FSUI_ICONSTR(ICON_FA_FOLDER_OPEN, "Select Notification Sound"), false, std::move(callback), GetAudioFileFilters());
}
if (MenuButton(FSUI_ICONSTR(ICON_FA_MUSIC, "Unlock Sound"), bsi->GetTinyStringValue("Achievements", "UnlockSoundName")))
{
auto callback = [bsi](const std::string& path) {
if (!path.empty())
{
bsi->SetStringValue("Achievements", "UnlockSoundName", path.c_str());
SetSettingsChanged(bsi);
}
CloseFileSelector();
};
OpenFileSelector(FSUI_ICONSTR(ICON_FA_FOLDER_OPEN, "Select Unlock Sound"), false, std::move(callback), GetAudioFileFilters());
}
if (MenuButton(FSUI_ICONSTR(ICON_FA_MUSIC, "Leaderboard Submit Sound"), bsi->GetTinyStringValue("Achievements", "LBSubmitSoundName")))
{
auto callback = [bsi](const std::string& path) {
if (!path.empty())
{
bsi->SetStringValue("Achievements", "LBSubmitSoundName", path.c_str());
SetSettingsChanged(bsi);
}
CloseFileSelector();
};
OpenFileSelector(FSUI_ICONSTR(ICON_FA_FOLDER_OPEN, "Select Leaderboard Submit Sound"), false, std::move(callback), GetAudioFileFilters());
}
MenuHeading(FSUI_CSTR("Account"));
if (bsi->ContainsValue("Achievements", "Token"))
{
@@ -7669,6 +7776,7 @@ TRANSLATE_NOOP("FullscreenUI", "Shows icons in the lower-right corner of the scr
TRANSLATE_NOOP("FullscreenUI", "When enabled, each session will behave as if no achievements have been unlocked.");
TRANSLATE_NOOP("FullscreenUI", "When enabled, PCSX2 will assume all achievements are locked and not send any unlock notifications to the server.");
TRANSLATE_NOOP("FullscreenUI", "When enabled, PCSX2 will list achievements from unofficial sets. These achievements are not tracked by RetroAchievements.");
TRANSLATE_NOOP("FullscreenUI", "Sound Effects");
TRANSLATE_NOOP("FullscreenUI", "Account");
TRANSLATE_NOOP("FullscreenUI", "Logs out of RetroAchievements.");
TRANSLATE_NOOP("FullscreenUI", "Logs in to RetroAchievements.");
@@ -7683,6 +7791,7 @@ TRANSLATE_NOOP("FullscreenUI", "Automatic mapping failed for {}.");
TRANSLATE_NOOP("FullscreenUI", "Game settings initialized with global settings for '{}'.");
TRANSLATE_NOOP("FullscreenUI", "Game settings have been cleared for '{}'.");
TRANSLATE_NOOP("FullscreenUI", "Uses {} as confirm when using a controller");
TRANSLATE_NOOP("FullscreenUI", "Swaps both {}/{} (When Swap OK/Cancel is set to automatic) and {}/{} buttons");
TRANSLATE_NOOP("FullscreenUI", "Slot {}");
TRANSLATE_NOOP("FullscreenUI", "{} (Current)");
TRANSLATE_NOOP("FullscreenUI", "{} (Folder)");
@@ -7955,6 +8064,7 @@ TRANSLATE_NOOP("FullscreenUI", "Confirm Shutdown");
TRANSLATE_NOOP("FullscreenUI", "Save State On Shutdown");
TRANSLATE_NOOP("FullscreenUI", "Create Save State Backups");
TRANSLATE_NOOP("FullscreenUI", "Swap OK/Cancel in Big Picture Mode");
TRANSLATE_NOOP("FullscreenUI", "Use Legacy Nintendo Layout in Big Picture Mode");
TRANSLATE_NOOP("FullscreenUI", "Enable Discord Presence");
TRANSLATE_NOOP("FullscreenUI", "Start Fullscreen");
TRANSLATE_NOOP("FullscreenUI", "Double-Click Toggles Fullscreen");
@@ -8081,11 +8191,16 @@ TRANSLATE_NOOP("FullscreenUI", "Enable Achievements");
TRANSLATE_NOOP("FullscreenUI", "Hardcore Mode");
TRANSLATE_NOOP("FullscreenUI", "Achievement Notifications");
TRANSLATE_NOOP("FullscreenUI", "Leaderboard Notifications");
TRANSLATE_NOOP("FullscreenUI", "Sound Effects");
TRANSLATE_NOOP("FullscreenUI", "Enable In-Game Overlays");
TRANSLATE_NOOP("FullscreenUI", "Encore Mode");
TRANSLATE_NOOP("FullscreenUI", "Spectator Mode");
TRANSLATE_NOOP("FullscreenUI", "Test Unofficial Achievements");
TRANSLATE_NOOP("FullscreenUI", "Notification Sound");
TRANSLATE_NOOP("FullscreenUI", "Select Notification Sound");
TRANSLATE_NOOP("FullscreenUI", "Unlock Sound");
TRANSLATE_NOOP("FullscreenUI", "Select Unlock Sound");
TRANSLATE_NOOP("FullscreenUI", "Leaderboard Submit Sound");
TRANSLATE_NOOP("FullscreenUI", "Select Leaderboard Submit Sound");
TRANSLATE_NOOP("FullscreenUI", "Username: {}");
TRANSLATE_NOOP("FullscreenUI", "Login token generated on {}");
TRANSLATE_NOOP("FullscreenUI", "Logout");

View File

@@ -89,6 +89,8 @@ static std::atomic_bool s_imgui_wants_keyboard{false};
static std::atomic_bool s_imgui_wants_mouse{false};
static std::atomic_bool s_imgui_wants_text{false};
static bool s_gamepad_swap_noth_west = false;
// mapping of host key -> imgui key
static std::unordered_map<u32, ImGuiKey> s_imgui_key_map;
@@ -488,7 +490,7 @@ ImFont* ImGuiManager::AddFixedFont(float size)
bool ImGuiManager::AddIconFonts(float size)
{
// clang-format off
static constexpr ImWchar range_fa[] = { 0xe06f,0xe06f,0xf002,0xf002,0xf005,0xf005,0xf007,0xf007,0xf00c,0xf00e,0xf011,0xf011,0xf013,0xf013,0xf017,0xf017,0xf019,0xf019,0xf021,0xf023,0xf025,0xf028,0xf02b,0xf02b,0xf02e,0xf02e,0xf030,0xf030,0xf03a,0xf03a,0xf03d,0xf03e,0xf04b,0xf04c,0xf04e,0xf04e,0xf050,0xf050,0xf052,0xf052,0xf05a,0xf05a,0xf05e,0xf05e,0xf063,0xf063,0xf067,0xf067,0xf06a,0xf06a,0xf06e,0xf06e,0xf071,0xf071,0xf077,0xf078,0xf07b,0xf07c,0xf084,0xf084,0xf091,0xf091,0xf0ac,0xf0ad,0xf0b0,0xf0b0,0xf0c5,0xf0c5,0xf0c7,0xf0c8,0xf0cb,0xf0cb,0xf0d0,0xf0d0,0xf0dc,0xf0dc,0xf0e2,0xf0e2,0xf0eb,0xf0eb,0xf0f3,0xf0f3,0xf0fe,0xf0fe,0xf11b,0xf11c,0xf120,0xf121,0xf129,0xf12a,0xf140,0xf140,0xf14a,0xf14a,0xf15b,0xf15b,0xf15d,0xf15d,0xf187,0xf188,0xf191,0xf192,0xf1b3,0xf1b3,0xf1de,0xf1de,0xf1e6,0xf1e6,0xf1ea,0xf1eb,0xf1f8,0xf1f8,0xf1fc,0xf1fc,0xf21e,0xf21e,0xf245,0xf245,0xf26c,0xf26c,0xf279,0xf279,0xf2bd,0xf2bd,0xf2db,0xf2db,0xf2f2,0xf2f2,0xf302,0xf302,0xf3c1,0xf3c1,0xf3fd,0xf3fd,0xf410,0xf410,0xf462,0xf462,0xf466,0xf466,0xf4e2,0xf4e2,0xf51f,0xf51f,0xf545,0xf545,0xf54c,0xf54c,0xf553,0xf553,0xf56d,0xf56d,0xf5a2,0xf5a2,0xf65d,0xf65e,0xf6a9,0xf6a9,0xf70e,0xf70e,0xf756,0xf756,0xf780,0xf780,0xf794,0xf794,0xf815,0xf815,0xf84c,0xf84c,0xf8cc,0xf8cc,0x0,0x0 };
static constexpr ImWchar range_fa[] = { 0xe06f,0xe06f,0xf001,0xf002,0xf005,0xf005,0xf007,0xf007,0xf00c,0xf00e,0xf011,0xf011,0xf013,0xf013,0xf017,0xf017,0xf019,0xf019,0xf021,0xf023,0xf025,0xf028,0xf02b,0xf02b,0xf02e,0xf02e,0xf030,0xf030,0xf03a,0xf03a,0xf03d,0xf03e,0xf04b,0xf04c,0xf04e,0xf04e,0xf050,0xf050,0xf052,0xf052,0xf05a,0xf05a,0xf05e,0xf05e,0xf063,0xf063,0xf067,0xf067,0xf06a,0xf06a,0xf06e,0xf06e,0xf071,0xf071,0xf077,0xf078,0xf07b,0xf07c,0xf084,0xf084,0xf091,0xf091,0xf0ac,0xf0ad,0xf0b0,0xf0b0,0xf0c5,0xf0c5,0xf0c7,0xf0c8,0xf0cb,0xf0cb,0xf0d0,0xf0d0,0xf0dc,0xf0dc,0xf0e2,0xf0e2,0xf0eb,0xf0eb,0xf0f3,0xf0f3,0xf0fe,0xf0fe,0xf11b,0xf11c,0xf120,0xf121,0xf129,0xf12a,0xf140,0xf140,0xf14a,0xf14a,0xf15b,0xf15b,0xf15d,0xf15d,0xf187,0xf188,0xf191,0xf192,0xf1b3,0xf1b3,0xf1de,0xf1de,0xf1e6,0xf1e6,0xf1ea,0xf1eb,0xf1f8,0xf1f8,0xf1fc,0xf1fc,0xf21e,0xf21e,0xf245,0xf245,0xf26c,0xf26c,0xf279,0xf279,0xf2bd,0xf2bd,0xf2db,0xf2db,0xf2f2,0xf2f2,0xf302,0xf302,0xf3c1,0xf3c1,0xf3fd,0xf3fd,0xf410,0xf410,0xf462,0xf462,0xf466,0xf466,0xf4e2,0xf4e2,0xf51f,0xf51f,0xf545,0xf545,0xf54c,0xf54c,0xf553,0xf553,0xf56d,0xf56d,0xf5a2,0xf5a2,0xf65d,0xf65e,0xf6a9,0xf6a9,0xf70e,0xf70e,0xf756,0xf756,0xf780,0xf780,0xf794,0xf794,0xf815,0xf815,0xf84c,0xf84c,0xf8cc,0xf8cc,0x0,0x0 };
static constexpr ImWchar range_pf[] = { 0x2198,0x2199,0x219e,0x21a7,0x21b0,0x21b3,0x21ba,0x21c3,0x21ce,0x21ce,0x21d0,0x21d4,0x21dc,0x21dd,0x21e0,0x21e3,0x21e6,0x21e8,0x21f3,0x21f3,0x21f7,0x21f8,0x21fa,0x21fb,0x2206,0x2208,0x221a,0x221a,0x227a,0x227d,0x22bf,0x22c8,0x2349,0x2349,0x235a,0x235e,0x2360,0x2361,0x2364,0x2367,0x237a,0x237b,0x237d,0x237d,0x237f,0x237f,0x23b2,0x23b5,0x23cc,0x23cc,0x23f4,0x23f7,0x2427,0x243a,0x243d,0x243d,0x2443,0x2443,0x2460,0x246b,0x248f,0x248f,0x24f5,0x24fd,0x24ff,0x24ff,0x2605,0x2605,0x2699,0x2699,0x278a,0x278e,0xe000,0xe001,0xff21,0xff3a,0x0,0x0 };
// clang-format on
@@ -959,7 +961,15 @@ bool ImGuiManager::ProcessGenericInputEvent(GenericInputBinding key, InputLayout
return false;
MTGS::RunOnGSThread(
[key = key_map[static_cast<u32>(key)], value, layout]() {
[key = key_map[static_cast<u32>(key)], value, layout]() mutable {
if (s_gamepad_swap_noth_west)
{
if (key == ImGuiKey_GamepadFaceUp)
key = ImGuiKey_GamepadFaceLeft;
else if (key == ImGuiKey_GamepadFaceLeft)
key = ImGuiKey_GamepadFaceUp;
}
ImGuiFullscreen::ReportGamepadLayout(layout);
ImGui::GetIO().AddKeyAnalogEvent(key, (value > 0.0f), value);
});
@@ -967,6 +977,16 @@ bool ImGuiManager::ProcessGenericInputEvent(GenericInputBinding key, InputLayout
return s_imgui_wants_keyboard.load(std::memory_order_acquire);
}
void ImGuiManager::SwapGamepadNorthWest(bool value)
{
s_gamepad_swap_noth_west = value;
}
bool ImGuiManager::IsGamepadNorthWestSwapped()
{
return s_gamepad_swap_noth_west;
}
void ImGuiManager::CreateSoftwareCursorTextures()
{
for (u32 i = 0; i < InputManager::MAX_POINTER_DEVICES; i++)

View File

@@ -97,6 +97,12 @@ namespace ImGuiManager
/// Called on the CPU thread when any input event fires. Allows imgui to take over controller navigation.
bool ProcessGenericInputEvent(GenericInputBinding key, InputLayout layout, float value);
/// Called to swap North/West gamepad buttons within ImGui
void SwapGamepadNorthWest(bool value);
/// Checks if the North/West gamepad buttons are swapped within ImGui
bool IsGamepadNorthWestSwapped();
/// 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);
bool HasSoftwareCursor(u32 index);

View File

@@ -6,6 +6,8 @@
#include "Input/InputManager.h"
#include "Host.h"
#include "ImGui/FullscreenUI.h"
#include "common/Assertions.h"
#include "common/Console.h"
#include "common/Error.h"
@@ -700,6 +702,20 @@ std::optional<InputBindingKey> SDLInputSource::ParseKeyString(const std::string_
TRANSLATE("SDLInputSource", "As part of our upgrade to SDL3, we've had to migrate your binds\n"
"Your controller did not match the Xbox layout and may need rebinding\n"
"Please verify your controller settings and amend if required"));
// Also apply BPM setting for legacy binds
// We assume this is a Nintendo controller, BPM will check if it is
// Defer this, as we are probably under a setting lock
Host::RunOnCPUThread([] {
if (!Host::ContainsBaseSettingValue("UI", "SDL2NintendoLayout"))
{
Host::SetBaseStringSettingValue("UI", "SDL2NintendoLayout", "auto");
Host::CommitBaseSettingChanges();
// Get FSUI to recheck setting
if (FullscreenUI::IsInitialized())
FullscreenUI::GamepadLayoutChanged();
}
});
}
key.data = pos;
}

View File

@@ -1830,6 +1830,9 @@ Pcsx2Config::AchievementsOptions::AchievementsOptions()
Notifications = true;
LeaderboardNotifications = true;
SoundEffects = true;
InfoSound = true;
UnlockSound = true;
LBSubmitSound = true;
Overlays = true;
}
@@ -1837,6 +1840,15 @@ void Pcsx2Config::AchievementsOptions::LoadSave(SettingsWrapper& wrap)
{
SettingsWrapSection("Achievements");
if (InfoSoundName.empty())
InfoSoundName = Path::Combine(EmuFolders::Resources, DEFAULT_INFO_SOUND_NAME);
if (UnlockSoundName.empty())
UnlockSoundName = Path::Combine(EmuFolders::Resources, DEFAULT_UNLOCK_SOUND_NAME);
if (LBSubmitSoundName.empty())
LBSubmitSoundName = Path::Combine(EmuFolders::Resources, DEFAULT_LBSUBMIT_SOUND_NAME);
SettingsWrapBitBool(Enabled);
SettingsWrapBitBoolEx(HardcoreMode, "ChallengeMode");
SettingsWrapBitBool(EncoreMode);
@@ -1845,9 +1857,15 @@ void Pcsx2Config::AchievementsOptions::LoadSave(SettingsWrapper& wrap)
SettingsWrapBitBool(Notifications);
SettingsWrapBitBool(LeaderboardNotifications);
SettingsWrapBitBool(SoundEffects);
SettingsWrapBitBool(InfoSound);
SettingsWrapBitBool(UnlockSound);
SettingsWrapBitBool(LBSubmitSound);
SettingsWrapBitBool(Overlays);
SettingsWrapEntry(NotificationsDuration);
SettingsWrapEntry(LeaderboardsDuration);
SettingsWrapEntry(InfoSoundName);
SettingsWrapEntry(UnlockSoundName);
SettingsWrapEntry(LBSubmitSoundName);
if (wrap.IsLoading())
{
@@ -1877,6 +1895,7 @@ Pcsx2Config::Pcsx2Config()
EnableRecordingTools = true;
EnableGameFixes = true;
InhibitScreensaver = true;
UseSavestateSelector = true;
BackupSavestate = true;
WarnAboutUnsafeSettings = true;
ManuallySetRealTimeClock = false;

View File

@@ -3,4 +3,4 @@
/// Version number for GS and other shaders. Increment whenever any of the contents of the
/// shaders change, to invalidate the cache.
static constexpr u32 SHADER_CACHE_VERSION = 60;
static constexpr u32 SHADER_CACHE_VERSION = 61;