Merge pull request #12486 from iota97/dpad

Rebindable touch right analog
This commit is contained in:
Henrik Rydgård 2020-05-17 20:51:40 +02:00 committed by GitHub
commit 2843b8ef5f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 228 additions and 15 deletions

View File

@ -456,6 +456,12 @@ 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),
ConfigSetting("RightAnalogDown", &g_Config.iRightAnalogDown, 0),
ConfigSetting("RightAnalogLeft", &g_Config.iRightAnalogLeft, 0),
ConfigSetting("RightAnalogRight", &g_Config.iRightAnalogRight, 0),
ConfigSetting("RightAnalogPress", &g_Config.iRightAnalogPress, 0),
ConfigSetting("RightAnalogCustom", &g_Config.bRightAnalogCustom, false),
// "default" means let emulator decide, "" means disable.
ConfigSetting("ReportingHost", &g_Config.sReportHost, "default"),

View File

@ -288,6 +288,14 @@ public:
//Combo key screen flag
int iComboMode;
// Right analog binding
int iRightAnalogUp;
int iRightAnalogDown;
int iRightAnalogLeft;
int iRightAnalogRight;
int iRightAnalogPress;
bool bRightAnalogCustom;
// Disable diagonals
bool bDisableDpadDiagonals;
bool bGamepadOnlyFocused;

View File

@ -490,6 +490,138 @@ void PSPStick::ProcessTouch(float x, float y, bool down) {
}
}
PSPCustomStick::PSPCustomStick(ImageID bgImg, ImageID stickImg, ImageID stickDownImg, float scale, UI::LayoutParams *layoutParams)
: PSPStick(bgImg, stickImg, stickDownImg, -1, scale, layoutParams) {
}
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_;
dy = -posY_;
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_ = 0.0f;
posY_ = 0.0f;
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) {
float inv_stick_size = 1.0f / (stick_size_ * scale_);
float dx = (x - centerX_) * inv_stick_size;
float dy = (y - centerY_) * inv_stick_size;
dx = std::min(1.0f, std::max(-1.0f, dx));
dy = std::min(1.0f, std::max(-1.0f, dy));
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_ = dx;
posY_ = dy;
} else {
if (g_Config.iRightAnalogUp != 0)
__CtrlButtonUp(button[g_Config.iRightAnalogUp-1]);
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]);
posX_ = 0.0f;
posY_ = 0.0f;
}
}
void InitPadLayout(float xres, float yres, float globalScale) {
const float scale = globalScale;
const int halfW = xres / 2;
@ -720,8 +852,12 @@ UI::ViewGroup *CreatePadLayout(float xres, float yres, bool *pause) {
if (g_Config.touchAnalogStick.show)
root->Add(new PSPStick(stickBg, stickImage, ImageID("I_STICK"), 0, g_Config.touchAnalogStick.scale, buttonLayoutParams(g_Config.touchAnalogStick)));
if (g_Config.touchRightAnalogStick.show)
root->Add(new PSPStick(stickBg, stickImage, ImageID("I_STICK"), 1, g_Config.touchRightAnalogStick.scale, buttonLayoutParams(g_Config.touchRightAnalogStick)));
if (g_Config.touchRightAnalogStick.show) {
if (g_Config.bRightAnalogCustom)
root->Add(new PSPCustomStick(stickBg, stickImage, ImageID("I_STICK"), g_Config.touchRightAnalogStick.scale, buttonLayoutParams(g_Config.touchRightAnalogStick)));
else
root->Add(new PSPStick(stickBg, stickImage, ImageID("I_STICK"), 1, g_Config.touchRightAnalogStick.scale, buttonLayoutParams(g_Config.touchRightAnalogStick)));
}
addComboKey(g_Config.iCombokey0, g_Config.bComboToggle0, roundImage, ImageID("I_ROUND"), comboKeyImages[0], g_Config.touchCombo0);
addComboKey(g_Config.iCombokey1, g_Config.bComboToggle1, roundImage, ImageID("I_ROUND"), comboKeyImages[1], g_Config.touchCombo1);

View File

@ -160,9 +160,7 @@ public:
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);
protected:
int dragPointerId_;
ImageID bgImg_;
ImageID stickImageIndex_;
@ -174,6 +172,23 @@ private:
float centerX_;
float centerY_;
private:
void ProcessTouch(float x, float y, bool down);
};
class PSPCustomStick : public PSPStick {
public:
PSPCustomStick(ImageID bgImg, ImageID stickImg, ImageID stickDownImg, float scale, UI::LayoutParams *layoutParams);
void Touch(const TouchInput &input) override;
void Draw(UIContext &dc) override;
private:
void ProcessTouch(float x, float y, bool down);
float posX_ = 0.0f;
float posY_ = 0.0f;
};
//initializes the layout from Config. if a default layout does not exist,

