mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-01-31 02:23:51 +00:00
Merge pull request #12486 from iota97/dpad
Rebindable touch right analog
This commit is contained in:
commit
2843b8ef5f
@ -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"),
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user