public void destroy() { // Destroy EVERYTHING. device.ConnectionStatusChanged -= Device_ConnectionStatusChanged; try { controller.Disconnect(); } catch (Exception) { } device.Dispose(); isDisconnected = true; }
public override void Close() { if (Connected) { Connected = false; controller.FeedbackReceived -= FeedbackReceived; controller.Disconnect(); } }
public void destroy() { // Destroy EVERYTHING. shouldStop = true; try { controller.Disconnect(); } catch (Exception) { } runTimer.Stop(); runTimer.Dispose(); t.Abort(); device.Close(); }
public override void Close() { if (Connected) { Connected = false; controller.FeedbackReceived -= FeedbackReceived; controller.Disconnect(); InvokeClosedEvent(new DeviceDisconnectedEventArgs()); } }
public override void Disconnect() { if (forceFeedbackCall != null) { cont.FeedbackReceived -= forceFeedbackCall; forceFeedbackCall = null; } connected = false; cont.Disconnect(); cont = null; }
public override void Disconnect() { foreach (KeyValuePair <int, Xbox360FeedbackReceivedEventHandler> pair in forceFeedbacksDict) { cont.FeedbackReceived -= pair.Value; } forceFeedbacksDict.Clear(); connected = false; cont.Disconnect(); cont = null; }
private void Dispose(bool disposing) { if (!disposing) { return; } try { _controller.Disconnect(); _client.Dispose(); } catch (Exception) { // ignored } }
public void DeviceRemoved(IDualShockDevice device) { Log.Information("ViGEmNavMergeX360: Device with index {Index} detached", device.DeviceIndex); // Only remove the virtual 360 controller if we only had one controller left connected if (_deviceCount == 1) { _target.Disconnect(); _target = null; } _deviceCount--; if (device.DeviceIndex == 0) { _Nav0Report = null; } if (device.DeviceIndex == 1) { _Nav1Report = null; } }
private void input_thread() { target360.Connect(); bool ss_button_pressed = false; bool ss_button_held = false; _stream.ReadTimeout = Timeout.Infinite; byte[] data = new byte[_device.GetMaxInputReportLength()]; while (running) { int read = 0; try { read = _stream.Read(data); } catch (TimeoutException e) { read = 0; } catch { unplug(joinInputThread: false); } if (read > 0) { if (data[0] == 0x03 && read == 10) { target360.ResetReport(); if ((data[3] & 64) != 0) { target360.SetButtonState(Xbox360Button.A, true); } if ((data[3] & 32) != 0) { target360.SetButtonState(Xbox360Button.B, true); } if ((data[3] & 16) != 0) { target360.SetButtonState(Xbox360Button.X, true); } if ((data[3] & 8) != 0) { target360.SetButtonState(Xbox360Button.Y, true); } if ((data[3] & 4) != 0) { target360.SetButtonState(Xbox360Button.LeftShoulder, true); } if ((data[3] & 2) != 0) { target360.SetButtonState(Xbox360Button.RightShoulder, true); } if ((data[3] & 1) != 0) { target360.SetButtonState(Xbox360Button.LeftThumb, true); } if ((data[2] & 128) != 0) { target360.SetButtonState(Xbox360Button.RightThumb, true); } ss_button_pressed = (data[2] & 1) != 0; //assistant_button_pressed = ( currentState[2] & 2 ) != 0; // [2] & 2 == Assistant, [2] & 1 == Screenshot switch (data[1]) { default: break; case 0: target360.SetButtonState(Xbox360Button.Up, true); break; case 1: target360.SetButtonState(Xbox360Button.Up, true); target360.SetButtonState(Xbox360Button.Right, true); break; case 2: target360.SetButtonState(Xbox360Button.Right, true); break; case 3: target360.SetButtonState(Xbox360Button.Down, true); target360.SetButtonState(Xbox360Button.Right, true); break; case 4: target360.SetButtonState(Xbox360Button.Down, true); break; case 5: target360.SetButtonState(Xbox360Button.Down, true); target360.SetButtonState(Xbox360Button.Left, true); break; case 6: target360.SetButtonState(Xbox360Button.Left, true); break; case 7: target360.SetButtonState(Xbox360Button.Up, true); target360.SetButtonState(Xbox360Button.Left, true); break; } if ((data[2] & 32) != 0) { target360.SetButtonState(Xbox360Button.Start, true); } if ((data[2] & 64) != 0) { target360.SetButtonState(Xbox360Button.Back, true); } if ((data[2] & 16) != 0) { target360.SetButtonState(Xbox360Button.Guide, true); } // Note: The HID reports do not allow stick values of 00. // This seems to make sense: 0x80 is center, so usable values are: // 0x01 to 0x7F and 0x81 to 0xFF. // For our purposes I believe this is undesirable. Subtract 1 from negative // values to allow maxing out the stick values. // TODO: Get an Xbox controller and verify this is standard behavior. for (int i = 4; i <= 7; ++i) { if (data[i] <= 0x7F && data[i] > 0x00) { data[i] -= 0x01; } } ushort LeftStickXunsigned = (ushort)(data[4] << 8 | (data[4] << 1 & 255)); if (LeftStickXunsigned == 0xFFFE) { LeftStickXunsigned = 0xFFFF; } short LeftStickX = (short)(LeftStickXunsigned - 0x8000); ushort LeftStickYunsigned = (ushort)(data[5] << 8 | (data[5] << 1 & 255)); if (LeftStickYunsigned == 0xFFFE) { LeftStickYunsigned = 0xFFFF; } short LeftStickY = (short)(-LeftStickYunsigned + 0x7FFF); if (LeftStickY == -1) { LeftStickY = 0; } ushort RightStickXunsigned = (ushort)(data[6] << 8 | (data[6] << 1 & 255)); if (RightStickXunsigned == 0xFFFE) { RightStickXunsigned = 0xFFFF; } short RightStickX = (short)(RightStickXunsigned - 0x8000); ushort RightStickYunsigned = (ushort)(data[7] << 8 | (data[7] << 1 & 255)); if (RightStickYunsigned == 0xFFFE) { RightStickYunsigned = 0xFFFF; } short RightStickY = (short)(-RightStickYunsigned + 0x7FFF); if (RightStickY == -1) { RightStickY = 0; } target360.SetAxisValue(Xbox360Axis.LeftThumbX, LeftStickX); target360.SetAxisValue(Xbox360Axis.LeftThumbY, LeftStickY); target360.SetAxisValue(Xbox360Axis.RightThumbX, RightStickX); target360.SetAxisValue(Xbox360Axis.RightThumbY, RightStickY); target360.SetSliderValue(Xbox360Slider.LeftTrigger, data[8]); target360.SetSliderValue(Xbox360Slider.RightTrigger, data[9]); target360.SubmitReport(); } } if (ss_button_pressed && !ss_button_held) { ss_button_held = true; try { // TODO: Allow configuring this keybind. ssThread = new Thread(() => System.Windows.Forms.SendKeys.SendWait("^+Z")); ssThread.Start(); } catch { } } else if (ss_button_held && !ss_button_pressed) { ss_button_held = false; } } target360.Disconnect(); }
public void Disconnect() { xbox_controller.Disconnect(); }
static void Main(string[] args) { ViGEmClient client = new ViGEmClient(); IXbox360Controller controller = client.CreateXbox360Controller(); controller.AutoSubmitReport = false; controller.Connect(); using (Host server = new Host()) { server.InitializeServer(6789, 2); Event netEvent; while (true) { bool polled = false; while (!polled) { if (server.CheckEvents(out netEvent) == false) { if (server.Service(15, out netEvent) == false) { break; } polled = true; } switch (netEvent.Type) { case EventType.None: break; case EventType.Connect: Console.WriteLine("Client connected - ID: " + netEvent.ChannelID + ", IP: " + netEvent.Peer.Host); break; case EventType.Disconnect: Console.WriteLine("Client disconnected - ID: " + netEvent.ChannelID + ", IP: " + netEvent.Peer.Host); break; case EventType.Receive: Console.WriteLine("Packet received from - ID: " + netEvent.ChannelID + ", IP: " + netEvent.Peer.Host + ", Channel ID: " + netEvent.ChannelID + ", Data length: " + netEvent.Packet.Length); int t; Console.WriteLine(System.Text.Encoding.Default.GetString(netEvent.Packet.GetBytes())); if (Int32.TryParse(System.Text.Encoding.Default.GetString(netEvent.Packet.GetBytes()), out t)) { bool press = t < 20; if (!keyboard_mode) { if (t % 20 < 14) { controller.SetButtonState(t % 20, press); } else if (t % 20 == 14) { controller.SetSliderValue(Xbox360Slider.LeftTrigger, press ? (byte)0xFF : (byte)0x00); } else if (t % 20 == 15) { controller.SetSliderValue(Xbox360Slider.RightTrigger, press ? (byte)0xFF : (byte)0x00); } controller.SubmitReport(); } else { switch (t % 20) { case 0: if (press) { WindowsInput.Simulate.Events().Hold(WindowsInput.Events.KeyCode.D4).Invoke(); } else { WindowsInput.Simulate.Events().Release(WindowsInput.Events.KeyCode.D4).Invoke(); } break; case 1: if (press) { WindowsInput.Simulate.Events().Hold(WindowsInput.Events.KeyCode.D5).Invoke(); } else { WindowsInput.Simulate.Events().Release(WindowsInput.Events.KeyCode.D5).Invoke(); } break; case 2: if (press) { WindowsInput.Simulate.Events().Hold(WindowsInput.Events.KeyCode.D6).Invoke(); } else { WindowsInput.Simulate.Events().Release(WindowsInput.Events.KeyCode.D6).Invoke(); } break; case 3: if (press) { WindowsInput.Simulate.Events().Hold(WindowsInput.Events.KeyCode.D7).Invoke(); } else { WindowsInput.Simulate.Events().Release(WindowsInput.Events.KeyCode.D7).Invoke(); } break; case 4: if (press) { WindowsInput.Simulate.Events().Hold(WindowsInput.Events.KeyCode.R).Invoke(); } else { WindowsInput.Simulate.Events().Release(WindowsInput.Events.KeyCode.R).Invoke(); } break; case 5: if (press) { WindowsInput.Simulate.Events().Hold(WindowsInput.Events.KeyCode.T).Invoke(); } else { WindowsInput.Simulate.Events().Release(WindowsInput.Events.KeyCode.T).Invoke(); } break; case 6: if (press) { WindowsInput.Simulate.Events().Hold(WindowsInput.Events.KeyCode.Y).Invoke(); } else { WindowsInput.Simulate.Events().Release(WindowsInput.Events.KeyCode.Y).Invoke(); } break; case 7: if (press) { WindowsInput.Simulate.Events().Hold(WindowsInput.Events.KeyCode.U).Invoke(); } else { WindowsInput.Simulate.Events().Release(WindowsInput.Events.KeyCode.U).Invoke(); } break; case 8: if (press) { WindowsInput.Simulate.Events().Hold(WindowsInput.Events.KeyCode.F).Invoke(); } else { WindowsInput.Simulate.Events().Release(WindowsInput.Events.KeyCode.F).Invoke(); } break; case 9: if (press) { WindowsInput.Simulate.Events().Hold(WindowsInput.Events.KeyCode.G).Invoke(); } else { WindowsInput.Simulate.Events().Release(WindowsInput.Events.KeyCode.G).Invoke(); } break; case 10: if (press) { WindowsInput.Simulate.Events().Hold(WindowsInput.Events.KeyCode.H).Invoke(); } else { WindowsInput.Simulate.Events().Release(WindowsInput.Events.KeyCode.H).Invoke(); } break; case 11: if (press) { WindowsInput.Simulate.Events().Hold(WindowsInput.Events.KeyCode.J).Invoke(); } else { WindowsInput.Simulate.Events().Release(WindowsInput.Events.KeyCode.J).Invoke(); } break; case 12: if (press) { WindowsInput.Simulate.Events().Hold(WindowsInput.Events.KeyCode.V).Invoke(); } else { WindowsInput.Simulate.Events().Release(WindowsInput.Events.KeyCode.V).Invoke(); } break; case 13: if (press) { WindowsInput.Simulate.Events().Hold(WindowsInput.Events.KeyCode.B).Invoke(); } else { WindowsInput.Simulate.Events().Release(WindowsInput.Events.KeyCode.B).Invoke(); } break; case 14: if (press) { WindowsInput.Simulate.Events().Hold(WindowsInput.Events.KeyCode.N).Invoke(); } else { WindowsInput.Simulate.Events().Release(WindowsInput.Events.KeyCode.N).Invoke(); } break; case 15: if (press) { WindowsInput.Simulate.Events().Hold(WindowsInput.Events.KeyCode.M).Invoke(); } else { WindowsInput.Simulate.Events().Release(WindowsInput.Events.KeyCode.M).Invoke(); } break; } } } netEvent.Packet.Dispose(); break; } } } server.Flush(); } controller.Disconnect(); }
private void DeviceWorker() { _Logger.Information("Starting worker thread for {Device}", _Device); DisableReEnableDevice(); // Open HID device to read input from the gamepad _Logger.Information("Opening HID device {Device}", _Device); _Device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.Exclusive); ExclusiveMode = true; // If exclusive mode is not available, retry in shared mode. if (!_Device.IsOpen) { _Logger.Warning("Cannot access HID device in exclusive mode, retrying in shared mode: {Device}", _Device); _Device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.ShareRead | ShareMode.ShareWrite); ExclusiveMode = false; } if (_Device.IsOpen) { // Init Xiaomi Gamepad vibration _Device.WriteFeatureData(new byte[] { 0x20, 0x00, 0x00 }); // Connect the virtual Xbox360 gamepad try { _Logger.Information("Connecting to ViGEm client"); _Target.Connect(); } catch (VigemAlreadyConnectedException e) { _Logger.Warning(e, "ViGEm client was already opened, closing and reopening it"); _Target.Disconnect(); _Target.Connect(); } Started?.Invoke(this, EventArgs.Empty); HidReport hidReport; while (!_CTS.Token.IsCancellationRequested) { // Is device has been closed, exit the loop if (!_Device.IsOpen) { break; } // Otherwise read a report hidReport = _Device.ReadReport(1000); if (hidReport.ReadStatus == HidDeviceData.ReadStatus.WaitTimedOut) { continue; } else if (hidReport.ReadStatus != HidDeviceData.ReadStatus.Success) { _Logger.Error("Cannot read HID report for device {Device}, got {Report}", _Device, hidReport.ReadStatus); break; } var data = hidReport.Data; /* * [0] Buttons state, 1 bit per button * [1] Buttons state, 1 bit per button * [2] 0x00 * [3] D-Pad * [4] Left thumb, X axis * [5] Left thumb, Y axis * [6] Right thumb, X axis * [7] Right thumb, Y axis * [8] 0x00 * [9] 0x00 * [10] L trigger * [11] R trigger * [12] Accelerometer axis 1 * [13] Accelerometer axis 1 * [14] Accelerometer axis 2 * [15] Accelerometer axis 2 * [16] Accelerometer axis 3 * [17] Accelerometer axis 3 * [18] Battery level * [19] MI button */ lock (_Target) { _Target.SetButtonState(Xbox360Button.A, GetBit(data[0], 0)); _Target.SetButtonState(Xbox360Button.B, GetBit(data[0], 1)); _Target.SetButtonState(Xbox360Button.X, GetBit(data[0], 3)); _Target.SetButtonState(Xbox360Button.Y, GetBit(data[0], 4)); _Target.SetButtonState(Xbox360Button.LeftShoulder, GetBit(data[0], 6)); _Target.SetButtonState(Xbox360Button.RightShoulder, GetBit(data[0], 7)); _Target.SetButtonState(Xbox360Button.Back, GetBit(data[1], 2)); _Target.SetButtonState(Xbox360Button.Start, GetBit(data[1], 3)); _Target.SetButtonState(Xbox360Button.LeftThumb, GetBit(data[1], 5)); _Target.SetButtonState(Xbox360Button.RightThumb, GetBit(data[1], 6)); // Reset Hat switch status, as is set to 15 (all directions set, impossible state) _Target.SetButtonState(Xbox360Button.Up, false); _Target.SetButtonState(Xbox360Button.Left, false); _Target.SetButtonState(Xbox360Button.Down, false); _Target.SetButtonState(Xbox360Button.Right, false); if (data[3] < 8) { var btns = HatSwitches[data[3]]; // Hat Switch is a number from 0 to 7, where 0 is Up, 1 is Up-Left, etc. foreach (var b in btns) { _Target.SetButtonState(b, true); } } // Analog axis _Target.SetAxisValue(Xbox360Axis.LeftThumbX, MapAnalog(data[4])); _Target.SetAxisValue(Xbox360Axis.LeftThumbY, MapAnalog(data[5], true)); _Target.SetAxisValue(Xbox360Axis.RightThumbX, MapAnalog(data[6])); _Target.SetAxisValue(Xbox360Axis.RightThumbY, MapAnalog(data[7], true)); // Triggers _Target.SetSliderValue(Xbox360Slider.LeftTrigger, data[10]); _Target.SetSliderValue(Xbox360Slider.RightTrigger, data[11]); // Logo ("home") button if (GetBit(data[19], 0)) { _Target.SetButtonState(Xbox360Button.Guide, true); Task.Delay(200).ContinueWith(DelayedReleaseGuideButton); } // Update battery level BatteryLevel = data[18]; _Target.SubmitReport(); } } // Disconnect the virtual Xbox360 gamepad // Let Dispose handle that, otherwise it will rise a NotPluggedIn exception _Logger.Information("Disconnecting ViGEm client"); _Target.Disconnect(); // Close the HID device _Logger.Information("Closing HID device {Device}", _Device); _Device.CloseDevice(); DisableReEnableDevice(); } else { _Logger.Error("Cannot open HID device {Device}", _Device); Ended?.Invoke(this, EventArgs.Empty); return; } _Logger.Information("Exiting worker thread for {0}", _Device.ToString()); Ended?.Invoke(this, EventArgs.Empty); }
public override void Close() { controller.Disconnect(); }