Skip to content

Commit

Permalink
Basic mappable gesture
Browse files Browse the repository at this point in the history
  • Loading branch information
iota97 committed Aug 4, 2020
1 parent 9f147e8 commit 859de98
Show file tree
Hide file tree
Showing 6 changed files with 197 additions and 0 deletions.
9 changes: 9 additions & 0 deletions Core/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -458,12 +458,21 @@ static ConfigSetting generalSettings[] = {
ConfigSetting("GridView2", &g_Config.bGridView2, true),
ConfigSetting("GridView3", &g_Config.bGridView3, false),
ConfigSetting("ComboMode", &g_Config.iComboMode, 0),

ConfigSetting("RightAnalogUp", &g_Config.iRightAnalogUp, 0, true, true),
ConfigSetting("RightAnalogDown", &g_Config.iRightAnalogDown, 0, true, true),
ConfigSetting("RightAnalogLeft", &g_Config.iRightAnalogLeft, 0, true, true),
ConfigSetting("RightAnalogRight", &g_Config.iRightAnalogRight, 0, true, true),
ConfigSetting("RightAnalogPress", &g_Config.iRightAnalogPress, 0, true, true),
ConfigSetting("RightAnalogCustom", &g_Config.bRightAnalogCustom, false, true, true),
ConfigSetting("SwipeUp", &g_Config.iSwipeUp, 0, true, true),
ConfigSetting("SwipeDown", &g_Config.iSwipeDown, 0, true, true),
ConfigSetting("SwipeLeft", &g_Config.iSwipeLeft, 0, true, true),
ConfigSetting("SwipeRight", &g_Config.iSwipeRight, 0, true, true),
ConfigSetting("SwipeSensitivity", &g_Config.fSwipeSensitivity, 1.0f, true, true),
ConfigSetting("SwipeSmoothing", &g_Config.fSwipeSmoothing, 0.3f, true, true),
ConfigSetting("DoubleTapGesture", &g_Config.iDoubleTapGesture, 0, true, true),
ConfigSetting("GestureControlEnabled", &g_Config.bGestureControlEnabled, false),

// "default" means let emulator decide, "" means disable.
ConfigSetting("ReportingHost", &g_Config.sReportHost, "default"),
Expand Down
10 changes: 10 additions & 0 deletions Core/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,16 @@ struct Config {
int iRightAnalogPress;
bool bRightAnalogCustom;

// Motion gesture controller
bool bGestureControlEnabled;
int iSwipeUp;
int iSwipeDown;
int iSwipeLeft;
int iSwipeRight;
float fSwipeSensitivity;
float fSwipeSmoothing;
int iDoubleTapGesture;

// Disable diagonals
bool bDisableDpadDiagonals;
bool bGamepadOnlyFocused;
Expand Down
33 changes: 33 additions & 0 deletions UI/GameSettingsScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,10 @@ void GameSettingsScreen::CreateViews() {
static const char *touchControlStyles[] = {"Classic", "Thin borders", "Glowing borders"};
View *style = controlsSettings->Add(new PopupMultiChoice(&g_Config.iTouchButtonStyle, co->T("Button style"), touchControlStyles, 0, ARRAY_SIZE(touchControlStyles), co->GetName(), screenManager()));
style->SetEnabledPtr(&g_Config.bShowTouchControls);
controlsSettings->Add(new Choice(co->T("Gesture mapping")))->OnClick.Add([=](EventParams &e) {
screenManager()->push(new GestureMappingScreen());
return UI::EVENT_DONE;
});
}

#ifdef _WIN32
Expand Down Expand Up @@ -1976,3 +1980,32 @@ void SettingInfoMessage::Draw(UIContext &dc) {
text_->SetTextColor(whiteAlpha(alpha));
ViewGroup::Draw(dc);
}

void GestureMappingScreen::CreateViews() {
using namespace UI;

auto di = GetI18NCategory("Dialog");
auto co = GetI18NCategory("Controls");
auto mc = GetI18NCategory("MappableControls");

root_ = new AnchorLayout(new LayoutParams(FILL_PARENT, FILL_PARENT));
Choice *back = new Choice(di->T("Back"), "", false, new AnchorLayoutParams(130, WRAP_CONTENT, 10, NONE, NONE, 10));
root_->Add(back)->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
TabHolder *tabHolder = new TabHolder(ORIENT_VERTICAL, 140, new AnchorLayoutParams(10, 0, 10, 0, false));
root_->Add(tabHolder);
ScrollView *rightPanel = new ScrollView(ORIENT_VERTICAL);
tabHolder->AddTab(co->T("Gesture"), rightPanel);
LinearLayout *vert = rightPanel->Add(new LinearLayout(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, FILL_PARENT)));
vert->SetSpacing(0);

static const char *gestureButton[] = {"None", "L", "R", "Square", "Triangle", "Circle", "Cross", "D-pad up", "D-pad down", "D-pad left", "D-pad right", "Start", "Select"};
vert->Add(new CheckBox(&g_Config.bGestureControlEnabled, co->T("Enable gesture control")));
vert->Add(new PopupMultiChoice(&g_Config.iSwipeUp, mc->T("Swipe Up"), gestureButton, 0, ARRAY_SIZE(gestureButton), mc->GetName(), screenManager()))->SetEnabledPtr(&g_Config.bGestureControlEnabled);
vert->Add(new PopupMultiChoice(&g_Config.iSwipeDown, mc->T("Swipe Down"), gestureButton, 0, ARRAY_SIZE(gestureButton), mc->GetName(), screenManager()))->SetEnabledPtr(&g_Config.bGestureControlEnabled);
vert->Add(new PopupMultiChoice(&g_Config.iSwipeLeft, mc->T("Swipe Left"), gestureButton, 0, ARRAY_SIZE(gestureButton), mc->GetName(), screenManager()))->SetEnabledPtr(&g_Config.bGestureControlEnabled);
vert->Add(new PopupMultiChoice(&g_Config.iSwipeRight, mc->T("Swipe Right"), gestureButton, 0, ARRAY_SIZE(gestureButton), mc->GetName(), screenManager()))->SetEnabledPtr(&g_Config.bGestureControlEnabled);
vert->Add(new PopupSliderChoiceFloat(&g_Config.fSwipeSensitivity, 0.01f, 1.0f, co->T("Swipe sensitivity"), 0.01f, screenManager(), "x"))->SetEnabledPtr(&g_Config.bGestureControlEnabled);
vert->Add(new PopupSliderChoiceFloat(&g_Config.fSwipeSmoothing, 0.0f, 0.95f, co->T("Swipe smoothing"), 0.05f, screenManager(), "x"))->SetEnabledPtr(&g_Config.bGestureControlEnabled);
vert->Add(new PopupMultiChoice(&g_Config.iDoubleTapGesture, mc->T("Double tap button"), gestureButton, 0, ARRAY_SIZE(gestureButton), mc->GetName(), screenManager()))->SetEnabledPtr(&g_Config.bGestureControlEnabled);
}

6 changes: 6 additions & 0 deletions UI/GameSettingsScreen.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,3 +238,9 @@ class HostnameSelectScreen : public PopupScreen {
std::string lastResolved_ = "";
bool lastResolvedResult_ = false;
};


class GestureMappingScreen : public UIDialogScreenWithBackground {
public:
void CreateViews() override;
};
116 changes: 116 additions & 0 deletions UI/GamepadEmu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
#include "math/math_util.h"
#include "ui/ui_context.h"

static uint32_t usedPointerMask = 0;

static u32 GetButtonColor() {
return g_Config.iTouchButtonStyle != 0 ? 0xFFFFFF : 0xc0b080;
}
Expand Down Expand Up @@ -84,6 +86,7 @@ void MultiTouchButton::Touch(const TouchInput &input) {
GamepadView::Touch(input);
if ((input.flags & TOUCH_DOWN) && bounds_.Contains(input.x, input.y)) {
pointerDownMask_ |= 1 << input.id;
usedPointerMask |= 1 << input.id;
}
if (input.flags & TOUCH_MOVE) {
if (bounds_.Contains(input.x, input.y))
Expand All @@ -93,9 +96,11 @@ void MultiTouchButton::Touch(const TouchInput &input) {
}
if (input.flags & TOUCH_UP) {
pointerDownMask_ &= ~(1 << input.id);
usedPointerMask &= ~(1 << input.id);
}
if (input.flags & TOUCH_RELEASE_ALL) {
pointerDownMask_ = 0;
usedPointerMask = 0;
}
}

Expand Down Expand Up @@ -273,6 +278,7 @@ void PSPDpad::Touch(const TouchInput &input) {
if (input.flags & TOUCH_DOWN) {
if (dragPointerId_ == -1 && bounds_.Contains(input.x, input.y)) {
dragPointerId_ = input.id;
usedPointerMask |= 1 << input.id;
ProcessTouch(input.x, input.y, true);
}
}
Expand All @@ -284,6 +290,7 @@ void PSPDpad::Touch(const TouchInput &input) {
if (input.flags & TOUCH_UP) {
if (input.id == dragPointerId_) {
dragPointerId_ = -1;
usedPointerMask &= ~(1 << input.id);
ProcessTouch(input.x, input.y, false);
}
}
Expand Down Expand Up @@ -433,6 +440,7 @@ void PSPStick::Touch(const TouchInput &input) {
centerY_ = bounds_.centerY();
__CtrlSetAnalogX(0.0f, stick_);
__CtrlSetAnalogY(0.0f, stick_);
usedPointerMask = 0;
return;
}
if (input.flags & TOUCH_DOWN) {
Expand All @@ -445,6 +453,7 @@ void PSPStick::Touch(const TouchInput &input) {
centerY_ = bounds_.centerY();
}
dragPointerId_ = input.id;
usedPointerMask |= 1 << input.id;
ProcessTouch(input.x, input.y, true);
}
}
Expand All @@ -458,6 +467,7 @@ void PSPStick::Touch(const TouchInput &input) {
dragPointerId_ = -1;
centerX_ = bounds_.centerX();
centerY_ = bounds_.centerY();
usedPointerMask &= ~(1 << input.id);
ProcessTouch(input.x, input.y, false);
}
}
Expand Down Expand Up @@ -533,6 +543,7 @@ void PSPCustomStick::Touch(const TouchInput &input) {
centerY_ = bounds_.centerY();
posX_ = 0.0f;
posY_ = 0.0f;
usedPointerMask = 0;
return;
}
if (input.flags & TOUCH_DOWN) {
Expand All @@ -545,6 +556,7 @@ void PSPCustomStick::Touch(const TouchInput &input) {
centerY_ = bounds_.centerY();
}
dragPointerId_ = input.id;
usedPointerMask |= 1 << input.id;
ProcessTouch(input.x, input.y, true);
}
}
Expand All @@ -558,6 +570,7 @@ void PSPCustomStick::Touch(const TouchInput &input) {
dragPointerId_ = -1;
centerX_ = bounds_.centerX();
centerY_ = bounds_.centerY();
usedPointerMask &= ~(1 << input.id);
ProcessTouch(input.x, input.y, false);
}
}
Expand Down Expand Up @@ -865,5 +878,108 @@ UI::ViewGroup *CreatePadLayout(float xres, float yres, bool *pause) {
addComboKey(g_Config.iCombokey3, g_Config.bComboToggle3, roundImage, ImageID("I_ROUND"), comboKeyImages[3], g_Config.touchCombo3);
addComboKey(g_Config.iCombokey4, g_Config.bComboToggle4, roundImage, ImageID("I_ROUND"), comboKeyImages[4], g_Config.touchCombo4);

if (g_Config.bGestureControlEnabled)
root->Add(new GestureGamepad());

return root;
}


