66#include " ../application/application.h"
77#include " ../names.h"
88
9- // Standard library:
10- #include < cmath>
11-
129// Namespace(s):
1310namespace iosync
1411{
@@ -120,7 +117,7 @@ namespace iosync
120117 #endif
121118
122119 #ifdef GAMEPAD_VJOY_ENABLED
123- gamepad::vJoyDriverState gamepad::vJoyInfo = gamepad:: VJOY_UNDEFINED;
120+ vJoy::vJoyDriver gamepad::vJoyInfo = { vJoy::vJoyDriver:: VJOY_UNDEFINED } ;
124121 #endif
125122
126123 // Functions:
@@ -181,123 +178,188 @@ namespace iosync
181178 }
182179
183180 #ifdef GAMEPAD_VJOY_ENABLED
184- gamepad ::vJoyDriverState gamepad::__winnt__vJoy__init ()
181+ vJoy::vJoyDriver ::vJoyDriverState gamepad::__winnt__vJoy__init ()
185182 {
186- vJoyInfo = ((vJoyEnabled () == TRUE ) ? VJOY_ENABLED : VJOY_DISABLED);
183+ // Namespace(s):
184+ using namespace vJoy ;
185+
186+ vJoyInfo.state = ((vJoyEnabled () == TRUE ) ? vJoyDriver::VJOY_ENABLED : vJoyDriver::VJOY_DISABLED);
187187
188- if (vJoyInfo == VJOY_ENABLED)
188+ if (vJoyInfo. state == vJoyDriver:: VJOY_ENABLED)
189189 {
190190 WORD DLLVer, driverVer;
191191
192192 if (!DriverMatch (&DLLVer, &driverVer))
193193 {
194- vJoyInfo = VJOY_DISABLED;
194+ vJoyInfo. state = vJoyDriver:: VJOY_DISABLED;
195195 }
196196 }
197197
198- return vJoyInfo;
198+ return vJoyInfo.state ;
199+ }
200+
201+ vJoy::vJoyDriver::vJoyDriverState gamepad::__winnt__vJoy__deinit ()
202+ {
203+ // Namespace(s):
204+ using namespace vJoy ;
205+
206+ if (vJoyInfo.state == vJoyDriver::VJOY_ENABLED)
207+ {
208+ // Nothing so far.
209+
210+ vJoyInfo.state = vJoyDriver::VJOY_DISABLED;
211+ }
212+
213+ return vJoyInfo.state ;
199214 }
200215
201216 VjdStat gamepad::__winnt__vJoy__getStatus (const gamepadID internal_identifier)
202217 {
203218 return GetVJDStatus (__winnt__vJoy__vDevice (internal_identifier));
204219 }
205220
206- LONG gamepad::__winnt__vJoy__capAxis (const UINT vJoyDevice , const LONG value, const UINT axis)
221+ LONG gamepad::__winnt__vJoy__capAxis (const UINT vJoyID , const LONG value, const UINT axis, const UINT maximum_value )
207222 {
208223 #ifdef GAMEPAD_VJOY_SAFE
209- LONG axis_min, axis_max;
224+ auto & device = vJoyInfo.getDevice (vJoyID);
225+ auto axisInfo = device.getAxis (axis)->second ;
226+ auto axis_mid = ((axisInfo.max - axisInfo.min ) / 2 );
210227
211- GetVJDAxisMin (vJoyDevice, axis, &axis_min);
212- GetVJDAxisMax (vJoyDevice, axis, &axis_max);
228+ // return axis_mid + value;
229+ // return axis_mid + max(axis_min, min(value, axis_max));
230+
231+ auto scalar = max (axis_mid / maximum_value, 1 );
213232
214- return max (axis_min , min (value, axis_max ));
233+ return max (axisInfo. min , min ((LONG)(axis_mid + ( value * scalar)), axisInfo. max ));
215234 #else
216235 return value;
217236 #endif
218237 }
219238
220- void gamepad::__winnt__vJoy__transferAxis (const UINT vJoyDevice , const gamepadState& state, JOYSTICK_POSITION& vState, const UINT axis)
239+ void gamepad::__winnt__vJoy__transferAxis (const UINT vJoyID , const gamepadState& state, JOYSTICK_POSITION& vState, const UINT axis)
221240 {
222241 switch (axis)
223242 {
224243 case HID_USAGE_X:
225- vState.wAxisX = __winnt__vJoy__capAxis (vJoyDevice , state.native .Gamepad .sThumbLX , axis);
244+ vState.wAxisX = __winnt__vJoy__capAxis (vJoyID , state.native .Gamepad .sThumbLX , axis);
226245
227246 break ;
228247 case HID_USAGE_Y:
229- vState.wAxisX = __winnt__vJoy__capAxis (vJoyDevice, state.native .Gamepad .sThumbLY , axis);
248+ vState.wAxisY = __winnt__vJoy__capAxis (vJoyID, - state.native .Gamepad .sThumbLY , axis);
230249
231250 break ;
232251 case HID_USAGE_Z:
233- vState.wAxisZ = __winnt__vJoy__capAxis (vJoyDevice, state.native .Gamepad .bRightTrigger -state.native .Gamepad .bLeftTrigger , axis);
252+ {
253+ LONG m = vJoyInfo.getDevice (vJoyID).axisMax (axis);
254+
255+ m = ((m+1 )/2 );
256+ // m = m+1;
257+
258+ auto value = m;
259+
260+ int scalar = max (m / (UCHAR_MAX), 1 );
261+
262+ if (state.native .Gamepad .bRightTrigger != 0 )
263+ value += ((state.native .Gamepad .bRightTrigger * scalar) + scalar);
264+
265+ if (state.native .Gamepad .bLeftTrigger != 0 )
266+ value -= ((state.native .Gamepad .bLeftTrigger * scalar) + scalar);
267+
268+ vState.wAxisZ = value;
269+ // vState.wAxisZ = __winnt__vJoy__capAxis(vJoyID, value, axis);
270+ }
234271
235272 break ;
236273 case HID_USAGE_RX:
237- vState.wAxisXRot = __winnt__vJoy__capAxis (vJoyDevice , state.native .Gamepad .sThumbRX , axis);
274+ vState.wAxisXRot = __winnt__vJoy__capAxis (vJoyID , state.native .Gamepad .sThumbRX , axis);
238275
239276 break ;
240277 case HID_USAGE_RY:
241- vState.wAxisYRot = __winnt__vJoy__capAxis (vJoyDevice, state.native .Gamepad .sThumbRY , axis);
278+ vState.wAxisYRot = __winnt__vJoy__capAxis (vJoyID, - state.native .Gamepad .sThumbRY , axis);
242279
243280 break ;
244- case HID_USAGE_RZ:
245- vState.wAxisZRot = __winnt__vJoy__capAxis (vJoyDevice, -(state.native .Gamepad .bRightTrigger -state.native .Gamepad .bLeftTrigger ), axis);
281+ case HID_USAGE_POV:
282+ {
283+ // Local variable(s):
284+
285+ // Get a reference to the vJoy-device.
286+ auto & device = vJoyInfo.getDevice (vJoyID);
287+
288+ // Check the POV mode:
289+ if (device.contPOVNumber > 0 )
290+ {
291+ if ((state.native .Gamepad .wButtons & gamepadState::padMask) > 0 )
292+ {
293+ vState.bHats = (((int )joyHat (state))*100 );
294+ }
295+ else
296+ {
297+ // Disable the HAT.
298+ vState.bHats = 36001 ;
299+ }
300+ }
301+ else
302+ {
303+ vState.bHats = 4 ;
304+
305+ if (state.native .Gamepad .wButtons & XINPUT_GAMEPAD_DPAD_RIGHT)
306+ vState.bHats = 1 ;
307+ else if (state.native .Gamepad .wButtons & XINPUT_GAMEPAD_DPAD_LEFT)
308+ vState.bHats = 3 ;
309+ else if (state.native .Gamepad .wButtons & XINPUT_GAMEPAD_DPAD_DOWN)
310+ vState.bHats = 2 ;
311+ else if (state.native .Gamepad .wButtons & XINPUT_GAMEPAD_DPAD_UP)
312+ vState.bHats = 0 ;
313+ }
314+ }
246315
247316 break ;
248317 }
249318
250319 return ;
251320 }
252321
253- void gamepad::__winnt__vJoy__autoTransferAxis (const UINT vJoyDevice , const gamepadState& state, JOYSTICK_POSITION& vState, const UINT axis)
322+ void gamepad::__winnt__vJoy__autoTransferAxis (const UINT vJoyID , const gamepadState& state, JOYSTICK_POSITION& vState, const UINT axis)
254323 {
255- if (GetVJDAxisExist (vJoyDevice, axis))
324+ // Local variable(s):
325+ auto & device = vJoyInfo.getDevice (vJoyID);
326+
327+ if (device.hasAxis (axis))
256328 {
257- __winnt__vJoy__transferAxis (vJoyDevice , state, vState, axis);
329+ __winnt__vJoy__transferAxis (vJoyID , state, vState, axis);
258330 }
259331
260332 return ;
261333 }
262334
263- void gamepad::__winnt__vJoy__simulateState (const gamepadState& state, const UINT vJoyDevice , const VjdStat status)
335+ void gamepad::__winnt__vJoy__simulateState (const gamepadState& state, const UINT vJoyID , const VjdStat status)
264336 {
265- if (status == VJD_STAT_FREE)
266- {
267- // Acquire control over the device:
268- if (!AcquireVJD (vJoyDevice))
269- return ;
270- }
271-
272- ResetVJD (vJoyDevice);
337+ // ResetVJD(vJoyID);
273338
339+ // Local variable(s):
274340 JOYSTICK_POSITION vState;
275341
276342 ZeroVar (vState);
277343
278- vState.bDevice = vJoyDevice ;
344+ vState.bDevice = vJoyID ;
279345
280346 // Automatically transfer the axes to the output-state:
281- __winnt__vJoy__autoTransferAxis (vJoyDevice , state, vState, HID_USAGE_X);
282- __winnt__vJoy__autoTransferAxis (vJoyDevice , state, vState, HID_USAGE_Y);
347+ __winnt__vJoy__autoTransferAxis (vJoyID , state, vState, HID_USAGE_X);
348+ __winnt__vJoy__autoTransferAxis (vJoyID , state, vState, HID_USAGE_Y);
283349
284- __winnt__vJoy__autoTransferAxis (vJoyDevice , state, vState, HID_USAGE_RX);
285- __winnt__vJoy__autoTransferAxis (vJoyDevice , state, vState, HID_USAGE_RY);
350+ __winnt__vJoy__autoTransferAxis (vJoyID , state, vState, HID_USAGE_RX);
351+ __winnt__vJoy__autoTransferAxis (vJoyID , state, vState, HID_USAGE_RY);
286352
287- __winnt__vJoy__autoTransferAxis (vJoyDevice , state, vState, HID_USAGE_Z );
288- __winnt__vJoy__autoTransferAxis (vJoyDevice , state, vState, HID_USAGE_RZ );
353+ __winnt__vJoy__autoTransferAxis (vJoyID , state, vState, HID_USAGE_POV );
354+ __winnt__vJoy__autoTransferAxis (vJoyID , state, vState, HID_USAGE_Z );
289355
290- vState.lButtons = state.native .Gamepad .wButtons ;
356+ vState.lButtons = (state.native .Gamepad .wButtons ^ (state.native .Gamepad .wButtons & gamepadState::padMask));
357+ vState.lButtons = ((((vState.lButtons >> 12 ) & SHRT_MAX) | (vState.lButtons ^ (vState.lButtons & gamepadState::faceMask))) & SHRT_MAX);
291358
292- #ifdef GAMEPAD_VJOY_SAFE
293- // vState.lButtons &= (int)pow(2, GetVJDButtonNumber(vJoyDevice));
294- #endif
359+ // cout << "vState.lButtons: " << vState.lButtons << endl;
295360
296361 // Update the vJoy-device.
297- UpdateVJD (vJoyDevice, &vState);
298-
299- // Relinquish control over the device.
300- RelinquishVJD (vJoyDevice);
362+ UpdateVJD (vJoyID, &vState);
301363
302364 return ;
303365 }
@@ -307,30 +369,6 @@ namespace iosync
307369 void gamepad::simulateState (const gamepadState& state, const gamepadID localIdentifier)
308370 {
309371 #ifdef PLATFORM_WINDOWS
310- #ifdef GAMEPAD_VJOY_ENABLED
311- // Check the current state of vJoy:
312- if (vJoyInfo == VJOY_ENABLED)
313- {
314- // Calculate the internal status.
315- auto status = __winnt__vJoy__getStatus (localIdentifier);
316-
317- switch (status)
318- {
319- case VJD_STAT_OWN:
320- case VJD_STAT_FREE:
321- __winnt__vJoy__simulateState (state, __winnt__vJoy__vDevice (localIdentifier), status);
322-
323- break ;
324- case VJD_STAT_BUSY:
325- break ;
326- case VJD_STAT_MISS:
327- break ;
328- default :
329- break ;
330- }
331- }
332- #endif
333-
334372 if (__winnt__sharedMemoryOpen ())
335373 {
336374 return ;
@@ -458,6 +496,28 @@ namespace iosync
458496 simulateState (state, localGamepadNumber);
459497
460498 #ifdef PLATFORM_WINDOWS
499+ #ifdef GAMEPAD_VJOY_ENABLED
500+ // Check the current state of vJoy:
501+ if (vJoyInfo.state == vJoy::vJoyDriver::VJOY_ENABLED)
502+ {
503+ // Calculate the internal status.
504+ switch (vJoy_status)
505+ {
506+ case VJD_STAT_OWN:
507+ case VJD_STAT_FREE:
508+ __winnt__vJoy__simulateState (state, __winnt__vJoy__vDevice (localGamepadNumber), vJoy_status);
509+
510+ break ;
511+ case VJD_STAT_BUSY:
512+ break ;
513+ case VJD_STAT_MISS:
514+ break ;
515+ default :
516+ break ;
517+ }
518+ }
519+ #endif
520+
461521 __winnt__lastPacketNumber = state.native .dwPacketNumber ;
462522 #endif
463523
0 commit comments