From 2b98f15f17f0ead8da8fa54c39f7d94bef7e2da2 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Thu, 5 Mar 2015 10:58:25 +0100 Subject: [PATCH] Add option to auto-center the analog stick on touch within the boundaries of the stick TODO: Should this be default? Does this make sense for d-pad too? --- Core/Config.cpp | 1 + Core/Config.h | 3 +++ UI/GameSettingsScreen.cpp | 4 ++++ UI/GamepadEmu.cpp | 26 ++++++++++++++++++++------ UI/GamepadEmu.h | 3 +++ 5 files changed, 31 insertions(+), 6 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 7661eb2b26..9cb45f26c8 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -543,6 +543,7 @@ static ConfigSetting controlSettings[] = { ConfigSetting("GamepadOnlyFocused", &g_Config.bGamepadOnlyFocused, false, true, true), ConfigSetting("TouchButtonStyle", &g_Config.iTouchButtonStyle, 1, true, true), ConfigSetting("TouchButtonOpacity", &g_Config.iTouchButtonOpacity, 65, true, true), + ConfigSetting("AutoCenterTouchAnalog", &g_Config.bAutoCenterTouchAnalog, false, true, true), // -1.0f means uninitialized, set in GamepadEmu::CreatePadLayout(). ConfigSetting("ActionButtonSpacing2", &g_Config.fActionButtonSpacing, 1.0f, true, true), diff --git a/Core/Config.h b/Core/Config.h index eff36a0401..a1da8e3920 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -239,6 +239,9 @@ public: int iTouchButtonStyle; // Control Positions int iTouchButtonOpacity; + // Floating analog stick (recenters on thumb on press). + bool bAutoCenterTouchAnalog; + //space between PSP buttons //the PSP button's center (triangle, circle, square, cross) float fActionButtonCenterX, fActionButtonCenterY; diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 98dab6f4fc..1008613640 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -388,6 +388,10 @@ void GameSettingsScreen::CreateViews() { layoutEditorChoice_->OnClick.Handle(this, &GameSettingsScreen::OnTouchControlLayout); layoutEditorChoice_->SetEnabledPtr(&g_Config.bShowTouchControls); + // Re-centers itself to the touch location on touch-down. + CheckBox *floatingAnalog = controlsSettings->Add(new CheckBox(&g_Config.bAutoCenterTouchAnalog, c->T("Auto-centering analog stick"))); + floatingAnalog->SetEnabledPtr(&g_Config.bShowTouchControls); + // On systems that aren't Symbian, iOS, and Maemo, offer to let the user see this button. // Some Windows touch devices don't have a back button or other button to call up the menu. #if !defined(__SYMBIAN32__) && !defined(IOS) && !defined(MAEMO) diff --git a/UI/GamepadEmu.cpp b/UI/GamepadEmu.cpp index 702fd8761a..fc15e83022 100644 --- a/UI/GamepadEmu.cpp +++ b/UI/GamepadEmu.cpp @@ -218,7 +218,7 @@ void PSPDpad::Draw(UIContext &dc) { } PSPStick::PSPStick(int bgImg, int stickImg, int stick, float scale, UI::LayoutParams *layoutParams) - : UI::View(layoutParams), dragPointerId_(-1), bgImg_(bgImg), stickImageIndex_(stickImg), stick_(stick), scale_(scale) { + : UI::View(layoutParams), dragPointerId_(-1), bgImg_(bgImg), stickImageIndex_(stickImg), stick_(stick), scale_(scale), centerX_(-1), centerY_(-1) { stick_size_ = 50; } @@ -234,8 +234,13 @@ void PSPStick::Draw(UIContext &dc) { uint32_t colorBg = colorAlpha(GetButtonColor(), opacity); uint32_t color = colorAlpha(0x808080, opacity); - float stickX = bounds_.centerX(); - float stickY = bounds_.centerY(); + if (centerX_ < 0.0f) { + centerX_ = bounds_.centerX(); + centerY_ = bounds_.centerY(); + } + + float stickX = centerX_; + float stickY = centerY_; float dx, dy; __CtrlPeekAnalog(stick_, &dx, &dy); @@ -247,6 +252,13 @@ void PSPStick::Draw(UIContext &dc) { void PSPStick::Touch(const TouchInput &input) { if (input.flags & TOUCH_DOWN) { if (dragPointerId_ == -1 && bounds_.Contains(input.x, input.y)) { + if (g_Config.bAutoCenterTouchAnalog) { + centerX_ = input.x; + centerY_ = input.y; + } else { + centerX_ = bounds_.centerX(); + centerY_ = bounds_.centerY(); + } dragPointerId_ = input.id; ProcessTouch(input.x, input.y, true); } @@ -259,17 +271,19 @@ void PSPStick::Touch(const TouchInput &input) { if (input.flags & TOUCH_UP) { if (input.id == dragPointerId_) { dragPointerId_ = -1; + centerX_ = bounds_.centerX(); + centerY_ = bounds_.centerY(); ProcessTouch(input.x, input.y, false); } } } void PSPStick::ProcessTouch(float x, float y, bool down) { - if (down) { + if (down && centerX_ >= 0.0f) { float inv_stick_size = 1.0f / (stick_size_ * scale_); - float dx = (x - bounds_.centerX()) * inv_stick_size; - float dy = (y - bounds_.centerY()) * inv_stick_size; + float dx = (x - centerX_) * inv_stick_size; + float dy = (y - centerY_) * inv_stick_size; // Do not clamp to a circle! The PSP has nearly square range! // Old code to clamp to a circle diff --git a/UI/GamepadEmu.h b/UI/GamepadEmu.h index a1f552e71c..8b78d7aafd 100644 --- a/UI/GamepadEmu.h +++ b/UI/GamepadEmu.h @@ -118,6 +118,9 @@ private: float scale_; bool dragging_[MAX_POINTERS]; bool lastPointerDown_[MAX_POINTERS]; + + float centerX_; + float centerY_; }; //initializes the layout from Config. if a default layout does not exist,