public void reader_DataReceived(object sender, EndpointDataEventArgs e) { if (run) { var data = e.Buffer; var input1 = GCNState.GetState(getFastInput1(ref data)); var input2 = GCNState.GetState(getFastInput2(ref data)); var input3 = GCNState.GetState(getFastInput3(ref data)); var input4 = GCNState.GetState(getFastInput4(ref data)); if (gcn1ok) { JoystickHelper.setJoystick(input1, 1, gcn1DZ); } if (gcn2ok) { JoystickHelper.setJoystick(input2, 2, gcn2DZ); } if (gcn3ok) { JoystickHelper.setJoystick(input3, 3, gcn3DZ); } if (gcn4ok) { JoystickHelper.setJoystick(input4, 4, gcn4DZ); } } else { reader.DataReceivedEnabled = false; if (GCNAdapter != null) { if (GCNAdapter.IsOpen) { if (!ReferenceEquals(wholeGCNAdapter, null)) { wholeGCNAdapter.ReleaseInterface(0); } GCNAdapter.Close(); } GCNAdapter = null; UsbDevice.Exit(); Log(null, new LogEventArgs("Closing driver thread...")); } Log(null, new LogEventArgs("Driver thread has been stopped.")); } }
public void Start() { //WUP-028 //VENDORID 0x57E //PRODUCT ID 0x337 var USBFinder = new UsbDeviceFinder(0x057E, 0x0337); GCNAdapter = UsbDevice.OpenUsbDevice(USBFinder); if (GCNAdapter != null) { int transferLength; reader = GCNAdapter.OpenEndpointReader(ReadEndpointID.Ep01); writer = GCNAdapter.OpenEndpointWriter(WriteEndpointID.Ep02); //prompt controller to start sending writer.Write(Convert.ToByte((char)19), 10, out transferLength); try { if (gcn1Enabled && !JoystickHelper.checkJoystick(1)) { JoystickHelper.CreateJoystick(1); } if (gcn2Enabled && !JoystickHelper.checkJoystick(2)) { JoystickHelper.CreateJoystick(2); } if (gcn3Enabled && !JoystickHelper.checkJoystick(3)) { JoystickHelper.CreateJoystick(3); } if (gcn4Enabled && !JoystickHelper.checkJoystick(4)) { JoystickHelper.CreateJoystick(4); } if (gcn1Enabled && JoystickHelper.Acquire(1)) { gcn1ok = true; } if (gcn2Enabled && JoystickHelper.Acquire(2)) { gcn2ok = true; } if (gcn3Enabled && JoystickHelper.Acquire(3)) { gcn3ok = true; } if (gcn4Enabled && JoystickHelper.Acquire(4)) { gcn4ok = true; } } catch (Exception ex) { if (ex.Message.Contains("HRESULT: 0x8007000B")) { Log(null, new LogEventArgs("Error: vJoy driver mismatch. Did you install the wrong version (x86/x64)?")); Driver.run = false; return; } } if (noEventMode) { // PORT 1: bytes 02-09 // PORT 2: bytes 11-17 // PORT 3: bytes 20-27 // PORT 4: bytes 29-36l byte[] ReadBuffer = new byte[37]; // 32 (4 players x 8) bytes for input, 5 bytes for formatting byte[] WriteBuffer = new byte[5]; // 1 for command, 4 for rumble state WriteBuffer[0] = 0x11; WriteBuffer[1] = 0; Log(null, new LogEventArgs("Driver successfully started, entering input loop.")); run = true; Stopwatch sw = Stopwatch.StartNew(); while (run) { var ec = reader.Read(ReadBuffer, 10, out transferLength); var input1 = GCNState.GetState(getFastInput1(ref ReadBuffer)); var input2 = GCNState.GetState(getFastInput2(ref ReadBuffer)); var input3 = GCNState.GetState(getFastInput3(ref ReadBuffer)); var input4 = GCNState.GetState(getFastInput4(ref ReadBuffer)); if (gcn1ok) { JoystickHelper.setJoystick(input1, 1, gcn1DZ); } if (gcn2ok) { JoystickHelper.setJoystick(input2, 2, gcn2DZ); } if (gcn3ok) { JoystickHelper.setJoystick(input3, 3, gcn3DZ); } if (gcn4ok) { JoystickHelper.setJoystick(input4, 4, gcn4DZ); } long elapsed = sw.ElapsedMilliseconds; sw.Reset(); sw.Start(); if (Interlocked.Read(ref gcn1Ffb) > 0) { if (gcn1FfbInf == false) { Interlocked.Add(ref gcn1Ffb, -elapsed); } WriteBuffer[1] = (byte)(gcn1FfbActive ? 1 : 0); } else { WriteBuffer[1] = 0; } if (Interlocked.Read(ref gcn2Ffb) > 0) { if (gcn2FfbInf == false) { Interlocked.Add(ref gcn2Ffb, -elapsed); } WriteBuffer[2] = (byte)(gcn2FfbActive ? 1 : 0); } else { WriteBuffer[2] = 0; } if (Interlocked.Read(ref gcn3Ffb) > 0) { if (gcn3FfbInf == false) { Interlocked.Add(ref gcn3Ffb, -elapsed); } WriteBuffer[3] = (byte)(gcn3FfbActive ? 1 : 0); } else { WriteBuffer[3] = 0; } if (Interlocked.Read(ref gcn4Ffb) > 0) { if (gcn4FfbInf == false) { Interlocked.Add(ref gcn4Ffb, -elapsed); } WriteBuffer[4] = (byte)(gcn4FfbActive ? 1 : 0); } else { WriteBuffer[4] = 0; } writer.Write(WriteBuffer, 10, out transferLength); System.Threading.Thread.Sleep(5); } WriteBuffer[1] = 0; WriteBuffer[2] = 0; WriteBuffer[3] = 0; WriteBuffer[4] = 0; writer.Write(WriteBuffer, 10, out transferLength); if (GCNAdapter != null) { if (GCNAdapter.IsOpen) { if (!ReferenceEquals(wholeGCNAdapter, null)) { wholeGCNAdapter.ReleaseInterface(0); } GCNAdapter.Close(); } GCNAdapter = null; UsbDevice.Exit(); Log(null, new LogEventArgs("Closing driver thread...")); } Log(null, new LogEventArgs("Driver thread has been stopped.")); } else { Log(null, new LogEventArgs("Driver successfully started, entering input loop.")); //using Interrupt request instead of looping behavior. reader.DataReceivedEnabled = true; reader.DataReceived += reader_DataReceived; reader.ReadBufferSize = 37; reader.ReadThreadPriority = System.Threading.ThreadPriority.Highest; run = true; } } else { Log(null, new LogEventArgs("GCN Adapter not detected.")); Driver.run = false; } }
public static void setJoystick(GCNState input, int joystickID, ControllerDeadZones deadZones) { int multiplier = 302; X360Controller controller = Controllers[joystickID - 1]; //32767 //analog stick controller.LeftStickX = (short)(multiplier * (128 - input.analogX)); controller.LeftStickY = (short)(multiplier * (128 - input.analogY)); //c stick controller.RightStickX = (short)(multiplier * (128 - input.cstickX)); controller.RightStickY = (short)(multiplier * (128 - input.cstickY)); //triggers controller.LeftTrigger = (byte)input.analogL; controller.RightTrigger = (byte)input.analogR; controller.Buttons = 0; //dpad button mode for DDR pad support if (input.up) { controller.Buttons |= X360Buttons.Up; } if (input.down) { controller.Buttons |= X360Buttons.Down; } if (input.left) { controller.Buttons |= X360Buttons.Left; } if (input.right) { controller.Buttons |= X360Buttons.Right; } //buttons if (input.A) { controller.Buttons |= X360Buttons.A; } if (input.B) { controller.Buttons |= X360Buttons.X; } if (input.X) { controller.Buttons |= X360Buttons.B; } if (input.Y) { controller.Buttons |= X360Buttons.Y; } if (input.Z) { controller.Buttons |= X360Buttons.Logo; } if (input.R) { controller.Buttons |= X360Buttons.RightBumper; } if (input.L) { controller.Buttons |= X360Buttons.LeftBumper; } if (input.start) { controller.Buttons |= X360Buttons.Start; } scp.Report(joystickID, controller.GetReport()); }
public static GCNState GetState(byte[] input) { //[0] joystick enabled //[1] upper end D-Pad, lower end a,b,x,y //[2] R button, L Button, z, start //[3] analog X //[4] analog Y //[5] c-stick X //[6] c-stick Y //[7] L axis //[8] R Axis //[1] [0]: A // [1]: B // [2]: X // [3]: Y // [4]: Left // [5]: Right // [6]: Down // [7]: Up //[2] [0]: start // [1]: z // [2]: R button // [3]: L Button // [4]: not used // [5]: not used // [6]: not used // [7]: not used GCNState pad = new GCNState(); if (input.Length == 9) { if ((int)input[0] > 0) { byte b1 = input[1]; pad.A = (b1 & (1 << 0)) != 0; pad.B = (b1 & (1 << 1)) != 0; pad.X = (b1 & (1 << 2)) != 0; pad.Y = (b1 & (1 << 3)) != 0; pad.left = (b1 & (1 << 4)) != 0; pad.right = (b1 & (1 << 5)) != 0; pad.down = (b1 & (1 << 6)) != 0; pad.up = (b1 & (1 << 7)) != 0; //Generate POV state for vJoy. if (pad.right) { pad.POVstate = 1; } else if (pad.down) { pad.POVstate = 2; } else if (pad.left) { pad.POVstate = 3; } else if (pad.up) { pad.POVstate = 0; } else { pad.POVstate = -1; } byte b2 = input[2]; pad.start = (b2 & (1 << 0)) != 0; pad.Z = (b2 & (1 << 1)) != 0; pad.R = (b2 & (1 << 2)) != 0; pad.L = (b2 & (1 << 3)) != 0; pad.analogX = (int)input[3]; pad.analogY = (int)input[4]; pad.cstickX = (int)input[5]; pad.cstickY = (int)input[6]; pad.analogL = (int)input[7]; pad.analogR = (int)input[8]; } return(pad); } else { throw new Exception("Invalid byte array for input"); } }
public static void setJoystick(ref vJoy joystick, GCNState input, uint joystickID, ControllerDeadZones deadZones) { bool res; int multiplier = 127; //32767 //analog stick if (!deadZones.analogStick.inDeadZone(input.analogX, input.analogY)) { res = joystick.SetAxis(multiplier * input.analogX, joystickID, HID_USAGES.HID_USAGE_X); res = joystick.SetAxis(multiplier * (255 - input.analogY), joystickID, HID_USAGES.HID_USAGE_Y); } else { res = joystick.SetAxis(multiplier * 129, joystickID, HID_USAGES.HID_USAGE_X); res = joystick.SetAxis(multiplier * 129, joystickID, HID_USAGES.HID_USAGE_Y); } //c stick if (!deadZones.cStick.inDeadZone(input.cstickX, input.cstickY)) { res = joystick.SetAxis(multiplier * input.cstickX, joystickID, HID_USAGES.HID_USAGE_RX); res = joystick.SetAxis(multiplier * (255 - input.cstickY), joystickID, HID_USAGES.HID_USAGE_RY); } else { res = joystick.SetAxis(multiplier * 129, joystickID, HID_USAGES.HID_USAGE_RX); res = joystick.SetAxis(multiplier * 129, joystickID, HID_USAGES.HID_USAGE_RY); } //triggers if (!deadZones.LTrigger.inDeadZone(input.analogL)) { res = joystick.SetAxis(multiplier * input.analogL, joystickID, HID_USAGES.HID_USAGE_Z); } else { res = joystick.SetAxis(0, joystickID, HID_USAGES.HID_USAGE_Z); } if (!deadZones.RTrigger.inDeadZone(input.analogR)) { res = joystick.SetAxis(multiplier * input.analogR, joystickID, HID_USAGES.HID_USAGE_RZ); } else { res = joystick.SetAxis(0, joystickID, HID_USAGES.HID_USAGE_RZ); } //dpad button mode for DDR pad support res = joystick.SetBtn(input.up, joystickID, 9); res = joystick.SetBtn(input.down, joystickID, 10); res = joystick.SetBtn(input.left, joystickID, 11); res = joystick.SetBtn(input.right, joystickID, 12); //buttons res = joystick.SetBtn(input.A, joystickID, 1); res = joystick.SetBtn(input.B, joystickID, 2); res = joystick.SetBtn(input.X, joystickID, 3); res = joystick.SetBtn(input.Y, joystickID, 4); res = joystick.SetBtn(input.Z, joystickID, 5); res = joystick.SetBtn(input.R, joystickID, 6); res = joystick.SetBtn(input.L, joystickID, 7); res = joystick.SetBtn(input.start, joystickID, 8); }