#include "stdafx.h" #include "Input.h" #include #include #include "XGamepad.h" namespace{ const DWORD g_dwNumToPort[] = {XDEVICE_PORT0, XDEVICE_PORT1, XDEVICE_PORT2, XDEVICE_PORT3}; } #define NumToPort(X) g_dwNumToPort[X] CXGamepad::CXGamepad() { memset(m_hGamepads, NULL, sizeof(HANDLE) * MAX_XBOX_CONTROLLERS); memset(m_xbStatus, NULL, sizeof(XINPUT_STATE) * MAX_XBOX_CONTROLLERS); memset(m_xbLastStatus, NULL, sizeof(XINPUT_STATE) * MAX_XBOX_CONTROLLERS); //memset(m_bKeys, false, sizeof(bool) * 256); //m_hDebugKeyboard = NULL; m_bExponentialStick = true; m_fLX = m_fLY = m_fRX = m_fRY = 0.0f; } CXGamepad::~CXGamepad() { ShutDown(); } bool CXGamepad::Init(ILog *pLog) { XDEVICE_PREALLOC_TYPE sDeviceTypes[] = { { XDEVICE_TYPE_GAMEPAD, MAX_XBOX_CONTROLLERS }, #ifdef DEBUG_KEYBOARD { XDEVICE_TYPE_DEBUG_KEYBOARD, 1 }, #endif //DEBUG_KEYBOARD }; // Initialize all four gamepads and the debug keyboard XInitDevices(sizeof(sDeviceTypes) / sizeof(XDEVICE_PREALLOC_TYPE), sDeviceTypes); return true; } void CXGamepad::ShutDown() { unsigned int i; // Close all opened gamepad handles for (i=0; i 1.0f) fAccumValueX = 1.0; if (fAccumValueY < -1.0f) fAccumValueY = -1.0; if (fAccumValueY > 1.0f) fAccumValueY = 1.0; // Return clamped value fX = fAccumValueX; fY = fAccumValueY; return; } // Should we check the primary controller ? if (eWhichController == ePrimary) { // Read out the controller ReadAnalogStickValue(GetPrimaryController(), eWhichStick, m_bExponentialStick, fX, fY); return; } // Check the specified controller if (IsControllerReady(eWhichController)) { if (eWhichStick == eLeft) { // Left stick fX = Ignore(m_xbStatus[eWhichController].Gamepad.sThumbLX) / 32768.0f; fY = Ignore(m_xbStatus[eWhichController].Gamepad.sThumbLY) / 32768.0f; } else if (eWhichStick == eRight) { // Right stick fX = Ignore(m_xbStatus[eWhichController].Gamepad.sThumbRX) / 32768.0f; fY = Ignore(m_xbStatus[eWhichController].Gamepad.sThumbRY) / 32768.0f; } return; } else { // Specified controller not ready fX = 0.0f; fY = 0.0f; } } void CXGamepad::ReadAnalogStickValue(const unsigned __int8 iControllerID, const eSide eWhichSide, const bool bExponential, float& fX, float& fY) const { ////////////////////////////////////////////////////////////////////// // Read the axis values of one of the analog sticks. Perform linear // or exponential attenuation, take deadzone into account ////////////////////////////////////////////////////////////////////// float fValX, fValY; // Abort when controller is not inserted / opened if (iControllerID + 1 >= MAX_XBOX_CONTROLLERS || IsControllerReady(iControllerID) == false) { fX = 0.0f; fY = 0.0f; return; } if (bExponential) { // Exponential change of intensity if (eWhichSide == eRight) { // Read values from the right stick and scale to 0 - 50 fValX = Ignore(m_xbStatus[iControllerID].Gamepad.sThumbRX) / 32768.0f * 50.0f; fValY = Ignore(m_xbStatus[iControllerID].Gamepad.sThumbRY) / 32768.0f * 50.0f; } else { // Read values from the left stick and scale to 0 - 50 fValX = Ignore(m_xbStatus[iControllerID].Gamepad.sThumbLX) / 32768.0f * 50.0f; fValY = Ignore(m_xbStatus[iControllerID].Gamepad.sThumbLY) / 32768.0f * 50.0f; } // Attenuate fX = fValX * fValX / 2500.0f; fY = fValY * fValY / 2500.0f; // Restore sign if (fValX < 0.0f) fX = -fX; if (fValY < 0.0f) fY = -fY; } else { // Linear change of intensity if (eWhichSide == eRight) { // Read from the right side fX = Ignore(m_xbStatus[iControllerID].Gamepad.sThumbRX) / 32768.0f; fY = Ignore(m_xbStatus[iControllerID].Gamepad.sThumbRY) / 32768.0f; } else { // Read from the left side fX = Ignore(m_xbStatus[iControllerID].Gamepad.sThumbLX) / 32768.0f; fY = Ignore(m_xbStatus[iControllerID].Gamepad.sThumbLY) / 32768.0f; } } } namespace{ eDigitalButton but_dig[] = { eDigitalUp, eDigitalDown, eDigitalLeft, eDigitalRight, eStart, eBack, eLeftStick, eRightStick }; eAnalogButton but_an[] = {eA,eB,eX,eY, eBlack, eWhite, eLeftTrigger, eRightTrigger }; } bool CXGamepad::KeyDown(int p_key) { if(p_key == XKEY_MAXIS_X || p_key == XKEY_MAXIS_Y) return true; if(XKEY_GP_A <= p_key && p_key <= XKEY_GP_RIGHT_TRIGGER) { int b = ( p_key>> 24) - (XKEY_GP_A >> 24); return (GetAnalogButtonValue(but_an[b], eAll) > 0.4f); } if(XKEY_GP_DPAD_UP <= p_key && p_key <= XKEY_GP_RIGHT_THUMB) { int b = ( p_key>> 24) - (XKEY_GP_DPAD_UP >> 24); return IsDigitalButtonPressed(but_dig[b], false, eAll); } if(XKEY_GP_STHUMBLUP <= p_key && p_key <= XKEY_GP_STHUMBLRIGHT) { if (m_xbLastStatus[0].dwPacketNumber != m_xbStatus[0].dwPacketNumber) GetAnalogStickValue(m_fRX, m_fRY, eLeft, eAll); switch(p_key) { case XKEY_GP_STHUMBLUP: return (m_fRY > 0.4f); case XKEY_GP_STHUMBLDOWN: return (m_fRY < -0.4f); case XKEY_GP_STHUMBLLEFT: return (m_fRX < -0.4f); case XKEY_GP_STHUMBLRIGHT: return (m_fRX > 0.4f); } } return false; } bool CXGamepad::KeyPressed(int p_key) { if(XKEY_GP_A <= p_key && p_key <= XKEY_GP_RIGHT_TRIGGER) { int b = ( p_key>> 24) - (XKEY_GP_A >> 24); return (GetAnalogButtonValue(but_an[b], eAll) > 0.4f); } if(XKEY_GP_DPAD_UP <= p_key && p_key <= XKEY_GP_RIGHT_THUMB) { int b = ( p_key>> 24) - (XKEY_GP_DPAD_UP >> 24); return IsDigitalButtonPressed(but_dig[b], true, eAll); } return false; } bool CXGamepad::KeyReleased(int p_key) { return false; } float CXGamepad::GetDeltaX() { if (m_xbLastStatus[0].dwPacketNumber != m_xbStatus[0].dwPacketNumber) GetAnalogStickValue(m_fLX, m_fLY, eRight, eAll); return m_fLX * 5; } float CXGamepad::GetDeltaY() { if (m_xbLastStatus[0].dwPacketNumber != m_xbStatus[0].dwPacketNumber) GetAnalogStickValue(m_fLX, m_fLY, eRight, eAll); return m_fLY * 5; }