Hattiwatti

Untitled

Dec 16th, 2016
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.78 KB | None | 0 0
  1. #include "InputManager.h"
  2. #include "..\Main.h"
  3. #include "..\Utils\Log.h"
  4. #include <xinput.h>
  5.  
  6. #define DINPUT_MAX 65535
  7. #define DINPUT_HALF 32767
  8.  
  9. InputManager* InputManager::m_Instance;
  10.  
  11. BOOL DIEnumDevicesCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
  12. {
  13.     HRESULT hr;
  14.     InputManager* pInput = (InputManager*)pvRef;
  15.  
  16.  
  17.     // Obtain an interface to the enumerated joystick.
  18.     hr = pInput->CreateDevice(lpddi);
  19.  
  20.     // If it failed, then we can't use this joystick. (Maybe the user unplugged
  21.     // it while we were in the middle of enumerating it.)
  22.     if (FAILED(hr)) {
  23.         printf("Failed\n");
  24.         return DIENUM_CONTINUE;
  25.     }
  26.  
  27.     // Stop enumeration. Note: we're just taking the first joystick we get. You
  28.     // could store all the enumerated joysticks and let the user pick.
  29.     return DIENUM_STOP;
  30. }
  31.  
  32. HRESULT InputManager::CreateDevice(LPCDIDEVICEINSTANCE lpddi)
  33. {
  34.     if (!lpdi) return 1;
  35.     return lpdi->CreateDevice(lpddi->guidInstance, &lpdiGamepad, NULL);
  36. }
  37.  
  38. void InputManager::Init()
  39. {
  40.     if (DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8A, (LPVOID*)&lpdi, NULL) != S_OK)
  41.         Log::Error("Unable to create DirectInput interface");
  42.  
  43.     if (FindXInputController() || FindDInputController())
  44.         m_hasController = true;
  45.     else
  46.         m_hasController = false;
  47.  
  48.     fb::System* pSystem = fb::System::GetInstance();
  49.     for (int i = 0; i < pSystem->deviceCount(); i++)
  50.     {
  51.         string name = pSystem->m_devices[i]->deviceName();
  52.         name.erase(name.end());
  53.         if (name == "Mouse")
  54.             m_pMouse = (fb::Mouse*)pSystem->m_devices[i];
  55.         if (name == "Gamepad")
  56.             m_pGamepad = (fb::Gamepad*)pSystem->m_devices[i];
  57.         if (name == "Keyboard")
  58.             m_pKeyboard = (fb::Keyboard*)pSystem->m_devices[i];
  59.     }
  60.  
  61.     m_Instance = this;
  62.  
  63.     CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)HotkeyThread, NULL, NULL, NULL);
  64.     CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ControllerThread, NULL, NULL, NULL);
  65. }
  66.  
  67. bool InputManager::GetGamepadData(GamepadInput& input)
  68. {
  69.     memset(&input, 0, sizeof(GamepadInput));
  70.     if (!m_hasController)
  71.         return false;
  72.  
  73.     if (m_controllerType == ControllerType::DirectInput)
  74.     {
  75.         DIJOYSTATE2 diState;
  76.         ZeroMemory(&diState, sizeof(DIJOYSTATE2));
  77.         HRESULT result = lpdiGamepad->GetDeviceState(sizeof(DIJOYSTATE2), &diState);
  78.         if (result != S_OK)
  79.         {
  80.             lpdiGamepad->Release();
  81.             lpdiGamepad = nullptr;
  82.             Log::Warning("DirectInput controller lost");
  83.             m_hasController = false;
  84.             return false;
  85.         }
  86.  
  87.         ParseDInputData(input, diState);
  88.         return true;
  89.     }
  90.     else
  91.     {
  92.         XINPUT_STATE xiState;
  93.         ZeroMemory(&xiState, sizeof(XINPUT_STATE));
  94.         DWORD dwResult = XInputGetState(m_xinputID, &xiState);
  95.         if (dwResult != ERROR_SUCCESS)
  96.         {
  97.             m_hasController = false;
  98.             Log::Warning("Xbox controller lost");
  99.             return false;
  100.         }
  101.  
  102.         ParseXInputData(input, xiState);
  103.         return true;
  104.     }
  105.  
  106.     return false;
  107. }
  108.  
  109. bool InputManager::FindXInputController()
  110. {
  111.     for (DWORD i = 0; i < XUSER_MAX_COUNT; i++)
  112.     {
  113.         ZeroMemory(&m_xiState, sizeof(XINPUT_STATE));
  114.         DWORD dwResult = XInputGetState(i, &m_xiState);
  115.         if (dwResult == ERROR_SUCCESS)
  116.         {
  117.             m_xinputID = i;
  118.             m_controllerType = ControllerType::XInput;
  119.             Log::Write("Found an Xbox controller");
  120.             m_hasController = true;
  121.             return true;
  122.         }
  123.     }
  124.     return false;
  125. }
  126.  
  127. bool InputManager::FindDInputController()
  128. {
  129.     HRESULT result;
  130.     if (lpdi == NULL)
  131.         return false;
  132.  
  133.     if (lpdi->EnumDevices(DI8DEVCLASS_GAMECTRL, (LPDIENUMDEVICESCALLBACKW)DIEnumDevicesCallback, this, DIEDFL_ATTACHEDONLY) != S_OK)
  134.         return false;
  135.  
  136.     if (lpdiGamepad == NULL)
  137.         return false;
  138.  
  139.     if ((result = lpdiGamepad->SetDataFormat(&c_dfDIJoystick2)) != S_OK)
  140.         return false;
  141.     if ((result = lpdiGamepad->Acquire()) != S_OK)
  142.         return false;
  143.  
  144.     m_controllerType = ControllerType::DirectInput;
  145.     m_hasController = true;
  146.     Log::Write("Found a DirectInput controller");
  147.     return true;
  148. }
  149.  
  150. void InputManager::ParseDInputData(GamepadInput& input, DIJOYSTATE2& state)
  151. {
  152.     // Left Stick
  153.     {
  154.         double lX = (double)state.lX - DINPUT_HALF;
  155.         double lY = (double)state.lY - DINPUT_HALF;
  156.  
  157.         double Magnitude = sqrt(lX*lX + lY*lY);
  158.         double NormalizedMagnitude = 0;
  159.  
  160.         if (Magnitude > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)
  161.         {
  162.             if (Magnitude > 32767) Magnitude = 32767;
  163.             Magnitude -= XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE;
  164.             NormalizedMagnitude = Magnitude / (32767 - XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE);
  165.         }
  166.         else
  167.         {
  168.             Magnitude = 0;
  169.             NormalizedMagnitude = 0;
  170.         }
  171.  
  172.         if (Magnitude > 0.0)
  173.         {
  174.             NormalizedMagnitude *= NormalizedMagnitude;
  175.             double NormalizedLX = lX / Magnitude;
  176.             double NormalizedLY = lY / Magnitude;
  177.             input.LeftStick.x += NormalizedLX * NormalizedMagnitude;
  178.             input.LeftStick.y += NormalizedLY * NormalizedMagnitude;
  179.         }
  180.     }
  181.  
  182.     // Right Stick
  183.     {
  184.         double lX = (double)state.lZ - DINPUT_HALF;
  185.         double lY = (double)state.lRz - DINPUT_HALF;
  186.  
  187.         double Magnitude = sqrt(lX*lX + lY*lY);
  188.         double NormalizedMagnitude = 0;
  189.  
  190.         if (Magnitude > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)
  191.         {
  192.             if (Magnitude > 32767) Magnitude = 32767;
  193.             Magnitude -= XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE;
  194.             NormalizedMagnitude = Magnitude / (32767 - XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE);
  195.         }
  196.         else
  197.         {
  198.             Magnitude = 0;
  199.             NormalizedMagnitude = 0;
  200.         }
  201.  
  202.         if (Magnitude > 0.0)
  203.         {
  204.             NormalizedMagnitude *= NormalizedMagnitude;
  205.             double NormalizedLX = lX / Magnitude;
  206.             double NormalizedLY = lY / Magnitude;
  207.             input.RightStick.x -= NormalizedLX * NormalizedMagnitude;
  208.             input.RightStick.y -= NormalizedLY * NormalizedMagnitude;
  209.         }
  210.     }
  211.  
  212.     // Triggers
  213.     {
  214.         int delta = -(int)(state.lRx) + (int)(state.lRy);
  215.         if (delta < 6553 / 2 && delta >(-6553 / 2)) {
  216.             delta = 0;
  217.         }
  218.         else if (delta < 0) {
  219.             delta += 6553 / 2;
  220.         }
  221.         else {
  222.             delta -= 6553 / 2;
  223.         }
  224.         input.Trigger += ((double)delta) / (65535.0 - 6553 / 2);
  225.     }
  226.  
  227.     input.LeftShoulder = state.rgbButtons[4] == 128;
  228.     input.RightShoulder = state.rgbButtons[5] == 128;
  229.     input.LeftThumbButton = state.rgbButtons[10] == 128;
  230.     input.RightThumbButton = state.rgbButtons[11] == 128;
  231.     input.DPad_Up = state.rgdwPOV[0] == 0;
  232.     input.DPad_Down = state.rgdwPOV[0] == 18000;
  233.     input.DPad_Left = state.rgdwPOV[0] == 27000;
  234.     input.DPad_Right = state.rgdwPOV[0] == 9000;
  235.  
  236.     for (int i = 0; i < 4; ++i)
  237.         input.Buttons[i] = state.rgbButtons[i] == 128;
  238. }
  239.  
  240. void InputManager::ParseXInputData(GamepadInput& input, XINPUT_STATE& state)
  241. {
  242.     {
  243.         double LX = state.Gamepad.sThumbLX;
  244.         double LY = state.Gamepad.sThumbLY;
  245.  
  246.         //determine how far the controller is pushed
  247.         double magnitude = sqrt(LX*LX + LY*LY);
  248.  
  249.         //determine the direction the controller is pushed
  250.         double normalizedLX = LX / magnitude;
  251.         double normalizedLY = LY / magnitude;
  252.  
  253.         double normalizedMagnitude = 0;
  254.  
  255.         //check if the controller is outside a circular dead zone
  256.         if (magnitude > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)
  257.         {
  258.             //clip the magnitude at its expected maximum value
  259.             if (magnitude > 32767) magnitude = 32767;
  260.  
  261.             //adjust magnitude relative to the end of the dead zone
  262.             magnitude -= XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE;
  263.  
  264.             //optionally normalize the magnitude with respect to its expected range
  265.             //giving a magnitude value of 0.0 to 1.0
  266.             normalizedMagnitude = magnitude / (32767 - XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE);
  267.         }
  268.         else //if the controller is in the deadzone zero out the magnitude
  269.         {
  270.             magnitude = 0.0;
  271.             normalizedMagnitude = 0.0;
  272.         }
  273.         if (magnitude > 0.0) {
  274.             normalizedMagnitude *= normalizedMagnitude;
  275.             // Determine the direction the controller is pushed
  276.             double normalizedLX = LX / magnitude;
  277.             double normalizedLY = LY / magnitude;
  278.             input.LeftStick.x += normalizedLX * normalizedMagnitude;
  279.             input.LeftStick.y -= normalizedLY * normalizedMagnitude;
  280.         }
  281.     }
  282.  
  283.     {
  284.         // Right thumb
  285.         double RX = state.Gamepad.sThumbRX;
  286.         double RY = state.Gamepad.sThumbRY;
  287.  
  288.         // Determine how far the controller is pushed
  289.         double magnitude = sqrt(RX*RX + RY*RY);
  290.  
  291.         double normalizedMagnitude = 0;
  292.  
  293.         // Check if the controller is outside a circular dead zone
  294.         if (magnitude > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE)
  295.         {
  296.             // Clip the magnitude at its expected maximum value
  297.             if (magnitude > 32767) magnitude = 32767;
  298.  
  299.             // Adjust magnitude relative to the end of the dead zone
  300.             magnitude -= XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE;
  301.  
  302.             // Optionally normalize the magnitude with respect to its expected range
  303.             // Giving a magnitude value of 0.0 to 1.0
  304.             normalizedMagnitude = magnitude / (32767 - XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE);
  305.         }
  306.         else {
  307.             // If the controller is in the deadzone zero out the magnitude
  308.             magnitude = 0.0;
  309.             normalizedMagnitude = 0.0;
  310.         }
  311.  
  312.         if (magnitude > 0.0) {
  313.             normalizedMagnitude *= normalizedMagnitude;
  314.             // Determine the direction the controller is pushed
  315.             double normalizedRX = RX / magnitude;
  316.             double normalizedRY = RY / magnitude;
  317.             input.RightStick.x -= normalizedRX * normalizedMagnitude;
  318.             input.RightStick.y += normalizedRY * normalizedMagnitude;
  319.         }
  320.     }
  321.  
  322.     {
  323.         // Triggers
  324.         int delta = -(int)(state.Gamepad.bLeftTrigger) + (int)(state.Gamepad.bRightTrigger);
  325.         if (delta < XINPUT_GAMEPAD_TRIGGER_THRESHOLD / 2 && delta >(-XINPUT_GAMEPAD_TRIGGER_THRESHOLD / 2)) {
  326.             delta = 0;
  327.         }
  328.         else if (delta < 0) {
  329.             delta += XINPUT_GAMEPAD_TRIGGER_THRESHOLD / 2;
  330.         }
  331.         else {
  332.             delta -= XINPUT_GAMEPAD_TRIGGER_THRESHOLD / 2;
  333.         }
  334.         input.Trigger += ((double)delta) / (255.0 - XINPUT_GAMEPAD_TRIGGER_THRESHOLD / 2);
  335.     }
  336.  
  337.     input.LeftShoulder = (state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) != 0;
  338.     input.RightShoulder = (state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER) != 0;
  339.     input.LeftThumbButton = (state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB);
  340.     input.RightThumbButton = (state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB);
  341.  
  342.     input.DPad_Left = (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT);
  343.     input.DPad_Right = (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT);
  344.     input.DPad_Up = (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP);
  345.     input.DPad_Down = (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN);
  346.  
  347.     input.Buttons[0] = (state.Gamepad.wButtons & XINPUT_GAMEPAD_X);
  348.     input.Buttons[1] = (state.Gamepad.wButtons & XINPUT_GAMEPAD_A);
  349.     input.Buttons[2] = (state.Gamepad.wButtons & XINPUT_GAMEPAD_B);
  350.     input.Buttons[3] = (state.Gamepad.wButtons & XINPUT_GAMEPAD_Y);
  351. }
  352.  
  353. void InputManager::HotkeyThread()
  354. {
  355.     while (!Main::IsExiting())
  356.     {
  357.         if (!fb::DxRenderer::GetInstance()->m_pScreen->m_TopWindow ||
  358.             Main::GetInputManager()->GetFBMouse()->m_uiOwnsInput)
  359.             continue;
  360.  
  361.         Main::GetCameraManager()->HotkeyUpdate();
  362.         Main::GetEffectManager()->HotkeyUpdate();
  363.         Sleep(1);
  364.     }
  365. }
  366.  
  367. void InputManager::ControllerThread()
  368. {
  369.     while (!Main::IsExiting())
  370.     {
  371.         Sleep(1000);
  372.  
  373.         if (m_Instance->m_hasController)
  374.             continue;
  375.  
  376.         m_Instance->FindDInputController();
  377.         m_Instance->FindXInputController();
  378.     }
  379.    
  380. }
Add Comment
Please, Sign In to add comment