Skip to content

Commit 2abb889

Browse files
committed
Fix Zwift Click V2 held shifting debounce
1 parent bb64b62 commit 2abb889

2 files changed

Lines changed: 117 additions & 18 deletions

File tree

src/zwift_play/abstractZapDevice.h

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ class AbstractZapDevice: public QObject {
179179
return 1;
180180
case 0x23: // zwift ride
181181
lastFrame = QDateTime::currentDateTime();
182-
if (processRideControllerNotification(bytes, zwiftplay_swap, DEBOUNCE)) {
182+
if (processRideControllerNotification(bytes, zwiftplay_swap, gears_volume_debouncing)) {
183183
risingEdge--;
184184
if(risingEdge < 0)
185185
risingEdge = 0;
@@ -336,7 +336,7 @@ class AbstractZapDevice: public QObject {
336336
bool rightPaddle = false;
337337
};
338338

339-
bool processRideControllerNotification(const QByteArray &bytes, bool zwiftplay_swap, bool debounce) {
339+
bool processRideControllerNotification(const QByteArray &bytes, bool zwiftplay_swap, bool gears_volume_debouncing) {
340340
quint32 buttonMap = 0xffffffff;
341341
bool buttonMapFound = false;
342342
RideAnalogState analogState;
@@ -435,8 +435,8 @@ class AbstractZapDevice: public QObject {
435435
emitIfChanged(current.rightPowerUp, lastRideButtonStateValid ? lastRideButtonState.rightPowerUp : false, &AbstractZapDevice::rideRightPowerUp);
436436
emitIfChanged(current.rightOnOff, lastRideButtonStateValid ? lastRideButtonState.rightOnOff : false, &AbstractZapDevice::rideRightOnOff);
437437

438-
processRideShiftGear(current, zwiftplay_swap, debounce);
439-
processRideAnalogState(analogState, zwiftplay_swap, debounce);
438+
processRideShiftGear(current, zwiftplay_swap, gears_volume_debouncing);
439+
processRideAnalogState(analogState, zwiftplay_swap, gears_volume_debouncing);
440440

441441
lastRideButtonState = current;
442442
lastRideButtonStateValid = true;
@@ -505,7 +505,7 @@ class AbstractZapDevice: public QObject {
505505
}
506506
}
507507

508-
void processRideAnalogState(const RideAnalogState &state, bool zwiftplay_swap, bool debounce) {
508+
void processRideAnalogState(const RideAnalogState &state, bool zwiftplay_swap, bool gears_volume_debouncing) {
509509
const bool previousLeftPaddle = lastRideAnalogStateValid ? lastRideAnalogState.leftPaddle : false;
510510
const bool previousRightPaddle = lastRideAnalogStateValid ? lastRideAnalogState.rightPaddle : false;
511511

@@ -516,45 +516,41 @@ class AbstractZapDevice: public QObject {
516516
emit rightPaddle(state.rightPaddle ? 100 : 0);
517517
}
518518

519-
if (debounce && state.leftPaddle && !previousLeftPaddle) {
519+
if (state.leftPaddle && (!gears_volume_debouncing || !previousLeftPaddle)) {
520520
applyGearButtonSetting(QZSettings::zwiftplay_gear_paddle_left, QZSettings::default_zwiftplay_gear_paddle_left, zwiftplay_swap);
521521
}
522-
if (debounce && state.rightPaddle && !previousRightPaddle) {
522+
if (state.rightPaddle && (!gears_volume_debouncing || !previousRightPaddle)) {
523523
applyGearButtonSetting(QZSettings::zwiftplay_gear_paddle_right, QZSettings::default_zwiftplay_gear_paddle_right, zwiftplay_swap);
524524
}
525525

526526
lastRideAnalogState = state;
527527
lastRideAnalogStateValid = true;
528528
}
529529

530-
void processRideShiftGear(const RideButtonState &state, bool zwiftplay_swap, bool debounce) {
531-
if (!debounce) {
532-
return;
533-
}
534-
530+
void processRideShiftGear(const RideButtonState &state, bool zwiftplay_swap, bool gears_volume_debouncing) {
535531
const bool previousLeftShiftUp = lastRideButtonStateValid ? lastRideButtonState.leftShiftUp : false;
536532
const bool previousLeftShiftDown = lastRideButtonStateValid ? lastRideButtonState.leftShiftDown : false;
537533
const bool previousRightShiftUp = lastRideButtonStateValid ? lastRideButtonState.rightShiftUp : false;
538534
const bool previousRightShiftDown = lastRideButtonStateValid ? lastRideButtonState.rightShiftDown : false;
539535
const bool previousLeftPowerUp = lastRideButtonStateValid ? lastRideButtonState.leftPowerUp : false;
540536
const bool previousRightPowerUp = lastRideButtonStateValid ? lastRideButtonState.rightPowerUp : false;
541537

542-
if (state.leftShiftUp && !previousLeftShiftUp) {
538+
if (state.leftShiftUp && (!gears_volume_debouncing || !previousLeftShiftUp)) {
543539
applyGearButtonSetting(QZSettings::zwiftplay_gear_ls1, QZSettings::default_zwiftplay_gear_ls1, zwiftplay_swap);
544540
}
545-
if (state.leftShiftDown && !previousLeftShiftDown) {
541+
if (state.leftShiftDown && (!gears_volume_debouncing || !previousLeftShiftDown)) {
546542
applyGearButtonSetting(QZSettings::zwiftplay_gear_ls2, QZSettings::default_zwiftplay_gear_ls2, zwiftplay_swap);
547543
}
548-
if (state.rightShiftUp && !previousRightShiftUp) {
544+
if (state.rightShiftUp && (!gears_volume_debouncing || !previousRightShiftUp)) {
549545
applyGearButtonSetting(QZSettings::zwiftplay_gear_rs1, QZSettings::default_zwiftplay_gear_rs1, zwiftplay_swap);
550546
}
551-
if (state.rightShiftDown && !previousRightShiftDown) {
547+
if (state.rightShiftDown && (!gears_volume_debouncing || !previousRightShiftDown)) {
552548
applyGearButtonSetting(QZSettings::zwiftplay_gear_rs2, QZSettings::default_zwiftplay_gear_rs2, zwiftplay_swap);
553549
}
554-
if (state.leftPowerUp && !previousLeftPowerUp) {
550+
if (state.leftPowerUp && (!gears_volume_debouncing || !previousLeftPowerUp)) {
555551
applyGearButtonSetting(QZSettings::zwiftplay_gear_lb, QZSettings::default_zwiftplay_gear_lb, zwiftplay_swap);
556552
}
557-
if (state.rightPowerUp && !previousRightPowerUp) {
553+
if (state.rightPowerUp && (!gears_volume_debouncing || !previousRightPowerUp)) {
558554
applyGearButtonSetting(QZSettings::zwiftplay_gear_rb, QZSettings::default_zwiftplay_gear_rb, zwiftplay_swap);
559555
}
560556
}

tst/Devices/TestZwiftRideController.cpp

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include <QByteArray>
66
#include <QObject>
7+
#include <QSettings>
78

89
namespace {
910

@@ -367,6 +368,9 @@ TEST(ZwiftRideControllerTest, May12ReplayMatchesLegendOrderWithoutAliases) {
367368
}
368369

369370
TEST(ZwiftRideControllerTest, May14ReplayRestoresPaddleGearsAndAvoidsPlayAliases) {
371+
QSettings settings;
372+
settings.setValue(QZSettings::gears_volume_debouncing, true);
373+
370374
ZwiftPlayDevice device;
371375
ButtonEvents events;
372376
connectButtonEvents(device, events);
@@ -428,4 +432,103 @@ TEST(ZwiftRideControllerTest, May14ReplayRestoresPaddleGearsAndAvoidsPlayAliases
428432
EXPECT_EQ(events.rightPaddleReleased, 1);
429433
EXPECT_EQ(events.gearMinus, 3);
430434
EXPECT_EQ(events.gearPlus, 3);
435+
436+
settings.remove(QZSettings::gears_volume_debouncing);
437+
}
438+
439+
TEST(ZwiftRideControllerTest, HeldShiftButtonsFollowGearDebouncingSetting) {
440+
QSettings settings;
441+
settings.setValue(QZSettings::gears_volume_debouncing, true);
442+
443+
{
444+
ZwiftPlayDevice device;
445+
ButtonEvents events;
446+
connectButtonEvents(device, events);
447+
448+
processRideFrame(device, kIdle);
449+
processRideFrame(device, 0xfffffeff); // LS1
450+
processRideFrame(device, 0xfffffeff);
451+
processRideFrame(device, 0xfffffeff);
452+
processRideFrame(device, kIdle);
453+
processRideFrame(device, 0xffffefff); // RS1
454+
processRideFrame(device, 0xffffefff);
455+
456+
EXPECT_EQ(events.gearMinus, 1);
457+
EXPECT_EQ(events.gearPlus, 1);
458+
}
459+
460+
settings.setValue(QZSettings::gears_volume_debouncing, false);
461+
462+
{
463+
ZwiftPlayDevice device;
464+
ButtonEvents events;
465+
connectButtonEvents(device, events);
466+
467+
processRideFrame(device, kIdle);
468+
processRideFrame(device, 0xfffffeff); // LS1
469+
processRideFrame(device, 0xfffffeff);
470+
processRideFrame(device, 0xfffffeff);
471+
processRideFrame(device, kIdle);
472+
processRideFrame(device, 0xffffefff); // RS1
473+
processRideFrame(device, 0xffffefff);
474+
475+
EXPECT_EQ(events.gearMinus, 3);
476+
EXPECT_EQ(events.gearPlus, 2);
477+
}
478+
479+
settings.setValue(QZSettings::zwiftplay_swap, true);
480+
481+
{
482+
ZwiftPlayDevice device;
483+
ButtonEvents events;
484+
connectButtonEvents(device, events);
485+
486+
processRideFrame(device, kIdle);
487+
processRideFrame(device, 0xfffffeff); // LS1, swapped to gear up
488+
processRideFrame(device, 0xfffffeff);
489+
490+
EXPECT_EQ(events.gearMinus, 0);
491+
EXPECT_EQ(events.gearPlus, 2);
492+
}
493+
494+
settings.remove(QZSettings::zwiftplay_swap);
495+
settings.remove(QZSettings::gears_volume_debouncing);
496+
}
497+
498+
TEST(ZwiftRideControllerTest, HeldRidePaddlesRepeatGearActionsOnlyWithDebouncingDisabled) {
499+
const char *leftPaddlePressed = "2308ffffffff0f1a05080010c7011a04080110001a04080210001a0408031000";
500+
QSettings settings;
501+
settings.setValue(QZSettings::gears_volume_debouncing, true);
502+
503+
{
504+
ZwiftPlayDevice device;
505+
ButtonEvents events;
506+
connectButtonEvents(device, events);
507+
508+
processRideFrame(device, kIdle);
509+
processRideFrame(device, leftPaddlePressed);
510+
processRideFrame(device, leftPaddlePressed);
511+
processRideFrame(device, leftPaddlePressed);
512+
513+
EXPECT_EQ(events.leftPaddlePressed, 1);
514+
EXPECT_EQ(events.gearMinus, 1);
515+
}
516+
517+
settings.setValue(QZSettings::gears_volume_debouncing, false);
518+
519+
{
520+
ZwiftPlayDevice device;
521+
ButtonEvents events;
522+
connectButtonEvents(device, events);
523+
524+
processRideFrame(device, kIdle);
525+
processRideFrame(device, leftPaddlePressed);
526+
processRideFrame(device, leftPaddlePressed);
527+
processRideFrame(device, leftPaddlePressed);
528+
529+
EXPECT_EQ(events.leftPaddlePressed, 1);
530+
EXPECT_EQ(events.gearMinus, 3);
531+
}
532+
533+
settings.remove(QZSettings::gears_volume_debouncing);
431534
}

0 commit comments

Comments
 (0)