View File

@ -70,6 +70,7 @@ void TouchControlVisibilityScreen::CreateViews() {
gridsettings.fillCells = true;
GridLayout *grid = vert->Add(new GridLayout(gridsettings, new LayoutParams(FILL_PARENT, WRAP_CONTENT)));
static const char* rightAnalogKey = "Right Analog Stick (tap to customize)";
toggles_.clear();
toggles_.push_back({ "Circle", &g_Config.bShowTouchCircle, ImageID("I_CIRCLE") });
toggles_.push_back({ "Cross", &g_Config.bShowTouchCross, ImageID("I_CROSS") });
@ -81,7 +82,7 @@ void TouchControlVisibilityScreen::CreateViews() {
toggles_.push_back({ "Select", &g_Config.touchSelectKey.show, ImageID("I_SELECT") });
toggles_.push_back({ "Dpad", &g_Config.touchDpad.show, ImageID::invalid() });
toggles_.push_back({ "Analog Stick", &g_Config.touchAnalogStick.show, ImageID::invalid() });
toggles_.push_back({ "Right Analog Stick\n(not used by most games)", &g_Config.touchRightAnalogStick.show, ImageID::invalid() });
toggles_.push_back({ rightAnalogKey, &g_Config.touchRightAnalogStick.show, ImageID::invalid() });
toggles_.push_back({ "Unthrottle", &g_Config.touchUnthrottleKey.show, ImageID::invalid() });
toggles_.push_back({ "Combo0", &g_Config.touchCombo0.show, ImageID("I_1") });
toggles_.push_back({ "Combo1", &g_Config.touchCombo1.show, ImageID("I_2") });
@ -95,7 +96,6 @@ void TouchControlVisibilityScreen::CreateViews() {
toggles_.push_back({ "Auto Analog Rotation (CCW)", &g_Config.touchAnalogRotationCCWKey.show, ImageID::invalid() });
auto mc = GetI18NCategory("MappableControls");
for (auto toggle : toggles_) {
LinearLayout *row = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT));
row->SetSpacing(0);
@ -103,16 +103,20 @@ void TouchControlVisibilityScreen::CreateViews() {
CheckBox *checkbox = new CheckBox(toggle.show, "", "", new LinearLayoutParams(50, WRAP_CONTENT));
row->Add(checkbox);
Choice *choice;
if (toggle.img.isValid()) {
choice = new CheckBoxChoice(toggle.img, checkbox, new LinearLayoutParams(1.0f));
if (toggle.key == rightAnalogKey) {
Choice *rightAnalog = new Choice(co->T(rightAnalogKey), "", false, new LinearLayoutParams(1.0f));
rightAnalog->SetCentered(true);
row->Add(rightAnalog)->OnClick.Handle(this, &TouchControlVisibilityScreen::RightAnalogBindScreen);
} else {
choice = new CheckBoxChoice(mc->T(toggle.key), checkbox, new LinearLayoutParams(1.0f));
Choice *choice;
if (toggle.img.isValid()) {
choice = new CheckBoxChoice(toggle.img, checkbox, new LinearLayoutParams(1.0f));
} else {
choice = new CheckBoxChoice(mc->T(toggle.key), checkbox, new LinearLayoutParams(1.0f));
}
choice->SetCentered(true);
row->Add(choice);
}
choice->SetCentered(true);
row->Add(choice);
grid->Add(row);
}
}
@ -121,6 +125,38 @@ void TouchControlVisibilityScreen::onFinish(DialogResult result) {
g_Config.Save("TouchControlVisibilityScreen::onFinish");
}
void RightAnalogMappingScreen::CreateViews() {
using namespace UI;
auto di = GetI18NCategory("Dialog");
auto co = GetI18NCategory("Controls");
root_ = new AnchorLayout(new LayoutParams(FILL_PARENT, FILL_PARENT));
Choice *back = new Choice(di->T("Back"), "", false, new AnchorLayoutParams(leftColumnWidth - 10, WRAP_CONTENT, 10, NONE, NONE, 10));
root_->Add(back)->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
TabHolder *tabHolder = new TabHolder(ORIENT_VERTICAL, leftColumnWidth, new AnchorLayoutParams(10, 0, 10, 0, false));
root_->Add(tabHolder);
ScrollView *rightPanel = new ScrollView(ORIENT_VERTICAL);
tabHolder->AddTab(co->T("Binds"), rightPanel);
LinearLayout *vert = rightPanel->Add(new LinearLayout(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, FILL_PARENT)));
vert->SetSpacing(0);
static const char *rightAnalogButton[] = {"None", "Left trigger", "Right trigger", "Square", "Triangle", "Circle", "Cross", "D-PAD Up", "D-PAD Down", "D-PAD Left", "D-PAD Right", "Start", "Select"};
vert->Add(new CheckBox(&g_Config.bRightAnalogCustom, co->T("Use custom right analog")));
PopupMultiChoice *rightAnalogUp = vert->Add(new PopupMultiChoice(&g_Config.iRightAnalogUp, co->T("Right analog up"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton), co->GetName(), screenManager()));
PopupMultiChoice *rightAnalogDown = vert->Add(new PopupMultiChoice(&g_Config.iRightAnalogDown, co->T("Right analog down"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton), co->GetName(), screenManager()));
PopupMultiChoice *rightAnalogLeft = vert->Add(new PopupMultiChoice(&g_Config.iRightAnalogLeft, co->T("Right analog left"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton), co->GetName(), screenManager()));
PopupMultiChoice *rightAnalogRight = vert->Add(new PopupMultiChoice(&g_Config.iRightAnalogRight, co->T("Right analog right"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton), co->GetName(), screenManager()));
PopupMultiChoice *rightAnalogPress = vert->Add(new PopupMultiChoice(&g_Config.iRightAnalogPress, co->T("Keep this button pressed when right analog is pressed"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton), co->GetName(), screenManager()));
vert->Add(new CheckBox(&g_Config.touchRightAnalogStick.show, co->T("Show right analog")));
rightAnalogUp->SetEnabledPtr(&g_Config.bRightAnalogCustom);
rightAnalogDown->SetEnabledPtr(&g_Config.bRightAnalogCustom);
rightAnalogLeft->SetEnabledPtr(&g_Config.bRightAnalogCustom);
rightAnalogRight->SetEnabledPtr(&g_Config.bRightAnalogCustom);
rightAnalogPress->SetEnabledPtr(&g_Config.bRightAnalogCustom);
}
UI::EventReturn TouchControlVisibilityScreen::OnToggleAll(UI::EventParams &e) {
for (auto toggle : toggles_) {
*toggle.show = nextToggleAll_;
@ -130,6 +166,12 @@ UI::EventReturn TouchControlVisibilityScreen::OnToggleAll(UI::EventParams &e) {
return UI::EVENT_DONE;
}
UI::EventReturn TouchControlVisibilityScreen::RightAnalogBindScreen(UI::EventParams &e) {
screenManager()->push(new RightAnalogMappingScreen());
return UI::EVENT_DONE;
}
UI::EventReturn CheckBoxChoice::HandleClick(UI::EventParams &e) {
checkbox_->Toggle();

View File

@ -37,8 +37,14 @@ public:
protected:
UI::EventReturn OnToggleAll(UI::EventParams &e);
UI::EventReturn RightAnalogBindScreen(UI::EventParams &e);
private:
std::vector<TouchButtonToggle> toggles_;
bool nextToggleAll_ = true;
};
class RightAnalogMappingScreen : public UIDialogScreenWithBackground {
public:
void CreateViews() override;
};