aboutsummaryrefslogtreecommitdiff
path: root/KaplaDemo/samples/sampleViewer3/SampleViewerGamepad.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'KaplaDemo/samples/sampleViewer3/SampleViewerGamepad.cpp')
-rw-r--r--KaplaDemo/samples/sampleViewer3/SampleViewerGamepad.cpp211
1 files changed, 211 insertions, 0 deletions
diff --git a/KaplaDemo/samples/sampleViewer3/SampleViewerGamepad.cpp b/KaplaDemo/samples/sampleViewer3/SampleViewerGamepad.cpp
new file mode 100644
index 00000000..ef6404c4
--- /dev/null
+++ b/KaplaDemo/samples/sampleViewer3/SampleViewerGamepad.cpp
@@ -0,0 +1,211 @@
+#include "SampleViewerGamepad.h"
+#include "SampleViewerScene.h"
+
+#include <stdio.h>
+#include <direct.h>
+
+#include "PsString.h"
+
+//////////////////////////////////////////////////////////////////////////
+
+static bool gTimeInit = false;
+static const unsigned int MAX_GAMEPADS = 4;
+static const unsigned int MAX_GAMEPAD_AXES = 4;
+static XINPUT_STATE m_lastInputState[MAX_GAMEPADS];
+static int m_lastAxisData[MAX_GAMEPADS][MAX_GAMEPAD_AXES];
+
+//////////////////////////////////////////////////////////////////////////
+
+SampleViewerGamepad::SampleViewerGamepad()
+ : mGamePadConnected(false), mConnectedPad(0), mXInputLibrary(), mpXInputGetState(0), mpXInputGetCapabilities(0)
+{
+}
+
+//////////////////////////////////////////////////////////////////////////
+SampleViewerGamepad::~SampleViewerGamepad()
+{
+ release();
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+void SampleViewerGamepad::init()
+{
+ static const unsigned int xInputLibCount = 4;
+ static const char* xInputLibs[xInputLibCount] = { "xinput1_4.dll",
+ "xinput1_3.dll",
+ "xinput1_2.dll",
+ "xinput1_1.dll" };
+ for (unsigned int i = 0; i < xInputLibCount; ++i)
+ {
+ mXInputLibrary = LoadLibraryA(xInputLibs[i]);
+ if (mXInputLibrary)
+ break;
+ }
+
+ if(!mXInputLibrary)
+ {
+ physx::shdfnd::printString("Could not load XInput library.");
+ }
+
+ if (mXInputLibrary)
+ {
+ mpXInputGetState = (LPXINPUTGETSTATE)GetProcAddress(mXInputLibrary, "XInputGetState");
+ mpXInputGetCapabilities = (LPXINPUTGETCAPABILITIES)GetProcAddress(mXInputLibrary, "XInputGetCapabilities");
+ if(!mpXInputGetState)
+ {
+ physx::shdfnd::printString("Error loading XInputGetState function.");
+ }
+
+ if(!mpXInputGetCapabilities)
+ {
+ physx::shdfnd::printString("Error loading XInputGetCapabilities function.");
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+void SampleViewerGamepad::release()
+{
+ if (mXInputLibrary)
+ {
+ FreeLibrary(mXInputLibrary);
+ mXInputLibrary = 0;
+ }
+
+ mpXInputGetState = 0;
+ mpXInputGetCapabilities = 0;
+ mGamePadConnected = false;
+ mConnectedPad = 0;
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+void SampleViewerGamepad::processGamepads(SampleViewerScene& viewerScene)
+{
+ if (!gTimeInit)
+ {
+ gTimeInit = true;
+
+ for (unsigned int p = 0; p < MAX_GAMEPADS; p++)
+ {
+ memset(&m_lastInputState[p], 0, sizeof(XINPUT_STATE));
+ for (unsigned int i = 0; i < MAX_GAMEPAD_AXES; i++)
+ {
+ m_lastAxisData[p][i] = 0;
+ }
+ }
+ }
+
+ static int32_t disConnected[4] = { 1, 2, 3, 4 };
+
+ if (!hasXInput())
+ return;
+
+ for (uint32_t p = 0; p < MAX_GAMEPADS; p++)
+ {
+ if ((--disConnected[p]) == 0)
+ {
+ XINPUT_STATE inputState;
+ DWORD state = mpXInputGetState(p, &inputState);
+ if (state == ERROR_DEVICE_NOT_CONNECTED)
+ {
+ disConnected[p] = 4;
+ if (mGamePadConnected && (mConnectedPad == p))
+ {
+ mGamePadConnected = false;
+ mConnectedPad = 0;
+ for (uint32_t k = 0; k < MAX_GAMEPADS; k++)
+ {
+ XINPUT_STATE inputStateDisc;
+ DWORD stateDisc = mpXInputGetState(k, &inputStateDisc);
+ if (stateDisc == ERROR_SUCCESS)
+ {
+ mConnectedPad = k;
+ mGamePadConnected = true;
+ break;
+ }
+ }
+ }
+ }
+ else if (state == ERROR_SUCCESS)
+ {
+ if (!mGamePadConnected)
+ {
+ mGamePadConnected = true;
+ mConnectedPad = p;
+ }
+
+ disConnected[p] = 1; //force to test next time
+ XINPUT_CAPABILITIES caps;
+ mpXInputGetCapabilities(p, XINPUT_FLAG_GAMEPAD, &caps);
+
+ //gamepad
+ {
+ // Process buttons
+ const WORD lastWButtons = m_lastInputState[p].Gamepad.wButtons;
+ const WORD currWButtons = inputState.Gamepad.wButtons;
+
+ const WORD buttonsDown = currWButtons & ~lastWButtons;
+ const WORD buttonsUp = ~currWButtons & lastWButtons;
+ // const WORD buttonsHeld = currWButtons & lastWButtons;
+
+ for (int i = 0; i < 14; i++)
+ {
+ // order has to match struct GamepadControls
+ static const WORD buttonMasks[] = {
+ XINPUT_GAMEPAD_DPAD_UP,
+ XINPUT_GAMEPAD_DPAD_DOWN,
+ XINPUT_GAMEPAD_DPAD_LEFT,
+ XINPUT_GAMEPAD_DPAD_RIGHT,
+ XINPUT_GAMEPAD_START,
+ XINPUT_GAMEPAD_BACK,
+ XINPUT_GAMEPAD_LEFT_THUMB,
+ XINPUT_GAMEPAD_RIGHT_THUMB,
+ XINPUT_GAMEPAD_Y,
+ XINPUT_GAMEPAD_A,
+ XINPUT_GAMEPAD_X,
+ XINPUT_GAMEPAD_B,
+ XINPUT_GAMEPAD_LEFT_SHOULDER,
+ XINPUT_GAMEPAD_RIGHT_SHOULDER,
+ };
+
+ if (buttonsDown & buttonMasks[i])
+ viewerScene.handleGamepadButton(i, true);
+ else if (buttonsUp & buttonMasks[i])
+ viewerScene.handleGamepadButton(i, false);
+ }
+
+ {
+ const BYTE newTriggerVal = inputState.Gamepad.bRightTrigger;
+ viewerScene.handleGamepadTrigger(GamepadTrigger::GAMEPAD_RIGHT_SHOULDER_TRIGGER, ((float)newTriggerVal) / 255);
+ }
+ {
+ const BYTE newTriggerVal = inputState.Gamepad.bLeftTrigger;
+ viewerScene.handleGamepadTrigger(GamepadTrigger::GAMEPAD_LEFT_SHOULDER_TRIGGER, ((float)newTriggerVal) / 255);
+ }
+ }
+
+ // Gamepad
+ const int axisData[] = { inputState.Gamepad.sThumbRX, inputState.Gamepad.sThumbRY, inputState.Gamepad.sThumbLX, inputState.Gamepad.sThumbLY };
+ for (uint32_t i = 0; i < MAX_GAMEPAD_AXES; i++)
+ {
+ if (axisData[i] != m_lastAxisData[p][i])
+ {
+ int data = axisData[i];
+ if (abs(data) < XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)
+ {
+ data = 0;
+ }
+ viewerScene.handleGamepadAxis(i, ((float)data) / SHRT_MAX);
+ }
+ m_lastAxisData[p][i] = axisData[i];
+ }
+ m_lastInputState[p] = inputState;
+ }
+ }
+ }
+
+}
+