1 module bindbc.jsl.joyshocklibrary;
2 
3 /**
4  * API difference: I decided to use an enumerator instead of individually defined values.
5  *
6  * Stores the values associated with types of possible controller types.
7  */
8 enum JoyShockTypes {
9 	JoyCon_Left     =   1,
10 	JoyCon_Right    =   2,
11 	ProController   =   3,
12 	DualShock4      =   4
13 }
14 /**
15  * API difference: I decided to use an enumerator instead of individually defined values.
16  *
17  * Stores the values associated with types of potential JoyCon splits.
18  */
19 enum JoyConSplitType {
20 	Left            =   1,
21 	Right           =   2,
22 	Full            =   3
23 }
24 /**
25  * API difference: I decided to use an enumerator instead of individually defined values.
26  *
27  * Stores the values associated with button events. For the right-hand-side buttons, south-east-west-north system 
28  * is used to avoid ambiguity between Microsoft and Nintendo systems. (Offsets)
29  */
30 enum ButtonOffsets {
31 	Up = 0,
32 	Down = 1,
33 	Left = 2,
34 	Right = 3,
35 	Plus = 4,
36 	Options = 4,
37 	Minus = 5,
38 	Share = 5,
39 	LClick = 6,
40 	RClick = 7,
41 	L = 8,
42 	R = 9,
43 	ZL = 10,
44 	ZR = 11,
45 	S = 12,
46 	E = 13,
47 	W = 14,
48 	N = 15,
49 	Home = 16,
50 	PS = 16,
51 	Capture = 17,
52 	TouchpadClick = 17,
53 	SL = 18,
54 	SR = 19,
55 }
56 /**
57  * API difference: I decided to use an enumerator instead of individually defined values.
58  *
59  * Stores the values associated with button events. For the right-hand-side buttons, south-east-west-north system 
60  * is used to avoid ambiguity between Microsoft and Nintendo systems. (Bitmasks)
61  */
62 enum ButtonMasks {
63 	Up = 1 << ButtonOffsets.Up,
64 	Down = 1 << ButtonOffsets.Down,
65 	Left = 1 << ButtonOffsets.Left,
66 	Right = 1 << ButtonOffsets.Right,
67 	Plus = 1 << ButtonOffsets.Plus,
68 	Options = 1 << ButtonOffsets.Options,
69 	Minus = 1 << ButtonOffsets.Minus,
70 	Share = 1 << ButtonOffsets.Share,
71 	LClick = 1 << ButtonOffsets.LClick,
72 	RClick = 1 << ButtonOffsets.RClick,
73 	L = 1 << ButtonOffsets.L,
74 	R = 1 << ButtonOffsets.R,
75 	ZL = 1 << ButtonOffsets.ZL,
76 	ZR = 1 << ButtonOffsets.ZR,
77 	S = 1 << ButtonOffsets.S,
78 	E = 1 << ButtonOffsets.E,
79 	W = 1 << ButtonOffsets.W,
80 	N = 1 << ButtonOffsets.N,
81 	Home = 1 << ButtonOffsets.Home,
82 	PS = 1 << ButtonOffsets.PS,
83 	Capture = 1 << ButtonOffsets.Capture,
84 	TouchpadClick = 1 << ButtonOffsets.TouchpadClick,
85 	SL = 1 << ButtonOffsets.SL,
86 	SR = 1 << ButtonOffsets.SR,
87 }
88 
89 struct JOY_SHOCK_STATE {
90 	int buttons;
91 	float lTrigger;
92 	float rTrigger;
93 	float stickLX;
94 	float stickLY;
95 	float stickRX;
96 	float stickRY;
97 }
98 
99 struct IMU_STATE {
100 	float accelX;
101 	float accelY;
102 	float accelZ;
103 	float gyroX;
104 	float gyroY;
105 	float gyroZ;
106 }
107 version(JSLV2_0) {
108 	struct MOTION_STATE {
109 		float quatW;
110 		float quatX;
111 		float quatY;
112 		float quatZ;
113 		float accelX;
114 		float accelY;
115 		float accelZ;
116 		float gravX;
117 		float gravY;
118 		float gravZ;
119 	}
120 
121 	struct TOUCH_STATE {
122 		int t0Id;
123 		int t1Id;
124 		bool t0Down;
125 		bool t1Down;
126 		float t0X;
127 		float t0Y;
128 		float t1X;
129 		float t1Y;
130 	}
131 }
132 
133 version(BindJSL_Static) {
134 extern(C) @nogc nothrow:
135 	// These are the best way to get all the buttons/triggers/sticks, gyro/accelerometer (IMU), orientation/acceleration/gravity (Motion), or touchpad
136 	JOY_SHOCK_STATE JslGetSimpleState(int deviceId);
137 	IMU_STATE JslGetIMUState(int deviceId);
138 	int JslGetButtons(int deviceId);
139 	version(JSLV2_0) {
140 		MOTION_STATE JslGetMotionState(int deviceId);
141 		TOUCH_STATE JslGetTouchState(int deviceId);
142 	}
143 	// get thumbsticks
144 	float JslGetLeftX(int deviceId);
145 	float JslGetLeftY(int deviceId);
146 	float JslGetRightX(int deviceId);
147 	float JslGetRightY(int deviceId);
148 
149 	// get triggers. Switch controllers don't have analogue triggers, but will report 0.0 or 1.0 so they can be used in the same way as others
150 	float JslGetLeftTrigger(int deviceId);
151 	float JslGetRightTrigger(int deviceId);
152 
153 	// get gyro
154 	float JslGetGyroX(int deviceId);
155 	float JslGetGyroY(int deviceId);
156 	float JslGetGyroZ(int deviceId);
157 
158 	// get accelerometor
159 	float JslGetAccelX(int deviceId);
160 	float JslGetAccelY(int deviceId);
161 	float JslGetAccelZ(int deviceId);
162 
163 	// analog parameters have different resolutions depending on device
164 	float JslGetStickStep(int deviceId);
165 	float JslGetTriggerStep(int deviceId);
166 	float JslGetPollRate(int deviceId);
167 
168 	// calibration
169 	void JslResetContinuousCalibration(int deviceId);
170 	void JslStartContinuousCalibration(int deviceId);
171 	void JslPauseContinuousCalibration(int deviceId);
172 	void JslGetCalibrationOffset(int deviceId, ref float xOffset, ref float yOffset, ref float zOffset);
173 	void JslSetCalibrationOffset(int deviceId, float xOffset, float yOffset, float zOffset);
174 
175 	/// this function will get called for each input event from each controller
176 	void JslSetCallback(void function(int, JOY_SHOCK_STATE, JOY_SHOCK_STATE, IMU_STATE, IMU_STATE, float) callback);
177 
178 	/// what kind of controller is this?
179 	int JslGetControllerType(int deviceId);
180 	/// is this a left, right, or full controller?
181 	int JslGetControllerSplitType(int deviceId);
182 	/// what colour is the controller (not all controllers support this; those that don't will report white)
183 	int JslGetControllerColour(int deviceId);
184 	/// set controller light colour (not all controllers have a light whose colour can be set, but that just means nothing will be done when this is called -- no harm)
185 	void JslSetLightColour(int deviceId, int colour);
186 	/// set controller rumble
187 	void JslSetRumble(int deviceId, int smallRumble, int bigRumble);
188 	/// set controller player number indicator (not all controllers have a number indicator which can be set, but that just means nothing will be done when this is called -- no harm)
189 	void JslSetPlayerNumber(int deviceId, int number);
190 } else {
191 	extern(C) @nogc nothrow {
192 		alias pJslGetSimpleState = JOY_SHOCK_STATE function(int deviceId);
193 		alias pJslGetIMUState = IMU_STATE function(int deviceId);
194 		alias pJslGetButtons = int function(int deviceId);
195 		alias pJslGetLeftX = float function(int deviceId);
196 		alias pJslGetLeftY = float function(int deviceId);
197 		alias pJslGetRightX = float function(int deviceId);
198 		alias pJslGetRightY = float function(int deviceId);
199 		alias pJslGetLeftTrigger = float function(int deviceId);
200 		alias pJslGetRightTrigger = float function(int deviceId);
201 		alias pJslGetGyroX = float function(int deviceId);
202 		alias pJslGetGyroY = float function(int deviceId);
203 		alias pJslGetGyroZ = float function(int deviceId);
204 		alias pJslGetAccelX = float function(int deviceId);
205 		alias pJslGetAccelY = float function(int deviceId);
206 		alias pJslGetAccelZ = float function(int deviceId);
207 		alias pJslGetStickStep = float function(int deviceId);
208 		alias pJslGetTriggerStep = float function(int deviceId);
209 		alias pJslGetPollRate = float function(int deviceId);
210 		alias pJslResetContinuousCalibration = void function(int deviceId);
211 		alias pJslStartContinuousCalibration = void function(int deviceId);
212 		alias pJslPauseContinuousCalibration = void function(int deviceId);
213 		alias pJslGetCalibrationOffset = void function(int deviceId, ref float xOffset, ref float yOffset, ref float zOffset);
214 		alias pJslSetCalibrationOffset = void function(int deviceId, float xOffset, float yOffset, float zOffset);
215 		alias pJslSetCallback = void function(void function(int, JOY_SHOCK_STATE, JOY_SHOCK_STATE, IMU_STATE, IMU_STATE, float) callback);
216 		alias pJslGetControllerType = int function(int deviceId);
217 		alias pJslGetControllerSplitType = int function(int deviceId);
218 		alias pJslGetControllerColour = int function(int deviceId);
219 		alias pJslSetLightColour = void function(int deviceId, int colour);
220 		alias pJslSetRumble = void function(int deviceId, int smallRumble, int bigRumble);
221 		alias pJslSetPlayerNumber = void function(int deviceId, int number);
222 		version(JSLV2_0) {
223 			alias pJslGetMotionState = MOTION_STATE function(int deviceId);
224 			alias pJslGetTouchState = TOUCH_STATE function(int deviceId);
225 		}
226 	}
227 	__gshared {
228 		pJslGetSimpleState JslGetSimpleState;
229 		pJslGetIMUState JslGetIMUState;
230 		pJslGetButtons JslGetButtons;
231 		pJslGetLeftX JslGetLeftX;
232 		pJslGetLeftY JslGetLeftY;
233 		pJslGetRightX JslGetRightX;
234 		pJslGetRightY JslGetRightY;
235 		pJslGetLeftTrigger JslGetLeftTrigger;
236 		pJslGetRightTrigger JslGetRightTrigger;
237 		pJslGetGyroX JslGetGyroX;
238 		pJslGetGyroY JslGetGyroY;
239 		pJslGetGyroZ JslGetGyroZ;
240 		pJslGetAccelX JslGetAccelX;
241 		pJslGetAccelY JslGetAccelY;
242 		pJslGetAccelZ JslGetAccelZ;
243 		pJslGetStickStep JslGetStickStep;
244 		pJslGetTriggerStep JslGetTriggerStep;
245 		pJslGetPollRate JslGetPollRate;
246 		pJslResetContinuousCalibration JslResetContinuousCalibration;
247 		pJslStartContinuousCalibration JslStartContinuousCalibration;
248 		pJslPauseContinuousCalibration JslPauseContinuousCalibration;
249 		pJslGetCalibrationOffset JslGetCalibrationOffset;
250 		pJslSetCalibrationOffset JslSetCalibrationOffset;
251 		/// this function will get called for each input event from each controller
252 		pJslSetCallback JslSetCallback;
253 		/// what kind of controller is this?
254 		pJslGetControllerType JslGetControllerType;
255 		/// is this a left, right, or full controller?
256 		pJslGetControllerSplitType JslGetControllerSplitType;
257 		/// what colour is the controller (not all controllers support this; those that don't will report white)
258 		pJslGetControllerColour JslGetControllerColour;
259 		/// set controller light colour (not all controllers have a light whose colour can be set, but that just means nothing will be done when this is called -- no harm)
260 		pJslSetLightColour JslSetLightColour;
261 		/// set controller rumble
262 		pJslSetRumble JslSetRumble;
263 		/// set controller player number indicator (not all controllers have a number indicator which can be set, but that just means nothing will be done when this is called -- no harm)
264 		pJslSetPlayerNumber JslSetPlayerNumber;
265 		version(JSLV2_0) {
266 			pJslGetMotionState JslGetMotionState;
267 			pJslGetTouchState JslGetTouchState;
268 		}
269 	}
270 }