From a266ca3737415859eb1fb24c344a3588277ec369 Mon Sep 17 00:00:00 2001 From: iota97 Date: Thu, 30 Jan 2020 11:27:58 +0100 Subject: [PATCH] Separate custom analog from sceCtrl --- Core/HLE/sceCtrl.cpp | 5 +- UI/GamepadEmu.cpp | 191 +++++++++++++++++++++++++++++++++---------- UI/GamepadEmu.h | 24 ++++++ 3 files changed, 174 insertions(+), 46 deletions(-) diff --git a/Core/HLE/sceCtrl.cpp b/Core/HLE/sceCtrl.cpp index d4511934294a..6074b1601f31 100644 --- a/Core/HLE/sceCtrl.cpp +++ b/Core/HLE/sceCtrl.cpp @@ -53,7 +53,7 @@ struct CtrlData { // The PSP has only one stick, but has space for more info. // The second stick is populated for HD remasters and possibly in the PSP emulator on PS3/Vita. u8 analog[2][2]; - u8 unused[4]; // First 2 byte are used from custom right analog + u8 unused[4]; }; struct CtrlLatch { @@ -321,9 +321,6 @@ void __CtrlInit() memset(&ctrlCurrent, 0, sizeof(ctrlCurrent)); memset(ctrlCurrent.analog, CTRL_ANALOG_CENTER, sizeof(ctrlCurrent.analog)); - // Set custom right analog to center - ctrlCurrent.unused[0] = CTRL_ANALOG_CENTER; - ctrlCurrent.unused[1] = CTRL_ANALOG_CENTER; analogEnabled = false; for (u32 i = 0; i < NUM_CTRL_BUFFERS; i++) diff --git a/UI/GamepadEmu.cpp b/UI/GamepadEmu.cpp index f3001d30fce0..be4488ed7a2f 100644 --- a/UI/GamepadEmu.cpp +++ b/UI/GamepadEmu.cpp @@ -29,6 +29,7 @@ #include "base/timeutil.h" #include "math/math_util.h" #include "ui/ui_context.h" +#include "Core/Util/AudioFormat.h" // for clamp_u8 static u32 GetButtonColor() { return g_Config.iTouchButtonStyle != 0 ? 0xFFFFFF : 0xc0b080; @@ -413,6 +414,115 @@ void PSPStick::Touch(const TouchInput &input) { } void PSPStick::ProcessTouch(float x, float y, bool down) { + if (down && centerX_ >= 0.0f) { + float inv_stick_size = 1.0f / (stick_size_ * scale_); + + 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 + // float len = sqrtf(dx * dx + dy * dy); + // if (len > 1.0f) { + // dx /= len; + // dy /= len; + //} + + // Still need to clamp to a square + dx = std::min(1.0f, std::max(-1.0f, dx)); + dy = std::min(1.0f, std::max(-1.0f, dy)); + + __CtrlSetAnalogX(dx, stick_); + __CtrlSetAnalogY(-dy, stick_); + } else { + __CtrlSetAnalogX(0.0f, stick_); + __CtrlSetAnalogY(0.0f, stick_); + } +} + +PSPCustomStick::PSPCustomStick(int bgImg, int stickImg, int stickDownImg, float scale, UI::LayoutParams *layoutParams) + : GamepadView(layoutParams), dragPointerId_(-1), bgImg_(bgImg), stickImageIndex_(stickImg), stickDownImg_(stickDownImg), scale_(scale), centerX_(-1), centerY_(-1) { + stick_size_ = 50; + posX_ = clamp_u8((int)ceilf(127.5f)); + posY_ = clamp_u8((int)ceilf(127.5f)); +} + +void PSPCustomStick::GetContentDimensions(const UIContext &dc, float &w, float &h) const { + const AtlasImage &image = dc.Draw()->GetAtlas()->images[bgImg_]; + w = image.w; + h = image.h; +} + +void PSPCustomStick::Draw(UIContext &dc) { + float opacity = GetButtonOpacity(); + if (opacity <= 0.0f) + return; + + if (dragPointerId_ != -1 && g_Config.iTouchButtonStyle == 2) { + opacity *= 1.35f; + } + + uint32_t colorBg = colorAlpha(GetButtonColor(), opacity); + uint32_t downBg = colorAlpha(0x00FFFFFF, opacity * 0.5f); + uint32_t color = colorAlpha(0x808080, opacity); + + if (centerX_ < 0.0f) { + centerX_ = bounds_.centerX(); + centerY_ = bounds_.centerY(); + } + + float stickX = centerX_; + float stickY = centerY_; + + float dx, dy; + dx = (posX_ - 127.5f) / 127.5f; + dy = -(posY_ - 127.5f) / 127.5f; + + dc.Draw()->DrawImage(bgImg_, stickX, stickY, 1.0f * scale_, colorBg, ALIGN_CENTER); + if (dragPointerId_ != -1 && g_Config.iTouchButtonStyle == 2 && stickDownImg_ != stickImageIndex_) + dc.Draw()->DrawImage(stickDownImg_, stickX + dx * stick_size_ * scale_, stickY - dy * stick_size_ * scale_, 1.0f * scale_, downBg, ALIGN_CENTER); + dc.Draw()->DrawImage(stickImageIndex_, stickX + dx * stick_size_ * scale_, stickY - dy * stick_size_ * scale_, 1.0f * scale_, colorBg, ALIGN_CENTER); +} + +void PSPCustomStick::Touch(const TouchInput &input) { + GamepadView::Touch(input); + if (input.flags & TOUCH_RELEASE_ALL) { + dragPointerId_ = -1; + centerX_ = bounds_.centerX(); + centerY_ = bounds_.centerY(); + posX_ = clamp_u8((int)ceilf(127.5f)); + posY_ = clamp_u8((int)ceilf(127.5f)); + return; + } + 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); + } + } + if (input.flags & TOUCH_MOVE) { + if (input.id == dragPointerId_) { + ProcessTouch(input.x, input.y, true); + } + } + if (input.flags & TOUCH_UP) { + if (input.id == dragPointerId_) { + dragPointerId_ = -1; + centerX_ = bounds_.centerX(); + centerY_ = bounds_.centerY(); + ProcessTouch(input.x, input.y, false); + } + } +} + +void PSPCustomStick::ProcessTouch(float x, float y, bool down) { static const int button[16] = {CTRL_LTRIGGER, CTRL_RTRIGGER, CTRL_SQUARE, CTRL_TRIANGLE, CTRL_CIRCLE, CTRL_CROSS, CTRL_UP, CTRL_DOWN, CTRL_LEFT, CTRL_RIGHT, CTRL_START, CTRL_SELECT}; if (down && centerX_ >= 0.0f) { @@ -433,53 +543,50 @@ void PSPStick::ProcessTouch(float x, float y, bool down) { dx = std::min(1.0f, std::max(-1.0f, dx)); dy = std::min(1.0f, std::max(-1.0f, dy)); - if (stick_ == 2) { // Custom right analog - if (g_Config.iRightAnalogRight != 0) { - if (dx > 0.5f) - __CtrlButtonDown(button[g_Config.iRightAnalogRight-1]); - else - __CtrlButtonUp(button[g_Config.iRightAnalogRight-1]); - } - if (g_Config.iRightAnalogLeft != 0) { - if (dx < -0.5f) - __CtrlButtonDown(button[g_Config.iRightAnalogLeft-1]); - else - __CtrlButtonUp(button[g_Config.iRightAnalogLeft-1]); - } - if (g_Config.iRightAnalogUp != 0) { - if (dy < -0.5f) - __CtrlButtonDown(button[g_Config.iRightAnalogUp-1]); - else - __CtrlButtonUp(button[g_Config.iRightAnalogUp-1]); - } - if (g_Config.iRightAnalogDown != 0) { - if (dy > 0.5f) - __CtrlButtonDown(button[g_Config.iRightAnalogDown-1]); - else - __CtrlButtonUp(button[g_Config.iRightAnalogDown-1]); - } - if (g_Config.iRightAnalogPress != 0) - __CtrlButtonDown(button[g_Config.iRightAnalogPress-1]); + if (g_Config.iRightAnalogRight != 0) { + if (dx > 0.5f) + __CtrlButtonDown(button[g_Config.iRightAnalogRight-1]); + else + __CtrlButtonUp(button[g_Config.iRightAnalogRight-1]); } + if (g_Config.iRightAnalogLeft != 0) { + if (dx < -0.5f) + __CtrlButtonDown(button[g_Config.iRightAnalogLeft-1]); + else + __CtrlButtonUp(button[g_Config.iRightAnalogLeft-1]); + } + if (g_Config.iRightAnalogUp != 0) { + if (dy < -0.5f) + __CtrlButtonDown(button[g_Config.iRightAnalogUp-1]); + else + __CtrlButtonUp(button[g_Config.iRightAnalogUp-1]); + } + if (g_Config.iRightAnalogDown != 0) { + if (dy > 0.5f) + __CtrlButtonDown(button[g_Config.iRightAnalogDown-1]); + else + __CtrlButtonUp(button[g_Config.iRightAnalogDown-1]); + } + if (g_Config.iRightAnalogPress != 0) + __CtrlButtonDown(button[g_Config.iRightAnalogPress-1]); + + posX_ = clamp_u8((int)ceilf(dx * 127.5f + 127.5f)); + posY_ = clamp_u8((int)ceilf(dy * 127.5f + 127.5f)); - __CtrlSetAnalogX(dx, stick_); - __CtrlSetAnalogY(-dy, stick_); } else { - if (stick_ == 2) { // Custom right analog - if (g_Config.iRightAnalogUp != 0) + if (g_Config.iRightAnalogUp != 0) __CtrlButtonUp(button[g_Config.iRightAnalogUp-1]); - if (g_Config.iRightAnalogDown != 0) + if (g_Config.iRightAnalogDown != 0) __CtrlButtonUp(button[g_Config.iRightAnalogDown-1]); - if (g_Config.iRightAnalogLeft != 0) - __CtrlButtonUp(button[g_Config.iRightAnalogLeft-1]); - if (g_Config.iRightAnalogRight != 0) - __CtrlButtonUp(button[g_Config.iRightAnalogRight-1]); - if (g_Config.iRightAnalogPress != 0) - __CtrlButtonUp(button[g_Config.iRightAnalogPress-1]); - } + if (g_Config.iRightAnalogLeft != 0) + __CtrlButtonUp(button[g_Config.iRightAnalogLeft-1]); + if (g_Config.iRightAnalogRight != 0) + __CtrlButtonUp(button[g_Config.iRightAnalogRight-1]); + if (g_Config.iRightAnalogPress != 0) + __CtrlButtonUp(button[g_Config.iRightAnalogPress-1]); - __CtrlSetAnalogX(0.0f, stick_); - __CtrlSetAnalogY(0.0f, stick_); + posX_ = clamp_u8((int)ceilf(127.5f)); + posY_ = clamp_u8((int)ceilf(127.5f)); } } @@ -697,7 +804,7 @@ UI::ViewGroup *CreatePadLayout(float xres, float yres, bool *pause) { if (g_Config.touchRightAnalogStick.show) { if (g_Config.bRightAnalogCustom) - root->Add(new PSPStick(stickBg, stickImage, I_STICK, 2, g_Config.touchRightAnalogStick.scale, buttonLayoutParams(g_Config.touchRightAnalogStick))); + root->Add(new PSPCustomStick(stickBg, stickImage, I_STICK, g_Config.touchRightAnalogStick.scale, buttonLayoutParams(g_Config.touchRightAnalogStick))); else root->Add(new PSPStick(stickBg, stickImage, I_STICK, 1, g_Config.touchRightAnalogStick.scale, buttonLayoutParams(g_Config.touchRightAnalogStick))); } diff --git a/UI/GamepadEmu.h b/UI/GamepadEmu.h index ec52ac575b92..0472e0f35455 100644 --- a/UI/GamepadEmu.h +++ b/UI/GamepadEmu.h @@ -153,6 +153,30 @@ class PSPStick : public GamepadView { float centerY_; }; +class PSPCustomStick : public GamepadView { +public: + PSPCustomStick(int bgImg, int stickImg, int stickDownImg, float scale, UI::LayoutParams *layoutParams); + + void Touch(const TouchInput &input) override; + void Draw(UIContext &dc) override; + void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; + +private: + void ProcessTouch(float x, float y, bool down); + + int dragPointerId_; + int bgImg_; + int stickImageIndex_; + int stickDownImg_; + float stick_size_; + float scale_; + + float centerX_; + float centerY_; + u8 posX_; + u8 posY_; +}; + //initializes the layout from Config. if a default layout does not exist, //it sets up default values void InitPadLayout(float xres, float yres, float globalScale = 1.15f);