From 46770aba3a9b76b7cb22b29c417b99574661640e Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 14 Sep 2021 22:33:47 -0700 Subject: [PATCH 1/7] Vulkan: Skip flips, not draw, for vsync unthrottle. --- Core/HLE/sceDisplay.cpp | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 98f237b3bc..f4c6910515 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -558,16 +558,7 @@ static void DoFrameTiming(bool &throttle, bool &skipFrame, float timestep) { bool doFrameSkip = g_Config.iFrameSkip != 0; bool fastForwardNeedsSkip = g_Config.iFastForwardMode == (int)FastForwardMode::SKIP_DRAW; - if (g_Config.bVSync && GetGPUBackend() == GPUBackend::VULKAN) { - // Vulkan doesn't support the interval setting, so we force frameskip. - fastForwardNeedsSkip = true; - // If it's not a clean multiple of 60, we may need frameskip to achieve it. - if (fpsLimit == 0 || (fpsLimit >= 0 && fpsLimit != 15 && fpsLimit != 30 && fpsLimit != 60)) { - doFrameSkip = true; - } - } if (!throttle && fastForwardNeedsSkip) { - doFrameSkip = true; skipFrame = true; if (numSkippedFrames >= 7) { skipFrame = false; @@ -751,9 +742,10 @@ void __DisplayFlip(int cyclesLate) { bool duplicateFrames = g_Config.bRenderDuplicateFrames && g_Config.iFrameSkip == 0; bool fastForwardNeedsSkip = g_Config.iFastForwardMode != (int)FastForwardMode::CONTINUOUS; + bool fastForwardSkipFlip = g_Config.iFastForwardMode == (int)FastForwardMode::SKIP_FLIP; if (g_Config.bVSync && GetGPUBackend() == GPUBackend::VULKAN) { - // Vulkan doesn't support the interval setting, so we force frameskip. - fastForwardNeedsSkip = true; + // Vulkan doesn't support the interval setting, so we force skipping the flip. + fastForwardSkipFlip = true; } // postEffectRequiresFlip is not compatible with frameskip fast-forward, see #12325. @@ -788,7 +780,7 @@ void __DisplayFlip(int cyclesLate) { bool forceNoFlip = false; // Alternative to frameskip fast-forward, where we draw everything. // Useful if skipping a frame breaks graphics or for checking drawing speed. - if (g_Config.iFastForwardMode == (int)FastForwardMode::SKIP_FLIP && !FrameTimingThrottled()) { + if (fastForwardSkipFlip && !FrameTimingThrottled()) { static double lastFlip = 0; double now = time_now_d(); if ((now - lastFlip) < 1.0f / System_GetPropertyFloat(SYSPROP_DISPLAY_REFRESH_RATE)) { From 9024c7111b32493ec692fea497b3f1d8c391bba5 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 14 Sep 2021 22:53:54 -0700 Subject: [PATCH 2/7] Vulkan: Fix faster alt speed with vsync. --- Core/HLE/sceDisplay.cpp | 42 ++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index f4c6910515..371dea59d4 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -511,14 +511,18 @@ void __DisplaySetWasPaused() { wasPaused = true; } +static int FrameTimingLimit() { + if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1) + return g_Config.iFpsLimit1; + if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM2) + return g_Config.iFpsLimit2; + if (PSP_CoreParameter().fastForward) + return 0; + return 60; +} + static bool FrameTimingThrottled() { - if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1 && g_Config.iFpsLimit1 == 0) { - return false; - } - if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM2 && g_Config.iFpsLimit2 == 0) { - return false; - } - return !PSP_CoreParameter().fastForward; + return FrameTimingLimit() != 0; } static void DoFrameDropLogging(float scaledTimestep) { @@ -546,10 +550,7 @@ static int CalculateFrameSkip() { // Let's collect all the throttling and frameskipping logic here. static void DoFrameTiming(bool &throttle, bool &skipFrame, float timestep) { PROFILE_THIS_SCOPE("timing"); - FPSLimit fpsLimiter = PSP_CoreParameter().fpsLimit; - int fpsLimit = 60; - if (fpsLimiter != FPSLimit::NORMAL) - fpsLimit = fpsLimiter == FPSLimit::CUSTOM1 ? g_Config.iFpsLimit1 : g_Config.iFpsLimit2; + int fpsLimit = FrameTimingLimit(); throttle = FrameTimingThrottled(); skipFrame = false; @@ -648,11 +649,10 @@ static void DoFrameIdleTiming() { } float scaledVblank = timePerVblank; - if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1 && g_Config.iFpsLimit1 > 0) { + int fpsLimit = FrameTimingLimit(); + if (fpsLimit != 0 && fpsLimit != 60) { // 0 is handled in FrameTimingThrottled(). - scaledVblank *= 60.0f / g_Config.iFpsLimit1; - } else if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM2 && g_Config.iFpsLimit2 > 0) { - scaledVblank *= 60.0f / g_Config.iFpsLimit2; + scaledVblank *= 60.0f / fpsLimit; } // If we have over at least a vblank of spare time, maintain at least 30fps in delay. @@ -778,12 +778,13 @@ void __DisplayFlip(int cyclesLate) { } bool forceNoFlip = false; + float refreshRate = System_GetPropertyFloat(SYSPROP_DISPLAY_REFRESH_RATE); // Alternative to frameskip fast-forward, where we draw everything. // Useful if skipping a frame breaks graphics or for checking drawing speed. - if (fastForwardSkipFlip && !FrameTimingThrottled()) { + if (fastForwardSkipFlip && (!FrameTimingThrottled() || FrameTimingLimit() > refreshRate)) { static double lastFlip = 0; double now = time_now_d(); - if ((now - lastFlip) < 1.0f / System_GetPropertyFloat(SYSPROP_DISPLAY_REFRESH_RATE)) { + if ((now - lastFlip) < 1.0f / refreshRate) { forceNoFlip = true; } else { lastFlip = now; @@ -876,11 +877,10 @@ void hleLagSync(u64 userdata, int cyclesLate) { } float scale = 1.0f; - if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1 && g_Config.iFpsLimit1 > 0) { + int fpsLimit = FrameTimingLimit(); + if (fpsLimit != 0 && fpsLimit != 60) { // 0 is handled in FrameTimingThrottled(). - scale = 60.0f / g_Config.iFpsLimit1; - } else if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM2 && g_Config.iFpsLimit2 > 0) { - scale = 60.0f / g_Config.iFpsLimit2; + scale = 60.0f / fpsLimit; } const double goal = lastLagSync + (scale / 1000.0f); From cf045dfbbc4c14d8d8e719f9b079c2d0aabe681e Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 14 Sep 2021 23:56:45 -0700 Subject: [PATCH 3/7] UI: When enabling chat, recreate views. Otherwise, the chat button doesn't show right away. Fixes #13090. --- UI/EmuScreen.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 1b499a4708..8bf682cc9b 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -488,6 +488,8 @@ void EmuScreen::sendMessage(const char *message, const char *value) { gstate_c.skipDrawReason &= ~SKIPDRAW_WINDOW_MINIMIZED; } } else if (!strcmp(message, "chat screen")) { + if (!chatButton_) + RecreateViews(); #if defined(USING_WIN_UI) //temporary workaround for hotkey its freeze the ui when open chat screen using hotkey and native keyboard is enable From 75f5c75045a8ae157d0a07fa1cb44983ecd6ffa3 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Wed, 15 Sep 2021 00:12:33 -0700 Subject: [PATCH 4/7] Windows: Disable auto-enable chat on Ctrl-C. It's annoying when this triggers unexpectedly. Sometimes it happens when using debug windows. --- UI/EmuScreen.cpp | 18 ++++++++---------- Windows/MainWindowMenu.cpp | 8 ++------ Windows/ppsspp.rc | 2 +- 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 8bf682cc9b..8eb51f2ace 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -488,25 +488,23 @@ void EmuScreen::sendMessage(const char *message, const char *value) { gstate_c.skipDrawReason &= ~SKIPDRAW_WINDOW_MINIMIZED; } } else if (!strcmp(message, "chat screen")) { - if (!chatButton_) - RecreateViews(); + if (g_Config.bEnableNetworkChat) { + if (!chatButton_) + RecreateViews(); #if defined(USING_WIN_UI) - //temporary workaround for hotkey its freeze the ui when open chat screen using hotkey and native keyboard is enable - if (g_Config.bBypassOSKWithKeyboard) { - osm.Show("Disable windows native keyboard options to use ctrl + c hotkey", 2.0f); - } else { - if (g_Config.bEnableNetworkChat) { + //temporary workaround for hotkey its freeze the ui when open chat screen using hotkey and native keyboard is enable + if (g_Config.bBypassOSKWithKeyboard) { + osm.Show("Disable windows native keyboard options to use ctrl + c hotkey", 2.0f); + } else { UI::EventParams e{}; OnChatMenu.Trigger(e); } - } #else - if (g_Config.bEnableNetworkChat) { UI::EventParams e{}; OnChatMenu.Trigger(e); - } #endif + } } else if (!strcmp(message, "app_resumed") && screenManager()->topScreen() == this) { if (System_GetPropertyInt(SYSPROP_DEVICE_TYPE) == DEVICE_TYPE_TV) { if (!KeyMap::IsKeyMapped(DEVICE_ID_PAD_0, VIRTKEY_PAUSE) || !KeyMap::IsKeyMapped(DEVICE_ID_PAD_1, VIRTKEY_PAUSE)) { diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index dac18e2a1e..a0ad58391f 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -80,6 +80,7 @@ namespace MainWindow { EnableMenuItem(menu, ID_EMULATION_STOP, menuEnable); EnableMenuItem(menu, ID_EMULATION_RESET, menuEnable); EnableMenuItem(menu, ID_EMULATION_SWITCH_UMD, umdSwitchEnable); + EnableMenuItem(menu, ID_EMULATION_CHAT, g_Config.bEnableNetworkChat ? menuInGameEnable : MF_GRAYED); EnableMenuItem(menu, ID_TOGGLE_BREAK, menuEnable); EnableMenuItem(menu, ID_DEBUG_LOADMAPFILE, menuEnable); EnableMenuItem(menu, ID_DEBUG_SAVEMAPFILE, menuEnable); @@ -636,10 +637,6 @@ namespace MainWindow { osm.ShowOnOff(gr->T("Cheats"), g_Config.bEnableCheats); break; case ID_EMULATION_CHAT: - if (!g_Config.bEnableNetworkChat) { - g_Config.bEnableNetworkChat = true; - UpdateCommands(); - } if (GetUIState() == UISTATE_INGAME) { NativeMessageReceived("chat screen", ""); } @@ -1371,7 +1368,7 @@ namespace MainWindow { static CoreState lastCoreState = CORE_BOOT_ERROR; HMENU menu = GetMenu(GetHWND()); - EnableMenuItem(menu, ID_DEBUG_LOG, !g_Config.bEnableLogging); + EnableMenuItem(menu, ID_DEBUG_LOG, g_Config.bEnableLogging ? MF_ENABLED : MF_GRAYED); SetIngameMenuItemStates(menu, GetUIState()); if (lastGlobalUIState == GetUIState() && lastCoreState == coreState) @@ -1382,7 +1379,6 @@ namespace MainWindow { bool isPaused = Core_IsStepping() && GetUIState() == UISTATE_INGAME; TranslateMenuItem(menu, ID_TOGGLE_BREAK, L"\tF8", isPaused ? "Run" : "Break"); - TranslateMenuItem(menu, ID_EMULATION_CHAT, L"\tCtrl+C", g_Config.bEnableNetworkChat ? "Open Chat" : "Enable Chat"); } void UpdateSwitchUMD() { diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index b9ea154e26..021caa67ff 100644 --- a/Windows/ppsspp.rc +++ b/Windows/ppsspp.rc @@ -664,7 +664,7 @@ BEGIN MENUITEM "", 0, MFT_SEPARATOR MENUITEM "Enable Cheats", ID_EMULATION_CHEATS MENUITEM "", 0, MFT_SEPARATOR - MENUITEM "Enable Chat", ID_EMULATION_CHAT + MENUITEM "Open Chat", ID_EMULATION_CHAT END POPUP "Help", ID_HELP_MENU From adf7c3f20b87b67fd10321aa0bbfa636302eccf0 Mon Sep 17 00:00:00 2001 From: iota97 Date: Wed, 15 Sep 2021 09:56:36 +0200 Subject: [PATCH 5/7] Fix jumpy resolve while typing --- UI/GameSettingsScreen.cpp | 19 +++++++++---------- UI/GameSettingsScreen.h | 1 - 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index b20236c225..9e94717fb1 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -1858,12 +1858,8 @@ void HostnameSelectScreen::CreatePopupContents(UI::ViewGroup *parent) { parent->Add(ipRows_); listIP.clear(); listIP.shrink_to_fit(); - errorView_ = parent->Add(new TextView(n->T("Invalid IP or hostname"), ALIGN_HCENTER, false, new LinearLayoutParams(Margins(0, 10, 0, 0)))); - errorView_->SetTextColor(0xFF3030FF); - errorView_->SetVisibility(V_GONE); - progressView_ = parent->Add(new TextView(n->T("Validating address..."), ALIGN_HCENTER, false, new LinearLayoutParams(Margins(0, 10, 0, 0)))); - progressView_->SetVisibility(V_GONE); + progressView_->SetVisibility(V_INVISIBLE); } void HostnameSelectScreen::SendEditKey(int keyCode, int flags) { @@ -1950,6 +1946,8 @@ void HostnameSelectScreen::ResolverThread() { } bool HostnameSelectScreen::CanComplete(DialogResult result) { + auto n = GetI18NCategory("Networking"); + if (result != DR_OK) return true; @@ -1981,12 +1979,12 @@ bool HostnameSelectScreen::CanComplete(DialogResult result) { lastResolvedResult_ = toResolveResult_; if (lastResolvedResult_) { - errorView_->SetVisibility(UI::V_GONE); + progressView_->SetVisibility(UI::V_INVISIBLE); } else { - errorView_->SetVisibility(UI::V_VISIBLE); + progressView_->SetText(n->T("Invalid IP or hostname")); + progressView_->SetTextColor(0xFF3030FF); + progressView_->SetVisibility(UI::V_VISIBLE); } - progressView_->SetVisibility(UI::V_GONE); - return true; } @@ -1998,8 +1996,9 @@ bool HostnameSelectScreen::CanComplete(DialogResult result) { toResolve_ = value; resolverCond_.notify_one(); + progressView_->SetText(n->T("Validating address...")); + progressView_->SetTextColor(0xFFFFFFFF); progressView_->SetVisibility(UI::V_VISIBLE); - errorView_->SetVisibility(UI::V_GONE); return false; } diff --git a/UI/GameSettingsScreen.h b/UI/GameSettingsScreen.h index c82bef73ca..fb892d6ea9 100644 --- a/UI/GameSettingsScreen.h +++ b/UI/GameSettingsScreen.h @@ -213,7 +213,6 @@ private: std::string *value_; UI::TextEdit *addrView_ = nullptr; - UI::TextView *errorView_ = nullptr; UI::TextView *progressView_ = nullptr; UI::LinearLayout *ipRows_ = nullptr; From eccb79464dd1e8afbf546e9484e68d5cd35e2366 Mon Sep 17 00:00:00 2001 From: iota97 Date: Wed, 15 Sep 2021 10:25:26 +0200 Subject: [PATCH 6/7] Fix chat here position --- UI/ChatScreen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UI/ChatScreen.cpp b/UI/ChatScreen.cpp index 41eef866ae..df311ad305 100644 --- a/UI/ChatScreen.cpp +++ b/UI/ChatScreen.cpp @@ -19,7 +19,7 @@ void ChatMenu::CreateContents(UI::ViewGroup *parent) { using namespace UI; auto n = GetI18NCategory("Networking"); LinearLayout *outer = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT,400)); - scroll_ = outer->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0))); + scroll_ = outer->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT, 1.0))); LinearLayout *bottom = outer->Add(new LinearLayout(ORIENT_HORIZONTAL, new LayoutParams(FILL_PARENT, WRAP_CONTENT))); #if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || defined(SDL) chatEdit_ = bottom->Add(new TextEdit("", n->T("Chat message"), n->T("Chat Here"), new LinearLayoutParams(1.0))); From d489c099a793cd66f8c838ffe02e82943ed1974a Mon Sep 17 00:00:00 2001 From: iota97 Date: Wed, 15 Sep 2021 14:32:54 +0200 Subject: [PATCH 7/7] Qt as well --- Qt/mainwindow.cpp | 5 ++++- Qt/mainwindow.h | 34 ++++++++++++++++++++-------------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/Qt/mainwindow.cpp b/Qt/mainwindow.cpp index 8b766110db..f2dd0410b4 100644 --- a/Qt/mainwindow.cpp +++ b/Qt/mainwindow.cpp @@ -657,7 +657,10 @@ void MainWindow::createMenus() gameSettingsMenu->add(new MenuAction(this, SLOT(cheatsAct()), QT_TR_NOOP("Enable &cheats"), Qt::CTRL + Qt::Key_T)) ->addEventChecked(&g_Config.bEnableCheats); gameSettingsMenu->addSeparator(); - gameSettingsMenu->add(new MenuAction(this, SLOT(chatAct()), QT_TR_NOOP("Enable chat"), Qt::CTRL + Qt::Key_C)); + gameSettingsMenu->add(new MenuAction(this, SLOT(chatAct()), QT_TR_NOOP("Open chat"), Qt::CTRL + Qt::Key_C)) + ->SetEnabledFunc([=]() { + return g_Config.bEnableNetworkChat && GetUIState() == UISTATE_INGAME; + }); // Help MenuTree* helpMenu = new MenuTree(this, menuBar(), QT_TR_NOOP("&Help")); diff --git a/Qt/mainwindow.h b/Qt/mainwindow.h index 2a9660d744..26ad5b521c 100644 --- a/Qt/mainwindow.h +++ b/Qt/mainwindow.h @@ -185,9 +185,9 @@ private slots: // Chat void chatAct() { - g_Config.bEnableNetworkChat = true; - updateMenus(); - NativeMessageReceived("chat screen", ""); + if (GetUIState() == UISTATE_INGAME) { + NativeMessageReceived("chat screen", ""); + } } void fullscrAct(); @@ -244,7 +244,7 @@ class MenuAction : public QAction public: // Add to QMenu MenuAction(QWidget* parent, const char *callback, const char *text, QKeySequence key = 0) : - QAction(parent), _text(text), _eventCheck(0), _eventUncheck(0), _stateEnable(-1), _stateDisable(-1), _enableStepping(false) + QAction(parent), _text(text) { if (key != (QKeySequence)0) { this->setShortcut(key); @@ -256,7 +256,7 @@ public: } // Add to QActionGroup MenuAction(QWidget* parent, QActionGroup* group, QVariant data, QString text, QKeySequence key = 0) : - QAction(parent), _eventCheck(0), _eventUncheck(0), _stateEnable(-1), _stateDisable(-1), _enableStepping(false) + QAction(parent) { this->setCheckable(true); this->setData(data); @@ -284,14 +284,19 @@ public: } // UI State which causes it to be enabled void addEnableState(int state) { + _enabledFunc = nullptr; _stateEnable = state; + _stateDisable = -1; } void addDisableState(int state) { + _enabledFunc = nullptr; + _stateEnable = -1; _stateDisable = state; } - MenuAction* addEnableStepping() { - _enableStepping = true; - return this; + void SetEnabledFunc(std::function func) { + _enabledFunc = func; + _stateEnable = -1; + _stateDisable = -1; } public slots: void retranslate() { @@ -306,15 +311,16 @@ public slots: setEnabled(GetUIState() == _stateEnable); if (_stateDisable >= 0) setEnabled(GetUIState() != _stateDisable); - if (_enableStepping && Core_IsStepping()) - setEnabled(true); + if (_enabledFunc) + setEnabled(_enabledFunc()); } private: const char *_text; - bool *_eventCheck; - bool *_eventUncheck; - int _stateEnable, _stateDisable; - bool _enableStepping; + bool *_eventCheck = nullptr; + bool *_eventUncheck = nullptr; + int _stateEnable = -1; + int _stateDisable = -1; + std::function _enabledFunc; }; class MenuActionGroup : public QActionGroup