Init
This commit is contained in:
238
kaplademo/source/kaplaDemo/SampleViewerGamepad.cpp
Normal file
238
kaplademo/source/kaplaDemo/SampleViewerGamepad.cpp
Normal file
@ -0,0 +1,238 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user