/// <summary> /// verify if a gamepad is connected, if it is then check which buttons are pressed and the directions of the thumb sticks, /// if no gamepad is connected change the timer to 1 every 5 seconds /// </summary> /// <param name="sender"></param> /// <param name="eventArgs"></param> static void CheckGamepad(object?sender, EventArgs eventArgs) { try { //Console.WriteLine("checked for gamepad input"); switch (XInputGetState(0, out CurrentState)) { case ERROR_SUCCESS: { // if a controller was just connected go back to checking for input ~60 times per second if (frameTimer.Interval == 5000) { frameTimer.Interval = 15; } if (CurrentState.dwPacketNumber != LastState.dwPacketNumber) { var listOfButtonPresses = new List <string>(); //apply the bitmask for each button and take it as a press only if the result is not equal to 0 and if the previous state was equal to 0 if ((CurrentState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP) != 0 && (LastState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP) == 0) { listOfButtonPresses.Add("D_pad_up"); } if ((CurrentState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN) != 0 && (LastState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN) == 0) { listOfButtonPresses.Add("D_pad_down"); } if ((CurrentState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) != 0 && (LastState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) == 0) { listOfButtonPresses.Add("D_pad_right"); } if ((CurrentState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) != 0 && (LastState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) == 0) { listOfButtonPresses.Add("D_pad_left"); } if ((CurrentState.Gamepad.wButtons & XINPUT_GAMEPAD_START) != 0 && (LastState.Gamepad.wButtons & XINPUT_GAMEPAD_START) == 0) { listOfButtonPresses.Add("start"); } if ((CurrentState.Gamepad.wButtons & XINPUT_GAMEPAD_BACK) != 0 && (LastState.Gamepad.wButtons & XINPUT_GAMEPAD_BACK) == 0) { listOfButtonPresses.Add("back"); } if ((CurrentState.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) != 0 && (LastState.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) == 0) { listOfButtonPresses.Add("left_shoulder"); } if ((CurrentState.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER) != 0 && (LastState.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER) == 0) { listOfButtonPresses.Add("right_shoulder"); } if ((CurrentState.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB) != 0 && (LastState.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB) == 0) { listOfButtonPresses.Add("left_thumb"); } if ((CurrentState.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) != 0 && (LastState.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) == 0) { listOfButtonPresses.Add("right_thumb"); } if ((CurrentState.Gamepad.wButtons & XINPUT_GAMEPAD_A) != 0 && (LastState.Gamepad.wButtons & XINPUT_GAMEPAD_A) == 0) { listOfButtonPresses.Add("a"); } if ((CurrentState.Gamepad.wButtons & XINPUT_GAMEPAD_B) != 0 && (LastState.Gamepad.wButtons & XINPUT_GAMEPAD_B) == 0) { listOfButtonPresses.Add("b"); } if ((CurrentState.Gamepad.wButtons & XINPUT_GAMEPAD_X) != 0 && (LastState.Gamepad.wButtons & XINPUT_GAMEPAD_X) == 0) { listOfButtonPresses.Add("x"); } if ((CurrentState.Gamepad.wButtons & XINPUT_GAMEPAD_Y) != 0 && (LastState.Gamepad.wButtons & XINPUT_GAMEPAD_Y) == 0) { listOfButtonPresses.Add("y"); } if (CurrentState.Gamepad.bLeftTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD && LastState.Gamepad.bLeftTrigger < XINPUT_GAMEPAD_TRIGGER_THRESHOLD) { listOfButtonPresses.Add("left_trigger"); } if (CurrentState.Gamepad.bRightTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD && LastState.Gamepad.bRightTrigger < XINPUT_GAMEPAD_TRIGGER_THRESHOLD) { listOfButtonPresses.Add("right_trigger"); } //take care of the cases where the absolute would underflow if (CurrentState.Gamepad.sThumbLY == short.MinValue) { CurrentState.Gamepad.sThumbLY = short.MinValue + 2; } if (CurrentState.Gamepad.sThumbLX == short.MinValue) { CurrentState.Gamepad.sThumbLX = short.MinValue + 2; } var directionL = MouseHookClass.MovementDirection( new Point(CurrentState.Gamepad.sThumbLX, CurrentState.Gamepad.sThumbLY), new Point(0, 0)); // update the direction of the left thumb stick only if it is outside of the dead zone and the previous state was inside the dead zone // or if the direction is different if ((Math.Abs(CurrentState.Gamepad.sThumbLY) > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE || Math.Abs(CurrentState.Gamepad.sThumbLX) > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) && !(Math.Abs(LastState.Gamepad.sThumbLY) > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE || Math.Abs(LastState.Gamepad.sThumbLX) > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) || (directionL != null && directionL != LastDirectionL)) { if (directionL != null) { listOfButtonPresses.Add("left_thumb_move_" + directionL); LastDirectionL = directionL; } } //take care of the cases where the absolute would underflow if (CurrentState.Gamepad.sThumbRY == short.MinValue) { CurrentState.Gamepad.sThumbRY = short.MinValue + 2; } if (CurrentState.Gamepad.sThumbRX == short.MinValue) { CurrentState.Gamepad.sThumbRX = short.MinValue + 2; } var directionR = MouseHookClass.MovementDirection( new Point(CurrentState.Gamepad.sThumbRX, CurrentState.Gamepad.sThumbRY), new Point(0, 0)); // update the direction of the right thumb stick only if it is outside of the dead zone and the previous state was inside the dead zone // or if the direction is different if ((Math.Abs(CurrentState.Gamepad.sThumbRX) > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE || Math.Abs(CurrentState.Gamepad.sThumbRY) > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE) && !(Math.Abs(LastState.Gamepad.sThumbRX) > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE || Math.Abs(LastState.Gamepad.sThumbRY) > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE) || (directionR != null && directionR != LastDirectionR)) { if (directionR != null) { listOfButtonPresses.Add("right_thumb_move_" + directionR); LastDirectionR = directionR; } } if (listOfButtonPresses.Count > 0) { ProfileManager.GamepadInputUpdate(listOfButtonPresses); } LastState = CurrentState; } break; } case ERROR_DEVICE_NOT_CONNECTED: { // if no gamepad is connected then search for input only once every 5 seconds if (frameTimer.Interval != 5000) { frameTimer.Interval = 5000; } break; } } } catch (Exception e) { if (e is ChainingException exception) { exception.AddErrorToChain("While trying to read gamepad input"); } else { exception = new ChainingException(e.Message); exception.AddErrorToChain("While trying to read gamepad input"); } throw exception; } }
/// <summary> /// handle the mouse event /// </summary> /// <param name="nCode"></param> /// <param name="wParam">parameter describing the type of event</param> /// <param name="lParam">pointer to a structure in memory containing the event parameters</param> /// <returns></returns> private static IntPtr HandleMouseEvent(int nCode, IntPtr wParam, IntPtr lParam) { try { //get the parameters to which the pointer point to var mouseStruct = (LowLevelMouseStructure)(Marshal.PtrToStructure(lParam, typeof(LowLevelMouseStructure)) ?? throw new NullReferenceException("Mouse structure was null")); // add to the CurrentProfile mouse dictionary the corresponding key switch ((int)wParam) { case 513: { ProfileManager.MouseInputUpdate("left_button"); break; } case 516: { ProfileManager.MouseInputUpdate("right_button"); break; } case 519: { ProfileManager.MouseInputUpdate("middle_button"); break; } case 523: { var button = 3 + short.Parse(mouseStruct.MouseData.ToString("X")) / 10000; ProfileManager.MouseInputUpdate("Button " + button); break; } case 522: { if (_lastMouseWheelMovement >= 0 && mouseStruct.MouseData < 0 || _lastMouseWheelMovement <= 0 && mouseStruct.MouseData > 0 || mouseStruct.TimeStamp - _lastMouseUpdate > 1500) { _lastMouseWheelMovement = mouseStruct.MouseData; _lastMouseUpdate = (int)mouseStruct.TimeStamp; ProfileManager.MouseInputUpdate(mouseStruct.MouseData > 0 ? "scroll_up" : "scroll_down"); } break; } case 512: { // detect a mouse movement only if the new coordinates are outside of a dead zone and if the time since the last update is big enough or if the direction // is different. // Also remember that the Y on monitor goes different than on a normal 2D space, so the true Y is height of the monitor - the given Y coordinate var direction = MovementDirection(new Point(mouseStruct.Point.X, Screen.PrimaryScreen.Bounds.Height - mouseStruct.Point.Y), _mousePos); var distance = Math.Sqrt(Math.Pow((mouseStruct.Point.X - _mousePos.X), 2) + Math.Pow((Screen.PrimaryScreen.Bounds.Height - mouseStruct.Point.Y - _mousePos.Y), 2)); if (direction != null && (mouseStruct.TimeStamp - _lastMouseUpdate > 750 || !direction.Equals(_lastMouseMovement)) && distance > 30) { _lastMouseWheelMovement = 0; _lastMouseUpdate = (int)mouseStruct.TimeStamp; _mousePos = new Point(mouseStruct.Point.X, Screen.PrimaryScreen.Bounds.Height - mouseStruct.Point.Y); ProfileManager.MouseInputUpdate(direction); _lastMouseMovement = direction; } break; } } return(CallNextHookEx(_mouseHookId, nCode, wParam, lParam)); } catch (Exception e) { if (e is ChainingException exception) { exception.AddErrorToChain("While trying to read mouse input"); } else { exception = new ChainingException(e.Message); exception.AddErrorToChain("While trying to read mouse input"); } throw exception; } }