From e48ea158e49503fff9023a9393b326fbd54e1da1 Mon Sep 17 00:00:00 2001 From: iota97 Date: Sun, 19 Jun 2022 15:18:05 +0200 Subject: [PATCH] Allow to repeat a "single" button --- Core/Config.cpp | 27 ++++++++++-------- Core/Config.h | 1 + UI/ComboKeyMappingScreen.cpp | 1 + UI/GamepadEmu.cpp | 53 ++++++++++++++++++++++++++++++------ UI/GamepadEmu.h | 7 +++-- 5 files changed, 66 insertions(+), 23 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 42a56958e7..0a87026bf1 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -190,8 +190,8 @@ struct ConfigSetting { default_.touchPos = def; } - ConfigSetting(const char *iniKey, const char *iniImage, const char *iniShape, const char *iniToggle, ConfigCustomButton *v, ConfigCustomButton def, bool save = true, bool perGame = false) - : iniKey_(iniKey), ini2_(iniImage), ini3_(iniShape), ini4_(iniToggle), type_(TYPE_CUSTOM_BUTTON), report_(false), save_(save), perGame_(perGame) { + ConfigSetting(const char *iniKey, const char *iniImage, const char *iniShape, const char *iniToggle, const char *iniRepeat, ConfigCustomButton *v, ConfigCustomButton def, bool save = true, bool perGame = false) + : iniKey_(iniKey), ini2_(iniImage), ini3_(iniShape), ini4_(iniToggle), ini5_(iniRepeat), type_(TYPE_CUSTOM_BUTTON), report_(false), save_(save), perGame_(perGame) { ptr_.customButton = v; cb_.customButton = nullptr; default_.customButton = def; @@ -315,6 +315,7 @@ struct ConfigSetting { section->Get(ini2_, &ptr_.customButton->image, default_.customButton.image); section->Get(ini3_, &ptr_.customButton->shape, default_.customButton.shape); section->Get(ini4_, &ptr_.customButton->toggle, default_.customButton.toggle); + section->Get(ini5_, &ptr_.customButton->repeat, default_.customButton.repeat); return true; default: _dbg_assert_msg_(false, "Unexpected ini setting type"); @@ -358,6 +359,7 @@ struct ConfigSetting { section->Set(ini2_, ptr_.customButton->image); section->Set(ini3_, ptr_.customButton->shape); section->Set(ini4_, ptr_.customButton->toggle); + section->Set(ini5_, ptr_.customButton->repeat); return; default: _dbg_assert_msg_(false, "Unexpected ini setting type"); @@ -400,6 +402,7 @@ struct ConfigSetting { const char *ini2_; const char *ini3_; const char *ini4_; + const char *ini5_; Type type_; bool report_; bool save_; @@ -965,16 +968,16 @@ static ConfigSetting controlSettings[] = { ConfigSetting("ShowTouchSquare", &g_Config.bShowTouchSquare, true, true, true), ConfigSetting("ShowTouchTriangle", &g_Config.bShowTouchTriangle, true, true, true), - ConfigSetting("Custom0Mapping", "Custom0Image", "Custom0Shape", "Custom0Toggle", &g_Config.CustomKey0, {0, 0, 0, false}, true, true), - ConfigSetting("Custom1Mapping", "Custom1Image", "Custom1Shape", "Custom1Toggle", &g_Config.CustomKey1, {0, 1, 0, false}, true, true), - ConfigSetting("Custom2Mapping", "Custom2Image", "Custom2Shape", "Custom2Toggle", &g_Config.CustomKey2, {0, 2, 0, false}, true, true), - ConfigSetting("Custom3Mapping", "Custom3Image", "Custom3Shape", "Custom3Toggle", &g_Config.CustomKey3, {0, 3, 0, false}, true, true), - ConfigSetting("Custom4Mapping", "Custom4Image", "Custom4Shape", "Custom4Toggle", &g_Config.CustomKey4, {0, 4, 0, false}, true, true), - ConfigSetting("Custom5Mapping", "Custom5Image", "Custom5Shape", "Custom5Toggle", &g_Config.CustomKey5, {0, 0, 1, false}, true, true), - ConfigSetting("Custom6Mapping", "Custom6Image", "Custom6Shape", "Custom6Toggle", &g_Config.CustomKey6, {0, 1, 1, false}, true, true), - ConfigSetting("Custom7Mapping", "Custom7Image", "Custom7Shape", "Custom7Toggle", &g_Config.CustomKey7, {0, 2, 1, false}, true, true), - ConfigSetting("Custom8Mapping", "Custom8Image", "Custom8Shape", "Custom8Toggle", &g_Config.CustomKey8, {0, 3, 1, false}, true, true), - ConfigSetting("Custom9Mapping", "Custom9Image", "Custom9Shape", "Custom9Toggle", &g_Config.CustomKey9, {0, 4, 1, false}, true, true), + ConfigSetting("Custom0Mapping", "Custom0Image", "Custom0Shape", "Custom0Toggle", "Custom0Repeat", &g_Config.CustomKey0, {0, 0, 0, false, false}, true, true), + ConfigSetting("Custom1Mapping", "Custom1Image", "Custom1Shape", "Custom1Toggle", "Custom1Repeat", &g_Config.CustomKey1, {0, 1, 0, false, false}, true, true), + ConfigSetting("Custom2Mapping", "Custom2Image", "Custom2Shape", "Custom2Toggle", "Custom2Repeat", &g_Config.CustomKey2, {0, 2, 0, false, false}, true, true), + ConfigSetting("Custom3Mapping", "Custom3Image", "Custom3Shape", "Custom3Toggle", "Custom3Repeat", &g_Config.CustomKey3, {0, 3, 0, false, false}, true, true), + ConfigSetting("Custom4Mapping", "Custom4Image", "Custom4Shape", "Custom4Toggle", "Custom4Repeat", &g_Config.CustomKey4, {0, 4, 0, false, false}, true, true), + ConfigSetting("Custom5Mapping", "Custom5Image", "Custom5Shape", "Custom5Toggle", "Custom5Repeat", &g_Config.CustomKey5, {0, 0, 1, false, false}, true, true), + ConfigSetting("Custom6Mapping", "Custom6Image", "Custom6Shape", "Custom6Toggle", "Custom6Repeat", &g_Config.CustomKey6, {0, 1, 1, false, false}, true, true), + ConfigSetting("Custom7Mapping", "Custom7Image", "Custom7Shape", "Custom7Toggle", "Custom7Repeat", &g_Config.CustomKey7, {0, 2, 1, false, false}, true, true), + ConfigSetting("Custom8Mapping", "Custom8Image", "Custom8Shape", "Custom8Toggle", "Custom8Repeat", &g_Config.CustomKey8, {0, 3, 1, false, false}, true, true), + ConfigSetting("Custom9Mapping", "Custom9Image", "Custom9Shape", "Custom9Toggle", "Custom9Repeat", &g_Config.CustomKey9, {0, 4, 1, false, false}, true, true), #if defined(_WIN32) // A win32 user seeing touch controls is likely using PPSSPP on a tablet. There it makes diff --git a/Core/Config.h b/Core/Config.h index 1337a82d33..9df0ad0ec8 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -62,6 +62,7 @@ struct ConfigCustomButton { int image; int shape; bool toggle; + bool repeat; }; struct Config { diff --git a/UI/ComboKeyMappingScreen.cpp b/UI/ComboKeyMappingScreen.cpp index 11d3ad0aef..3a4bc277d1 100644 --- a/UI/ComboKeyMappingScreen.cpp +++ b/UI/ComboKeyMappingScreen.cpp @@ -235,6 +235,7 @@ void ComboKeyScreen::CreateViews() { vertLayout->Add(new ItemHeader(co->T("Button Binding"))); vertLayout->Add(new CheckBox(&(cfg->toggle), co->T("Toggle mode"))); + vertLayout->Add(new CheckBox(&(cfg->repeat), co->T("Repeat mode"))); const int cellSize = 400; UI::GridLayoutSettings gridsettings(cellSize, 64, 5); diff --git a/UI/GamepadEmu.cpp b/UI/GamepadEmu.cpp index 1b837345f3..809f2cf31f 100644 --- a/UI/GamepadEmu.cpp +++ b/UI/GamepadEmu.cpp @@ -201,19 +201,54 @@ void ComboKey::Touch(const TouchInput &input) { if (down && !lastDown) { if (g_Config.bHapticFeedback) Vibrate(HAPTIC_VIRTUAL_KEY); - for (int i = 0; i < ARRAY_SIZE(comboKeyList); i++) { - if (pspButtonBit_ & (1ULL << i)) { - controllMapper_->pspKey(comboKeyList[i].c, (on_ && toggle_) ? KEY_UP : KEY_DOWN); + + if (!repeat_) { + for (int i = 0; i < ARRAY_SIZE(comboKeyList); i++) { + if (pspButtonBit_ & (1ULL << i)) { + controllMapper_->pspKey(comboKeyList[i].c, (on_ && toggle_) ? KEY_UP : KEY_DOWN); + } } } - if (toggle_) - on_ = !on_; + on_ = toggle_ ? !on_ : true; } else if (!toggle_ && lastDown && !down) { - for (int i = 0; i < ARRAY_SIZE(comboKeyList); i++) { - if (pspButtonBit_ & (1ULL << i)) { - controllMapper_->pspKey(comboKeyList[i].c, KEY_UP); + if (!repeat_) { + for (int i = 0; i < ARRAY_SIZE(comboKeyList); i++) { + if (pspButtonBit_ & (1ULL << i)) { + controllMapper_->pspKey(comboKeyList[i].c, KEY_UP); + } } } + on_ = false; + } +} + +void ComboKey::Update() { + MultiTouchButton::Update(); + using namespace CustomKey; + + if (repeat_) { + // Give the game some time to process the input, frame based so it's faster when fast-forwarding. + static constexpr int DOWN_FRAME = 5; + + if (pressedFrames_ == 2*DOWN_FRAME) { + pressedFrames_ = 0; + } else if (pressedFrames_ == DOWN_FRAME) { + for (int i = 0; i < ARRAY_SIZE(comboKeyList); i++) { + if (pspButtonBit_ & (1ULL << i)) { + controllMapper_->pspKey(comboKeyList[i].c, KEY_UP); + } + } + } else if (on_ && pressedFrames_ == 0) { + for (int i = 0; i < ARRAY_SIZE(comboKeyList); i++) { + if (pspButtonBit_ & (1ULL << i)) { + controllMapper_->pspKey(comboKeyList[i].c, KEY_DOWN); + } + } + pressedFrames_ = 1; + } + + if (pressedFrames_ > 0) + pressedFrames_++; } } @@ -782,7 +817,7 @@ UI::ViewGroup *CreatePadLayout(float xres, float yres, bool *pause, bool showPau auto addComboKey = [=](const ConfigCustomButton& cfg, const char *key, const ConfigTouchPos &touch) -> ComboKey * { using namespace CustomKey; if (touch.show) { - auto aux = root->Add(new ComboKey(cfg.key, key, cfg.toggle, controllMapper, + auto aux = root->Add(new ComboKey(cfg.key, key, cfg.toggle, cfg.repeat, controllMapper, g_Config.iTouchButtonStyle == 0 ? comboKeyShapes[cfg.shape].i : comboKeyShapes[cfg.shape].l, comboKeyShapes[cfg.shape].i, comboKeyImages[cfg.image].i, touch.scale, comboKeyShapes[cfg.shape].d, buttonLayoutParams(touch))); aux->SetAngle(comboKeyImages[cfg.image].r, comboKeyShapes[cfg.shape].r); diff --git a/UI/GamepadEmu.h b/UI/GamepadEmu.h index 3b320b3ce8..978425cd4d 100644 --- a/UI/GamepadEmu.h +++ b/UI/GamepadEmu.h @@ -169,16 +169,19 @@ const int baseActionButtonSpacing = 60; class ComboKey : public MultiTouchButton { public: - ComboKey(uint64_t pspButtonBit, const char *key, bool toggle, ControlMapper* controllMapper, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, bool invertedContextDimension, UI::LayoutParams *layoutParams) - : MultiTouchButton(key, bgImg, bgDownImg, img, scale, layoutParams), pspButtonBit_(pspButtonBit), toggle_(toggle), controllMapper_(controllMapper), on_(false), invertedContextDimension_(invertedContextDimension) { + ComboKey(uint64_t pspButtonBit, const char *key, bool toggle, bool repeat, ControlMapper* controllMapper, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, bool invertedContextDimension, UI::LayoutParams *layoutParams) + : MultiTouchButton(key, bgImg, bgDownImg, img, scale, layoutParams), pspButtonBit_(pspButtonBit), toggle_(toggle), repeat_(repeat), controllMapper_(controllMapper), on_(false), invertedContextDimension_(invertedContextDimension) { } void Touch(const TouchInput &input) override; + void Update() override; bool IsDown() override; void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; private: uint64_t pspButtonBit_; bool toggle_; + bool repeat_; + int pressedFrames_ = 0; ControlMapper* controllMapper_; bool on_; bool invertedContextDimension_; // Swap width and height