1 /* antimicro Gamepad to KB+M event mapper 2 * Copyright (C) 2015 Travis Nickles <nickles.travis@gmail.com> 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #ifndef JOYBUTTON_H 19 #define JOYBUTTON_H 20 21 #include <QObject> 22 #include <QTimer> 23 #include <QElapsedTimer> 24 #include <QTime> 25 #include <QList> 26 #include <QListIterator> 27 #include <QHash> 28 #include <QQueue> 29 #include <QReadWriteLock> 30 #include <QXmlStreamReader> 31 #include <QXmlStreamWriter> 32 33 #include "joybuttonslot.h" 34 #include "springmousemoveinfo.h" 35 #include "joybuttonmousehelper.h" 36 37 #ifdef Q_OS_WIN 38 #include "joykeyrepeathelper.h" 39 #endif 40 41 class VDPad; 42 class SetJoystick; 43 44 class JoyButton : public QObject 45 { 46 Q_OBJECT 47 public: 48 explicit JoyButton(int index, int originset, SetJoystick *parentSet, QObject *parent=0); 49 ~JoyButton(); 50 51 enum SetChangeCondition {SetChangeDisabled=0, SetChangeOneWay, 52 SetChangeTwoWay, SetChangeWhileHeld}; 53 54 enum JoyMouseMovementMode {MouseCursor=0, MouseSpring}; 55 enum JoyMouseCurve {EnhancedPrecisionCurve=0, LinearCurve, QuadraticCurve, 56 CubicCurve, QuadraticExtremeCurve, PowerCurve, 57 EasingQuadraticCurve, EasingCubicCurve}; 58 enum JoyExtraAccelerationCurve {LinearAccelCurve, EaseOutSineCurve, 59 EaseOutQuadAccelCurve, EaseOutCubicAccelCurve}; 60 enum TurboMode {NormalTurbo=0, GradientTurbo, PulseTurbo}; 61 62 void joyEvent(bool pressed, bool ignoresets=false); 63 void queuePendingEvent(bool pressed, bool ignoresets=false); 64 void activatePendingEvent(); 65 bool hasPendingEvent(); 66 void clearPendingEvent(); 67 68 int getJoyNumber(); 69 virtual int getRealJoyNumber(); 70 void setJoyNumber(int index); 71 72 bool getToggleState(); 73 int getTurboInterval(); 74 bool isUsingTurbo(); 75 void setCustomName(QString name); 76 QString getCustomName(); 77 78 QList<JoyButtonSlot*> *getAssignedSlots(); 79 80 virtual void readConfig(QXmlStreamReader *xml); 81 virtual void writeConfig(QXmlStreamWriter *xml); 82 83 virtual QString getPartialName(bool forceFullFormat=false, bool displayNames=false); 84 virtual QString getSlotsSummary(); 85 virtual QString getSlotsString(); 86 virtual QList<JoyButtonSlot*> getActiveZoneList(); 87 virtual QString getActiveZoneSummary(); 88 virtual QString getCalculatedActiveZoneSummary(); 89 virtual QString getName(bool forceFullFormat=false, bool displayNames=false); 90 virtual QString getXmlName(); 91 92 int getMouseSpeedX(); 93 int getMouseSpeedY(); 94 95 int getWheelSpeedX(); 96 int getWheelSpeedY(); 97 98 void setChangeSetSelection(int index, bool updateActiveString=true); 99 int getSetSelection(); 100 101 virtual void setChangeSetCondition(SetChangeCondition condition, 102 bool passive=false, bool updateActiveString=true); 103 SetChangeCondition getChangeSetCondition(); 104 105 bool getButtonState(); 106 int getOriginSet(); 107 108 bool containsSequence(); 109 bool containsDistanceSlots(); 110 bool containsReleaseSlots(); 111 112 virtual double getDistanceFromDeadZone(); 113 virtual double getMouseDistanceFromDeadZone(); 114 virtual double getLastMouseDistanceFromDeadZone(); 115 116 // Don't use direct assignment but copying from a current button. 117 virtual void copyLastMouseDistanceFromDeadZone(JoyButton *srcButton); 118 virtual void copyLastAccelerationDistance(JoyButton *srcButton); 119 120 void copyExtraAccelerationState(JoyButton *srcButton); 121 void setUpdateInitAccel(bool state); 122 123 virtual void setVDPad(VDPad *vdpad); 124 void removeVDPad(); 125 bool isPartVDPad(); 126 VDPad* getVDPad(); 127 128 virtual bool isDefault(); 129 void setIgnoreEventState(bool ignore); 130 bool getIgnoreEventState(); 131 132 void setMouseMode(JoyMouseMovementMode mousemode); 133 JoyMouseMovementMode getMouseMode(); 134 135 void setMouseCurve(JoyMouseCurve selectedCurve); 136 JoyMouseCurve getMouseCurve(); 137 138 int getSpringWidth(); 139 int getSpringHeight(); 140 141 double getSensitivity(); 142 143 bool getWhileHeldStatus(); 144 void setWhileHeldStatus(bool status); 145 146 QString getActionName(); 147 QString getButtonName(); 148 149 virtual void setDefaultButtonName(QString tempname); 150 virtual QString getDefaultButtonName(); 151 152 SetJoystick* getParentSet(); 153 154 void setCycleResetTime(unsigned int interval); 155 unsigned int getCycleResetTime(); 156 157 void setCycleResetStatus(bool enabled); 158 bool isCycleResetActive(); 159 160 bool isRelativeSpring(); 161 void copyAssignments(JoyButton *destButton); 162 163 virtual void setTurboMode(TurboMode mode); 164 TurboMode getTurboMode(); 165 virtual bool isPartRealAxis(); 166 virtual bool isModifierButton(); 167 168 bool hasActiveSlots(); 169 170 static int calculateFinalMouseSpeed(JoyMouseCurve curve, int value); 171 double getEasingDuration(); 172 173 static void moveMouseCursor(int &movedX, int &movedY, int &movedElapsed); 174 static void moveSpringMouse(int &movedX, int &movedY, bool &hasMoved); 175 176 static JoyButtonMouseHelper* getMouseHelper(); 177 static QList<JoyButton*>* getPendingMouseButtons(); 178 static bool hasCursorEvents(); 179 static bool hasSpringEvents(); 180 181 static double getWeightModifier(); 182 static void setWeightModifier(double modifier); 183 184 static int getMouseHistorySize(); 185 static void setMouseHistorySize(int size); 186 187 static int getMouseRefreshRate(); 188 static void setMouseRefreshRate(int refresh); 189 190 static int getSpringModeScreen(); 191 static void setSpringModeScreen(int screen); 192 193 static void resetActiveButtonMouseDistances(); 194 void resetAccelerationDistances(); 195 196 void setExtraAccelerationStatus(bool status); 197 void setExtraAccelerationMultiplier(double value); 198 199 bool isExtraAccelerationEnabled(); 200 double getExtraAccelerationMultiplier(); 201 202 virtual void initializeDistanceValues(); 203 204 void setMinAccelThreshold(double value); 205 double getMinAccelThreshold(); 206 207 void setMaxAccelThreshold(double value); 208 double getMaxAccelThreshold(); 209 210 void setStartAccelMultiplier(double value); 211 double getStartAccelMultiplier(); 212 213 void setAccelExtraDuration(double value); 214 double getAccelExtraDuration(); 215 216 void setExtraAccelerationCurve(JoyExtraAccelerationCurve curve); 217 JoyExtraAccelerationCurve getExtraAccelerationCurve(); 218 219 virtual double getAccelerationDistance(); 220 virtual double getLastAccelerationDistance(); 221 222 void setSpringDeadCircleMultiplier(int value); 223 int getSpringDeadCircleMultiplier(); 224 225 static int getGamepadRefreshRate(); 226 static void setGamepadRefreshRate(int refresh); 227 228 static void restartLastMouseTime(); 229 230 static void setStaticMouseThread(QThread *thread); 231 static void indirectStaticMouseThread(QThread *thread); 232 233 static bool shouldInvokeMouseEvents(); 234 static void invokeMouseEvents(); 235 236 static const QString xmlName; 237 238 // Define default values for many properties. 239 static const int ENABLEDTURBODEFAULT; 240 static const double DEFAULTMOUSESPEEDMOD; 241 static const unsigned int DEFAULTKEYREPEATDELAY; 242 static const unsigned int DEFAULTKEYREPEATRATE; 243 static const JoyMouseCurve DEFAULTMOUSECURVE; 244 static const bool DEFAULTTOGGLE; 245 static const int DEFAULTTURBOINTERVAL; 246 static const bool DEFAULTUSETURBO; 247 static const int DEFAULTMOUSESPEEDX; 248 static const int DEFAULTMOUSESPEEDY; 249 static const int DEFAULTSETSELECTION; 250 static const SetChangeCondition DEFAULTSETCONDITION; 251 static const JoyMouseMovementMode DEFAULTMOUSEMODE; 252 static const int DEFAULTSPRINGWIDTH; 253 static const int DEFAULTSPRINGHEIGHT; 254 static const double DEFAULTSENSITIVITY; 255 static const int DEFAULTWHEELX; 256 static const int DEFAULTWHEELY; 257 static const bool DEFAULTCYCLERESETACTIVE; 258 static const int DEFAULTCYCLERESET; 259 static const bool DEFAULTRELATIVESPRING; 260 static const TurboMode DEFAULTTURBOMODE; 261 static const double DEFAULTEASINGDURATION; 262 static const double MINIMUMEASINGDURATION; 263 static const double MAXIMUMEASINGDURATION; 264 265 static const int DEFAULTMOUSEHISTORYSIZE; 266 static const double DEFAULTWEIGHTMODIFIER; 267 268 static const int MAXIMUMMOUSEHISTORYSIZE; 269 static const double MAXIMUMWEIGHTMODIFIER; 270 271 static const int MAXIMUMMOUSEREFRESHRATE; 272 static const int DEFAULTIDLEMOUSEREFRESHRATE; 273 static int IDLEMOUSEREFRESHRATE; 274 275 static const unsigned int MINCYCLERESETTIME; 276 static const unsigned int MAXCYCLERESETTIME; 277 278 static const double DEFAULTEXTRACCELVALUE; 279 static const double DEFAULTMINACCELTHRESHOLD; 280 static const double DEFAULTMAXACCELTHRESHOLD; 281 static const double DEFAULTSTARTACCELMULTIPLIER; 282 static const double DEFAULTACCELEASINGDURATION; 283 static const JoyExtraAccelerationCurve DEFAULTEXTRAACCELCURVE; 284 285 static const int DEFAULTSPRINGRELEASERADIUS; 286 287 static QList<double> mouseHistoryX; 288 static QList<double> mouseHistoryY; 289 290 static double cursorRemainderX; 291 static double cursorRemainderY; 292 293 protected: 294 double getTotalSlotDistance(JoyButtonSlot *slot); 295 bool distanceEvent(); 296 void clearAssignedSlots(bool signalEmit=true); 297 void releaseSlotEvent(); 298 void findReleaseEventEnd(); 299 void findReleaseEventIterEnd(QListIterator<JoyButtonSlot*> *tempiter); 300 void findHoldEventEnd(); 301 bool checkForDelaySequence(); 302 void checkForPressedSetChange(); 303 bool insertAssignedSlot(JoyButtonSlot *newSlot, bool updateActiveString=true); 304 unsigned int getPreferredKeyPressTime(); 305 void checkTurboCondition(JoyButtonSlot *slot); 306 static bool hasFutureSpringEvents(); 307 virtual double getCurrentSpringDeadCircle(); 308 void vdpadPassEvent(bool pressed, bool ignoresets=false); 309 310 QString buildActiveZoneSummary(QList<JoyButtonSlot*> &tempList); 311 void localBuildActiveZoneSummaryString(); 312 313 virtual bool readButtonConfig(QXmlStreamReader *xml); 314 315 typedef struct _mouseCursorInfo 316 { 317 JoyButtonSlot *slot; 318 double code; 319 } mouseCursorInfo; 320 321 // Used to denote whether the actual joypad button is pressed 322 bool isButtonPressed; 323 // Used to denote whether the virtual key is pressed 324 bool isKeyPressed; 325 bool toggle; 326 bool quitEvent; 327 // Used to denote the SDL index of the actual joypad button 328 int index; 329 int turboInterval; 330 331 QTimer turboTimer; 332 QTimer pauseTimer; 333 QTimer holdTimer; 334 QTimer pauseWaitTimer; 335 QTimer createDeskTimer; 336 QTimer releaseDeskTimer; 337 QTimer mouseWheelVerticalEventTimer; 338 QTimer mouseWheelHorizontalEventTimer; 339 QTimer setChangeTimer; 340 QTimer keyPressTimer; 341 QTimer delayTimer; 342 QTimer slotSetChangeTimer; 343 static QTimer staticMouseEventTimer; 344 345 bool isDown; 346 bool toggleActiveState; 347 bool useTurbo; 348 QList<JoyButtonSlot*> assignments; 349 QList<JoyButtonSlot*> activeSlots; 350 QString customName; 351 352 int mouseSpeedX; 353 int mouseSpeedY; 354 int wheelSpeedX; 355 int wheelSpeedY; 356 357 int setSelection; 358 SetChangeCondition setSelectionCondition; 359 int originset; 360 361 QListIterator<JoyButtonSlot*> *slotiter; 362 JoyButtonSlot *currentPause; 363 JoyButtonSlot *currentHold; 364 JoyButtonSlot *currentCycle; 365 JoyButtonSlot *previousCycle; 366 JoyButtonSlot *currentDistance; 367 JoyButtonSlot *currentMouseEvent; 368 JoyButtonSlot *currentRelease; 369 JoyButtonSlot *currentWheelVerticalEvent; 370 JoyButtonSlot *currentWheelHorizontalEvent; 371 JoyButtonSlot *currentKeyPress; 372 JoyButtonSlot *currentDelay; 373 JoyButtonSlot *currentSetChangeSlot; 374 375 bool ignoresets; 376 QTime buttonHold; 377 QTime pauseHold; 378 QTime inpauseHold; 379 QTime buttonHeldRelease; 380 QTime keyPressHold; 381 QTime buttonDelay; 382 QTime turboHold; 383 QTime wheelVerticalTime; 384 QTime wheelHorizontalTime; 385 //static QElapsedTimer lastMouseTime; 386 static QTime testOldMouseTime; 387 388 QQueue<bool> ignoreSetQueue; 389 QQueue<bool> isButtonPressedQueue; 390 391 QQueue<JoyButtonSlot*> mouseEventQueue; 392 QQueue<JoyButtonSlot*> mouseWheelVerticalEventQueue; 393 QQueue<JoyButtonSlot*> mouseWheelHorizontalEventQueue; 394 395 int currentRawValue; 396 VDPad *vdpad; 397 bool ignoreEvents; 398 JoyMouseMovementMode mouseMode; 399 JoyMouseCurve mouseCurve; 400 401 int springWidth; 402 int springHeight; 403 double sensitivity; 404 bool smoothing; 405 bool whileHeldStatus; 406 double lastDistance; 407 double lastWheelVerticalDistance; 408 double lastWheelHorizontalDistance; 409 int tempTurboInterval; 410 411 // Keep track of the previous mouse distance from the previous gamepad 412 // poll. 413 double lastMouseDistance; 414 415 // Keep track of the previous full distance from the previous gamepad 416 // poll. 417 double lastAccelerationDistance; 418 419 // Multiplier and time used for acceleration easing. 420 double currentAccelMulti; 421 QTime accelExtraDurationTime; 422 double accelDuration; 423 double oldAccelMulti; 424 double accelTravel; // Track travel when accel started 425 426 // Should lastMouseDistance be updated. Set after mouse event. 427 bool updateLastMouseDistance; 428 429 // Should startingMouseDistance be updated. Set after acceleration 430 // has finally been applied. 431 bool updateStartingMouseDistance; 432 433 double updateOldAccelMulti; 434 435 bool updateInitAccelValues; 436 437 // Keep track of the current mouse distance after a poll. Used 438 // to update lastMouseDistance later. 439 double currentMouseDistance; 440 441 // Keep track of the current mouse distance after a poll. Used 442 // to update lastMouseDistance later. 443 double currentAccelerationDistance; 444 445 // Take into account when mouse acceleration started 446 double startingAccelerationDistance; 447 448 double minMouseDistanceAccelThreshold; 449 double maxMouseDistanceAccelThreshold; 450 double startAccelMultiplier; 451 452 JoyExtraAccelerationCurve extraAccelCurve; 453 454 QString actionName; 455 QString buttonName; // User specified button name 456 QString defaultButtonName; // Name used by the system 457 458 SetJoystick *parentSet; // Pointer to set that button is assigned to. 459 460 bool cycleResetActive; 461 unsigned int cycleResetInterval; 462 QTime cycleResetHold; 463 464 bool relativeSpring; 465 TurboMode currentTurboMode; 466 467 double easingDuration; 468 469 bool extraAccelerationEnabled; 470 double extraAccelerationMultiplier; 471 472 int springDeadCircleMultiplier; 473 474 bool pendingPress; 475 bool pendingEvent; 476 bool pendingIgnoreSets; 477 478 QReadWriteLock activeZoneLock; 479 QReadWriteLock assignmentsLock; 480 QReadWriteLock activeZoneStringLock; 481 482 QString activeZoneString; 483 QTimer activeZoneTimer; 484 485 static double mouseSpeedModifier; 486 static QList<JoyButtonSlot*> mouseSpeedModList; 487 488 static QList<mouseCursorInfo> cursorXSpeeds; 489 static QList<mouseCursorInfo> cursorYSpeeds; 490 491 static QList<PadderCommon::springModeInfo> springXSpeeds; 492 static QList<PadderCommon::springModeInfo> springYSpeeds; 493 494 static QList<JoyButton*> pendingMouseButtons; 495 496 static QHash<unsigned int, int> activeKeys; 497 static QHash<unsigned int, int> activeMouseButtons; 498 #ifdef Q_OS_WIN 499 static JoyKeyRepeatHelper repeatHelper; 500 #endif 501 502 static JoyButtonSlot *lastActiveKey; 503 static JoyButtonMouseHelper mouseHelper; 504 static double weightModifier; 505 static int mouseHistorySize; 506 static int mouseRefreshRate; 507 static int springModeScreen; 508 static int gamepadRefreshRate; 509 510 signals: 511 void clicked (int index); 512 void released (int index); 513 void keyChanged(int keycode); 514 void mouseChanged(int mousecode); 515 void setChangeActivated(int index); 516 void setAssignmentChanged(int current_button, int associated_set, int mode); 517 void finishedPause(); 518 void turboChanged(bool state); 519 void toggleChanged(bool state); 520 void turboIntervalChanged(int interval); 521 void slotsChanged(); 522 void actionNameChanged(); 523 void buttonNameChanged(); 524 void propertyUpdated(); 525 void activeZoneChanged(); 526 527 public slots: 528 void setTurboInterval (int interval); 529 void setToggle (bool toggle); 530 void setUseTurbo(bool useTurbo); 531 void setMouseSpeedX(int speed); 532 void setMouseSpeedY(int speed); 533 534 void setWheelSpeedX(int speed); 535 void setWheelSpeedY(int speed); 536 537 void setSpringWidth(int value); 538 void setSpringHeight(int value); 539 540 void setSensitivity(double value); 541 void setSpringRelativeStatus(bool value); 542 543 void setActionName(QString tempName); 544 void setButtonName(QString tempName); 545 546 void setEasingDuration(double value); 547 548 virtual void reset(); 549 virtual void reset(int index); 550 virtual void resetProperties(); 551 552 virtual void clearSlotsEventReset(bool clearSignalEmit=true); 553 virtual void eventReset(); 554 555 bool setAssignedSlot(int code, unsigned int alias, int index, 556 JoyButtonSlot::JoySlotInputAction mode=JoyButtonSlot::JoyKeyboard); 557 558 bool setAssignedSlot(int code, 559 JoyButtonSlot::JoySlotInputAction mode=JoyButtonSlot::JoyKeyboard); 560 561 bool setAssignedSlot(int code, unsigned int alias, 562 JoyButtonSlot::JoySlotInputAction mode=JoyButtonSlot::JoyKeyboard); 563 564 bool setAssignedSlot(JoyButtonSlot *otherSlot, int index); 565 566 bool insertAssignedSlot(int code, unsigned int alias, int index, 567 JoyButtonSlot::JoySlotInputAction mode=JoyButtonSlot::JoyKeyboard); 568 569 void removeAssignedSlot(int index); 570 571 static void establishMouseTimerConnections(); 572 void establishPropertyUpdatedConnections(); 573 void disconnectPropertyUpdatedConnections(); 574 575 virtual void mouseEvent(); 576 577 protected slots: 578 virtual void turboEvent(); 579 virtual void wheelEventVertical(); 580 virtual void wheelEventHorizontal(); 581 void createDeskEvent(); 582 void releaseDeskEvent(bool skipsetchange=false); 583 void buildActiveZoneSummaryString(); 584 585 private slots: 586 void releaseActiveSlots(); 587 void activateSlots(); 588 void waitForDeskEvent(); 589 void waitForReleaseDeskEvent(); 590 void holdEvent(); 591 void delayEvent(); 592 593 void pauseWaitEvent(); 594 void checkForSetChange(); 595 void keyPressEvent(); 596 void slotSetChange(); 597 }; 598 599 600 #endif // JOYBUTTON_H 601