diff --git a/CMakeLists.txt b/CMakeLists.txt index 768c2b84b9..bf8f62a191 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1291,6 +1291,8 @@ list(APPEND NativeAppSource UI/TouchControlVisibilityScreen.cpp UI/GamepadEmu.h UI/GamepadEmu.cpp + UI/JoystickHistoryView.h + UI/JoystickHistoryView.cpp UI/OnScreenDisplay.h UI/OnScreenDisplay.cpp UI/ControlMappingScreen.h diff --git a/UI/ControlMappingScreen.cpp b/UI/ControlMappingScreen.cpp index b733b1c54c..a639d29b26 100644 --- a/UI/ControlMappingScreen.cpp +++ b/UI/ControlMappingScreen.cpp @@ -45,6 +45,7 @@ #include "Core/Config.h" #include "UI/ControlMappingScreen.h" #include "UI/GameSettingsScreen.h" +#include "UI/JoystickHistoryView.h" #if PPSSPP_PLATFORM(ANDROID) #include "android/jni/app-android.h" @@ -446,132 +447,6 @@ void KeyMappingNewMouseKeyDialog::axis(const AxisInput &axis) { } } -enum class StickHistoryViewType { - INPUT, - OUTPUT -}; - -class JoystickHistoryView : public UI::InertView { -public: - JoystickHistoryView(StickHistoryViewType type, std::string title, UI::LayoutParams *layoutParams = nullptr) - : UI::InertView(layoutParams), title_(title), type_(type) {} - void Draw(UIContext &dc) override; - std::string DescribeText() const override { return "Analog Stick View"; } - void Update() override; - void SetXY(float x, float y) { - curX_ = x; - curY_ = y; - } - -private: - struct Location { - float x; - float y; - }; - - float curX_ = 0.0f; - float curY_ = 0.0f; - - std::deque locations_; - int maxCount_ = 500; - std::string title_; - StickHistoryViewType type_; -}; - -void JoystickHistoryView::Draw(UIContext &dc) { - const AtlasImage *image = dc.Draw()->GetAtlas()->getImage(ImageID("I_CROSS")); - if (!image) { - return; - } - float minRadius = std::min(bounds_.w, bounds_.h) * 0.5f - image->w; - dc.Begin(); - Bounds textBounds(bounds_.x, bounds_.centerY() + minRadius + 5.0, bounds_.w, bounds_.h/2 - minRadius - 5.0); - dc.DrawTextShadowRect(title_.c_str(), textBounds, 0xFFFFFFFF, ALIGN_TOP | ALIGN_HCENTER | FLAG_WRAP_TEXT); - dc.Flush(); - dc.BeginNoTex(); - dc.Draw()->RectOutline(bounds_.centerX() - minRadius, bounds_.centerY() - minRadius, minRadius * 2.0f, minRadius * 2.0f, 0x80FFFFFF); - dc.Flush(); - dc.Begin(); - - // First draw a grid. - float dx = 1.0f / 10.0f; - for (int ix = -10; ix <= 10; ix++) { - // First draw vertical lines. - float fx = ix * dx; - for (int iy = -10; iy < 10; iy++) { - float ax = fx; - float ay = iy * dx; - float bx = fx; - float by = (iy + 1) * dx; - - if (type_ == StickHistoryViewType::OUTPUT) { - ConvertAnalogStick(ax, ay); - ConvertAnalogStick(bx, by); - } - - ax = ax * minRadius + bounds_.centerX(); - ay = ay * minRadius + bounds_.centerY(); - - bx = bx * minRadius + bounds_.centerX(); - by = by * minRadius + bounds_.centerY(); - - dc.Draw()->Line(dc.theme->whiteImage, ax, ay, bx, by, 1.0, 0x70FFFFFF); - } - } - - for (int iy = -10; iy <= 10; iy++) { - // Then horizontal. - float fy = iy * dx; - for (int ix = -10; ix < 10; ix++) { - float ax = ix * dx; - float ay = fy; - float bx = (ix + 1) * dx; - float by = fy; - - if (type_ == StickHistoryViewType::OUTPUT) { - ConvertAnalogStick(ax, ay); - ConvertAnalogStick(bx, by); - } - - ax = ax * minRadius + bounds_.centerX(); - ay = ay * minRadius + bounds_.centerY(); - - bx = bx * minRadius + bounds_.centerX(); - by = by * minRadius + bounds_.centerY(); - - dc.Draw()->Line(dc.theme->whiteImage, ax, ay, bx, by, 1.0, 0x70FFFFFF); - } - } - - - int a = maxCount_ - (int)locations_.size(); - for (auto iter = locations_.begin(); iter != locations_.end(); ++iter) { - float x = bounds_.centerX() + minRadius * iter->x; - float y = bounds_.centerY() - minRadius * iter->y; - float alpha = (float)a / (float)(maxCount_ - 1); - if (alpha < 0.0f) { - alpha = 0.0f; - } - // Emphasize the newest (higher) ones. - alpha = powf(alpha, 3.7f); - // Highlight the output. - if (alpha >= 1.0f && type_ == StickHistoryViewType::OUTPUT) { - dc.Draw()->DrawImage(ImageID("I_CIRCLE"), x, y, 1.0f, colorAlpha(0xFFFFFF, 1.0), ALIGN_CENTER); - } else { - dc.Draw()->DrawImage(ImageID("I_CIRCLE"), x, y, 0.8f, colorAlpha(0xC0C0C0, alpha * 0.5f), ALIGN_CENTER); - } - a++; - } - dc.Flush(); -} - -void JoystickHistoryView::Update() { - locations_.push_back(Location{ curX_, curY_ }); - if ((int)locations_.size() > maxCount_) { - locations_.pop_front(); - } -} - AnalogSetupScreen::AnalogSetupScreen(const Path &gamePath) : UIDialogScreenWithGameBackground(gamePath) { mapper_.SetCallbacks([](int vkey) {}, [](int vkey) {}, [&](int stick, float x, float y) { analogX_[stick] = x; diff --git a/UI/JoystickHistoryView.cpp b/UI/JoystickHistoryView.cpp new file mode 100644 index 0000000000..73d45eb5bf --- /dev/null +++ b/UI/JoystickHistoryView.cpp @@ -0,0 +1,100 @@ +#include "UI/JoystickHistoryView.h" +#include "Common/UI/Context.h" +#include "Common/UI/UI.h" + +// From ControlMapper.h +void ConvertAnalogStick(float &x, float &y); + +void JoystickHistoryView::Draw(UIContext &dc) { + const AtlasImage *image = dc.Draw()->GetAtlas()->getImage(ImageID("I_CROSS")); + if (!image) { + return; + } + float minRadius = std::min(bounds_.w, bounds_.h) * 0.5f - image->w; + dc.Begin(); + Bounds textBounds(bounds_.x, bounds_.centerY() + minRadius + 5.0, bounds_.w, bounds_.h / 2 - minRadius - 5.0); + dc.DrawTextShadowRect(title_.c_str(), textBounds, 0xFFFFFFFF, ALIGN_TOP | ALIGN_HCENTER | FLAG_WRAP_TEXT); + dc.Flush(); + dc.BeginNoTex(); + dc.Draw()->RectOutline(bounds_.centerX() - minRadius, bounds_.centerY() - minRadius, minRadius * 2.0f, minRadius * 2.0f, 0x80FFFFFF); + dc.Flush(); + dc.Begin(); + + // First draw a grid. + float dx = 1.0f / 10.0f; + for (int ix = -10; ix <= 10; ix++) { + // First draw vertical lines. + float fx = ix * dx; + for (int iy = -10; iy < 10; iy++) { + float ax = fx; + float ay = iy * dx; + float bx = fx; + float by = (iy + 1) * dx; + + if (type_ == StickHistoryViewType::OUTPUT) { + ConvertAnalogStick(ax, ay); + ConvertAnalogStick(bx, by); + } + + ax = ax * minRadius + bounds_.centerX(); + ay = ay * minRadius + bounds_.centerY(); + + bx = bx * minRadius + bounds_.centerX(); + by = by * minRadius + bounds_.centerY(); + + dc.Draw()->Line(dc.theme->whiteImage, ax, ay, bx, by, 1.0, 0x70FFFFFF); + } + } + + for (int iy = -10; iy <= 10; iy++) { + // Then horizontal. + float fy = iy * dx; + for (int ix = -10; ix < 10; ix++) { + float ax = ix * dx; + float ay = fy; + float bx = (ix + 1) * dx; + float by = fy; + + if (type_ == StickHistoryViewType::OUTPUT) { + ConvertAnalogStick(ax, ay); + ConvertAnalogStick(bx, by); + } + + ax = ax * minRadius + bounds_.centerX(); + ay = ay * minRadius + bounds_.centerY(); + + bx = bx * minRadius + bounds_.centerX(); + by = by * minRadius + bounds_.centerY(); + + dc.Draw()->Line(dc.theme->whiteImage, ax, ay, bx, by, 1.0, 0x70FFFFFF); + } + } + + + int a = maxCount_ - (int)locations_.size(); + for (auto iter = locations_.begin(); iter != locations_.end(); ++iter) { + float x = bounds_.centerX() + minRadius * iter->x; + float y = bounds_.centerY() - minRadius * iter->y; + float alpha = (float)a / (float)(maxCount_ - 1); + if (alpha < 0.0f) { + alpha = 0.0f; + } + // Emphasize the newest (higher) ones. + alpha = powf(alpha, 3.7f); + // Highlight the output. + if (alpha >= 1.0f && type_ == StickHistoryViewType::OUTPUT) { + dc.Draw()->DrawImage(ImageID("I_CIRCLE"), x, y, 1.0f, colorAlpha(0xFFFFFF, 1.0), ALIGN_CENTER); + } else { + dc.Draw()->DrawImage(ImageID("I_CIRCLE"), x, y, 0.8f, colorAlpha(0xC0C0C0, alpha * 0.5f), ALIGN_CENTER); + } + a++; + } + dc.Flush(); +} + +void JoystickHistoryView::Update() { + locations_.push_back(Location{ curX_, curY_ }); + if ((int)locations_.size() > maxCount_) { + locations_.pop_front(); + } +} diff --git a/UI/JoystickHistoryView.h b/UI/JoystickHistoryView.h new file mode 100644 index 0000000000..a68b0d2b60 --- /dev/null +++ b/UI/JoystickHistoryView.h @@ -0,0 +1,38 @@ +#pragma once + +#include + +#include "Common/UI/View.h" + +enum class StickHistoryViewType { + INPUT, + OUTPUT +}; + +class JoystickHistoryView : public UI::InertView { +public: + JoystickHistoryView(StickHistoryViewType type, std::string title, UI::LayoutParams *layoutParams = nullptr) + : UI::InertView(layoutParams), title_(title), type_(type) {} + + void Draw(UIContext &dc) override; + std::string DescribeText() const override { return "Analog Stick View"; } + void Update() override; + void SetXY(float x, float y) { + curX_ = x; + curY_ = y; + } + +private: + struct Location { + float x; + float y; + }; + + float curX_ = 0.0f; + float curY_ = 0.0f; + + std::deque locations_; + int maxCount_ = 500; + std::string title_; + StickHistoryViewType type_; +}; diff --git a/UI/TiltAnalogSettingsScreen.cpp b/UI/TiltAnalogSettingsScreen.cpp index 6c0068b909..587c3cb082 100644 --- a/UI/TiltAnalogSettingsScreen.cpp +++ b/UI/TiltAnalogSettingsScreen.cpp @@ -34,7 +34,7 @@ void TiltAnalogSettingsScreen::CreateViews() { settings->SetSpacing(0); settings->Add(new ItemHeader(co->T("Calibration"))); - InfoItem *calibrationInfo = new InfoItem(co->T("To Calibrate", "To calibrate, keep device on a flat surface and press calibrate."), ""); + InfoItem *calibrationInfo = new InfoItem(co->T("To Calibrate", "Keep device on a flat surface and press calibrate."), ""); settings->Add(calibrationInfo); Choice *calibrate = new Choice(co->T("Calibrate")); calibrate->OnClick.Handle(this, &TiltAnalogSettingsScreen::OnCalibrate); @@ -53,7 +53,6 @@ void TiltAnalogSettingsScreen::CreateViews() { settings->Add(new PopupSliderChoiceFloat(&g_Config.fDeadzoneRadius, 0.0, 1.0, co->T("Deadzone radius"), 0.01f, screenManager(),"/ 1.0")); settings->Add(new PopupSliderChoiceFloat(&g_Config.fTiltDeadzoneSkip, 0.0, 1.0, co->T("Tilt Base Radius"), 0.01f, screenManager(),"/ 1.0")); - root_->Add(settings); settings->Add(new BorderView(BORDER_BOTTOM, BorderStyle::HEADER_FG, 2.0f, new LayoutParams(FILL_PARENT, 40.0f))); settings->Add(new Choice(di->T("Back")))->OnClick.Handle(this, &UIScreen::OnBack); diff --git a/UI/TiltAnalogSettingsScreen.h b/UI/TiltAnalogSettingsScreen.h index 567ed73ae0..dcc4e9b583 100644 --- a/UI/TiltAnalogSettingsScreen.h +++ b/UI/TiltAnalogSettingsScreen.h @@ -22,8 +22,6 @@ class TiltAnalogSettingsScreen : public UIDialogScreenWithBackground { public: - TiltAnalogSettingsScreen() {} - void CreateViews() override; void axis(const AxisInput &axis) override; @@ -34,4 +32,3 @@ private: float currentTiltX_ = 0.0f; float currentTiltY_ = 0.0f; }; - diff --git a/UI/TiltEventProcessor.cpp b/UI/TiltEventProcessor.cpp index e10c0bf90a..36c51124d1 100644 --- a/UI/TiltEventProcessor.cpp +++ b/UI/TiltEventProcessor.cpp @@ -9,6 +9,8 @@ namespace TiltEventProcessor { static u32 tiltButtonsDown = 0; +float rawTiltAnalogX; +float rawTiltAnalogY; //deadzone is normalized - 0 to 1 //sensitivity controls how fast the deadzone reaches max value @@ -71,6 +73,9 @@ Tilt GenTilt(const Tilt &baseTilt, const Tilt ¤tTilt, bool invertX, bool i } void TranslateTiltToInput(const Tilt &tilt) { + rawTiltAnalogX = tilt.x_; + rawTiltAnalogY = tilt.y_; + switch (g_Config.iTiltInputType) { case TILT_NULL: break; diff --git a/UI/TiltEventProcessor.h b/UI/TiltEventProcessor.h index c7c3c754df..8e613d00e9 100644 --- a/UI/TiltEventProcessor.h +++ b/UI/TiltEventProcessor.h @@ -39,4 +39,8 @@ void GenerateTriggerButtonEvent(const Tilt &tilt); void ResetTiltEvents(); +// Lets you preview the amount of tilt in TiltAnalogSettingsScreen. +extern float rawTiltAnalogX; +extern float rawTiltAnalogY; + } // namespace diff --git a/UI/UI.vcxproj b/UI/UI.vcxproj index df884f757b..77977d1616 100644 --- a/UI/UI.vcxproj +++ b/UI/UI.vcxproj @@ -49,6 +49,7 @@ + @@ -83,6 +84,7 @@ + diff --git a/UI/UI.vcxproj.filters b/UI/UI.vcxproj.filters index 3743fe242f..092df509d0 100644 --- a/UI/UI.vcxproj.filters +++ b/UI/UI.vcxproj.filters @@ -2,7 +2,6 @@ - @@ -80,10 +79,15 @@ Screens + + Views + + + Views + - Screens @@ -161,10 +165,19 @@ Screens + + Views + + + Views + {faee5dce-633b-4ba6-b19d-ea70ee3c1c38} + + {071baa63-c681-4ad6-945b-e126645d1b55} + \ No newline at end of file diff --git a/UWP/UI_UWP/UI_UWP.vcxproj b/UWP/UI_UWP/UI_UWP.vcxproj index e2698447e0..43e4bfd18a 100644 --- a/UWP/UI_UWP/UI_UWP.vcxproj +++ b/UWP/UI_UWP/UI_UWP.vcxproj @@ -395,6 +395,7 @@ + @@ -429,6 +430,7 @@ + diff --git a/UWP/UI_UWP/UI_UWP.vcxproj.filters b/UWP/UI_UWP/UI_UWP.vcxproj.filters index e26481b823..0469c1be78 100644 --- a/UWP/UI_UWP/UI_UWP.vcxproj.filters +++ b/UWP/UI_UWP/UI_UWP.vcxproj.filters @@ -33,6 +33,7 @@ + @@ -68,5 +69,6 @@ + \ No newline at end of file diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 64a98c675d..8aa57d384b 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -720,6 +720,7 @@ LOCAL_SRC_FILES := \ $(SRC)/UI/SavedataScreen.cpp \ $(SRC)/UI/Store.cpp \ $(SRC)/UI/GamepadEmu.cpp \ + $(SRC)/UI/JoystickHistoryView.cpp \ $(SRC)/UI/GameInfoCache.cpp \ $(SRC)/UI/GameScreen.cpp \ $(SRC)/UI/ControlMappingScreen.cpp \