From d6d2c24e2429fddf18b09f88bf1e0f672f6e7e90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 5 Feb 2026 00:27:17 +0100 Subject: [PATCH] Fix the toggle touch controls input (properly this time) --- Common/UI/ViewGroup.cpp | 3 ++- Core/TiltEventProcessor.cpp | 10 ++++++++++ UI/EmuScreen.cpp | 3 +-- UI/GamepadEmu.cpp | 30 ++++++++++++++++++++++-------- UI/GamepadEmu.h | 18 +++++++++++------- unittest/UnitTest.cpp | 14 ++++++++++++++ 6 files changed, 60 insertions(+), 18 deletions(-) diff --git a/Common/UI/ViewGroup.cpp b/Common/UI/ViewGroup.cpp index 3f10b062be..1bad784e62 100644 --- a/Common/UI/ViewGroup.cpp +++ b/Common/UI/ViewGroup.cpp @@ -203,7 +203,8 @@ std::string ViewGroup::DescribeText() const { ss << s; needNewline = s[s.length() - 1] != '\n'; } - return ss.str(); + const std::string desc = ss.str(); + return desc.empty() ? "empty viewgroup" : desc; } std::string ViewGroup::DescribeListUnordered(std::string_view heading) const { diff --git a/Core/TiltEventProcessor.cpp b/Core/TiltEventProcessor.cpp index 541506bf6c..ab093a578f 100644 --- a/Core/TiltEventProcessor.cpp +++ b/Core/TiltEventProcessor.cpp @@ -124,6 +124,16 @@ void ProcessTilt(bool landscape, float calibrationAngle, float x, float y, float Lin::Vec3 down = Lin::Vec3(x, y, z).normalized(); + if (my_isnanorinf(down.x) || my_isnanorinf(down.y) || my_isnanorinf(down.z)) { + // Invalid data - ignore. + static int count = 0; + if (count < 20) { + WARN_LOG(Log::System, "Bad accelerometer data: %f %f %f (will stop logging after 20)", x, y, z); + } + count++; + return; + } + float angleAroundX = atan2(down.z, down.y); g_currentYAngle = angleAroundX; // TODO: Should smooth this out over time a bit. float yAngle = angleAroundX - calibrationAngle; diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 887d937623..09b2c399ed 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -1004,8 +1004,7 @@ void EmuScreen::ProcessVKey(VirtKey virtKey) { if (GamepadGetOpacity() < 0.01f) { GamepadTouch(); } else { - // Reset. - GamepadTouch(true); + GamepadResetTouch(); } } else { // If touch controls are disabled though, they'll get enabled. diff --git a/UI/GamepadEmu.cpp b/UI/GamepadEmu.cpp index cdb76b36de..40e1b8dd9a 100644 --- a/UI/GamepadEmu.cpp +++ b/UI/GamepadEmu.cpp @@ -73,8 +73,12 @@ void GamepadUpdateOpacity(float force) { g_gamepadOpacity = opacity * multiplier; } -void GamepadTouch(bool reset) { - g_lastTouch = reset ? 0.0f : time_now_d(); +void GamepadResetTouch() { + g_lastTouch = 0.0f; +} + +void GamepadTouch() { + g_lastTouch = time_now_d(); } float GamepadGetOpacity() { @@ -88,8 +92,7 @@ static u32 GetButtonColor() { GamepadComponent::GamepadComponent(std::string_view key, UI::LayoutParams *layoutParams) : UI::View(layoutParams), key_(key) {} std::string GamepadComponent::DescribeText() const { - auto co = GetI18NCategory(I18NCat::CONTROLS); - return std::string(co->T(key_)); + return key_; } void MultiTouchButton::GetContentDimensions(const UIContext &dc, float &w, float &h) const { @@ -211,6 +214,17 @@ bool CustomButton::IsDown() const { return (toggle_ && on_) || (!toggle_ && pointerDownMask_ != 0); } +bool CustomButton::IsDownForFadeoutCheck() const { + // This check is due to a stupid mistake, see the header. +#ifdef MOBILE_DEVICE + constexpr int bitNumber = 36; +#else + constexpr int bitNumber = 38; +#endif + const bool down = IsDown() && !(pspButtonBit_ & (1ULL << bitNumber)); // VIRTKEY_TOGGLE_TOUCH_CONTROLS from g_customKeyList + return down; +} + void CustomButton::GetContentDimensions(const UIContext &dc, float &w, float &h) const { MultiTouchButton::GetContentDimensions(dc, w, h); if (invertedContentDimension_) { @@ -1047,14 +1061,14 @@ void GamepadEmuView::Update() { bool anyDown = false; for (auto view : views_) { GamepadComponent *component = dynamic_cast(view); - if (component) { - if (component->IsDownForFadeoutCheck()) { - anyDown = true; - } + if (component && component->IsDownForFadeoutCheck()) { + // INFO_LOG(Log::System, "GamepadEmuView::Update: component is down for fadeout check: %s", component->DescribeText().c_str()); + anyDown = true; } } if (anyDown) { + // INFO_LOG(Log::System, "last touch in update"); g_lastTouch = time_now_d(); } } diff --git a/UI/GamepadEmu.h b/UI/GamepadEmu.h index 36d2b9636c..1e59d140e5 100644 --- a/UI/GamepadEmu.h +++ b/UI/GamepadEmu.h @@ -190,10 +190,9 @@ public: } bool Touch(const TouchInput &input) override; void Update() override; + bool IsDown() const override; // For visual purpose - bool IsDownForFadeoutCheck() const override { - return !(pspButtonBit_ & (1ULL << 38)); // VIRTKEY_TOGGLE_TOUCH_CONTROLS from g_customKeyList - } + bool IsDownForFadeoutCheck() const override; void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; private: @@ -216,6 +215,9 @@ public: void Update() override; void Draw(UIContext &dc) override; +protected: + virtual std::string DescribeText() const override { return zoneIndex_ == 0 ? "gesture-left" : "gesture-right"; } + private: const GestureControlConfig &GetZone(); @@ -311,6 +313,7 @@ namespace CustomKeyData { uint32_t c; // Key code }; // For CustomButton. NOTE: This list can NOT be freely reordered! We store a bitmask of the indices. + // NOTE 2: Unfortunately we messed up here, we should NOT have used ifdefs! This breaks the order. static const keyList g_customKeyList[] = { { ImageID("I_SQUARE"), CTRL_SQUARE }, { ImageID("I_TRIANGLE"), CTRL_TRIANGLE }, @@ -331,7 +334,7 @@ namespace CustomKeyData { { ImageID::invalid(), VIRTKEY_SAVE_STATE }, { ImageID::invalid(), VIRTKEY_LOAD_STATE }, { ImageID::invalid(), VIRTKEY_NEXT_SLOT }, -#if !defined(MOBILE_DEVICE) +#if !defined(MOBILE_DEVICE) // BAD!! { ImageID::invalid(), VIRTKEY_TOGGLE_FULLSCREEN }, #endif { ImageID::invalid(), VIRTKEY_SPEED_CUSTOM1 }, @@ -346,7 +349,7 @@ namespace CustomKeyData { { ImageID::invalid(), VIRTKEY_PAUSE }, { ImageID::invalid(), VIRTKEY_RESET_EMULATION }, { ImageID::invalid(), VIRTKEY_DEVMENU }, -#ifndef MOBILE_DEVICE +#ifndef MOBILE_DEVICE // BAD!!! { ImageID::invalid(), VIRTKEY_RECORD }, #endif { ImageID::invalid(), VIRTKEY_AXIS_X_MIN }, @@ -354,7 +357,7 @@ namespace CustomKeyData { { ImageID::invalid(), VIRTKEY_AXIS_X_MAX }, { ImageID::invalid(), VIRTKEY_AXIS_Y_MAX }, { ImageID::invalid(), VIRTKEY_PREVIOUS_SLOT }, - { ImageID::invalid(), VIRTKEY_TOGGLE_TOUCH_CONTROLS }, // See IsDownForFadeoutCheck + { ImageID::invalid(), VIRTKEY_TOGGLE_TOUCH_CONTROLS }, // 38 if !MOBILE_DEVICE, 36 if MOBILE_DEVICE. See IsDownForFadeoutCheck { ImageID::invalid(), VIRTKEY_TOGGLE_DEBUGGER }, { ImageID::invalid(), VIRTKEY_PAUSE_NO_MENU }, { ImageID::invalid(), VIRTKEY_TOGGLE_TILT }, @@ -407,6 +410,7 @@ namespace GestureKey { }; } -void GamepadTouch(bool reset = false); +void GamepadTouch(); +void GamepadResetTouch(); void GamepadUpdateOpacity(float force = -1.0f); float GamepadGetOpacity(); diff --git a/unittest/UnitTest.cpp b/unittest/UnitTest.cpp index 225dec102f..05ed83af5a 100644 --- a/unittest/UnitTest.cpp +++ b/unittest/UnitTest.cpp @@ -34,6 +34,8 @@ #include "ppsspp_config.h" +#include + #include #include #include @@ -1333,6 +1335,17 @@ bool TestFriendlyPath() { return true; } +// Check that RTTI is working. +bool TestLang() { + struct Base { virtual ~Base() = default; }; + struct Derived : Base {}; + + Base* b = new Derived; + bool equals = typeid(*b) == typeid(Derived); + EXPECT_TRUE(equals); + return true; +} + typedef bool (*TestFunc)(); struct TestItem { const char *name; @@ -1405,6 +1418,7 @@ TestItem availableTests[] = { TEST_ITEM(SplitSearch), TEST_ITEM(FriendlyPath), TEST_ITEM(LinAlg), + TEST_ITEM(Lang), }; int main(int argc, const char *argv[]) {