Qt: Revamp the status bar

This commit is contained in:
KamFretoZ
2026-04-13 19:45:19 +07:00
committed by Ty
parent 04438ace57
commit 9f67f72d3c
17 changed files with 453 additions and 100 deletions
+290 -60
View File
@@ -36,6 +36,9 @@
#include "pcsx2/ImGui/FullscreenUI.h"
#include "pcsx2/MTGS.h"
#include "pcsx2/PerformanceMetrics.h"
#include "pcsx2/VMManager.h"
#include "pcsx2/ImGui/ImGuiOverlays.h"
#include "pcsx2/SPU2/spu2.h"
#include "pcsx2/Recording/InputRecording.h"
#include "pcsx2/Recording/InputRecordingControls.h"
#include "pcsx2/SaveState.h"
@@ -54,8 +57,11 @@
#include <QtWidgets/QInputDialog>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QProgressBar>
#include <QtWidgets/QSlider>
#include <QtWidgets/QStyle>
#include <QtWidgets/QStyleFactory>
#include <QtWidgets/QWidgetAction>
#include <QtWidgets/QHBoxLayout>
#ifdef _WIN32
#include "common/RedtapeWindows.h"
@@ -185,6 +191,7 @@ void MainWindow::setupAdditionalUi()
{
makeIconsMasks(menuBar());
updateAdvancedSettingsVisibility();
setupStatusBarWidgets();
const bool toolbar_visible = Host::GetBaseBoolSettingValue("UI", "ShowToolbar", false);
m_ui.actionViewToolbar->setChecked(toolbar_visible);
@@ -195,58 +202,6 @@ void MainWindow::setupAdditionalUi()
m_ui.toolBar->setMovable(!toolbars_locked);
m_ui.toolBar->setContextMenuPolicy(Qt::PreventContextMenu);
const bool status_bar_visible = Host::GetBaseBoolSettingValue("UI", "ShowStatusBar", true);
m_ui.actionViewStatusBar->setChecked(status_bar_visible);
m_ui.statusBar->setVisible(status_bar_visible);
const bool show_game_grid = Host::GetBaseBoolSettingValue("UI", "GameListGridView", false);
updateGameGridActions(show_game_grid);
m_game_list_widget = new GameListWidget(getContentParent());
m_game_list_widget->initialize();
m_ui.actionGridViewShowTitles->setChecked(m_game_list_widget->getShowGridCoverTitles());
m_ui.mainContainer->addWidget(m_game_list_widget);
m_status_progress_widget = new QProgressBar(m_ui.statusBar);
m_status_progress_widget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
m_status_progress_widget->setFixedSize(140, 16);
m_status_progress_widget->setMinimum(0);
m_status_progress_widget->setMaximum(100);
m_status_progress_widget->hide();
m_status_verbose_widget = new QLabel(m_ui.statusBar);
m_status_verbose_widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
m_status_verbose_widget->setFixedHeight(16);
m_status_verbose_widget->hide();
m_status_renderer_widget = new QLabel(m_ui.statusBar);
m_status_renderer_widget->setFixedHeight(16);
m_status_renderer_widget->setFixedSize(65, 16);
m_status_renderer_widget->hide();
m_status_resolution_widget = new QLabel(m_ui.statusBar);
m_status_resolution_widget->setFixedHeight(16);
m_status_resolution_widget->setFixedSize(75, 16);
m_status_resolution_widget->hide();
m_status_fps_widget = new QLabel(m_ui.statusBar);
m_status_fps_widget->setFixedHeight(16);
m_status_fps_widget->setMinimumWidth(60);
m_status_fps_widget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
m_status_fps_widget->hide();
m_status_vps_widget = new QLabel(m_ui.statusBar);
m_status_vps_widget->setFixedHeight(16);
m_status_vps_widget->setMinimumWidth(60);
m_status_vps_widget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
m_status_vps_widget->hide();
m_status_speed_widget = new QLabel(m_ui.statusBar);
m_status_speed_widget->setFixedHeight(16);
m_status_speed_widget->setMinimumWidth(130);
m_status_speed_widget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
m_status_speed_widget->hide();
m_settings_toolbar_menu = new QMenu(m_ui.toolBar);
m_settings_toolbar_menu->addAction(m_ui.actionSettings);
m_settings_toolbar_menu->addAction(m_ui.actionViewGameProperties);
@@ -257,6 +212,14 @@ void MainWindow::setupAdditionalUi()
connect(action, &QAction::triggered, [scale]() { g_emu_thread->requestDisplaySize(static_cast<float>(scale)); });
}
const bool show_game_grid = Host::GetBaseBoolSettingValue("UI", "GameListGridView", false);
updateGameGridActions(show_game_grid);
m_game_list_widget = new GameListWidget(getContentParent());
m_game_list_widget->initialize();
m_ui.actionGridViewShowTitles->setChecked(m_game_list_widget->getShowGridCoverTitles());
m_ui.mainContainer->addWidget(m_game_list_widget);
updateEmulationActions(false, false, false);
updateDisplayRelatedActions(false, false, false);
@@ -292,6 +255,216 @@ void MainWindow::setupAdditionalUi()
#endif
}
void MainWindow::setupStatusBarWidgets()
{
const bool status_bar_visible = Host::GetBaseBoolSettingValue("UI", "ShowStatusBar", true);
m_ui.actionViewStatusBar->setChecked(status_bar_visible);
m_ui.statusBar->setVisible(status_bar_visible);
m_status_progress_widget = new QProgressBar(m_ui.statusBar);
m_status_progress_widget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
m_status_progress_widget->setFixedSize(140, 16);
m_status_progress_widget->setMinimum(0);
m_status_progress_widget->setMaximum(100);
m_status_progress_widget->hide();
m_status_verbose_widget = new QLabel(m_ui.statusBar);
m_status_verbose_widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
m_status_verbose_widget->setContentsMargins(10, 0, 10, 0);
m_status_verbose_widget->setFixedHeight(20);
m_status_verbose_widget->setMinimumWidth(20);
m_status_verbose_widget->hide();
m_status_renderer_widget = new QLabel(m_ui.statusBar);
m_status_renderer_widget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
m_status_renderer_widget->setContentsMargins(10, 0, 10, 0);
m_status_renderer_widget->setAlignment(Qt::AlignCenter);
m_status_renderer_widget->setFixedHeight(20);
m_status_renderer_widget->hide();
m_status_resolution_widget = new QLabel(m_ui.statusBar);
m_status_resolution_widget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
m_status_resolution_widget->setContentsMargins(10, 0, 10, 0);
m_status_resolution_widget->setAlignment(Qt::AlignCenter);
m_status_resolution_widget->setFixedHeight(20);
m_status_resolution_widget->hide();
m_status_volume_widget = new QToolButton(m_ui.statusBar);
m_status_volume_widget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
m_status_volume_widget->setContentsMargins(10, 0, 10, 0);
m_status_volume_widget->setAutoRaise(true);
m_status_volume_widget->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
m_status_volume_widget->setIcon(QIcon::fromTheme(QStringLiteral("volume-up-line")));
m_status_volume_widget->setPopupMode(QToolButton::InstantPopup);
m_status_volume_widget->setFixedHeight(20);
m_status_volume_menu = new QMenu(m_status_volume_widget);
m_status_volume_per_game_action = new QAction(tr("Adjust Per-Game"), m_status_volume_menu);
m_status_volume_per_game_action->setCheckable(true);
connect(m_status_volume_menu, &QMenu::aboutToShow, this, [this]() {
auto lock = Host::GetSettingsLock();
SettingsInterface* game_layer = Host::Internal::GetGameSettingsLayer();
m_status_volume_per_game_action->setEnabled(game_layer != nullptr && QtHost::IsVMValid());
m_status_volume_per_game_action->setChecked(game_layer &&
(game_layer->ContainsValue("SPU2/Output", "StandardVolume") || game_layer->ContainsValue("SPU2/Output", "OutputMuted")));
});
connect(m_status_volume_per_game_action, &QAction::triggered, this, [this](bool checked) {
m_status_volume_slider_applied = true;
applyStatusBarVolumeChanges(std::nullopt, false, checked);
});
m_status_volume_toggle_mute_action = new QAction(tr("Toggle Mute"), m_status_volume_menu);
m_status_volume_toggle_mute_action->setIcon(QIcon::fromTheme(QStringLiteral("volume-mute-line")));
connect(m_status_volume_toggle_mute_action, &QAction::triggered, this, [this]() {
m_status_volume_slider_applied = true;
applyStatusBarVolumeChanges(std::nullopt, true, std::nullopt);
});
m_status_volume_menu->addAction(m_status_volume_per_game_action);
m_status_volume_menu->addAction(m_status_volume_toggle_mute_action);
m_status_volume_menu->addSeparator();
m_status_volume_slider = new QSlider(Qt::Horizontal, m_status_volume_menu);
m_status_volume_slider->setRange(0, 100);
m_status_volume_slider->setFixedWidth(120);
m_status_volume_slider->setValue(Host::GetIntSettingValue("SPU2/Output", "StandardVolume", 100));
connect(m_status_volume_slider, &QSlider::valueChanged, this, [this](int value) {
Host::RunOnCPUThread([value]() {
if (!VMManager::HasValidVM())
return;
EmuConfig.SPU2.StandardVolume = static_cast<u32>(value);
SPU2::SetOutputVolume(static_cast<u32>(value));
});
if (m_status_volume_slider->isSliderDown())
setStatusVolumeText(m_status_volume_muted ? tr("Volume: Muted") : tr("Volume: %1%").arg(value), value, m_status_volume_muted);
});
connect(m_status_volume_slider, &QSlider::sliderReleased, this, [this]() {
m_status_volume_slider_applied = true;
applyStatusBarVolumeChanges(m_status_volume_slider->value(), false);
});
connect(m_status_volume_menu, &QMenu::aboutToHide, this, [this]() {
if (!m_status_volume_slider_applied)
applyStatusBarVolumeChanges(m_status_volume_slider->value(), false);
m_status_volume_slider_applied = false;
});
QWidget* container = new QWidget(m_status_volume_menu);
QHBoxLayout* layout = new QHBoxLayout(container);
layout->setContentsMargins(8, 4, 8, 4);
layout->addWidget(m_status_volume_slider);
QWidgetAction* slider_action = new QWidgetAction(m_status_volume_menu);
slider_action->setDefaultWidget(container);
m_status_volume_menu->addAction(slider_action);
m_status_volume_widget->setMenu(m_status_volume_menu);
m_status_volume_widget->hide();
m_status_speed_widget = new QToolButton(m_ui.statusBar);
m_status_speed_widget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
m_status_speed_widget->setContentsMargins(10, 0, 10, 0);
m_status_speed_widget->setAutoRaise(true);
m_status_speed_widget->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
m_status_speed_widget->setPopupMode(QToolButton::InstantPopup);
m_status_speed_widget->setFixedHeight(20);
m_status_speed_widget->hide();
m_status_speed_menu = new QMenu(m_status_speed_widget);
m_status_speed_menu->addAction(tr("Unlimited"), []() { Host::RunOnCPUThread([]() { VMManager::SetLimiterMode(LimiterModeType::Unlimited); }); });
m_status_speed_menu->addAction(tr("Turbo"), []() { Host::RunOnCPUThread([]() { VMManager::SetLimiterMode(LimiterModeType::Turbo); }); });
m_status_speed_menu->addAction(tr("Slow-Motion"), []() { Host::RunOnCPUThread([]() { VMManager::SetLimiterMode(LimiterModeType::Slomo); }); });
m_status_speed_menu->addAction(tr("Normal"), []() { Host::RunOnCPUThread([]() { VMManager::SetLimiterMode(LimiterModeType::Nominal); }); });
m_status_speed_widget->setMenu(m_status_speed_menu);
m_status_speed_widget->hide();
m_status_gpu_widget = new QLabel(m_ui.statusBar);
m_status_gpu_widget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
m_status_gpu_widget->setContentsMargins(10, 0, 10, 0);
m_status_gpu_widget->setAlignment(Qt::AlignCenter);
m_status_gpu_widget->setFixedHeight(20);
m_status_gpu_widget->hide();
m_status_fps_widget = new QLabel(m_ui.statusBar);
m_status_fps_widget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
m_status_fps_widget->setContentsMargins(10, 0, 10, 0);
m_status_fps_widget->setAlignment(Qt::AlignCenter);
m_status_fps_widget->setFixedHeight(20);
m_status_fps_widget->hide();
m_status_vps_widget = new QLabel(m_ui.statusBar);
m_status_vps_widget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
m_status_vps_widget->setContentsMargins(10, 0, 10, 0);
m_status_vps_widget->setAlignment(Qt::AlignCenter);
m_status_vps_widget->setFixedHeight(20);
m_status_vps_widget->hide();
}
void MainWindow::applyStatusBarVolumeChanges(std::optional<int> volume, bool toggle_mute, std::optional<bool> override_per_game)
{
const bool use_per_game = override_per_game.value_or(m_status_volume_per_game_action->isChecked());
Host::RunOnCPUThread([this, volume, toggle_mute, use_per_game]() {
int target_vol = 100;
bool target_mute = false;
{
auto lock = Host::GetSettingsLock();
SettingsInterface* per_game_settings = Host::Internal::GetGameSettingsLayer();
SettingsInterface* global_settings = Host::Internal::GetBaseSettingsLayer();
SettingsInterface* active_setting = (use_per_game && per_game_settings) ? per_game_settings : global_settings;
if (active_setting)
{
if (!active_setting->GetIntValue("SPU2/Output", "StandardVolume", &target_vol) && global_settings)
global_settings->GetIntValue("SPU2/Output", "StandardVolume", &target_vol);
if (!active_setting->GetBoolValue("SPU2/Output", "OutputMuted", &target_mute) && global_settings)
global_settings->GetBoolValue("SPU2/Output", "OutputMuted", &target_mute);
}
target_vol = volume.value_or(target_vol);
if (toggle_mute)
target_mute = !(VMManager::HasValidVM() ? SPU2::IsOutputMuted() : target_mute);
if (active_setting)
{
active_setting->SetIntValue("SPU2/Output", "StandardVolume", target_vol);
active_setting->SetBoolValue("SPU2/Output", "OutputMuted", target_mute);
}
if (per_game_settings && active_setting == per_game_settings)
QtHost::SaveGameSettings(per_game_settings, true);
else
{
if (per_game_settings)
{
const bool had_per_game_volume =
per_game_settings->ContainsValue("SPU2/Output", "StandardVolume") ||
per_game_settings->ContainsValue("SPU2/Output", "OutputMuted");
per_game_settings->DeleteValue("SPU2/Output", "StandardVolume");
per_game_settings->DeleteValue("SPU2/Output", "OutputMuted");
if (had_per_game_volume)
QtHost::SaveGameSettings(per_game_settings, true);
}
Host::CommitBaseSettingChanges();
}
}
if (VMManager::HasValidVM())
{
EmuConfig.SPU2.StandardVolume = static_cast<u32>(target_vol);
EmuConfig.SPU2.OutputMuted = target_mute;
SPU2::SetOutputMuted(target_mute);
SPU2::SetOutputVolume(static_cast<u32>(target_vol));
}
QTimer::singleShot(0, this, [this, target_vol, target_mute]() {
setStatusVolumeText(target_mute ? tr("Volume: Muted") : tr("Volume: %1%").arg(target_vol), target_vol, target_mute);
});
});
}
void MainWindow::connectSignals()
{
connect(m_ui.actionStartFile, &QAction::triggered, this, &MainWindow::onStartFileActionTriggered);
@@ -496,12 +669,11 @@ void MainWindow::createRendererSwitchMenu()
QString::fromUtf8(Pcsx2Config::GSOptions::GetRendererName(renderer)), switch_renderer_group);
action->setCheckable(true);
action->setChecked(current_renderer == renderer);
connect(action,
&QAction::triggered, [renderer] {
Host::SetBaseIntSettingValue("EmuCore/GS", "Renderer", static_cast<int>(renderer));
Host::CommitBaseSettingChanges();
g_emu_thread->applySettings();
});
connect(action, &QAction::triggered, [renderer] {
Host::SetBaseIntSettingValue("EmuCore/GS", "Renderer", static_cast<int>(renderer));
Host::CommitBaseSettingChanges();
g_emu_thread->applySettings();
});
}
m_ui.menuDebugSwitchRenderer->addActions(switch_renderer_group->actions());
@@ -1019,13 +1191,15 @@ void MainWindow::updateDisplayRelatedActions(bool has_surface, bool render_to_ma
void MainWindow::updateStatusBarWidgetVisibility()
{
auto Update = [this](QWidget* widget, bool visible, int stretch) {
if (widget->isVisible() == visible)
return;
if (widget->isVisible())
{
m_ui.statusBar->removeWidget(widget);
widget->hide();
}
if (visible)
else
{
m_ui.statusBar->addPermanentWidget(widget, stretch);
widget->show();
@@ -1035,9 +1209,63 @@ void MainWindow::updateStatusBarWidgetVisibility()
Update(m_status_verbose_widget, s_vm_valid, 1);
Update(m_status_renderer_widget, s_vm_valid, 0);
Update(m_status_resolution_widget, s_vm_valid, 0);
Update(m_status_gpu_widget, s_vm_valid, 0);
Update(m_status_fps_widget, s_vm_valid, 0);
Update(m_status_vps_widget, s_vm_valid, 0);
Update(m_status_speed_widget, s_vm_valid, 0);
Update(m_status_volume_widget, s_vm_valid, 0);
}
void MainWindow::setStatusVerboseText(const QString& text)
{
m_status_verbose_widget->setText(text);
}
void MainWindow::setStatusRendererText(const QString& text)
{
m_status_renderer_widget->setText(text);
}
void MainWindow::setStatusResolutionText(const QString& text)
{
m_status_resolution_widget->setText(text);
}
void MainWindow::setStatusVolumeText(const QString& text, int volume, bool muted)
{
m_status_volume_widget->setText(text);
if (muted != m_status_volume_muted)
{
m_status_volume_muted = muted;
m_status_volume_widget->setIcon(QIcon::fromTheme(muted ? QStringLiteral("volume-mute-line") : QStringLiteral("volume-up-line")));
m_status_volume_toggle_mute_action->setIcon(QIcon::fromTheme(muted ? QStringLiteral("volume-up-line") : QStringLiteral("volume-mute-line")));
}
if (!muted && !m_status_volume_slider->isSliderDown())
{
QSignalBlocker blocker(m_status_volume_slider);
m_status_volume_slider->setValue(volume);
}
}
void MainWindow::setStatusGPUText(const QString& text)
{
m_status_gpu_widget->setText(text);
}
void MainWindow::setStatusFPSText(const QString& text)
{
m_status_fps_widget->setText(text);
}
void MainWindow::setStatusVPSText(const QString& text)
{
m_status_vps_widget->setText(text);
}
void MainWindow::setStatusSpeedText(const QString& text)
{
m_status_speed_widget->setText(text);
}
void MainWindow::updateWindowTitle()
@@ -2218,6 +2446,8 @@ void MainWindow::onVMStopped()
m_last_fps_status = empty_string;
m_status_renderer_widget->setText(empty_string);
m_status_resolution_widget->setText(empty_string);
m_status_volume_widget->setText(empty_string);
m_status_gpu_widget->setText(empty_string);
m_status_fps_widget->setText(empty_string);
m_status_vps_widget->setText(empty_string);
m_status_speed_widget->setText(empty_string);
+26 -2
View File
@@ -8,6 +8,8 @@
#include <QtWidgets/QLabel>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QMenu>
#include <QtWidgets/QSlider>
#include <QtWidgets/QToolButton>
#include <functional>
#include <optional>
@@ -96,11 +98,13 @@ public:
/// Accessors for the status bar widgets, updated by the emulation thread.
__fi QLabel* getStatusVerboseWidget() const { return m_status_verbose_widget; }
__fi QToolButton* getStatusSpeedWidget() const { return m_status_speed_widget; }
__fi QToolButton* getStatusVolumeWidget() const { return m_status_volume_widget; }
__fi QLabel* getStatusRendererWidget() const { return m_status_renderer_widget; }
__fi QLabel* getStatusResolutionWidget() const { return m_status_resolution_widget; }
__fi QLabel* getStatusGPUWidget() const { return m_status_gpu_widget; }
__fi QLabel* getStatusFPSWidget() const { return m_status_fps_widget; }
__fi QLabel* getStatusVPSWidget() const { return m_status_vps_widget; }
__fi QLabel* getStatusSpeedWidget() const { return m_status_speed_widget; }
/// Rescans a single file. NOTE: Happens on UI thread.
void rescanFile(const std::string& path);
@@ -125,6 +129,15 @@ public Q_SLOTS:
void reportStateLoadError(const QString& message, std::optional<s32> slot, bool backup);
void reportStateSaveError(const QString& message, std::optional<s32> slot);
void setStatusVerboseText(const QString& text);
void setStatusRendererText(const QString& text);
void setStatusResolutionText(const QString& text);
void setStatusVolumeText(const QString& text, int volume, bool muted);
void setStatusGPUText(const QString& text);
void setStatusFPSText(const QString& text);
void setStatusVPSText(const QString& text);
void setStatusSpeedText(const QString& text);
void runOnUIThread(const std::function<void()>& func);
void requestReset();
bool requestShutdown(bool allow_confirm = true, bool allow_save_to_state = true, bool default_save_to_state = true);
@@ -227,6 +240,8 @@ protected:
private:
void setupAdditionalUi();
void setupStatusBarWidgets();
void applyStatusBarVolumeChanges(std::optional<int> volume, bool toggle_mute, std::optional<bool> override_per_game = std::nullopt);
void connectSignals();
void createRendererSwitchMenu();
void recreate();
@@ -309,14 +324,23 @@ private:
QProgressBar* m_status_progress_widget = nullptr;
QLabel* m_status_verbose_widget = nullptr;
QLabel* m_status_renderer_widget = nullptr;
QToolButton* m_status_volume_widget = nullptr;
QMenu* m_status_volume_menu = nullptr;
QAction* m_status_volume_per_game_action = nullptr;
QAction* m_status_volume_toggle_mute_action = nullptr;
QSlider* m_status_volume_slider = nullptr;
QLabel* m_status_gpu_widget = nullptr;
QLabel* m_status_fps_widget = nullptr;
QLabel* m_status_vps_widget = nullptr;
QLabel* m_status_speed_widget = nullptr;
QToolButton* m_status_speed_widget = nullptr;
QMenu* m_status_speed_menu = nullptr;
QLabel* m_status_resolution_widget = nullptr;
QMenu* m_settings_toolbar_menu = nullptr;
bool m_display_created = false;
bool m_status_volume_muted = false;
bool m_status_volume_slider_applied = false;
bool m_display_is_exclusive_fullscreen = false;
bool m_relative_mouse_mode = false;
bool m_hide_mouse_cursor = false;
+89 -31
View File
@@ -433,10 +433,16 @@ void EmuThread::run()
void EmuThread::destroyVM()
{
m_last_speed = 0.0f;
m_last_gpu_usage = 0.0f;
m_last_game_fps = 0.0f;
m_last_video_fps = 0.0f;
m_last_internal_width = 0;
m_last_internal_height = 0;
m_last_upscale = 0.0f;
m_last_volume = 0;
m_last_muted = false;
m_last_renderer = GSRendererType::Auto;
m_last_limiter_mode = LimiterModeType::Nominal;
m_was_paused_by_focus_loss = false;
VMManager::Shutdown(m_save_state_on_shutdown);
m_save_state_on_shutdown = false;
@@ -970,8 +976,15 @@ void EmuThread::updatePerformanceMetrics(bool force)
if (!g_main_window)
return;
const s32 slot = SaveStateSelectorUI::GetCurrentSlot();
u32 volume = 0;
bool muted = false;
if (VMManager::HasValidVM())
{
volume = SPU2::GetOutputVolume();
muted = SPU2::IsOutputMuted();
QString gs_stat;
if (m_verbose_status)
{
@@ -980,58 +993,90 @@ void EmuThread::updatePerformanceMetrics(bool force)
if (THREAD_VU1)
{
gs_stat = tr("Slot: %1 | Volume: %2% | %3 | EE: %4% | VU: %5% | GS: %6%")
.arg(SaveStateSelectorUI::GetCurrentSlot())
.arg(SPU2::GetOutputVolume())
.arg(gs_stat_str.c_str())
.arg(PerformanceMetrics::GetCPUThreadUsage(), 0, 'f', 0)
.arg(PerformanceMetrics::GetVUThreadUsage(), 0, 'f', 0)
.arg(PerformanceMetrics::GetGSThreadUsage(), 0, 'f', 0);
gs_stat = tr("Slot: %1 | %2 | EE: %3% | VU: %4% | GS: %5%")
.arg(slot)
.arg(gs_stat_str.c_str())
.arg(PerformanceMetrics::GetCPUThreadUsage(), 0, 'f', 0)
.arg(PerformanceMetrics::GetVUThreadUsage(), 0, 'f', 0)
.arg(PerformanceMetrics::GetGSThreadUsage(), 0, 'f', 0);
}
else
{
gs_stat = tr("Slot: %1 | Volume: %2% | %3 | EE: %4% | GS: %5%")
.arg(SaveStateSelectorUI::GetCurrentSlot())
.arg(SPU2::GetOutputVolume())
.arg(gs_stat_str.c_str())
.arg(PerformanceMetrics::GetCPUThreadUsage(), 0, 'f', 0)
.arg(PerformanceMetrics::GetGSThreadUsage(), 0, 'f', 0);
gs_stat = tr("Slot: %1 | %2 | EE: %3% | GS: %4%")
.arg(slot)
.arg(gs_stat_str.c_str())
.arg(PerformanceMetrics::GetCPUThreadUsage(), 0, 'f', 0)
.arg(PerformanceMetrics::GetGSThreadUsage(), 0, 'f', 0);
}
}
QMetaObject::invokeMethod(g_main_window->getStatusVerboseWidget(), "setText", Qt::QueuedConnection, Q_ARG(const QString&, gs_stat));
QMetaObject::invokeMethod(g_main_window, "setStatusVerboseText", Qt::QueuedConnection, Q_ARG(const QString&, gs_stat));
}
const GSRendererType renderer = GSGetCurrentRenderer(); // Reading from GS thread, therefore racey, but it's just visual.
const float upscale = EmuConfig.GS.UpscaleMultiplier;
const float speed = std::round(PerformanceMetrics::GetSpeed());
const LimiterModeType limiter_mode = VMManager::GetLimiterMode();
const float gpu_usage = std::round(PerformanceMetrics::GetGPUUsage());
const float gfps = std::round(PerformanceMetrics::GetInternalFPS());
const float vfps = std::round(PerformanceMetrics::GetFPS());
int iwidth, iheight;
GSgetInternalResolution(&iwidth, &iheight);
if (iwidth != m_last_internal_width || iheight != m_last_internal_height || speed != m_last_speed || gfps != m_last_game_fps ||
vfps != m_last_video_fps || renderer != m_last_renderer || force)
if (iwidth != m_last_internal_width || iheight != m_last_internal_height || upscale != m_last_upscale ||
speed != m_last_speed || gpu_usage != m_last_gpu_usage || gfps != m_last_game_fps || vfps != m_last_video_fps || renderer != m_last_renderer ||
volume != m_last_volume || muted != m_last_muted || force)
{
if (volume != m_last_volume || muted != m_last_muted || force)
{
QString vol_text = tr("Volume: %1%").arg(volume);
if (muted)
vol_text = tr("Volume: Muted");
QMetaObject::invokeMethod(g_main_window, "setStatusVolumeText", Qt::QueuedConnection,
Q_ARG(const QString&, vol_text), Q_ARG(int, static_cast<int>(volume)), Q_ARG(bool, muted));
m_last_volume = volume;
m_last_muted = muted;
}
if (renderer != m_last_renderer || force)
{
QMetaObject::invokeMethod(g_main_window->getStatusRendererWidget(), "setText", Qt::QueuedConnection,
Q_ARG(const QString&, QString::fromUtf8(Pcsx2Config::GSOptions::GetRendererName(renderer))));
QString renderer_name = QString::fromUtf8(Pcsx2Config::GSOptions::GetRendererName(renderer));
if (EmuConfig.GS.Renderer == GSRendererType::Auto && renderer != GSRendererType::Auto)
renderer_name = tr("Auto (%1)").arg(renderer_name);
QMetaObject::invokeMethod(g_main_window, "setStatusRendererText", Qt::QueuedConnection,
Q_ARG(const QString&, renderer_name));
m_last_renderer = renderer;
}
if (iwidth != m_last_internal_width || iheight != m_last_internal_height || force)
if (iwidth != m_last_internal_width || iheight != m_last_internal_height || upscale != m_last_upscale || force)
{
QString text;
if (iwidth == 0 || iheight == 0)
text = tr("No Image");
else
text = tr("%1x%2").arg(iwidth).arg(iheight);
text = tr("%1x%2 (%3x)").arg(iwidth).arg(iheight).arg(upscale, 0, 'g', 3);
QMetaObject::invokeMethod(
g_main_window->getStatusResolutionWidget(), "setText", Qt::QueuedConnection, Q_ARG(const QString&, text));
g_main_window, "setStatusResolutionText", Qt::QueuedConnection, Q_ARG(const QString&, text));
m_last_internal_width = iwidth;
m_last_internal_height = iheight;
m_last_upscale = upscale;
}
if (gpu_usage != m_last_gpu_usage || force)
{
QString text;
if (gpu_usage == 0)
text = tr("GPU: N/A");
else
text = tr("GPU: %1%").arg(gpu_usage, 0, 'f', 0);
QMetaObject::invokeMethod(g_main_window, "setStatusGPUText", Qt::QueuedConnection,
Q_ARG(const QString&, text));
m_last_gpu_usage = gpu_usage;
}
if (gfps != m_last_game_fps || force)
@@ -1042,24 +1087,37 @@ void EmuThread::updatePerformanceMetrics(bool force)
else
text = tr("FPS: %1").arg(gfps, 0, 'f', 0);
QMetaObject::invokeMethod(g_main_window->getStatusFPSWidget(), "setText", Qt::QueuedConnection,
QMetaObject::invokeMethod(g_main_window, "setStatusFPSText", Qt::QueuedConnection,
Q_ARG(const QString&, text));
m_last_game_fps = gfps;
}
if (vfps != m_last_video_fps || force)
{
QMetaObject::invokeMethod(g_main_window->getStatusVPSWidget(), "setText", Qt::QueuedConnection,
Q_ARG(const QString&, tr("VPS: %1 ").arg(vfps, 0, 'f', 0)));
QMetaObject::invokeMethod(g_main_window, "setStatusVPSText", Qt::QueuedConnection,
Q_ARG(const QString&, vfps == 0 ? tr("VPS: N/A") : tr("VPS: %1").arg(vfps, 0, 'f', 0)));
m_last_video_fps = vfps;
if (speed != m_last_speed || force)
{
QMetaObject::invokeMethod(g_main_window->getStatusSpeedWidget(), "setText", Qt::QueuedConnection,
Q_ARG(const QString&, tr("Speed: %1% ").arg(speed, 0, 'f', 0)));
m_last_speed = speed;
}
}
if (speed != m_last_speed || force)
{
QMetaObject::invokeMethod(g_main_window, "setStatusSpeedText", Qt::QueuedConnection,
Q_ARG(const QString&, tr("Speed: %1%").arg(speed, 0, 'f', 0)));
m_last_speed = speed;
}
if (limiter_mode != m_last_limiter_mode || force)
{
QMetaObject::invokeMethod(g_main_window, [limiter_mode]() {
g_main_window->getStatusSpeedWidget()->setIcon(QIcon::fromTheme(
limiter_mode == LimiterModeType::Turbo ? QStringLiteral("fast-forward-line") :
limiter_mode == LimiterModeType::Slomo ? QStringLiteral("slow-mo") :
limiter_mode == LimiterModeType::Unlimited ? QStringLiteral("speed-line") :
QStringLiteral("dashboard-line")));
}, Qt::QueuedConnection);
m_last_limiter_mode = limiter_mode;
}
}
}
+5
View File
@@ -212,11 +212,16 @@ private:
bool m_was_paused_by_focus_loss = false;
float m_last_speed = 0.0f;
float m_last_gpu_usage = 0.0f;
float m_last_game_fps = 0.0f;
float m_last_video_fps = 0.0f;
int m_last_internal_width = 0;
int m_last_internal_height = 0;
float m_last_upscale = 0.0f;
u32 m_last_volume = 0;
bool m_last_muted = false;
GSRendererType m_last_renderer = GSRendererType::Auto;
LimiterModeType m_last_limiter_mode = LimiterModeType::Nominal;
};
extern EmuThread* g_emu_thread;
@@ -0,0 +1 @@
<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="m12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10-10-4.477-10-10 4.477-10 10-10m0 2a8 8 0 1 0 0 16 8 8 0 0 0 0-16m3.833 3.337a.596.596 0 0 1 .763.067.59.59 0 0 1 .063.76q-3.27 4.569-3.598 4.897a1.5 1.5 0 0 1 -2.122-2.122q.56-.56 4.894-3.602m1.667 3.663a1 1 0 1 1 0 2 1 1 0 0 1 0-2m-11 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2m2.318-3.596a1 1 0 1 1 -1.414 1.414 1 1 0 0 1 1.414-1.414m3.182-1.904a1 1 0 1 1 0 2 1 1 0 0 1 0-2"/></svg>

After

Width:  |  Height:  |  Size: 507 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M22 4a1 1 0 0 0-1 1v5.666l-9.223-6.148a.5.5 0 0 0-.777.416v5.732L1.777 4.518A.5.5 0 0 0 1 4.934v14.132a.5.5 0 0 0 .777.416L11 13.333v5.733a.5.5 0 0 0 .777.416L21 13.333V19a1 1 0 1 0 2 0V5a1 1 0 0 0-1-1M3 7.737L9.394 12L3 16.263zm10 8.526V7.737L19.394 12z" />
</svg>

After

Width:  |  Height:  |  Size: 360 B

@@ -0,0 +1 @@
<svg height="512" viewBox="0 0 512 512" width="512" xmlns="http://www.w3.org/2000/svg"><g fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round"><path d="m158.61169 32.411431 327.37685 189.011119-327.37685 189.01111z" stroke-width="43.2072" transform="matrix(.75450544 0 0 .77725456 100.32662 82.344678)"/><path d="m106.51372 100v309.27423" stroke-width="76.6719"/></g></svg>

After

Width:  |  Height:  |  Size: 393 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="m12 13.333l-9.223 6.149A.5.5 0 0 1 2 19.066V4.934a.5.5 0 0 1 .777-.416L12 10.667V4.934a.5.5 0 0 1 .777-.416l10.599 7.066a.5.5 0 0 1 0 .832l-10.599 7.066a.5.5 0 0 1-.777-.416zM10.394 12L4 7.737v8.526zM14 7.737v8.526L20.394 12z" />
</svg>

After

Width:  |  Height:  |  Size: 331 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M10 7.22L6.603 10H3v4h3.603L10 16.78zM5.889 16H2a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1h3.889l5.294-4.332a.5.5 0 0 1 .817.387v15.89a.5.5 0 0 1-.817.387zm14.525-4l3.536 3.536l-1.415 1.414L19 13.414l-3.536 3.536l-1.414-1.414L17.586 12L14.05 8.465l1.414-1.415L19 10.586l3.535-3.536l1.415 1.415z"/></svg>

After

Width:  |  Height:  |  Size: 403 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path fill="#fff" d="M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12S6.477 2 12 2m0 2a8 8 0 1 0 0 16a8 8 0 0 0 0-16m3.833 3.337a.596.596 0 0 1 .763.067a.59.59 0 0 1 .063.76q-3.27 4.569-3.598 4.897a1.5 1.5 0 0 1-2.122-2.122q.56-.56 4.894-3.602M17.5 11a1 1 0 1 1 0 2a1 1 0 0 1 0-2m-11 0a1 1 0 1 1 0 2a1 1 0 0 1 0-2m2.318-3.596a1 1 0 1 1-1.414 1.414a1 1 0 0 1 1.414-1.414M12 5.5a1 1 0 1 1 0 2a1 1 0 0 1 0-2" />
</svg>

After

Width:  |  Height:  |  Size: 510 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path fill="#fff" d="M22 4a1 1 0 0 0-1 1v5.666l-9.223-6.148a.5.5 0 0 0-.777.416v5.732L1.777 4.518A.5.5 0 0 0 1 4.934v14.132a.5.5 0 0 0 .777.416L11 13.333v5.733a.5.5 0 0 0 .777.416L21 13.333V19a1 1 0 1 0 2 0V5a1 1 0 0 0-1-1M3 7.737L9.394 12L3 16.263zm10 8.526V7.737L19.394 12z" />
</svg>

After

Width:  |  Height:  |  Size: 372 B

@@ -0,0 +1 @@
<svg height="512" viewBox="0 0 512 512" width="512" xmlns="http://www.w3.org/2000/svg"><g fill="none" stroke="#fff" stroke-linecap="round" stroke-linejoin="round"><path d="m158.61169 32.411431 327.37685 189.011119-327.37685 189.01111z" stroke-width="43.2072" transform="matrix(.75450544 0 0 .77725456 100.32662 82.344678)"/><path d="m106.51372 100v309.27423" stroke-width="76.6719"/></g></svg>

After

Width:  |  Height:  |  Size: 393 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path fill="#fff" d="m12 13.333l-9.223 6.149A.5.5 0 0 1 2 19.066V4.934a.5.5 0 0 1 .777-.416L12 10.667V4.934a.5.5 0 0 1 .777-.416l10.599 7.066a.5.5 0 0 1 0 .832l-10.599 7.066a.5.5 0 0 1-.777-.416zM10.394 12L4 7.737v8.526zM14 7.737v8.526L20.394 12z" />
</svg>

After

Width:  |  Height:  |  Size: 343 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="#fff" d="M10 7.22L6.603 10H3v4h3.603L10 16.78zM5.889 16H2a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1h3.889l5.294-4.332a.5.5 0 0 1 .817.387v15.89a.5.5 0 0 1-.817.387zm14.525-4l3.536 3.536l-1.415 1.414L19 13.414l-3.536 3.536l-1.414-1.414L17.586 12L14.05 8.465l1.414-1.415L19 10.586l3.535-3.536l1.415 1.415z"/></svg>

After

Width:  |  Height:  |  Size: 395 B

+10
View File
@@ -18,6 +18,7 @@
<file>icons/black/svg/close-line.svg</file>
<file>icons/black/svg/controller-line.svg</file>
<file>icons/black/svg/controller-strike-line.svg</file>
<file>icons/black/svg/dashboard-line.svg</file>
<file>icons/black/svg/debug-step-into-line.svg</file>
<file>icons/black/svg/debug-step-out-line.svg</file>
<file>icons/black/svg/debug-step-over-line.svg</file>
@@ -32,6 +33,7 @@
<file>icons/black/svg/eject-line.svg</file>
<file>icons/black/svg/emulation-line.svg</file>
<file>icons/black/svg/eyetoy-line.svg</file>
<file>icons/black/svg/fast-forward-line.svg</file>
<file>icons/black/svg/file-add-line.svg</file>
<file>icons/black/svg/file-line.svg</file>
<file>icons/black/svg/file-list-line.svg</file>
@@ -90,6 +92,8 @@
<file>icons/black/svg/settings-3-line.svg</file>
<file>icons/black/svg/shut-down-line.svg</file>
<file>icons/black/svg/singstar-line.svg</file>
<file>icons/black/svg/slow-mo.svg</file>
<file>icons/black/svg/speed-line.svg</file>
<file>icons/black/svg/tools-line.svg</file>
<file>icons/black/svg/train-line.svg</file>
<file>icons/black/svg/trance-vibrator-line.svg</file>
@@ -97,6 +101,7 @@
<file>icons/black/svg/trophy-line.svg</file>
<file>icons/black/svg/tv-2-line.svg</file>
<file>icons/black/svg/usb-fill.svg</file>
<file>icons/black/svg/volume-mute-line.svg</file>
<file>icons/black/svg/volume-up-line.svg</file>
<file>icons/black/svg/warning-line.svg</file>
<file>icons/black/svg/wheel-line.svg</file>
@@ -123,6 +128,7 @@
<file>icons/white/svg/close-line.svg</file>
<file>icons/white/svg/controller-line.svg</file>
<file>icons/white/svg/controller-strike-line.svg</file>
<file>icons/white/svg/dashboard-line.svg</file>
<file>icons/white/svg/debug-step-into-line.svg</file>
<file>icons/white/svg/debug-step-out-line.svg</file>
<file>icons/white/svg/debug-step-over-line.svg</file>
@@ -137,6 +143,7 @@
<file>icons/white/svg/eject-line.svg</file>
<file>icons/white/svg/emulation-line.svg</file>
<file>icons/white/svg/eyetoy-line.svg</file>
<file>icons/white/svg/fast-forward-line.svg</file>
<file>icons/white/svg/file-add-line.svg</file>
<file>icons/white/svg/file-line.svg</file>
<file>icons/white/svg/file-list-line.svg</file>
@@ -198,6 +205,8 @@
<file>icons/white/svg/settings-3-line.svg</file>
<file>icons/white/svg/shut-down-line.svg</file>
<file>icons/white/svg/singstar-line.svg</file>
<file>icons/white/svg/slow-mo.svg</file>
<file>icons/white/svg/speed-line.svg</file>
<file>icons/white/svg/tools-line.svg</file>
<file>icons/white/svg/train-line.svg</file>
<file>icons/white/svg/trance-vibrator-line.svg</file>
@@ -205,6 +214,7 @@
<file>icons/white/svg/trophy-line.svg</file>
<file>icons/white/svg/tv-2-line.svg</file>
<file>icons/white/svg/usb-fill.svg</file>
<file>icons/white/svg/volume-mute-line.svg</file>
<file>icons/white/svg/volume-up-line.svg</file>
<file>icons/white/svg/warning-line.svg</file>
<file>icons/white/svg/wheel-line.svg</file>