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 //#include <QDebug>
19 #include <cmath>
20
21 #include "joyaxis.h"
22 #include "joycontrolstick.h"
23 #include "inputdevice.h"
24 #include "event.h"
25
26 // Set default values for many properties.
27 const int JoyAxis::AXISMIN = -32767;
28 const int JoyAxis::AXISMAX = 32767;
29 const int JoyAxis::AXISDEADZONE = 6000;
30 const int JoyAxis::AXISMAXZONE = 32000;
31
32 // Speed in pixels/second
33 const float JoyAxis::JOYSPEED = 20.0;
34
35 const JoyAxis::ThrottleTypes JoyAxis::DEFAULTTHROTTLE = JoyAxis::NormalThrottle;
36
37 const QString JoyAxis::xmlName = "axis";
38
JoyAxis(int index,int originset,SetJoystick * parentSet,QObject * parent)39 JoyAxis::JoyAxis(int index, int originset, SetJoystick *parentSet,
40 QObject *parent) :
41 QObject(parent)
42 {
43 stick = 0;
44 lastKnownThottledValue = 0;
45 lastKnownRawValue = 0;
46 this->originset = originset;
47 this->parentSet = parentSet;
48 naxisbutton = new JoyAxisButton(this, 0, originset, parentSet, this);
49 paxisbutton = new JoyAxisButton(this, 1, originset, parentSet, this);
50
51 reset();
52 this->index = index;
53 }
54
~JoyAxis()55 JoyAxis::~JoyAxis()
56 {
57 reset();
58 }
59
queuePendingEvent(int value,bool ignoresets,bool updateLastValues)60 void JoyAxis::queuePendingEvent(int value, bool ignoresets, bool updateLastValues)
61 {
62 pendingEvent = false;
63 pendingValue = 0;
64 pendingIgnoreSets = false;
65 //pendingUpdateLastValues = true;
66
67 if (this->stick)
68 {
69 stickPassEvent(value, ignoresets, updateLastValues);
70 }
71 else
72 {
73 pendingEvent = true;
74 pendingValue = value;
75 pendingIgnoreSets = ignoresets;
76 //pendingUpdateLastValues = updateLastValues;
77 }
78 }
79
activatePendingEvent()80 void JoyAxis::activatePendingEvent()
81 {
82 if (pendingEvent)
83 {
84 joyEvent(pendingValue, pendingIgnoreSets);
85
86 pendingEvent = false;
87 pendingValue = false;
88 pendingIgnoreSets = false;
89 //pendingUpdateLastValues = true;
90 }
91 }
92
hasPendingEvent()93 bool JoyAxis::hasPendingEvent()
94 {
95 return pendingEvent;
96 }
97
clearPendingEvent()98 void JoyAxis::clearPendingEvent()
99 {
100 pendingEvent = false;
101 pendingValue = false;
102 pendingIgnoreSets = false;
103 }
104
stickPassEvent(int value,bool ignoresets,bool updateLastValues)105 void JoyAxis::stickPassEvent(int value, bool ignoresets, bool updateLastValues)
106 {
107 if (this->stick)
108 {
109 if (updateLastValues)
110 {
111 lastKnownThottledValue = currentThrottledValue;
112 lastKnownRawValue = currentRawValue;
113 }
114
115 setCurrentRawValue(value);
116 //currentRawValue = value;
117 bool safezone = !inDeadZone(currentRawValue);
118 currentThrottledValue = calculateThrottledValue(value);
119
120 if (safezone && !isActive)
121 {
122 isActive = eventActive = true;
123 emit active(value);
124 }
125 else if (!safezone && isActive)
126 {
127 isActive = eventActive = false;
128 emit released(value);
129 }
130
131 if (!ignoresets)
132 {
133 stick->queueJoyEvent(ignoresets);
134 }
135 else
136 {
137 stick->joyEvent(ignoresets);
138 }
139
140 emit moved(currentRawValue);
141 }
142 }
143
joyEvent(int value,bool ignoresets,bool updateLastValues)144 void JoyAxis::joyEvent(int value, bool ignoresets, bool updateLastValues)
145 {
146 if (this->stick && !pendingEvent)
147 {
148 stickPassEvent(value, ignoresets, updateLastValues);
149 }
150 else
151 {
152 if (updateLastValues)
153 {
154 lastKnownThottledValue = currentThrottledValue;
155 lastKnownRawValue = currentRawValue;
156 }
157
158 setCurrentRawValue(value);
159 //currentRawValue = value;
160 bool safezone = !inDeadZone(currentRawValue);
161 currentThrottledValue = calculateThrottledValue(value);
162
163 // If in joystick mode and this is the first detected event,
164 // use the current value as the axis center point. If the value
165 // is below -30,000 then consider it a trigger.
166 InputDevice *device = parentSet->getInputDevice();
167 if (!device->isGameController() && !device->hasCalibrationThrottle(index))
168 {
169 performCalibration(currentRawValue);
170 safezone = !inDeadZone(currentRawValue);
171 currentThrottledValue = calculateThrottledValue(value);
172 }
173
174 if (safezone && !isActive)
175 {
176 isActive = eventActive = true;
177 emit active(value);
178 createDeskEvent(ignoresets);
179 }
180 else if (!safezone && isActive)
181 {
182 isActive = eventActive = false;
183 emit released(value);
184
185 createDeskEvent(ignoresets);
186 }
187 else if (isActive)
188 {
189 createDeskEvent(ignoresets);
190 }
191 }
192
193 emit moved(currentRawValue);
194 }
195
inDeadZone(int value)196 bool JoyAxis::inDeadZone(int value)
197 {
198 bool result = false;
199 int temp = calculateThrottledValue(value);
200
201 if (abs(temp) <= deadZone)
202 {
203 result = true;
204 }
205
206 return result;
207 }
208
getName(bool forceFullFormat,bool displayNames)209 QString JoyAxis::getName(bool forceFullFormat, bool displayNames)
210 {
211 QString label = getPartialName(forceFullFormat, displayNames);
212
213 label.append(": ");
214
215 if (throttle == NormalThrottle)
216 {
217 label.append("-");
218 if (!naxisbutton->getActionName().isEmpty() && displayNames)
219 {
220 label.append(naxisbutton->getActionName());
221 }
222 else
223 {
224 label.append(naxisbutton->getCalculatedActiveZoneSummary());
225 }
226
227 label.append(" | +");
228 if (!paxisbutton->getActionName().isEmpty() && displayNames)
229 {
230 label.append(paxisbutton->getActionName());
231 }
232 else
233 {
234 label.append(paxisbutton->getCalculatedActiveZoneSummary());
235 }
236 }
237 else if (throttle == PositiveThrottle || throttle == PositiveHalfThrottle)
238 {
239 label.append("+");
240 if (!paxisbutton->getActionName().isEmpty() && displayNames)
241 {
242 label.append(paxisbutton->getActionName());
243 }
244 else
245 {
246 label.append(paxisbutton->getCalculatedActiveZoneSummary());
247 }
248 }
249 else if (throttle == NegativeThrottle || throttle == NegativeHalfThrottle)
250 {
251 label.append("-");
252 if (!naxisbutton->getActionName().isEmpty() && displayNames)
253 {
254 label.append(naxisbutton->getActionName());
255 }
256 else
257 {
258 label.append(naxisbutton->getCalculatedActiveZoneSummary());
259 }
260 }
261
262 return label;
263 }
264
getRealJoyIndex()265 int JoyAxis::getRealJoyIndex()
266 {
267 return index + 1;
268 }
269
getCurrentThrottledValue()270 int JoyAxis::getCurrentThrottledValue()
271 {
272 return currentThrottledValue;
273 }
274
calculateThrottledValue(int value)275 int JoyAxis::calculateThrottledValue(int value)
276 {
277 int temp = value;
278
279 if (throttle == NegativeHalfThrottle)
280 {
281 value = value <= 0 ? value : -value;
282 temp = value;
283 }
284 else if (throttle == NegativeThrottle)
285 {
286 temp = (value + AXISMIN) / 2;
287 }
288 else if (throttle == PositiveThrottle)
289 {
290 temp = (value + AXISMAX) / 2;
291 }
292 else if (throttle == PositiveHalfThrottle)
293 {
294 value = value >= 0 ? value : -value;
295 temp = value;
296 }
297
298 return temp;
299 }
300
setIndex(int index)301 void JoyAxis::setIndex(int index)
302 {
303 this->index = index;
304 }
305
getIndex()306 int JoyAxis::getIndex()
307 {
308 return index;
309 }
310
311
createDeskEvent(bool ignoresets)312 void JoyAxis::createDeskEvent(bool ignoresets)
313 {
314 JoyAxisButton *eventbutton = 0;
315 if (currentThrottledValue > deadZone)
316 {
317 eventbutton = paxisbutton;
318 }
319 else if (currentThrottledValue < -deadZone)
320 {
321 eventbutton = naxisbutton;
322 }
323
324 if (eventbutton && !activeButton)
325 {
326 // There is no active button. Call joyEvent and set current
327 // button as active button
328 eventbutton->joyEvent(eventActive, ignoresets);
329 activeButton = eventbutton;
330 }
331 else if (!eventbutton && activeButton)
332 {
333 // Currently in deadzone. Disable currently active button.
334 activeButton->joyEvent(eventActive, ignoresets);
335 activeButton = 0;
336 }
337 else if (eventbutton && activeButton && eventbutton == activeButton)
338 {
339 //Button is currently active. Just pass current value
340 eventbutton->joyEvent(eventActive, ignoresets);
341 }
342 else if (eventbutton && activeButton && eventbutton != activeButton)
343 {
344 // Deadzone skipped. Button for new event is not the currently
345 // active button. Disable the active button before enabling
346 // the new button
347 activeButton->joyEvent(!eventActive, ignoresets);
348 eventbutton->joyEvent(eventActive, ignoresets);
349 activeButton = eventbutton;
350 }
351 }
352
setDeadZone(int value)353 void JoyAxis::setDeadZone(int value)
354 {
355 deadZone = abs(value);
356 emit propertyUpdated();
357 }
358
getDeadZone()359 int JoyAxis::getDeadZone()
360 {
361 return deadZone;
362 }
363
setMaxZoneValue(int value)364 void JoyAxis::setMaxZoneValue(int value)
365 {
366 value = abs(value);
367 if (value >= AXISMAX)
368 {
369 maxZoneValue = AXISMAX;
370 emit propertyUpdated();
371 }
372 else
373 {
374 maxZoneValue = value;
375 emit propertyUpdated();
376 }
377 }
378
getMaxZoneValue()379 int JoyAxis::getMaxZoneValue()
380 {
381 return maxZoneValue;
382 }
383
384 /**
385 * @brief Set throttle value for axis.
386 * @param Current value for axis.
387 */
setThrottle(int value)388 void JoyAxis::setThrottle(int value)
389 {
390 if (value >= JoyAxis::NegativeHalfThrottle && value <= JoyAxis::PositiveHalfThrottle)
391 {
392 if (value != throttle)
393 {
394 throttle = value;
395 adjustRange();
396 emit throttleChanged();
397 emit propertyUpdated();
398 }
399 }
400 }
401
402 /**
403 * @brief Set the initial calibrated throttle based on the first event
404 * passed by SDL.
405 * @param Current value for axis.
406 */
setInitialThrottle(int value)407 void JoyAxis::setInitialThrottle(int value)
408 {
409 if (value >= JoyAxis::NegativeHalfThrottle && value <= JoyAxis::PositiveHalfThrottle)
410 {
411 if (value != throttle)
412 {
413 throttle = value;
414 adjustRange();
415 emit throttleChanged();
416 }
417 }
418 }
419
getThrottle()420 int JoyAxis::getThrottle()
421 {
422 return throttle;
423 }
424
readConfig(QXmlStreamReader * xml)425 void JoyAxis::readConfig(QXmlStreamReader *xml)
426 {
427 if (xml->isStartElement() && xml->name() == getXmlName())
428 {
429 //reset();
430
431 xml->readNextStartElement();
432 while (!xml->atEnd() && (!xml->isEndElement() && xml->name() != getXmlName()))
433 {
434 bool found = false;
435 found = readMainConfig(xml);
436 if (!found && xml->name() == naxisbutton->getXmlName() && xml->isStartElement())
437 {
438 found = true;
439 readButtonConfig(xml);
440 }
441
442 if (!found)
443 {
444 xml->skipCurrentElement();
445 }
446
447 xml->readNextStartElement();
448 }
449 }
450 }
451
writeConfig(QXmlStreamWriter * xml)452 void JoyAxis::writeConfig(QXmlStreamWriter *xml)
453 {
454 bool currentlyDefault = isDefault();
455
456 xml->writeStartElement(getXmlName());
457 xml->writeAttribute("index", QString::number(index+1));
458
459 if (!currentlyDefault)
460 {
461 if (deadZone != AXISDEADZONE)
462 {
463 xml->writeTextElement("deadZone", QString::number(deadZone));
464 }
465
466 if (maxZoneValue != AXISMAXZONE)
467 {
468 xml->writeTextElement("maxZone", QString::number(maxZoneValue));
469 }
470 }
471
472
473 //if (throttle != DEFAULTTHROTTLE)
474 //{
475 xml->writeStartElement("throttle");
476
477 if (throttle == JoyAxis::NegativeHalfThrottle)
478 {
479 xml->writeCharacters("negativehalf");
480 }
481 else if (throttle == JoyAxis::NegativeThrottle)
482 {
483 xml->writeCharacters("negative");
484 }
485 else if (throttle == JoyAxis::NormalThrottle)
486 {
487 xml->writeCharacters("normal");
488 }
489 else if (throttle == JoyAxis::PositiveThrottle)
490 {
491 xml->writeCharacters("positive");
492 }
493 else if (throttle == JoyAxis::PositiveHalfThrottle)
494 {
495 xml->writeCharacters("positivehalf");
496 }
497
498 xml->writeEndElement();
499 //}
500
501 if (!currentlyDefault)
502 {
503 naxisbutton->writeConfig(xml);
504 paxisbutton->writeConfig(xml);
505 }
506
507 xml->writeEndElement();
508 }
509
510
readMainConfig(QXmlStreamReader * xml)511 bool JoyAxis::readMainConfig(QXmlStreamReader *xml)
512 {
513 bool found = false;
514
515 if (xml->name() == "deadZone" && xml->isStartElement())
516 {
517 found = true;
518 QString temptext = xml->readElementText();
519 int tempchoice = temptext.toInt();
520 this->setDeadZone(tempchoice);
521 }
522 else if (xml->name() == "maxZone" && xml->isStartElement())
523 {
524 found = true;
525 QString temptext = xml->readElementText();
526 int tempchoice = temptext.toInt();
527 this->setMaxZoneValue(tempchoice);
528 }
529 else if (xml->name() == "throttle" && xml->isStartElement())
530 {
531 found = true;
532 QString temptext = xml->readElementText();
533 if (temptext == "negativehalf")
534 {
535 this->setThrottle(JoyAxis::NegativeHalfThrottle);
536 }
537 else if (temptext == "negative")
538 {
539 this->setThrottle(JoyAxis::NegativeThrottle);
540 }
541 else if (temptext == "normal")
542 {
543 this->setThrottle(JoyAxis::NormalThrottle);
544 }
545 else if (temptext == "positive")
546 {
547 this->setThrottle(JoyAxis::PositiveThrottle);
548 }
549 else if (temptext == "positivehalf")
550 {
551 this->setThrottle(JoyAxis::PositiveHalfThrottle);
552 }
553
554 InputDevice *device = parentSet->getInputDevice();
555 if (!device->hasCalibrationThrottle(index))
556 {
557 device->setCalibrationStatus(index,
558 static_cast<JoyAxis::ThrottleTypes>(throttle));
559 }
560
561 setCurrentRawValue(currentThrottledDeadValue);
562 //currentRawValue = currentThrottledDeadValue;
563 currentThrottledValue = calculateThrottledValue(currentRawValue);
564 }
565
566 return found;
567 }
568
readButtonConfig(QXmlStreamReader * xml)569 bool JoyAxis::readButtonConfig(QXmlStreamReader *xml)
570 {
571 bool found = false;
572
573 int index = xml->attributes().value("index").toString().toInt();
574 if (index == 1)
575 {
576 found = true;
577 naxisbutton->readConfig(xml);
578 }
579 else if (index == 2)
580 {
581 found = true;
582 paxisbutton->readConfig(xml);
583 }
584
585 return found;
586 }
587
reset()588 void JoyAxis::reset()
589 {
590 deadZone = getDefaultDeadZone();
591 isActive = false;
592
593 eventActive = false;
594 maxZoneValue = getDefaultMaxZone();
595 throttle = getDefaultThrottle();
596
597 paxisbutton->reset();
598 naxisbutton->reset();
599 activeButton = 0;
600 lastKnownThottledValue = 0;
601 lastKnownRawValue = 0;
602
603 adjustRange();
604 setCurrentRawValue(currentThrottledDeadValue);
605 currentThrottledValue = calculateThrottledValue(currentRawValue);
606 axisName.clear();
607
608 pendingEvent = false;
609 pendingValue = currentRawValue;
610 pendingIgnoreSets = false;
611 //pendingUpdateLastValues = true;
612 }
613
reset(int index)614 void JoyAxis::reset(int index)
615 {
616 reset();
617 this->index = index;
618 }
619
getPAxisButton()620 JoyAxisButton* JoyAxis::getPAxisButton()
621 {
622 return paxisbutton;
623 }
624
getNAxisButton()625 JoyAxisButton* JoyAxis::getNAxisButton()
626 {
627 return naxisbutton;
628 }
629
getCurrentRawValue()630 int JoyAxis::getCurrentRawValue()
631 {
632 return currentRawValue;
633 }
634
adjustRange()635 void JoyAxis::adjustRange()
636 {
637 if (throttle == JoyAxis::NegativeThrottle)
638 {
639 currentThrottledDeadValue = AXISMAX;
640 }
641 else if (throttle == JoyAxis::NormalThrottle ||
642 throttle == JoyAxis::PositiveHalfThrottle ||
643 throttle == JoyAxis::NegativeHalfThrottle)
644 {
645 currentThrottledDeadValue = 0;
646 }
647 else if (throttle == JoyAxis::PositiveThrottle)
648 {
649 currentThrottledDeadValue = AXISMIN;
650 }
651
652 currentThrottledValue = calculateThrottledValue(currentRawValue);
653 }
654
getCurrentThrottledDeadValue()655 int JoyAxis::getCurrentThrottledDeadValue()
656 {
657 return currentThrottledDeadValue;
658 }
659
getDistanceFromDeadZone()660 double JoyAxis::getDistanceFromDeadZone()
661 {
662 return getDistanceFromDeadZone(currentThrottledValue);
663 }
664
getDistanceFromDeadZone(int value)665 double JoyAxis::getDistanceFromDeadZone(int value)
666 {
667 double distance = 0.0;
668 int currentValue = value;
669
670 if (currentValue >= deadZone)
671 {
672 distance = (currentValue - deadZone)/static_cast<double>(maxZoneValue - deadZone);
673 }
674 else if (currentValue <= -deadZone)
675 {
676 distance = (currentValue + deadZone)/static_cast<double>(-maxZoneValue + deadZone);
677 }
678
679 distance = qBound(0.0, distance, 1.0);
680 return distance;
681 }
682
683 /**
684 * @brief Get the current value for an axis in either direction converted to
685 * the range of -1.0 to 1.0.
686 * @param Current interger value of the axis
687 * @return Axis value in the range of -1.0 to 1.0
688 */
getRawDistance(int value)689 double JoyAxis::getRawDistance(int value)
690 {
691 double distance = 0.0;
692 int currentValue = value;
693
694 distance = currentValue / static_cast<double>(maxZoneValue);
695 distance = qBound(-1.0, distance, 1.0);
696
697 return distance;
698 }
699
propogateThrottleChange()700 void JoyAxis::propogateThrottleChange()
701 {
702 emit throttleChangePropogated(this->index);
703 }
704
getCurrentlyAssignedSet()705 int JoyAxis::getCurrentlyAssignedSet()
706 {
707 return originset;
708 }
709
setControlStick(JoyControlStick * stick)710 void JoyAxis::setControlStick(JoyControlStick *stick)
711 {
712 removeVDPads();
713 removeControlStick();
714 this->stick = stick;
715 emit propertyUpdated();
716 }
717
isPartControlStick()718 bool JoyAxis::isPartControlStick()
719 {
720 return (this->stick != 0);
721 }
722
getControlStick()723 JoyControlStick* JoyAxis::getControlStick()
724 {
725 return this->stick;
726 }
727
removeControlStick(bool performRelease)728 void JoyAxis::removeControlStick(bool performRelease)
729 {
730 if (stick)
731 {
732 if (performRelease)
733 {
734 stick->releaseButtonEvents();
735 }
736
737 this->stick = 0;
738 emit propertyUpdated();
739 }
740 }
741
742
743
hasControlOfButtons()744 bool JoyAxis::hasControlOfButtons()
745 {
746 bool value = true;
747 if (paxisbutton->isPartVDPad() || naxisbutton->isPartVDPad())
748 {
749 value = false;
750 }
751
752 return value;
753 }
754
removeVDPads()755 void JoyAxis::removeVDPads()
756 {
757 if (paxisbutton->isPartVDPad())
758 {
759 paxisbutton->joyEvent(false, true);
760 paxisbutton->removeVDPad();
761 }
762
763 if (naxisbutton->isPartVDPad())
764 {
765 naxisbutton->joyEvent(false, true);
766 naxisbutton->removeVDPad();
767 }
768 }
769
isDefault()770 bool JoyAxis::isDefault()
771 {
772 bool value = true;
773 value = value && (deadZone == getDefaultDeadZone());
774 value = value && (maxZoneValue == getDefaultMaxZone());
775 //value = value && (throttle == getDefaultThrottle());
776 value = value && (paxisbutton->isDefault());
777 value = value && (naxisbutton->isDefault());
778 return value;
779 }
780
781 /* Use this method to keep currentRawValue in the expected range.
782 * SDL has a minimum axis value of -32768 which should be ignored to
783 * ensure that JoyControlStick will not encounter overflow problems
784 * on a 32 bit machine.
785 */
setCurrentRawValue(int value)786 void JoyAxis::setCurrentRawValue(int value)
787 {
788 if (value >= JoyAxis::AXISMIN && value <= JoyAxis::AXISMAX)
789 {
790 currentRawValue = value;
791 }
792 else if (value > JoyAxis::AXISMAX)
793 {
794 currentRawValue = JoyAxis::AXISMAX;
795 }
796 else if (value < JoyAxis::AXISMIN)
797 {
798 currentRawValue = JoyAxis::AXISMIN;
799 }
800 }
801
setButtonsMouseMode(JoyButton::JoyMouseMovementMode mode)802 void JoyAxis::setButtonsMouseMode(JoyButton::JoyMouseMovementMode mode)
803 {
804 paxisbutton->setMouseMode(mode);
805 naxisbutton->setMouseMode(mode);
806 }
807
hasSameButtonsMouseMode()808 bool JoyAxis::hasSameButtonsMouseMode()
809 {
810 bool result = true;
811 if (paxisbutton->getMouseMode() != naxisbutton->getMouseMode())
812 {
813 result = false;
814 }
815
816 return result;
817 }
818
getButtonsPresetMouseMode()819 JoyButton::JoyMouseMovementMode JoyAxis::getButtonsPresetMouseMode()
820 {
821 JoyButton::JoyMouseMovementMode resultMode = JoyButton::MouseCursor;
822 if (paxisbutton->getMouseMode() == naxisbutton->getMouseMode())
823 {
824 resultMode = paxisbutton->getMouseMode();
825 }
826
827 return resultMode;
828 }
829
setButtonsMouseCurve(JoyButton::JoyMouseCurve mouseCurve)830 void JoyAxis::setButtonsMouseCurve(JoyButton::JoyMouseCurve mouseCurve)
831 {
832 paxisbutton->setMouseCurve(mouseCurve);
833 naxisbutton->setMouseCurve(mouseCurve);
834 }
835
hasSameButtonsMouseCurve()836 bool JoyAxis::hasSameButtonsMouseCurve()
837 {
838 bool result = true;
839 if (paxisbutton->getMouseCurve() != naxisbutton->getMouseCurve())
840 {
841 result = false;
842 }
843
844 return result;
845 }
846
getButtonsPresetMouseCurve()847 JoyButton::JoyMouseCurve JoyAxis::getButtonsPresetMouseCurve()
848 {
849 JoyButton::JoyMouseCurve resultCurve = JoyButton::LinearCurve;
850 if (paxisbutton->getMouseCurve() == naxisbutton->getMouseCurve())
851 {
852 resultCurve = paxisbutton->getMouseCurve();
853 }
854
855 return resultCurve;
856 }
857
setButtonsSpringWidth(int value)858 void JoyAxis::setButtonsSpringWidth(int value)
859 {
860 paxisbutton->setSpringWidth(value);
861 naxisbutton->setSpringWidth(value);
862 }
863
setButtonsSpringHeight(int value)864 void JoyAxis::setButtonsSpringHeight(int value)
865 {
866 paxisbutton->setSpringHeight(value);
867 naxisbutton->setSpringHeight(value);
868 }
869
getButtonsPresetSpringWidth()870 int JoyAxis::getButtonsPresetSpringWidth()
871 {
872 int presetSpringWidth = 0;
873
874 if (paxisbutton->getSpringWidth() == naxisbutton->getSpringWidth())
875 {
876 presetSpringWidth = paxisbutton->getSpringWidth();
877 }
878
879 return presetSpringWidth;
880 }
881
getButtonsPresetSpringHeight()882 int JoyAxis::getButtonsPresetSpringHeight()
883 {
884 int presetSpringHeight = 0;
885
886 if (paxisbutton->getSpringHeight() == naxisbutton->getSpringHeight())
887 {
888 presetSpringHeight = paxisbutton->getSpringHeight();
889 }
890
891 return presetSpringHeight;
892 }
893
setButtonsSensitivity(double value)894 void JoyAxis::setButtonsSensitivity(double value)
895 {
896 paxisbutton->setSensitivity(value);
897 naxisbutton->setSensitivity(value);
898 }
899
getButtonsPresetSensitivity()900 double JoyAxis::getButtonsPresetSensitivity()
901 {
902 double presetSensitivity = 1.0;
903
904 if (paxisbutton->getSensitivity() == naxisbutton->getSensitivity())
905 {
906 presetSensitivity = paxisbutton->getSensitivity();
907 }
908
909 return presetSensitivity;
910 }
911
getAxisButtonByValue(int value)912 JoyAxisButton* JoyAxis::getAxisButtonByValue(int value)
913 {
914 JoyAxisButton *eventbutton = 0;
915 int throttledValue = calculateThrottledValue(value);
916 if (throttledValue > deadZone)
917 {
918 eventbutton = paxisbutton;
919 }
920 else if (throttledValue < -deadZone)
921 {
922 eventbutton = naxisbutton;
923 }
924
925 return eventbutton;
926 }
927
setAxisName(QString tempName)928 void JoyAxis::setAxisName(QString tempName)
929 {
930 if (tempName.length() <= 20 && tempName != axisName)
931 {
932 axisName = tempName;
933 emit axisNameChanged();
934 emit propertyUpdated();
935 }
936 }
937
getAxisName()938 QString JoyAxis::getAxisName()
939 {
940 return axisName;
941 }
942
setButtonsWheelSpeedX(int value)943 void JoyAxis::setButtonsWheelSpeedX(int value)
944 {
945 paxisbutton->setWheelSpeedX(value);
946 naxisbutton->setWheelSpeedX(value);
947 }
948
setButtonsWheelSpeedY(int value)949 void JoyAxis::setButtonsWheelSpeedY(int value)
950 {
951 paxisbutton->setWheelSpeedY(value);
952 naxisbutton->setWheelSpeedY(value);
953 }
954
setDefaultAxisName(QString tempname)955 void JoyAxis::setDefaultAxisName(QString tempname)
956 {
957 defaultAxisName = tempname;
958 }
959
getDefaultAxisName()960 QString JoyAxis::getDefaultAxisName()
961 {
962 return defaultAxisName;
963 }
964
getPartialName(bool forceFullFormat,bool displayNames)965 QString JoyAxis::getPartialName(bool forceFullFormat, bool displayNames)
966 {
967 QString label;
968
969 if (!axisName.isEmpty() && displayNames)
970 {
971 if (forceFullFormat)
972 {
973 label.append(tr("Axis")).append(" ");
974 }
975
976 label.append(axisName);
977 }
978 else if (!defaultAxisName.isEmpty())
979 {
980 if (forceFullFormat)
981 {
982 label.append(tr("Axis")).append(" ");
983 }
984 label.append(defaultAxisName);
985 }
986 else
987 {
988 label.append(tr("Axis")).append(" ");
989 label.append(QString::number(getRealJoyIndex()));
990 }
991
992 return label;
993 }
994
getXmlName()995 QString JoyAxis::getXmlName()
996 {
997 return this->xmlName;
998 }
999
getDefaultDeadZone()1000 int JoyAxis::getDefaultDeadZone()
1001 {
1002 return this->AXISDEADZONE;
1003 }
1004
getDefaultMaxZone()1005 int JoyAxis::getDefaultMaxZone()
1006 {
1007 return this->AXISMAXZONE;
1008 }
1009
getDefaultThrottle()1010 JoyAxis::ThrottleTypes JoyAxis::getDefaultThrottle()
1011 {
1012 return this->DEFAULTTHROTTLE;
1013 }
1014
getParentSet()1015 SetJoystick* JoyAxis::getParentSet()
1016 {
1017 return parentSet;
1018 }
1019
establishPropertyUpdatedConnection()1020 void JoyAxis::establishPropertyUpdatedConnection()
1021 {
1022 connect(this, SIGNAL(propertyUpdated()), getParentSet()->getInputDevice(), SLOT(profileEdited()));
1023 }
1024
disconnectPropertyUpdatedConnection()1025 void JoyAxis::disconnectPropertyUpdatedConnection()
1026 {
1027 disconnect(this, SIGNAL(propertyUpdated()), getParentSet()->getInputDevice(), SLOT(profileEdited()));
1028 }
1029
setButtonsSpringRelativeStatus(bool value)1030 void JoyAxis::setButtonsSpringRelativeStatus(bool value)
1031 {
1032 paxisbutton->setSpringRelativeStatus(value);
1033 naxisbutton->setSpringRelativeStatus(value);
1034 }
1035
isRelativeSpring()1036 bool JoyAxis::isRelativeSpring()
1037 {
1038 bool relative = false;
1039
1040 if (paxisbutton->isRelativeSpring() == naxisbutton->isRelativeSpring())
1041 {
1042 relative = paxisbutton->isRelativeSpring();
1043 }
1044
1045 return relative;
1046 }
1047
performCalibration(int value)1048 void JoyAxis::performCalibration(int value)
1049 {
1050 InputDevice *device = parentSet->getInputDevice();
1051 if (value <= -30000)
1052 {
1053 // Assume axis is a trigger. Set default throttle to Positive.
1054 device->setCalibrationThrottle(index, PositiveThrottle);
1055 }
1056 else
1057 {
1058 // Ensure that default throttle is used when a device is reset.
1059 device->setCalibrationThrottle(index,
1060 static_cast<JoyAxis::ThrottleTypes>(throttle));
1061 }
1062 //else if (value >= -15000 && value <= 15000)
1063 //{
1064 // device->setCalibrationThrottle(index, NormalThrottle);
1065 //}
1066 }
1067
copyAssignments(JoyAxis * destAxis)1068 void JoyAxis::copyAssignments(JoyAxis *destAxis)
1069 {
1070 destAxis->reset();
1071 destAxis->deadZone = deadZone;
1072 destAxis->maxZoneValue = maxZoneValue;
1073 destAxis->axisName = axisName;
1074 paxisbutton->copyAssignments(destAxis->paxisbutton);
1075 naxisbutton->copyAssignments(destAxis->naxisbutton);
1076
1077 if (!destAxis->isDefault())
1078 {
1079 emit propertyUpdated();
1080 }
1081 }
1082
setButtonsEasingDuration(double value)1083 void JoyAxis::setButtonsEasingDuration(double value)
1084 {
1085 paxisbutton->setEasingDuration(value);
1086 naxisbutton->setEasingDuration(value);
1087 }
1088
getButtonsEasingDuration()1089 double JoyAxis::getButtonsEasingDuration()
1090 {
1091 double result = JoyButton::DEFAULTEASINGDURATION;
1092 if (paxisbutton->getEasingDuration() == naxisbutton->getEasingDuration())
1093 {
1094 result = paxisbutton->getEasingDuration();
1095 }
1096
1097 return result;
1098 }
1099
getLastKnownThrottleValue()1100 int JoyAxis::getLastKnownThrottleValue()
1101 {
1102 return lastKnownThottledValue;
1103 }
1104
getLastKnownRawValue()1105 int JoyAxis::getLastKnownRawValue()
1106 {
1107 return lastKnownRawValue;
1108 }
1109
1110 /**
1111 * @brief Determine an appropriate release value for an axis depending
1112 * on the current throttle setting being used.
1113 * @return Release value for an axis
1114 */
getProperReleaseValue()1115 int JoyAxis::getProperReleaseValue()
1116 {
1117 // Handles NormalThrottle case
1118 int value = 0;
1119
1120 if (throttle == NegativeHalfThrottle)
1121 {
1122 value = 0;
1123 }
1124 else if (throttle == NegativeThrottle)
1125 {
1126 value = JoyAxis::AXISMAX;
1127 }
1128 else if (throttle == PositiveThrottle)
1129 {
1130 value = JoyAxis::AXISMIN;
1131 }
1132 else if (throttle == PositiveHalfThrottle)
1133 {
1134 value = 0;
1135 }
1136
1137 return value;
1138 }
1139
setExtraAccelerationCurve(JoyButton::JoyExtraAccelerationCurve curve)1140 void JoyAxis::setExtraAccelerationCurve(JoyButton::JoyExtraAccelerationCurve curve)
1141 {
1142 paxisbutton->setExtraAccelerationCurve(curve);
1143 naxisbutton->setExtraAccelerationCurve(curve);
1144 }
1145
getExtraAccelerationCurve()1146 JoyButton::JoyExtraAccelerationCurve JoyAxis::getExtraAccelerationCurve()
1147 {
1148 JoyButton::JoyExtraAccelerationCurve result = JoyButton::LinearAccelCurve;
1149 if (paxisbutton->getExtraAccelerationCurve() == naxisbutton->getExtraAccelerationCurve())
1150 {
1151 result = paxisbutton->getExtraAccelerationCurve();
1152 }
1153
1154 return result;
1155 }
1156
copyRawValues(JoyAxis * srcAxis)1157 void JoyAxis::copyRawValues(JoyAxis *srcAxis)
1158 {
1159 this->lastKnownRawValue = srcAxis->lastKnownRawValue;
1160 this->currentRawValue = srcAxis->currentRawValue;
1161 }
1162
copyThrottledValues(JoyAxis * srcAxis)1163 void JoyAxis::copyThrottledValues(JoyAxis *srcAxis)
1164 {
1165 this->lastKnownThottledValue = srcAxis->lastKnownThottledValue;
1166 this->currentThrottledValue = srcAxis->currentThrottledValue;
1167 }
1168
eventReset()1169 void JoyAxis::eventReset()
1170 {
1171 naxisbutton->eventReset();
1172 paxisbutton->eventReset();
1173 }
1174