From 25876bbeb8c43deaa46f7f9e664ee5150d3a0579 Mon Sep 17 00:00:00 2001 From: Dmugetsu Date: Mon, 10 Mar 2025 20:11:29 -0600 Subject: [PATCH] Suggestions / Fixes - Pause and FullScreen Buttons --- src/common/config.cpp | 12 +++ src/common/config.h | 2 + src/images/fullscreen_icon.png | Bin 0 -> 1996 bytes src/images/refresh_icon.png | Bin 3381 -> 3935 bytes src/qt_gui/main_window.cpp | 139 ++++++++++++++++++++++++++------- src/qt_gui/main_window.h | 6 ++ src/qt_gui/main_window_ui.h | 19 ++++- src/sdl_window.cpp | 30 +++++-- src/sdl_window.h | 3 + src/shadps4.qrc | 1 + 10 files changed, 175 insertions(+), 37 deletions(-) create mode 100644 src/images/fullscreen_icon.png diff --git a/src/common/config.cpp b/src/common/config.cpp index 16d9e5724..5c6cc944c 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -107,6 +107,7 @@ static bool showBackgroundImage = true; static bool isFullscreen = false; static std::string fullscreenMode = "Windowed"; static bool isHDRAllowed = false; +static bool showLabelsUnderIcons = true; // Language u32 m_language = 1; // english @@ -176,6 +177,14 @@ bool getIsFullscreen() { return isFullscreen; } +bool getShowLabelsUnderIcons() { + return showLabelsUnderIcons; +} + +bool setShowLabelsUnderIcons() { + return false; +} + std::string getFullscreenMode() { return fullscreenMode; } @@ -427,6 +436,9 @@ void setVblankDiv(u32 value) { void setIsFullscreen(bool enable) { isFullscreen = enable; } +void setShowLabelsUnderIcons(bool enable) { + showLabelsUnderIcons = enable; +} void setFullscreenMode(std::string mode) { fullscreenMode = mode; diff --git a/src/common/config.h b/src/common/config.h index 1025e9956..3a0bf252c 100644 --- a/src/common/config.h +++ b/src/common/config.h @@ -26,6 +26,8 @@ bool GetLoadGameSizeEnabled(); std::filesystem::path GetSaveDataPath(); void setLoadGameSizeEnabled(bool enable); bool getIsFullscreen(); +bool getShowLabelsUnderIcons(); +bool setShowLabelsUnderIcons(); std::string getFullscreenMode(); bool isNeoModeConsole(); bool isDevKitConsole(); diff --git a/src/images/fullscreen_icon.png b/src/images/fullscreen_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..327a30df58cf5daacc2a76ab5005d00fc8b86d0d GIT binary patch literal 1996 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 delta 3378 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 IM6N<$f^6(cmH+?% diff --git a/src/qt_gui/main_window.cpp b/src/qt_gui/main_window.cpp index caed3c3c5..a26953752 100644 --- a/src/qt_gui/main_window.cpp +++ b/src/qt_gui/main_window.cpp @@ -1,6 +1,8 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "SDL3/SDL_events.h" + #include #include #include @@ -132,41 +134,118 @@ void MainWindow::CreateActions() { m_theme_act_group->addAction(ui->setThemeOled); } -void MainWindow::AddUiWidgets() { - // add toolbar widgets +void MainWindow::PauseGame() { + SDL_Event event; + SDL_memset(&event, 0, sizeof(event)); + event.type = SDL_EVENT_TOGGLE_PAUSE; + SDL_PushEvent(&event); +} +void MainWindow::toggleLabelsUnderIcons() { + bool showLabels = ui->toggleLabelsAct->isChecked(); + Config::setShowLabelsUnderIcons(); + UpdateToolbarLabels(); +} + +void MainWindow::toggleFullscreen() { + SDL_Event event; + SDL_memset(&event, 0, sizeof(event)); + event.type = SDL_EVENT_TOGGLE_FULLSCREEN; + + SDL_PushEvent(&event); + + SDL_Event check_event; + while (SDL_PollEvent(&check_event)) { + SDL_PushEvent(&check_event); + } +} + +void MainWindow::AddUiWidgets() { + // Add toolbar widgets QApplication::setStyle("Fusion"); ui->toolBar->setObjectName("mw_toolbar"); - // Detect background color - QColor bgColor = palette().color(QPalette::Window); - QString textColor = (bgColor.lightness() > 128) ? "#000" : "#fff"; + ui->toolBar->clear(); - ui->playButton->setToolTip( - QString("Play").arg(textColor)); - ui->pauseButton->setToolTip( - QString("Pause").arg(textColor)); - ui->stopButton->setToolTip( - QString("Stop").arg(textColor)); - ui->settingsButton->setToolTip( - QString("Config").arg(textColor)); - ui->controllerButton->setToolTip( - QString("Pads").arg(textColor)); - ui->keyboardButton->setToolTip( - QString("KBM").arg(textColor)); - ui->refreshButton->setToolTip( - QString("RefreshList").arg(textColor)); + QWidget* toolbarContainer = new QWidget(this); + QHBoxLayout* mainLayout = new QHBoxLayout(toolbarContainer); + mainLayout->setContentsMargins(5, 5, 5, 5); + mainLayout->setSpacing(15); - ui->toolBar->addWidget(ui->playButton); - ui->toolBar->addWidget(ui->pauseButton); - ui->toolBar->addWidget(ui->stopButton); - ui->toolBar->addWidget(ui->settingsButton); - ui->toolBar->addWidget(ui->controllerButton); - ui->toolBar->addWidget(ui->keyboardButton); - ui->toolBar->addWidget(ui->refreshButton); + bool showLabels = ui->toggleLabelsAct->isChecked(); - ui->toolBar->addWidget(ui->sizeSliderContainer); - ui->toolBar->addWidget(ui->mw_searchbar); + auto createButtonWithLabel = [&](QPushButton* button, const QString& labelText) { + QWidget* container = new QWidget(this); + QVBoxLayout* layout = new QVBoxLayout(container); + layout->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); + layout->setContentsMargins(0, 0, 0, 0); + + layout->addWidget(button); + + if (ui->toggleLabelsAct->isChecked()) { + QLabel* label = new QLabel(labelText, this); + label->setAlignment(Qt::AlignCenter); + layout->addWidget(label); + } else { + + button->setToolTip( + QString("%2") + .arg(palette().color(QPalette::Window).lightness() > 128 ? "#000" : "#000", + labelText)); + } + + container->setLayout(layout); + return container; + }; + + QWidget* buttonGroup = new QWidget(this); + QHBoxLayout* buttonLayout = new QHBoxLayout(buttonGroup); + + auto createLine = [this]() { + QFrame* line = new QFrame(this); + line->setFrameShape(QFrame::VLine); + line->setFrameShadow(QFrame::Sunken); + line->setFixedWidth(2); + return line; + }; + + buttonLayout->setContentsMargins(0, 0, 0, 0); + buttonLayout->setSpacing(15); + + buttonLayout->addWidget(createButtonWithLabel(ui->playButton, tr("Play"))); + buttonLayout->addWidget(createButtonWithLabel(ui->pauseButton, tr("Pause"))); + buttonLayout->addWidget(createButtonWithLabel(ui->stopButton, tr("Stop"))); + buttonLayout->addWidget(createLine()); + + buttonLayout->addWidget(createButtonWithLabel(ui->settingsButton, tr("Settings"))); + buttonLayout->addWidget(createButtonWithLabel(ui->fullscreenButton, tr("Full Screen"))); + buttonLayout->addWidget(createLine()); + + buttonLayout->addWidget(createButtonWithLabel(ui->controllerButton, tr("Controllers"))); + buttonLayout->addWidget(createButtonWithLabel(ui->keyboardButton, tr("Keyboard"))); + buttonLayout->addWidget(createButtonWithLabel(ui->refreshButton, tr("Refresh List"))); + buttonLayout->addWidget(createLine()); + + QWidget* searchSliderContainer = new QWidget(this); + QHBoxLayout* searchSliderLayout = new QHBoxLayout(searchSliderContainer); + searchSliderLayout->setContentsMargins(0, 0, 0, 0); + searchSliderLayout->setSpacing(10); + + searchSliderLayout->addWidget(ui->sizeSliderContainer); + + searchSliderLayout->addWidget(ui->mw_searchbar); + + searchSliderContainer->setLayout(searchSliderLayout); + + mainLayout->addWidget(buttonGroup); + mainLayout->addWidget(searchSliderContainer); + + toolbarContainer->setLayout(mainLayout); + ui->toolBar->addWidget(toolbarContainer); +} + +void MainWindow::UpdateToolbarLabels() { + AddUiWidgets(); } void MainWindow::CreateDockWindows() { @@ -271,6 +350,8 @@ void MainWindow::CreateConnects() { connect(ui->refreshButton, &QPushButton::clicked, this, &MainWindow::RefreshGameTable); connect(ui->showGameListAct, &QAction::triggered, this, &MainWindow::ShowGameList); connect(this, &MainWindow::ExtractionFinished, this, &MainWindow::RefreshGameTable); + connect(ui->toggleLabelsAct, &QAction::toggled, this, &MainWindow::toggleLabelsUnderIcons); + connect(ui->fullscreenButton, &QPushButton::clicked, this, &MainWindow::toggleFullscreen); connect(ui->sizeSlider, &QSlider::valueChanged, this, [this](int value) { if (isTableList) { @@ -294,6 +375,7 @@ void MainWindow::CreateConnects() { }); connect(ui->playButton, &QPushButton::clicked, this, &MainWindow::StartGame); + connect(ui->pauseButton, &QPushButton::clicked, this, &MainWindow::PauseGame); connect(m_game_grid_frame.get(), &QTableWidget::cellDoubleClicked, this, &MainWindow::StartGame); connect(m_game_list_frame.get(), &QTableWidget::cellDoubleClicked, this, @@ -1236,6 +1318,7 @@ void MainWindow::SetUiIcons(bool isWhite) { ui->stopButton->setIcon(RecolorIcon(ui->stopButton->icon(), isWhite)); ui->refreshButton->setIcon(RecolorIcon(ui->refreshButton->icon(), isWhite)); ui->settingsButton->setIcon(RecolorIcon(ui->settingsButton->icon(), isWhite)); + ui->fullscreenButton->setIcon(RecolorIcon(ui->fullscreenButton->icon(), isWhite)); ui->controllerButton->setIcon(RecolorIcon(ui->controllerButton->icon(), isWhite)); ui->keyboardButton->setIcon(RecolorIcon(ui->keyboardButton->icon(), isWhite)); ui->refreshGameListAct->setIcon(RecolorIcon(ui->refreshGameListAct->icon(), isWhite)); diff --git a/src/qt_gui/main_window.h b/src/qt_gui/main_window.h index 5ac56e44c..54127cb2d 100644 --- a/src/qt_gui/main_window.h +++ b/src/qt_gui/main_window.h @@ -38,6 +38,7 @@ public: void InstallDragDropPkg(std::filesystem::path file, int pkgNum, int nPkg); void InstallDirectory(); void StartGame(); + void PauseGame(); private Q_SLOTS: void ConfigureGuiFromSettings(); @@ -47,15 +48,19 @@ private Q_SLOTS: void RefreshGameTable(); void HandleResize(QResizeEvent* event); void OnLanguageChanged(const std::string& locale); + void toggleLabelsUnderIcons(); private: Ui_MainWindow* ui; void AddUiWidgets(); + void UpdateToolbarLabels(); void CreateActions(); + void toggleFullscreen(); void CreateRecentGameActions(); void CreateDockWindows(); void GetPhysicalDevices(); void LoadGameLists(); + #ifdef ENABLE_UPDATER void CheckUpdateMain(bool checkSave); #endif @@ -70,6 +75,7 @@ private: void PlayBackgroundMusic(); QIcon RecolorIcon(const QIcon& icon, bool isWhite); void StartEmulator(std::filesystem::path); + bool is_paused = false; bool isIconBlack = false; bool isTableList = true; bool isGameRunning = false; diff --git a/src/qt_gui/main_window_ui.h b/src/qt_gui/main_window_ui.h index 246c2afd6..bb16560ad 100644 --- a/src/qt_gui/main_window_ui.h +++ b/src/qt_gui/main_window_ui.h @@ -20,6 +20,7 @@ public: QAction* setIconSizeSmallAct; QAction* setIconSizeMediumAct; QAction* setIconSizeLargeAct; + QAction* toggleLabelsAct; QAction* setlistModeListAct; QAction* setlistModeGridAct; QAction* setlistElfAct; @@ -50,6 +51,7 @@ public: QPushButton* settingsButton; QPushButton* controllerButton; QPushButton* keyboardButton; + QPushButton* fullscreenButton; QWidget* sizeSliderContainer; QHBoxLayout* sizeSliderContainer_layout; @@ -105,6 +107,14 @@ public: refreshGameListAct = new QAction(MainWindow); refreshGameListAct->setObjectName("refreshGameListAct"); refreshGameListAct->setIcon(QIcon(":images/refresh_icon.png")); + + toggleLabelsAct = new QAction(MainWindow); + toggleLabelsAct->setObjectName("toggleLabelsAct"); + toggleLabelsAct->setText( + QCoreApplication::translate("MainWindow", "Show Labels Under Icons")); + toggleLabelsAct->setCheckable(true); + toggleLabelsAct->setChecked(Config::getShowLabelsUnderIcons()); + setIconSizeTinyAct = new QAction(MainWindow); setIconSizeTinyAct->setObjectName("setIconSizeTinyAct"); setIconSizeTinyAct->setCheckable(true); @@ -211,11 +221,15 @@ public: refreshButton = new QPushButton(centralWidget); refreshButton->setFlat(true); refreshButton->setIcon(QIcon(":images/refresh_icon.png")); - refreshButton->setIconSize(QSize(32, 32)); + refreshButton->setIconSize(QSize(38, 38)); + fullscreenButton = new QPushButton(centralWidget); + fullscreenButton->setFlat(true); + fullscreenButton->setIcon(QIcon(":images/fullscreen_icon.png")); + fullscreenButton->setIconSize(QSize(38, 38)); settingsButton = new QPushButton(centralWidget); settingsButton->setFlat(true); settingsButton->setIcon(QIcon(":images/settings_icon.png")); - settingsButton->setIconSize(QSize(44, 44)); + settingsButton->setIconSize(QSize(42, 42)); controllerButton = new QPushButton(centralWidget); controllerButton->setFlat(true); controllerButton->setIcon(QIcon(":images/controller_icon.png")); @@ -304,6 +318,7 @@ public: menuView->addAction(refreshGameListAct); menuView->addAction(menuGame_List_Mode->menuAction()); menuView->addAction(menuGame_List_Icons->menuAction()); + menuView->addAction(toggleLabelsAct); menuView->addAction(menuThemes->menuAction()); menuThemes->addAction(setThemeDark); menuThemes->addAction(setThemeLight); diff --git a/src/sdl_window.cpp b/src/sdl_window.cpp index 80d196147..5746d2d7f 100644 --- a/src/sdl_window.cpp +++ b/src/sdl_window.cpp @@ -11,6 +11,7 @@ #include "common/config.h" #include "common/elf_info.h" #include "common/version.h" +#include "core/debug_state.h" #include "core/libraries/kernel/time.h" #include "core/libraries/pad/pad.h" #include "imgui/renderer/imgui_core.h" @@ -254,9 +255,10 @@ static Uint32 SDLCALL PollController(void* userdata, SDL_TimerID timer_id, Uint3 return controller->Poll(); } -WindowSDL::WindowSDL(s32 width_, s32 height_, Input::GameController* controller_, +WindowSDL::WindowSDL(s32 width, s32 height, Input::GameController* controller, std::string_view window_title) - : width{width_}, height{height_}, controller{controller_} { + : width(width), height(height), controller(controller), is_open(true), is_shown(true), + is_paused(false) { if (!SDL_SetHint(SDL_HINT_APP_NAME, "shadPS4")) { UNREACHABLE_MSG("Failed to set SDL window hint: {}", SDL_GetError()); } @@ -333,7 +335,6 @@ WindowSDL::WindowSDL(s32 width_, s32 height_, Input::GameController* controller_ WindowSDL::~WindowSDL() = default; void WindowSDL::WaitEvent() { - // Called on main thread SDL_Event event; if (!SDL_WaitEvent(&event)) { @@ -343,7 +344,7 @@ void WindowSDL::WaitEvent() { if (ImGui::Core::ProcessEvent(&event)) { return; } - + bool is_game_running = true; switch (event.type) { case SDL_EVENT_WINDOW_RESIZED: case SDL_EVENT_WINDOW_MAXIMIZED: @@ -379,8 +380,6 @@ void WindowSDL::WaitEvent() { case SDL_EVENT_GAMEPAD_AXIS_MOTION: OnGamepadEvent(&event); break; - // i really would have appreciated ANY KIND OF DOCUMENTATION ON THIS - // AND IT DOESN'T EVEN USE PROPER ENUMS case SDL_EVENT_GAMEPAD_SENSOR_UPDATE: switch ((SDL_SensorType)event.gsensor.sensor) { case SDL_SENSOR_GYRO: @@ -396,7 +395,24 @@ void WindowSDL::WaitEvent() { case SDL_EVENT_QUIT: is_open = false; break; - default: + case SDL_EVENT_TOGGLE_FULLSCREEN: { + if (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) { + SDL_SetWindowFullscreen(window, 0); + } else { + SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN); + } + break; + } + case SDL_EVENT_TOGGLE_PAUSE: + SDL_Log("Received SDL_EVENT_TOGGLE_PAUSE"); + is_paused = !is_paused; + if (is_paused) { + SDL_Log("Game Paused"); + DebugState.PauseGuestThreads(); + } else { + SDL_Log("Game Resumed"); + DebugState.ResumeGuestThreads(); + } break; } } diff --git a/src/sdl_window.h b/src/sdl_window.h index 03ba0797b..2b1505767 100644 --- a/src/sdl_window.h +++ b/src/sdl_window.h @@ -7,6 +7,8 @@ #include "core/libraries/pad/pad.h" #include "input/controller.h" #include "string" +#define SDL_EVENT_TOGGLE_FULLSCREEN (SDL_EVENT_USER + 1) +#define SDL_EVENT_TOGGLE_PAUSE (SDL_EVENT_USER + 2) struct SDL_Window; struct SDL_Gamepad; @@ -106,6 +108,7 @@ private: SDL_Window* window{}; bool is_shown{}; bool is_open{true}; + bool is_paused = false; }; } // namespace Frontend diff --git a/src/shadps4.qrc b/src/shadps4.qrc index 340756f5c..c37e7d5de 100644 --- a/src/shadps4.qrc +++ b/src/shadps4.qrc @@ -34,5 +34,6 @@ images/ps4_controller.png images/keyboard_icon.png images/KBM.png + images/fullscreen_icon.png