1 /*
2  *  Copyright (C) 2014-2018 Team Kodi
3  *  This file is part of Kodi - https://kodi.tv
4  *
5  *  SPDX-License-Identifier: GPL-2.0-or-later
6  *  See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 #include "JoystickTypes.h"
12 #include "input/keyboard/KeyboardTypes.h"
13 #include "input/mouse/MouseTypes.h"
14 
15 #include <stdint.h>
16 
17 namespace KODI
18 {
19 namespace JOYSTICK
20 {
21 /*!
22  * \ingroup joystick
23  * \brief Basic driver element associated with input events
24  *
25  * Driver input (bools, floats and enums) is split into primitives that better
26  * map to the physical features on a joystick.
27  *
28  * A bool obviously only maps to a single feature, so it is a driver
29  * primitive. Here, these are called "buttons".
30  *
31  * A hat enum encodes the state of the four hat directions. Each direction
32  * can map to a different feature, so a hat enum consists of four driver
33  * primitives called "hat directions".
34  *
35  * A float is a little trickier. Trivially, it can map to an analog stick or
36  * trigger. However, DirectInput combines two triggers onto a single axis.
37  * Therefore, the axis is split into two primitives called "semiaxes".
38  *
39  * The type determines the fields in use:
40  *
41  *    Button:
42  *       - driver index
43  *
44  *    Hat direction:
45  *       - driver index
46  *       - hat direction (up/right/down/left)
47  *
48  *    Semiaxis:
49  *       - driver index
50  *       - center (-1, 0 or 1)
51  *       - semiaxis direction (positive/negative)
52  *       - range (1 or 2)
53  *
54  *    Motor:
55  *       - driver index
56  *
57  *    Key:
58  *       - keycode
59  *
60  *    Mouse button:
61  *       - driver index
62  *
63  *    Relative pointer:
64  *       - pointer direction
65  *
66  * For more info, see "Chapter 2. Joystick drivers" in the documentation
67  * thread: http://forum.kodi.tv/showthread.php?tid=257764
68  */
69 class CDriverPrimitive
70 {
71 public:
72   /*!
73    * \brief Construct an invalid driver primitive
74    */
75   CDriverPrimitive(void);
76 
77   /*!
78    * \brief Construct a driver primitive representing a button or motor
79    */
80   CDriverPrimitive(PRIMITIVE_TYPE type, unsigned int index);
81 
82   /*!
83    * \brief Construct a driver primitive representing one of the four
84    *        direction arrows on a dpad
85    */
86   CDriverPrimitive(unsigned int hatIndex, HAT_DIRECTION direction);
87 
88   /*!
89    * \brief Construct a driver primitive representing the positive or negative
90    *        half of an axis
91    */
92   CDriverPrimitive(unsigned int axisIndex,
93                    int center,
94                    SEMIAXIS_DIRECTION direction,
95                    unsigned int range);
96 
97   /*!
98    * \brief Construct a driver primitive representing a key on a keyboard
99    */
100   CDriverPrimitive(KEYBOARD::KeySymbol keycode);
101 
102   /*!
103    * \brief Construct a driver primitive representing a mouse button
104    */
105   CDriverPrimitive(MOUSE::BUTTON_ID index);
106 
107   /*!
108    * \brief Construct a driver primitive representing a relative pointer
109    */
110   CDriverPrimitive(RELATIVE_POINTER_DIRECTION direction);
111 
112   bool operator==(const CDriverPrimitive& rhs) const;
113   bool operator<(const CDriverPrimitive& rhs) const;
114 
115   bool operator!=(const CDriverPrimitive& rhs) const { return !operator==(rhs); }
116   bool operator>(const CDriverPrimitive& rhs) const { return !(operator<(rhs) || operator==(rhs)); }
117   bool operator<=(const CDriverPrimitive& rhs) const { return operator<(rhs) || operator==(rhs); }
118   bool operator>=(const CDriverPrimitive& rhs) const { return !operator<(rhs); }
119 
120   /*!
121    * \brief The type of driver primitive
122    */
Type(void)123   PRIMITIVE_TYPE Type(void) const { return m_type; }
124 
125   /*!
126    * \brief The index used by the joystick driver
127    *
128    * Valid for:
129    *   - buttons
130    *   - hats
131    *   - semiaxes
132    *   - motors
133    */
Index(void)134   unsigned int Index(void) const { return m_driverIndex; }
135 
136   /*!
137    * \brief The direction arrow (valid for hat directions)
138    */
HatDirection(void)139   HAT_DIRECTION HatDirection(void) const { return m_hatDirection; }
140 
141   /*!
142    * \brief The location of the zero point of the semiaxis
143    */
Center()144   int Center() const { return m_center; }
145 
146   /*!
147    * \brief The semiaxis direction (valid for semiaxes)
148    */
SemiAxisDirection(void)149   SEMIAXIS_DIRECTION SemiAxisDirection(void) const { return m_semiAxisDirection; }
150 
151   /*!
152    * \brief The distance between the center and the farthest valid value (valid for semiaxes)
153    */
Range()154   unsigned int Range() const { return m_range; }
155 
156   /*!
157    * \brief The keybord symbol (valid for keys)
158    */
Keycode()159   KEYBOARD::KeySymbol Keycode() const { return m_keycode; }
160 
161   /*!
162    * \brief The mouse button ID (valid for mouse buttons)
163    */
MouseButton()164   MOUSE::BUTTON_ID MouseButton() const { return static_cast<MOUSE::BUTTON_ID>(m_driverIndex); }
165 
166   /*!
167    * \brief The relative pointer direction (valid for relative pointers)
168    */
PointerDirection()169   RELATIVE_POINTER_DIRECTION PointerDirection() const { return m_pointerDirection; }
170 
171   /*!
172    * \brief Test if an driver primitive is valid
173    *
174    * A driver primitive is valid if it has a known type and:
175    *
176    *   1) for hats, it is a cardinal direction
177    *   2) for semi-axes, it is a positive or negative direction
178    *   3) for keys, the keycode is non-empty
179    */
180   bool IsValid(void) const;
181 
182 private:
183   PRIMITIVE_TYPE m_type = PRIMITIVE_TYPE::UNKNOWN;
184   unsigned int m_driverIndex = 0;
185   HAT_DIRECTION m_hatDirection = HAT_DIRECTION::NONE;
186   int m_center = 0;
187   SEMIAXIS_DIRECTION m_semiAxisDirection = SEMIAXIS_DIRECTION::ZERO;
188   unsigned int m_range = 1;
189   KEYBOARD::KeySymbol m_keycode = XBMCK_UNKNOWN;
190   RELATIVE_POINTER_DIRECTION m_pointerDirection = RELATIVE_POINTER_DIRECTION::NONE;
191 };
192 } // namespace JOYSTICK
193 } // namespace KODI
194