Merge pull request #16419 from hrydgard/control-mapping-fixes

Stick input: Fix issue where deadzone noise from one device could drown out signal from another.
This commit is contained in:
Henrik Rydgård 2022-11-23 14:23:43 +01:00 committed by GitHub
commit cddf78c82a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 110 additions and 75 deletions

View File

@ -33,6 +33,7 @@ enum {
DEVICE_ID_ACCELEROMETER = 30,
DEVICE_ID_XR_CONTROLLER_LEFT = 40,
DEVICE_ID_XR_CONTROLLER_RIGHT = 41,
DEVICE_ID_TOUCH = 42,
};
//number of contiguous generic joypad IDs

View File

@ -15,6 +15,7 @@ static float MapAxisValue(float v) {
const float invDeadzone = g_Config.fAnalogInverseDeadzone;
const float sensitivity = g_Config.fAnalogSensitivity;
const float sign = v >= 0.0f ? 1.0f : -1.0f;
return sign * Clamp(invDeadzone + (abs(v) - deadzone) / (1.0f - deadzone) * (sensitivity - invDeadzone), 0.0f, 1.0f);
}
@ -49,24 +50,48 @@ void ControlMapper::SetRawCallback(std::function<void(int, float, float)> setRaw
setRawAnalog_ = setRawAnalog;
}
void ControlMapper::SetPSPAxis(char axis, float value, int stick) {
static float history[2][2] = {};
void ControlMapper::SetPSPAxis(int device, char axis, float value, int stick) {
int axisId = axis == 'X' ? 0 : 1;
history[stick][axisId] = value;
float position[2];
position[0] = history[stick][0];
position[1] = history[stick][1];
float x = history[stick][0];
float y = history[stick][1];
position[axisId] = value;
float x = position[0];
float y = position[1];
if (setRawAnalog_) {
setRawAnalog_(stick, x, y);
}
ConvertAnalogStick(x, y);
// NOTE: We need to use single-axis checks, since the other axis might be from another device,
// so we'll add a little leeway.
bool inDeadZone = fabsf(value) < g_Config.fAnalogDeadzone * 0.7f;
setPSPAnalog_(stick, x, y);
bool ignore = false;
if (inDeadZone && lastNonDeadzoneDeviceID_[stick] != device) {
// Ignore this event! See issue #15465
NOTICE_LOG(COMMON, "Ignoring deadzone event from device %d (%d, %f)", device, axis, value);
ignore = true;
}
if (!inDeadZone) {
NOTICE_LOG(COMMON, "Got a non deadzone event from device %d (%d, %f > %f)", device, axis, value, g_Config.fAnalogDeadzone);
lastNonDeadzoneDeviceID_[stick] = device;
}
if (!ignore) {
history[stick][axisId] = value;
float x = history[stick][0];
float y = history[stick][1];
ConvertAnalogStick(x, y);
setPSPAnalog_(stick, x, y);
}
}
bool ControlMapper::Key(const KeyInput &key, bool *pauseTrigger) {
@ -79,7 +104,7 @@ bool ControlMapper::Key(const KeyInput &key, bool *pauseTrigger) {
}
for (size_t i = 0; i < pspKeys.size(); i++) {
pspKey(pspKeys[i], key.flags);
pspKey(key.deviceId, pspKeys[i], key.flags);
}
DEBUG_LOG(SYSTEM, "Key: %d DeviceId: %d", key.keyCode, key.deviceId);
@ -155,7 +180,7 @@ static int RotatePSPKeyCode(int x) {
}
}
void ControlMapper::setVKeyAnalog(char axis, int stick, int virtualKeyMin, int virtualKeyMax, bool setZero) {
void ControlMapper::setVKeyAnalog(int deviceId, char axis, int stick, int virtualKeyMin, int virtualKeyMax, bool setZero) {
// The down events can repeat, so just trust the virtKeys array.
bool minDown = virtKeys[virtualKeyMin - VIRTKEY_FIRST];
bool maxDown = virtKeys[virtualKeyMax - VIRTKEY_FIRST];
@ -167,11 +192,11 @@ void ControlMapper::setVKeyAnalog(char axis, int stick, int virtualKeyMin, int v
if (maxDown)
value += scale;
if (setZero || minDown || maxDown) {
SetPSPAxis(axis, value, stick);
SetPSPAxis(deviceId, axis, value, stick);
}
}
void ControlMapper::pspKey(int pspKeyCode, int flags) {
void ControlMapper::pspKey(int deviceId, int pspKeyCode, int flags) {
int rotations = 0;
switch (g_Config.iInternalScreenRotation) {
case ROTATION_LOCKED_HORIZONTAL180:
@ -193,11 +218,11 @@ void ControlMapper::pspKey(int pspKeyCode, int flags) {
int vk = pspKeyCode - VIRTKEY_FIRST;
if (flags & KEY_DOWN) {
virtKeys[vk] = true;
onVKeyDown(pspKeyCode);
onVKeyDown(deviceId, pspKeyCode);
}
if (flags & KEY_UP) {
virtKeys[vk] = false;
onVKeyUp(pspKeyCode);
onVKeyUp(deviceId, pspKeyCode);
}
} else {
// INFO_LOG(SYSTEM, "pspKey %i %i", pspKeyCode, flags);
@ -208,32 +233,32 @@ void ControlMapper::pspKey(int pspKeyCode, int flags) {
}
}
void ControlMapper::onVKeyDown(int vkey) {
void ControlMapper::onVKeyDown(int deviceId, int vkey) {
switch (vkey) {
case VIRTKEY_AXIS_X_MIN:
case VIRTKEY_AXIS_X_MAX:
setVKeyAnalog('X', CTRL_STICK_LEFT, VIRTKEY_AXIS_X_MIN, VIRTKEY_AXIS_X_MAX);
setVKeyAnalog(deviceId, 'X', CTRL_STICK_LEFT, VIRTKEY_AXIS_X_MIN, VIRTKEY_AXIS_X_MAX);
break;
case VIRTKEY_AXIS_Y_MIN:
case VIRTKEY_AXIS_Y_MAX:
setVKeyAnalog('Y', CTRL_STICK_LEFT, VIRTKEY_AXIS_Y_MIN, VIRTKEY_AXIS_Y_MAX);
setVKeyAnalog(deviceId, 'Y', CTRL_STICK_LEFT, VIRTKEY_AXIS_Y_MIN, VIRTKEY_AXIS_Y_MAX);
break;
case VIRTKEY_AXIS_RIGHT_X_MIN:
case VIRTKEY_AXIS_RIGHT_X_MAX:
setVKeyAnalog('X', CTRL_STICK_RIGHT, VIRTKEY_AXIS_RIGHT_X_MIN, VIRTKEY_AXIS_RIGHT_X_MAX);
setVKeyAnalog(deviceId, 'X', CTRL_STICK_RIGHT, VIRTKEY_AXIS_RIGHT_X_MIN, VIRTKEY_AXIS_RIGHT_X_MAX);
break;
case VIRTKEY_AXIS_RIGHT_Y_MIN:
case VIRTKEY_AXIS_RIGHT_Y_MAX:
setVKeyAnalog('Y', CTRL_STICK_RIGHT, VIRTKEY_AXIS_RIGHT_Y_MIN, VIRTKEY_AXIS_RIGHT_Y_MAX);
setVKeyAnalog(deviceId, 'Y', CTRL_STICK_RIGHT, VIRTKEY_AXIS_RIGHT_Y_MIN, VIRTKEY_AXIS_RIGHT_Y_MAX);
break;
case VIRTKEY_ANALOG_LIGHTLY:
setVKeyAnalog('X', CTRL_STICK_LEFT, VIRTKEY_AXIS_X_MIN, VIRTKEY_AXIS_X_MAX, false);
setVKeyAnalog('Y', CTRL_STICK_LEFT, VIRTKEY_AXIS_Y_MIN, VIRTKEY_AXIS_Y_MAX, false);
setVKeyAnalog('X', CTRL_STICK_RIGHT, VIRTKEY_AXIS_RIGHT_X_MIN, VIRTKEY_AXIS_RIGHT_X_MAX, false);
setVKeyAnalog('Y', CTRL_STICK_RIGHT, VIRTKEY_AXIS_RIGHT_Y_MIN, VIRTKEY_AXIS_RIGHT_Y_MAX, false);
setVKeyAnalog(deviceId, 'X', CTRL_STICK_LEFT, VIRTKEY_AXIS_X_MIN, VIRTKEY_AXIS_X_MAX, false);
setVKeyAnalog(deviceId, 'Y', CTRL_STICK_LEFT, VIRTKEY_AXIS_Y_MIN, VIRTKEY_AXIS_Y_MAX, false);
setVKeyAnalog(deviceId, 'X', CTRL_STICK_RIGHT, VIRTKEY_AXIS_RIGHT_X_MIN, VIRTKEY_AXIS_RIGHT_X_MAX, false);
setVKeyAnalog(deviceId, 'Y', CTRL_STICK_RIGHT, VIRTKEY_AXIS_RIGHT_Y_MIN, VIRTKEY_AXIS_RIGHT_Y_MAX, false);
break;
case VIRTKEY_ANALOG_ROTATE_CW:
@ -252,32 +277,32 @@ void ControlMapper::onVKeyDown(int vkey) {
}
}
void ControlMapper::onVKeyUp(int vkey) {
void ControlMapper::onVKeyUp(int deviceId, int vkey) {
switch (vkey) {
case VIRTKEY_AXIS_X_MIN:
case VIRTKEY_AXIS_X_MAX:
setVKeyAnalog('X', CTRL_STICK_LEFT, VIRTKEY_AXIS_X_MIN, VIRTKEY_AXIS_X_MAX);
setVKeyAnalog(deviceId, 'X', CTRL_STICK_LEFT, VIRTKEY_AXIS_X_MIN, VIRTKEY_AXIS_X_MAX);
break;
case VIRTKEY_AXIS_Y_MIN:
case VIRTKEY_AXIS_Y_MAX:
setVKeyAnalog('Y', CTRL_STICK_LEFT, VIRTKEY_AXIS_Y_MIN, VIRTKEY_AXIS_Y_MAX);
setVKeyAnalog(deviceId, 'Y', CTRL_STICK_LEFT, VIRTKEY_AXIS_Y_MIN, VIRTKEY_AXIS_Y_MAX);
break;
case VIRTKEY_AXIS_RIGHT_X_MIN:
case VIRTKEY_AXIS_RIGHT_X_MAX:
setVKeyAnalog('X', CTRL_STICK_RIGHT, VIRTKEY_AXIS_RIGHT_X_MIN, VIRTKEY_AXIS_RIGHT_X_MAX);
setVKeyAnalog(deviceId, 'X', CTRL_STICK_RIGHT, VIRTKEY_AXIS_RIGHT_X_MIN, VIRTKEY_AXIS_RIGHT_X_MAX);
break;
case VIRTKEY_AXIS_RIGHT_Y_MIN:
case VIRTKEY_AXIS_RIGHT_Y_MAX:
setVKeyAnalog('Y', CTRL_STICK_RIGHT, VIRTKEY_AXIS_RIGHT_Y_MIN, VIRTKEY_AXIS_RIGHT_Y_MAX);
setVKeyAnalog(deviceId, 'Y', CTRL_STICK_RIGHT, VIRTKEY_AXIS_RIGHT_Y_MIN, VIRTKEY_AXIS_RIGHT_Y_MAX);
break;
case VIRTKEY_ANALOG_LIGHTLY:
setVKeyAnalog('X', CTRL_STICK_LEFT, VIRTKEY_AXIS_X_MIN, VIRTKEY_AXIS_X_MAX, false);
setVKeyAnalog('Y', CTRL_STICK_LEFT, VIRTKEY_AXIS_Y_MIN, VIRTKEY_AXIS_Y_MAX, false);
setVKeyAnalog('X', CTRL_STICK_RIGHT, VIRTKEY_AXIS_RIGHT_X_MIN, VIRTKEY_AXIS_RIGHT_X_MAX, false);
setVKeyAnalog('Y', CTRL_STICK_RIGHT, VIRTKEY_AXIS_RIGHT_Y_MIN, VIRTKEY_AXIS_RIGHT_Y_MAX, false);
setVKeyAnalog(deviceId, 'X', CTRL_STICK_LEFT, VIRTKEY_AXIS_X_MIN, VIRTKEY_AXIS_X_MAX, false);
setVKeyAnalog(deviceId, 'Y', CTRL_STICK_LEFT, VIRTKEY_AXIS_Y_MIN, VIRTKEY_AXIS_Y_MAX, false);
setVKeyAnalog(deviceId, 'X', CTRL_STICK_RIGHT, VIRTKEY_AXIS_RIGHT_X_MIN, VIRTKEY_AXIS_RIGHT_X_MAX, false);
setVKeyAnalog(deviceId, 'Y', CTRL_STICK_RIGHT, VIRTKEY_AXIS_RIGHT_Y_MIN, VIRTKEY_AXIS_RIGHT_Y_MAX, false);
break;
case VIRTKEY_ANALOG_ROTATE_CW:
@ -312,29 +337,29 @@ void ControlMapper::processAxis(const AxisInput &axis, int direction) {
float value = fabs(axis.value) * scale;
switch (result) {
case VIRTKEY_AXIS_X_MIN:
SetPSPAxis('X', -value, CTRL_STICK_LEFT);
SetPSPAxis(axis.deviceId, 'X', -value, CTRL_STICK_LEFT);
break;
case VIRTKEY_AXIS_X_MAX:
SetPSPAxis('X', value, CTRL_STICK_LEFT);
SetPSPAxis(axis.deviceId, 'X', value, CTRL_STICK_LEFT);
break;
case VIRTKEY_AXIS_Y_MIN:
SetPSPAxis('Y', -value, CTRL_STICK_LEFT);
SetPSPAxis(axis.deviceId, 'Y', -value, CTRL_STICK_LEFT);
break;
case VIRTKEY_AXIS_Y_MAX:
SetPSPAxis('Y', value, CTRL_STICK_LEFT);
SetPSPAxis(axis.deviceId, 'Y', value, CTRL_STICK_LEFT);
break;
case VIRTKEY_AXIS_RIGHT_X_MIN:
SetPSPAxis('X', -value, CTRL_STICK_RIGHT);
SetPSPAxis(axis.deviceId, 'X', -value, CTRL_STICK_RIGHT);
break;
case VIRTKEY_AXIS_RIGHT_X_MAX:
SetPSPAxis('X', value, CTRL_STICK_RIGHT);
SetPSPAxis(axis.deviceId, 'X', value, CTRL_STICK_RIGHT);
break;
case VIRTKEY_AXIS_RIGHT_Y_MIN:
SetPSPAxis('Y', -value, CTRL_STICK_RIGHT);
SetPSPAxis(axis.deviceId, 'Y', -value, CTRL_STICK_RIGHT);
break;
case VIRTKEY_AXIS_RIGHT_Y_MAX:
SetPSPAxis('Y', value, CTRL_STICK_RIGHT);
SetPSPAxis(axis.deviceId, 'Y', value, CTRL_STICK_RIGHT);
break;
case VIRTKEY_SPEED_ANALOG:
@ -366,22 +391,22 @@ void ControlMapper::processAxis(const AxisInput &axis, int direction) {
if (axisState != 0) {
for (size_t i = 0; i < results.size(); i++) {
if (!IsAnalogStickKey(results[i]))
pspKey(results[i], KEY_DOWN);
pspKey(axis.deviceId, results[i], KEY_DOWN);
}
// Also unpress the other direction (unless both directions press the same key.)
for (size_t i = 0; i < resultsOpposite.size(); i++) {
if (!IsAnalogStickKey(resultsOpposite[i]) && std::find(results.begin(), results.end(), resultsOpposite[i]) == results.end())
pspKey(resultsOpposite[i], KEY_UP);
pspKey(axis.deviceId, resultsOpposite[i], KEY_UP);
}
} else if (axisState == 0) {
// Release both directions, trying to deal with some erratic controllers that can cause it to stick.
for (size_t i = 0; i < results.size(); i++) {
if (!IsAnalogStickKey(results[i]))
pspKey(results[i], KEY_UP);
pspKey(axis.deviceId, results[i], KEY_UP);
}
for (size_t i = 0; i < resultsOpposite.size(); i++) {
if (!IsAnalogStickKey(resultsOpposite[i]))
pspKey(resultsOpposite[i], KEY_UP);
pspKey(axis.deviceId, resultsOpposite[i], KEY_UP);
}
}
}

View File

@ -16,7 +16,7 @@ public:
void Update();
bool Key(const KeyInput &key, bool *pauseTrigger);
void pspKey(int pspKeyCode, int flags);
void pspKey(int deviceId, int pspKeyCode, int flags);
bool Axis(const AxisInput &axis);
// Required callbacks
@ -30,13 +30,13 @@ public:
private:
void processAxis(const AxisInput &axis, int direction);
void setVKeyAnalog(char axis, int stick, int virtualKeyMin, int virtualKeyMax, bool setZero = true);
void setVKeyAnalog(int deviceId, char axis, int stick, int virtualKeyMin, int virtualKeyMax, bool setZero = true);
void SetPSPAxis(char axis, float value, int stick);
void SetPSPAxis(int deviceId, char axis, float value, int stick);
void ProcessAnalogSpeed(const AxisInput &axis, bool opposite);
void onVKeyDown(int vkey);
void onVKeyUp(int vkey);
void onVKeyDown(int deviceId, int vkey);
void onVKeyUp(int deviceId, int vkey);
// To track mappable virtual keys. We can have as many as we want.
bool virtKeys[VIRTKEY_COUNT]{};
@ -44,6 +44,10 @@ private:
// De-noise mapped axis updates
int axisState_[JOYSTICK_AXIS_MAX]{};
int lastNonDeadzoneDeviceID_[2]{};
float history[2][2] = {};
// Mappable auto-rotation. Useful for keyboard/dpad->analog in a few games.
bool autoRotatingAnalogCW_ = false;
bool autoRotatingAnalogCCW_ = false;

View File

@ -128,6 +128,8 @@ static const DefMappingStruct defaultXInputKeyMap[] = {
{VIRTKEY_SPEED_TOGGLE, NKCODE_BUTTON_THUMBR},
{VIRTKEY_PAUSE , JOYSTICK_AXIS_LTRIGGER, +1},
{VIRTKEY_PAUSE, NKCODE_HOME},
{VIRTKEY_FASTFORWARD , JOYSTICK_AXIS_GAS, +1},
{VIRTKEY_PAUSE , JOYSTICK_AXIS_BRAKE, +1},
};
static const DefMappingStruct defaultShieldKeyMap[] = {
@ -188,6 +190,8 @@ static const DefMappingStruct defaultAndroidXboxControllerMap[] = {
{CTRL_RTRIGGER , NKCODE_BUTTON_R1},
{VIRTKEY_FASTFORWARD , JOYSTICK_AXIS_RTRIGGER, +1},
{VIRTKEY_PAUSE , JOYSTICK_AXIS_LTRIGGER, +1},
{VIRTKEY_FASTFORWARD , JOYSTICK_AXIS_GAS, +1},
{VIRTKEY_PAUSE , JOYSTICK_AXIS_BRAKE, +1},
{VIRTKEY_AXIS_X_MIN, JOYSTICK_AXIS_X, -1},
{VIRTKEY_AXIS_X_MAX, JOYSTICK_AXIS_X, +1},
{VIRTKEY_AXIS_Y_MIN, JOYSTICK_AXIS_Y, +1},
@ -242,6 +246,8 @@ static const DefMappingStruct defaultPadMapAndroid[] = {
{VIRTKEY_FASTFORWARD , NKCODE_BUTTON_R2},
{VIRTKEY_PAUSE , JOYSTICK_AXIS_LTRIGGER, +1},
{VIRTKEY_PAUSE , NKCODE_BUTTON_L2 },
{VIRTKEY_FASTFORWARD , JOYSTICK_AXIS_GAS, +1},
{VIRTKEY_PAUSE , JOYSTICK_AXIS_BRAKE, +1},
{VIRTKEY_AXIS_X_MIN, JOYSTICK_AXIS_X, -1},
{VIRTKEY_AXIS_X_MAX, JOYSTICK_AXIS_X, +1},
{VIRTKEY_AXIS_Y_MIN, JOYSTICK_AXIS_Y, +1},

View File

@ -142,14 +142,14 @@ void SingleControlMapper::Refresh() {
std::string keyName = KeyMap::GetKeyOrAxisName(mappings[i].keyCode);
LinearLayout *row = rightColumn->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)));
row->SetSpacing(1.0f);
row->SetSpacing(2.0f);
rows_.push_back(row);
Choice *c = row->Add(new Choice(deviceName + "." + keyName, new LinearLayoutParams(FILL_PARENT, itemH, 1.0f)));
c->SetTag(StringFromFormat("%d_Change%d", (int)i, pspKey_));
c->OnClick.Handle(this, &SingleControlMapper::OnReplace);
Choice *d = row->Add(new Choice(" X ", new LayoutParams(WRAP_CONTENT, itemH)));
Choice *d = row->Add(new Choice(ImageID("I_TRASHCAN"), new LayoutParams(WRAP_CONTENT, itemH)));
d->SetTag(StringFromFormat("%d_Del%d", (int)i, pspKey_));
d->OnClick.Handle(this, &SingleControlMapper::OnDelete);
}
@ -583,6 +583,7 @@ void JoystickHistoryView::Update() {
AnalogSetupScreen::AnalogSetupScreen(const Path &gamePath) : UIDialogScreenWithGameBackground(gamePath) {
mapper_.SetCallbacks([](int vkey) {}, [](int vkey) {}, [&](int stick, float x, float y) {
NOTICE_LOG(COMMON, "analog value from mapper: %f %f", x, y);
analogX_[stick] = x;
analogY_[stick] = y;
});

View File

@ -136,8 +136,6 @@ static void __EmuScreenVblank()
}
// Handles control rotation due to internal screen rotation.
// TODO: This should be a callback too, so we don't actually call the __Ctrl functions
// from settings screens, etc.
static void SetPSPAnalog(int stick, float x, float y) {
switch (g_Config.iInternalScreenRotation) {
case ROTATION_LOCKED_HORIZONTAL:
@ -164,7 +162,6 @@ static void SetPSPAnalog(int stick, float x, float y) {
default:
break;
}
__CtrlSetAnalogXY(stick, x, y);
}

View File

@ -1804,11 +1804,11 @@ void DeveloperToolsScreen::CreateViews() {
list->Add(new CheckBox(&g_Config.bShowOnScreenMessages, dev->T("Show on-screen messages")));
list->Add(new CheckBox(&g_Config.bEnableLogging, dev->T("Enable Logging")))->OnClick.Handle(this, &DeveloperToolsScreen::OnLoggingChanged);
list->Add(new Choice(dev->T("Logging Channels")))->OnClick.Handle(this, &DeveloperToolsScreen::OnLogConfig);
list->Add(new CheckBox(&g_Config.bLogFrameDrops, dev->T("Log Dropped Frame Statistics")));
if (GetGPUBackend() == GPUBackend::VULKAN) {
list->Add(new CheckBox(&g_Config.bGpuLogProfiler, gr->T("GPU log profiler")));
}
list->Add(new CheckBox(&g_Config.bLogFrameDrops, dev->T("Log Dropped Frame Statistics")));
list->Add(new Choice(dev->T("Logging Channels")))->OnClick.Handle(this, &DeveloperToolsScreen::OnLogConfig);
list->Add(new ItemHeader(dev->T("Language")));
list->Add(new Choice(dev->T("Load language ini")))->OnClick.Handle(this, &DeveloperToolsScreen::OnLoadLanguageIni);
list->Add(new Choice(dev->T("Save language ini")))->OnClick.Handle(this, &DeveloperToolsScreen::OnSaveLanguageIni);

View File

@ -205,7 +205,7 @@ void ComboKey::Touch(const TouchInput &input) {
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);
controlMapper_->pspKey(DEVICE_ID_TOUCH, comboKeyList[i].c, (on_ && toggle_) ? KEY_UP : KEY_DOWN);
}
}
}
@ -214,7 +214,7 @@ void ComboKey::Touch(const TouchInput &input) {
if (!repeat_) {
for (int i = 0; i < ARRAY_SIZE(comboKeyList); i++) {
if (pspButtonBit_ & (1ULL << i)) {
controllMapper_->pspKey(comboKeyList[i].c, KEY_UP);
controlMapper_->pspKey(DEVICE_ID_TOUCH, comboKeyList[i].c, KEY_UP);
}
}
}
@ -235,13 +235,13 @@ void ComboKey::Update() {
} 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);
controlMapper_->pspKey(DEVICE_ID_TOUCH, 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);
controlMapper_->pspKey(DEVICE_ID_TOUCH, comboKeyList[i].c, KEY_DOWN);
}
}
pressedFrames_ = 1;
@ -912,7 +912,7 @@ void GestureGamepad::Touch(const TouchInput &input) {
const float now = time_now_d();
if (now - lastTapRelease_ < 0.3f && !haveDoubleTapped_) {
if (g_Config.iDoubleTapGesture != 0 )
controllMapper_->pspKey(GestureKey::keyList[g_Config.iDoubleTapGesture-1], KEY_DOWN);
controlMapper_->pspKey(DEVICE_ID_TOUCH, GestureKey::keyList[g_Config.iDoubleTapGesture-1], KEY_DOWN);
haveDoubleTapped_ = true;
}
@ -935,7 +935,7 @@ void GestureGamepad::Touch(const TouchInput &input) {
if (haveDoubleTapped_) {
if (g_Config.iDoubleTapGesture != 0)
controllMapper_->pspKey(GestureKey::keyList[g_Config.iDoubleTapGesture-1], KEY_UP);
controlMapper_->pspKey(DEVICE_ID_TOUCH, GestureKey::keyList[g_Config.iDoubleTapGesture-1], KEY_UP);
haveDoubleTapped_ = false;
}
}
@ -948,37 +948,37 @@ void GestureGamepad::Update() {
float dy = deltaY_ * g_dpi_scale_y * g_Config.fSwipeSensitivity;
if (g_Config.iSwipeRight != 0) {
if (dx > th) {
controllMapper_->pspKey(GestureKey::keyList[g_Config.iSwipeRight-1], KEY_DOWN);
controlMapper_->pspKey(DEVICE_ID_TOUCH, GestureKey::keyList[g_Config.iSwipeRight-1], KEY_DOWN);
swipeRightReleased_ = false;
} else if (!swipeRightReleased_) {
controllMapper_->pspKey(GestureKey::keyList[g_Config.iSwipeRight-1], KEY_UP);
controlMapper_->pspKey(DEVICE_ID_TOUCH, GestureKey::keyList[g_Config.iSwipeRight-1], KEY_UP);
swipeRightReleased_ = true;
}
}
if (g_Config.iSwipeLeft != 0) {
if (dx < -th) {
controllMapper_->pspKey(GestureKey::keyList[g_Config.iSwipeLeft-1], KEY_DOWN);
controlMapper_->pspKey(DEVICE_ID_TOUCH, GestureKey::keyList[g_Config.iSwipeLeft-1], KEY_DOWN);
swipeLeftReleased_ = false;
} else if (!swipeLeftReleased_) {
controllMapper_->pspKey(GestureKey::keyList[g_Config.iSwipeLeft-1], KEY_UP);
controlMapper_->pspKey(DEVICE_ID_TOUCH, GestureKey::keyList[g_Config.iSwipeLeft-1], KEY_UP);
swipeLeftReleased_ = true;
}
}
if (g_Config.iSwipeUp != 0) {
if (dy < -th) {
controllMapper_->pspKey(GestureKey::keyList[g_Config.iSwipeUp-1], KEY_DOWN);
controlMapper_->pspKey(DEVICE_ID_TOUCH, GestureKey::keyList[g_Config.iSwipeUp-1], KEY_DOWN);
swipeUpReleased_ = false;
} else if (!swipeUpReleased_) {
controllMapper_->pspKey(GestureKey::keyList[g_Config.iSwipeUp-1], KEY_UP);
controlMapper_->pspKey(DEVICE_ID_TOUCH, GestureKey::keyList[g_Config.iSwipeUp-1], KEY_UP);
swipeUpReleased_ = true;
}
}
if (g_Config.iSwipeDown != 0) {
if (dy > th) {
controllMapper_->pspKey(GestureKey::keyList[g_Config.iSwipeDown-1], KEY_DOWN);
controlMapper_->pspKey(DEVICE_ID_TOUCH, GestureKey::keyList[g_Config.iSwipeDown-1], KEY_DOWN);
swipeDownReleased_ = false;
} else if (!swipeDownReleased_) {
controllMapper_->pspKey(GestureKey::keyList[g_Config.iSwipeDown-1], KEY_UP);
controlMapper_->pspKey(DEVICE_ID_TOUCH, GestureKey::keyList[g_Config.iSwipeDown-1], KEY_UP);
swipeDownReleased_ = true;
}
}

View File

@ -170,7 +170,7 @@ const int baseActionButtonSpacing = 60;
class ComboKey : public MultiTouchButton {
public:
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) {
: MultiTouchButton(key, bgImg, bgDownImg, img, scale, layoutParams), pspButtonBit_(pspButtonBit), toggle_(toggle), repeat_(repeat), controlMapper_(controllMapper), on_(false), invertedContextDimension_(invertedContextDimension) {
}
void Touch(const TouchInput &input) override;
void Update() override;
@ -182,14 +182,14 @@ private:
bool toggle_;
bool repeat_;
int pressedFrames_ = 0;
ControlMapper* controllMapper_;
ControlMapper* controlMapper_;
bool on_;
bool invertedContextDimension_; // Swap width and height
};
class GestureGamepad : public UI::View {
public:
GestureGamepad(ControlMapper* controllMapper) : controllMapper_(controllMapper) {};
GestureGamepad(ControlMapper* controllMapper) : controlMapper_(controllMapper) {};
void Touch(const TouchInput &input) override;
void Update() override;
@ -208,7 +208,7 @@ protected:
bool swipeUpReleased_ = true;
bool swipeDownReleased_ = true;
bool haveDoubleTapped_ = false;
ControlMapper* controllMapper_;
ControlMapper* controlMapper_;
};
// Just edit this to add new image, shape or button function

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -60,3 +60,4 @@ image I_SQUARE_SHAPE source_assets/image/square_shape.png copy
image I_SQUARE_SHAPE_LINE source_assets/image/square_shape_line.png copy
image I_FOLDER_OPEN source_assets/image/folder_open_line.png copy
image I_WARNING source_assets/image/warning.png copy
image I_TRASHCAN source_assets/image/trashcan.png copy