void GestureGamepad::Touch(const TouchInput &input) {
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 (usedPointerMask & (1 << input.id)) {
if (input.id == dragPointerId_)
dragPointerId_ = -1;
return;
}

if (input.flags & TOUCH_RELEASE_ALL) {
dragPointerId_ = -1;
return;
}

if (input.flags & TOUCH_DOWN) {
if (dragPointerId_ == -1) {
dragPointerId_ = input.id;
lastX_ = input.x;
lastY_ = input.y;

const float now = time_now();
if (now - lastTapRelease_ < 0.3f && !haveDoubleTapped_) {
if (g_Config.iDoubleTapGesture != 0 )
__CtrlButtonDown(button[g_Config.iDoubleTapGesture-1]);
haveDoubleTapped_ = true;
}

lastTouchDown_ = now;
}
}
if (input.flags & TOUCH_MOVE) {
if (input.id == dragPointerId_) {
deltaX_ += input.x - lastX_;
deltaY_ += input.y - lastY_;
lastX_ = input.x;
lastY_ = input.y;
}
}
if (input.flags & TOUCH_UP) {
if (input.id == dragPointerId_) {
dragPointerId_ = -1;
if (time_now() - lastTouchDown_ < 0.3f)
lastTapRelease_ = time_now();

if (haveDoubleTapped_) {
if (g_Config.iDoubleTapGesture != 0)
__CtrlButtonUp(button[g_Config.iDoubleTapGesture-1]);
haveDoubleTapped_ = false;
}
}
}
}

void GestureGamepad::Update() {
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};

const float th = 1.0f;
float dx = deltaX_ * g_dpi_scale_x * g_Config.fSwipeSensitivity;
float dy = deltaY_ * g_dpi_scale_y * g_Config.fSwipeSensitivity;
if (g_Config.iSwipeRight != 0) {
if (dx > th) {
__CtrlButtonDown(button[g_Config.iSwipeRight-1]);
swipeRightReleased_ = false;
} else if (!swipeRightReleased_) {
__CtrlButtonUp(button[g_Config.iSwipeRight-1]);
swipeRightReleased_ = true;
}
}
if (g_Config.iSwipeLeft != 0) {
if (dx < -th) {
__CtrlButtonDown(button[g_Config.iSwipeLeft-1]);
swipeLeftReleased_ = false;
} else if (!swipeLeftReleased_) {
__CtrlButtonUp(button[g_Config.iSwipeLeft-1]);
swipeLeftReleased_ = true;
}
}
if (g_Config.iSwipeUp != 0) {
if (dy < -th) {
__CtrlButtonDown(button[g_Config.iSwipeUp-1]);
swipeUpReleased_ = false;
} else if (!swipeUpReleased_) {
__CtrlButtonUp(button[g_Config.iSwipeUp-1]);
swipeUpReleased_ = true;
}
}
if (g_Config.iSwipeDown != 0) {
if (dy > th) {
__CtrlButtonDown(button[g_Config.iSwipeDown-1]);
swipeDownReleased_ = false;
} else if (!swipeDownReleased_) {
__CtrlButtonUp(button[g_Config.iSwipeDown-1]);
swipeDownReleased_ = true;
}
}
deltaX_ *= g_Config.fSwipeSmoothing;
deltaY_ *= g_Config.fSwipeSmoothing;
}
23 changes: 23 additions & 0 deletions UI/GamepadEmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,3 +209,26 @@ class ComboKey : public MultiTouchButton {
int pspButtonBit_;
bool toggle_;
};

class GestureGamepad : public UI::View {
public:
GestureGamepad() {};

void Touch(const TouchInput &input) override;
void Update() override;

protected:

float lastX_ = 0.0f;
float lastY_ = 0.0f;
float deltaX_ = 0.0f;
float deltaY_ = 0.0f;
float lastTapRelease_ = 0.0f;
float lastTouchDown_ = 0.0f;
int dragPointerId_ = -1;
bool swipeLeftReleased_ = true;
bool swipeRightReleased_ = true;
bool swipeUpReleased_ = true;
bool swipeDownReleased_ = true;
bool haveDoubleTapped_ = false;
};

0 comments on commit 859de98

Please sign in to comment.