Exemplo n.º 1
0
 public static void Controler()
 {
     using (var scpBus = new ScpBus())
     {
         scpBus.PlugIn(1);
     }
 }
Exemplo n.º 2
0
        static void Main(string[] args)
        {
            Console.WriteLine("|-------------------------------|");
            Console.WriteLine("| Switch XBOX Controller Server |");
            Console.WriteLine("|-------------------------------|");
            Console.WriteLine();

            System.Timers.Timer timer;

            _handler += new EventHandler(onExitHandler);
            SetConsoleCtrlHandler(_handler, true);

            detectSwitch();

            Console.WriteLine("Running...");

            controller = new X360Controller();
            scpBus     = new ScpBus();
            scpBus.PlugIn(1);

            timer           = new System.Timers.Timer(1);
            timer.Elapsed  += (s, e) => scpBus.Report(1, controller.GetReport());
            timer.AutoReset = true;
            timer.Start();

            networkThread = new Thread(() => networking());
            displayThread = new Thread(() => displayButtons());

            networkThread.Start();
            displayThread.Start();

            Console.ReadLine();
        }
Exemplo n.º 3
0
        private Int32 SearchDevice()
        {
            var    compatibleDevices = HidDevices.Enumerate(0x2717, 0x3144).ToList();
            ScpBus scpBus            = GlobalScpBus;
            Dictionary <string, XiaomiGamepad> alreadyMapped = MappedDevices;

            //Debug.WriteLine(Device.DevicePath);
            foreach (var deviceInstance in compatibleDevices)
            {
                HidDevice device = deviceInstance;
                if (alreadyMapped.ContainsKey(device.DevicePath))
                {
                    continue;
                }

                try
                {
                    device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.Exclusive);
                }
                catch
                {
                    var instanceId = DevicePathToInstanceId(deviceInstance.DevicePath);
                    if (TryReEnableDevice(instanceId))
                    {
                        try
                        {
                            device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.Exclusive);
                        }
                        catch
                        {
                            device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped,
                                              ShareMode.ShareRead | ShareMode.ShareWrite);
                        }
                    }
                    else
                    {
                        device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped,
                                          ShareMode.ShareRead | ShareMode.ShareWrite);
                    }
                }

                byte[] vibration = { 0x20, 0x00, 0x00 };
                if (device.WriteFeatureData(vibration) == false)
                {
                    device.CloseDevice();
                    continue;
                }

                byte[] serialNumber;
                byte[] product;
                device.ReadSerialNumber(out serialNumber);
                device.ReadProduct(out product);

                Int32         index   = MappedDevices.Count + 1;
                XiaomiGamepad gamepad = new XiaomiGamepad(device, scpBus, index, this);
                MappedDevices.Add(device.DevicePath, gamepad);
            }

            return(MappedDevices.Count);
        }
Exemplo n.º 4
0
        public MixerController()
        {
            bus = new ScpBus();
            bus.PlugIn(1);


            sendThread = new Timer(SendData, null, 100, 100);
        }
Exemplo n.º 5
0
        static void Main(string[] args)
        {
            ScpBus scpBus = new ScpBus();

            scpBus.UnplugAll();
            global_scpBus = scpBus;

            handler = new ConsoleEventDelegate(ConsoleEventCallback);
            SetConsoleCtrlHandler(handler, true);

            Thread.Sleep(400);

            Xiaomi_gamepad[] gamepads = new Xiaomi_gamepad[4];
            int index             = 1;
            var compatibleDevices = HidDevices.Enumerate(0x2717, 0x3144).ToList();

            foreach (var deviceInstance in compatibleDevices)
            {
                Console.WriteLine(deviceInstance);
                HidDevice Device = deviceInstance;
                try {
                    Device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.Exclusive);
                } catch (Exception exception)
                {
                    Console.WriteLine("Could not open gamepad in exclusive mode. Please close anything that could be using the controller\nAttempting to open it in shared mode.");
                    Device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.ShareRead | ShareMode.ShareWrite);
                }

                byte[] Vibration = { 0x20, 0x00, 0x00 };
                if (Device.WriteFeatureData(Vibration) == false)
                {
                    Console.WriteLine("Could not write to gamepad (is it closed?), skipping");
                    Device.CloseDevice();
                    continue;
                }

                byte[] serialNumber;
                byte[] product;
                Device.ReadSerialNumber(out serialNumber);
                Device.ReadProduct(out product);


                gamepads[index - 1] = new Xiaomi_gamepad(Device, scpBus, index);
                ++index;

                if (index >= 5)
                {
                    break;
                }
            }

            Console.WriteLine("{0} controllers connected", index - 1);

            while (true)
            {
                Thread.Sleep(1000);
            }
        }
Exemplo n.º 6
0
        private void Connect()
        {
            ScpBus scpBus = new ScpBus();

            scpBus.UnplugAll();
            global_scpBus = scpBus;

            gamepads = new Xiaomi_gamepad[4];
            int index             = 1;
            var compatibleDevices = HidDevices.Enumerate(0x2717, 0x3144).ToList();

            foreach (var deviceInstance in compatibleDevices)
            {
                //Console.WriteLine(deviceInstance);
                textBox.AppendText(deviceInstance + Environment.NewLine);
                HidDevice Device = deviceInstance;
                global_device = deviceInstance;
                try
                {
                    Device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.Exclusive);
                }
                catch (Exception exception)
                {
                    //Console.WriteLine("Could not open gamepad in exclusive mode. Please close anything that could be using the controller\nAttempting to open it in shared mode.");
                    textBox.AppendText("Could not open gamepad in exclusive mode.Please close anything that could be using the controller" + Environment.NewLine + "Attempting to open it in shared mode." + Environment.NewLine);
                    Device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.ShareRead | ShareMode.ShareWrite);
                }

                byte[] Vibration = { 0x20, 0x00, 0x00 };
                if (Device.WriteFeatureData(Vibration) == false)
                {
                    //Console.WriteLine("Could not write to gamepad (is it closed?), skipping");
                    textBox.AppendText("Could not write to gamepad (is it closed?), skipping" + Environment.NewLine);
                    Device.CloseDevice();
                    continue;
                }

                byte[] serialNumber;
                byte[] product;
                Device.ReadSerialNumber(out serialNumber);
                Device.ReadProduct(out product);


                gamepads[index - 1] = new Xiaomi_gamepad(Device, scpBus, index);
                ++index;

                if (index >= 5)
                {
                    break;
                }
            }

            //Console.WriteLine("{0} controllers connected", index - 1);
            textBox.AppendText(index - 1 + " controllers connected" + Environment.NewLine);

            connected_controllers = index - 1;
        }
Exemplo n.º 7
0
        public static void SetGamepad(bool state)
        {
            scp.Unplug(gamepadIndex);
            scp     = new ScpBus();
            gamepad = new X360Controller();

            if (state)
            {
                scp.PlugIn(gamepadIndex);
            }
        }
Exemplo n.º 8
0
        public Xiaomi_gamepad(HidDevice Device, ScpBus scpBus, int index)
        {
            Device.WriteFeatureData(Vibration);

            rThread = new Thread(() => rumble_thread(Device));
            // rThread.Priority = ThreadPriority.BelowNormal;
            rThread.Start();

            iThread          = new Thread(() => input_thread(Device, scpBus, index));
            iThread.Priority = ThreadPriority.Highest;
            iThread.Start();
        }
Exemplo n.º 9
0
        static void Main(string[] args)
        {
            if (!IsSingleInstance())
            {
                Environment.Exit(0);
            }
            NIcon = new NotifyIcon();
            //ScpBus scpBus = null;
            ScpBus scpBus = new ScpBus();

            scpBus.UnplugAll();
            global_scpBus = scpBus;

            handler = new ConsoleEventDelegate(ConsoleEventCallback);
            SetConsoleCtrlHandler(handler, true);

            Thread.Sleep(400);
            var controllersManager = new Thread(() => ManageControllers(scpBus));


            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            try
            {
                try
                {
                    using (var pi = new ProcessIcon())
                    {
                        pi.Display();
                        controllersManager.Start();
                        Application.Run();
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Program Terminated Unexpectedly",
                                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                controllersManager.Abort();
                scpBus.UnplugAll();
                foreach (var device in Gamepads.Select(g => g.Device))
                {
                    device.CloseDevice();
                }
                singleInstanceMutex.ReleaseMutex();
            }
            finally
            {
                Environment.Exit(0);
            }
        }
Exemplo n.º 10
0
        //private byte[] enableAccelerometer = { 0x31, 0x01, 0x08 };

        public StadiaController(HidDevice device, ScpBus scpBus, int index)
        {
            Index  = index;
            ScpBus = scpBus;
            Device = device;
            Device.Write(Vibration);

            rThread = new Thread(() => rumble_thread(Device));
            // rThread.Priority = ThreadPriority.BelowNormal;
            rThread.Start();

            iThread          = new Thread(() => input_thread(Device, scpBus, index));
            iThread.Priority = ThreadPriority.Highest;
            iThread.Start();
        }
Exemplo n.º 11
0
 public FetchInput(ScpBus ctrlBus, int controller, int minHeldFrames, int maxHeldFrames, int maxSleepFrames, int maxHoldFrames, string newInputUrl, string doneInputUrl, string forceFocusProgram)
 {
     scpBus            = ctrlBus;
     scpController     = controller;
     maxSleep          = maxSleepFrames;
     minHeld           = minHeldFrames;
     maxHeld           = maxHeldFrames;
     maxHoldDuration   = maxHoldFrames;
     newInputEndpoint  = newInputUrl;
     doneInputEndpoint = doneInputUrl;
     currentInput      = new TPPInput();
     currentSeries     = new Queue <TPPInput>();
     webClient         = new ImpatientWebClient();
     forceFocus        = forceFocusProgram;
 }
Exemplo n.º 12
0
        private static X360Controller CreateController()
        {
            X360Controller controller = new X360Controller();

            try {
                scpbus = new ScpBus();
            } catch (Exception ex) {
                MessageBox.Show("SCP Bus failed to initialize");
                MessageBox.Show(ex.ToString());
            }

            scpbus.PlugIn(1);

            return(controller);
        }
Exemplo n.º 13
0
        public static void Start()
        {
            if (Started)
            {
                return;
            }

            scp.UnplugAll();

            scp = new ScpBus();
            scp.PlugIn(gamepadIndex);

            Started = true;

            Task.Run(() => Loop());
        }
Exemplo n.º 14
0
        public XiaomiGamepad(HidDevice device, ScpBus scpBus, int index)
        {
            device.WriteFeatureData(Vibration);

            Thread rThread = new Thread(() => rumble_thread(device));

            // rThread.Priority = ThreadPriority.BelowNormal;
            rThread.IsBackground = true;
            rThread.Start();

            Thread iThread = new Thread(() => input_thread(device, scpBus, index));

            iThread.Priority     = ThreadPriority.Highest;
            iThread.IsBackground = true;
            iThread.Start();
        }
Exemplo n.º 15
0
        private static X360Controller CreateController()
        {
            X360Controller controller = new X360Controller();

            try {
                scpbus = new ScpBus();
            } catch (Exception ex) {
                MessageBox.Show("You probably need to run the ScpToolkit Driver Installer." +
                                System.Environment.NewLine + System.Environment.NewLine + ex.ToString(),
                                "SCP Bus failed to initialize");
                Environment.Exit(-1);
            }

            scpbus.PlugIn(1);

            return(controller);
        }
Exemplo n.º 16
0
        static void Main(string[] args)
        {
            ScpBus scpBus = new ScpBus();

            scpBus.UnplugAll();
            global_scpBus = scpBus;

            handler = new ConsoleEventDelegate(ConsoleEventCallback);
            SetConsoleCtrlHandler(handler, true);

            Thread.Sleep(400);

            Xiaomi_gamepad[] gamepads = new Xiaomi_gamepad[4];
            int index             = 1;
            var compatibleDevices = HidDevices.Enumerate(0x2717, 0x3144).ToList();

            foreach (var deviceInstance in compatibleDevices)
            {
                Console.WriteLine(deviceInstance);
                HidDevice Device = deviceInstance;
                Device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.Exclusive);
                byte[] serialNumber;
                byte[] product;
                Device.ReadSerialNumber(out serialNumber);
                Device.ReadProduct(out product);


                gamepads[index - 1] = new Xiaomi_gamepad(Device, scpBus, index);
                ++index;

                if (index >= 5)
                {
                    break;
                }
            }

            Console.WriteLine("{0} controllers connected", index - 1);

            while (true)
            {
                Thread.Sleep(1000);
            }
        }
Exemplo n.º 17
0
        private void MainForm_Load(object sender, EventArgs e)
        {
            WindowState     = FormWindowState.Minimized;
            FormBorderStyle = FormBorderStyle.FixedToolWindow;
            ShowInTaskbar   = false;
//            Hide();

            var scpBus = new ScpBus();

            scpBus.UnplugAll();
            GlobalScpBus = scpBus;

            MappedDevices = new Dictionary <string, XiaomiGamepad>();

            var detectThread = new Thread(DetectDevices);

            detectThread.IsBackground = true;
            detectThread.Start();
        }
Exemplo n.º 18
0
        public void StartHooking()
        {
            KeyboardWatcher.Start();
            MouseWatcher.Start();

            MouseWatcher.OnMouseInput  += MouseWatcher_OnMouseInput;
            KeyboardWatcher.OnKeyInput += KeyboardWatcher_OnKeyInput;
            controller = new X360Controller();

            _outputReport = new byte[8];
            try
            {
                _scpBus = new ScpBus();

                _scpBus.PlugIn((int)1);
            }
            catch (Exception)
            {
                throw;
            }
        }
Exemplo n.º 19
0
        public XboxNavigation()
        {
            try
            {
                scpbus = new ScpBus();
            }
            catch (Exception ex)
            {
                Console.WriteLine("SCP Bus failed to initialize");
                Console.WriteLine(ex.ToString());
            }
            // scpbus.UnplugAll();
            // Thread.Sleep(3000);

            scpbus.PlugIn(CONTROLLER_NUMBER);
            Thread.Sleep(3000);

            Thread t2 = new Thread(() => keepalive());

            t2.Start();
        }
Exemplo n.º 20
0
        public ScpTester()
        {
            InitializeComponent();

            controllerNum.Tag = controllerNum.Value;
            leftTrigger.Tag   = leftTrigger.Value;
            rightTrigger.Tag  = rightTrigger.Value;
            leftStickX.Tag    = leftStickX.Value;
            leftStickY.Tag    = leftStickY.Value;
            rightStickX.Tag   = rightStickX.Value;
            rightStickY.Tag   = rightStickY.Value;

            try
            {
                _scpBus = new ScpBus();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Environment.Exit(1);
            }
        }
Exemplo n.º 21
0
        public MainForm()
        {
            InitializeComponent();
            ScpBus scpBus = new ScpBus();

            scpBus.UnplugAll();
            global_scpBus = scpBus;

            Thread.Sleep(400);

            Xiaomi_gamepad[] gamepads = new Xiaomi_gamepad[4];
            int index             = 1;
            var compatibleDevices = HidDevices.Enumerate(0x2717, 0x3144).ToList();

            foreach (var deviceInstance in compatibleDevices)
            {
                Log(deviceInstance.ToString());
                HidDevice Device = deviceInstance;
                try
                {
                    Device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.Exclusive);
                }
                catch
                {
                    Log("Could not open gamepad in exclusive mode. Try re-enable device.");
                    var instanceId = devicePathToInstanceId(deviceInstance.DevicePath);
                    if (TryReEnableDevice(instanceId))
                    {
                        try
                        {
                            Device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.Exclusive);
                            Log("Opened in exclusive mode.");
                        }
                        catch
                        {
                            Device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.ShareRead | ShareMode.ShareWrite);
                            Log("Opened in shared mode.");
                        }
                    }
                    else
                    {
                        Device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.ShareRead | ShareMode.ShareWrite);
                        Log("Opened in shared mode.");
                    }
                }

                byte[] Vibration = { 0x20, 0x00, 0x00 };
                if (Device.WriteFeatureData(Vibration) == false)
                {
                    Log("Could not write to gamepad (is it closed?), skipping");
                    Device.CloseDevice();
                    continue;
                }

                byte[] serialNumber;
                byte[] product;
                Device.ReadSerialNumber(out serialNumber);
                Device.ReadProduct(out product);


                gamepads[index - 1] = new Xiaomi_gamepad(Device, scpBus, index);
                ++index;

                if (index >= 5)
                {
                    break;
                }
            }
            Log(index - 1 + " controllers connected");
        }
Exemplo n.º 22
0
        private void input_thread(HidDevice Device, ScpBus scpBus, int index)
        {
            scpBus.PlugIn(index);
            X360Controller controller     = new X360Controller();
            int            timeout        = 30;
            long           last_changed   = 0;
            long           last_mi_button = 0;

            while (true)
            {
                HidDeviceData data         = Device.Read(timeout);
                var           currentState = data.Data;
                bool          changed      = false;
                if (data.Status == HidDeviceData.ReadStatus.Success && currentState.Length >= 21 && currentState[0] == 4)
                {
                    //Console.WriteLine(Program.ByteArrayToHexString(currentState));
                    X360Buttons Buttons = X360Buttons.None;
                    if ((currentState[1] & 1) != 0)
                    {
                        Buttons |= X360Buttons.A;
                    }
                    if ((currentState[1] & 2) != 0)
                    {
                        Buttons |= X360Buttons.B;
                    }
                    if ((currentState[1] & 8) != 0)
                    {
                        Buttons |= X360Buttons.X;
                    }
                    if ((currentState[1] & 16) != 0)
                    {
                        Buttons |= X360Buttons.Y;
                    }
                    if ((currentState[1] & 64) != 0)
                    {
                        Buttons |= X360Buttons.LeftBumper;
                    }
                    if ((currentState[1] & 128) != 0)
                    {
                        Buttons |= X360Buttons.RightBumper;
                    }

                    if ((currentState[2] & 32) != 0)
                    {
                        Buttons |= X360Buttons.LeftStick;
                    }
                    if ((currentState[2] & 64) != 0)
                    {
                        Buttons |= X360Buttons.RightStick;
                    }

                    if (currentState[4] != 15)
                    {
                        if (currentState[4] == 0 || currentState[4] == 1 || currentState[4] == 7)
                        {
                            Buttons |= X360Buttons.Up;
                        }
                        if (currentState[4] == 4 || currentState[4] == 3 || currentState[4] == 5)
                        {
                            Buttons |= X360Buttons.Down;
                        }
                        if (currentState[4] == 6 || currentState[4] == 5 || currentState[4] == 7)
                        {
                            Buttons |= X360Buttons.Left;
                        }
                        if (currentState[4] == 2 || currentState[4] == 1 || currentState[4] == 3)
                        {
                            Buttons |= X360Buttons.Right;
                        }
                    }

                    if ((currentState[2] & 8) != 0)
                    {
                        Buttons |= X360Buttons.Start;
                    }
                    if ((currentState[2] & 4) != 0)
                    {
                        Buttons |= X360Buttons.Back;
                    }



                    if ((currentState[20] & 1) != 0)
                    {
                        last_mi_button = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond);
                        Buttons       |= X360Buttons.Logo;
                    }
                    if (last_mi_button != 0)
                    {
                        Buttons |= X360Buttons.Logo;
                    }


                    if (controller.Buttons != Buttons)
                    {
                        changed            = true;
                        controller.Buttons = Buttons;
                    }

                    short LeftStickX = (short)((Math.Max(-127.0, currentState[5] - 128) / 127) * 32767);
                    if (LeftStickX != controller.LeftStickX)
                    {
                        changed = true;
                        controller.LeftStickX = LeftStickX;
                    }

                    short LeftStickY = (short)((Math.Max(-127.0, currentState[6] - 128) / 127) * -32767);
                    if (LeftStickY != controller.LeftStickY)
                    {
                        changed = true;
                        controller.LeftStickY = LeftStickY;
                    }

                    short RightStickX = (short)((Math.Max(-127.0, currentState[7] - 128) / 127) * 32767);
                    if (RightStickX != controller.RightStickX)
                    {
                        changed = true;
                        controller.RightStickX = RightStickX;
                    }

                    short RightStickY = (short)((Math.Max(-127.0, currentState[8] - 128) / 127) * -32767);
                    if (RightStickY != controller.RightStickY)
                    {
                        changed = true;
                        controller.RightStickY = RightStickY;
                    }

                    if (controller.LeftTrigger != currentState[11])
                    {
                        changed = true;
                        controller.LeftTrigger = currentState[11];
                    }

                    if (controller.RightTrigger != currentState[12])
                    {
                        changed = true;
                        controller.RightTrigger = currentState[12];
                    }
                }

                if (data.Status == HidDeviceData.ReadStatus.WaitTimedOut || (!changed && ((last_changed + timeout) < (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond))))
                {
                    changed = true;
                }

                if (changed)
                {
                    //Console.WriteLine("changed");
                    //Console.WriteLine((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond));
                    byte[] outputReport = new byte[8];
                    scpBus.Report(index, controller.GetReport(), outputReport);

                    if (outputReport[1] == 0x08)
                    {
                        byte bigMotor   = outputReport[3];
                        byte smallMotor = outputReport[4];
                        rumble_mutex.WaitOne();
                        if (bigMotor != Vibration[2] || Vibration[1] != smallMotor)
                        {
                            Vibration[1] = smallMotor;
                            Vibration[2] = bigMotor;
                        }
                        rumble_mutex.ReleaseMutex();
                    }

                    if (last_mi_button != 0)
                    {
                        if ((last_mi_button + 100) < (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond))
                        {
                            last_mi_button      = 0;
                            controller.Buttons ^= X360Buttons.Logo;
                        }
                    }

                    last_changed = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
                }
            }
        }
Exemplo n.º 23
0
        private void input_thread(HidDevice Device, ScpBus scpBus, int index)
        {
            scpBus.PlugIn(index);
            X360Controller controller   = new X360Controller();
            int            timeout      = 30;
            long           last_changed = 0;

            //long last_mi_button = 0;
            while (true)
            {
                HidDeviceData data         = Device.Read(timeout);
                var           currentState = data.Data;
                bool          changed      = false;

                string str = Program.ByteArrayToHexString(currentState);
                if (!string.IsNullOrEmpty(str))
                {
                    Console.WriteLine(Program.ByteArrayToHexString(currentState));
                }

                if (data.Status == HidDeviceData.ReadStatus.Success && currentState.Length >= 10 && currentState[0] == 0x02)
                {
                    // Console.WriteLine(Program.ByteArrayToHexString(currentState));
                    X360Buttons Buttons = X360Buttons.None;
                    if ((currentState[1] & 0x01) != 0)
                    {
                        Buttons |= X360Buttons.A;
                    }
                    if ((currentState[1] & 0x02) != 0)
                    {
                        Buttons |= X360Buttons.B;
                    }
                    if ((currentState[1] & 0x08) != 0)
                    {
                        Buttons |= X360Buttons.X;
                    }
                    if ((currentState[1] & 0x10) != 0)
                    {
                        Buttons |= X360Buttons.Y;
                    }
                    if ((currentState[1] & 0x40) != 0)
                    {
                        Buttons |= X360Buttons.LeftBumper;
                    }
                    if ((currentState[1] & 0x80) != 0)
                    {
                        Buttons |= X360Buttons.RightBumper;
                    }

                    if ((currentState[2] & 0x20) != 0)
                    {
                        Buttons |= X360Buttons.LeftStick;
                    }
                    if ((currentState[2] & 0x40) != 0)
                    {
                        Buttons |= X360Buttons.RightStick;
                    }

                    if (currentState[3] != 0x0F)
                    {
                        if (currentState[3] == 0 || currentState[3] == 1 || currentState[3] == 7)
                        {
                            Buttons |= X360Buttons.Up;
                        }
                        if (currentState[3] == 4 || currentState[3] == 3 || currentState[3] == 5)
                        {
                            Buttons |= X360Buttons.Down;
                        }
                        if (currentState[3] == 6 || currentState[3] == 5 || currentState[3] == 7)
                        {
                            Buttons |= X360Buttons.Left;
                        }
                        if (currentState[3] == 2 || currentState[3] == 1 || currentState[3] == 3)
                        {
                            Buttons |= X360Buttons.Right;
                        }
                    }

                    if ((currentState[2] & 0x04) != 0)
                    {
                        Buttons |= X360Buttons.Start;
                    }
                    if ((currentState[2] & 0x08) != 0)
                    {
                        Buttons |= X360Buttons.Back;
                    }

                    if ((currentState[2] & 0x10) != 0)
                    {
                        Buttons |= X360Buttons.Logo;
                    }
                    //按下Fuze Logo键一下是不触发任何按键的,0x10是短按并松开fuze键时触发的按键
                    if ((currentState[2] & 0x01) != 0)
                    {
                        Buttons |= X360Buttons.Logo;
                    }
                    //长按会触发0x01按键,在GNU/Linux系统下,会触发关机键

                    /*
                     * //if ((currentState[20] & 1) != 0)
                     * //{
                     * //    last_mi_button = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond);
                     * //    Buttons |= X360Buttons.Logo;
                     * //}
                     * //if (last_mi_button != 0) Buttons |= X360Buttons.Logo;
                     */

                    if (controller.Buttons != Buttons)
                    {
                        changed            = true;
                        controller.Buttons = Buttons;
                    }

                    short LeftStickX = (short)((Math.Max(-127.0, currentState[4] - 128) / 127) * 32767);
                    if (LeftStickX == -32767)
                    {
                        LeftStickX = -32768;
                    }

                    if (LeftStickX != controller.LeftStickX)
                    {
                        changed = true;
                        controller.LeftStickX = LeftStickX;
                    }

                    short LeftStickY = (short)((Math.Max(-127.0, currentState[5] - 128) / 127) * -32767);
                    if (LeftStickY == -32767)
                    {
                        LeftStickY = -32768;
                    }

                    if (LeftStickY != controller.LeftStickY)
                    {
                        changed = true;
                        controller.LeftStickY = LeftStickY;
                    }

                    short RightStickX = (short)((Math.Max(-127.0, currentState[6] - 128) / 127) * 32767);
                    if (RightStickX == -32767)
                    {
                        RightStickX = -32768;
                    }

                    if (RightStickX != controller.RightStickX)
                    {
                        changed = true;
                        controller.RightStickX = RightStickX;
                    }

                    short RightStickY = (short)((Math.Max(-127.0, currentState[7] - 128) / 127) * -32767);
                    if (RightStickY == -32767)
                    {
                        RightStickY = -32768;
                    }

                    if (RightStickY != controller.RightStickY)
                    {
                        changed = true;
                        controller.RightStickY = RightStickY;
                    }

                    if (controller.LeftTrigger != currentState[8])
                    {
                        changed = true;
                        controller.LeftTrigger = currentState[8];
                    }

                    if (controller.RightTrigger != currentState[9])
                    {
                        changed = true;
                        controller.RightTrigger = currentState[9];
                    }
                }

                if (data.Status == HidDeviceData.ReadStatus.WaitTimedOut || (!changed && ((last_changed + timeout) < (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond))))
                {
                    changed = true;
                }

                if (changed)
                {
                    //Console.WriteLine("changed");
                    //Console.WriteLine((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond));
                    byte[] outputReport = new byte[8];
                    scpBus.Report(index, controller.GetReport(), outputReport);

                    //TODO: 震动
                    //if (outputReport[1] == 0x08)
                    //{
                    //    byte bigMotor = outputReport[3];
                    //    byte smallMotor = outputReport[4];
                    //    rumble_mutex.WaitOne();
                    //    if (bigMotor != Vibration[2] || Vibration[1] != smallMotor)
                    //    {
                    //        Vibration[1] = smallMotor;
                    //        Vibration[2] = bigMotor;
                    //    }
                    //    rumble_mutex.ReleaseMutex();
                    //}

                    /*
                     * //if (last_mi_button != 0)
                     * //{
                     * //    if ((last_mi_button + 100) < (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond))
                     * //    {
                     * //        last_mi_button = 0;
                     * //        controller.Buttons ^= X360Buttons.Logo;
                     * //    }
                     * //}
                     *
                     * //last_changed = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
                     */
                }
            }
        }
Exemplo n.º 24
0
        static void Main(string[] args)
        {
            ScpBus scpBus = new ScpBus();

            scpBus.UnplugAll();
            global_scpBus = scpBus;

            handler = new ConsoleEventDelegate(ConsoleEventCallback);
            SetConsoleCtrlHandler(handler, true);

            Thread.Sleep(400);

            Xiaomi_gamepad[] gamepads = new Xiaomi_gamepad[4];
            int index = 1;

            string[] connectedDevices = new string[4];
            while (true)
            {
                var compatibleDevices = HidDevices.Enumerate(0x2717, 0x3144).ToList();
                foreach (var deviceInstance in compatibleDevices)
                {
                    if (index >= 5 || connectedDevices.Contains(deviceInstance.DevicePath))
                    {
                        continue;
                    }

                    HidDevice Device = deviceInstance;
                    try
                    {
                        Device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.Exclusive);
                    }
                    catch
                    {
                        Console.WriteLine("Could not open gamepad in exclusive mode. Try re-enable device.");
                        var instanceId = devicePathToInstanceId(deviceInstance.DevicePath);
                        if (TryReEnableDevice(instanceId))
                        {
                            try
                            {
                                Device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.Exclusive);
                                Console.WriteLine("Opened in exclusive mode.");
                            }
                            catch
                            {
                                Device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.ShareRead | ShareMode.ShareWrite);
                                Console.WriteLine("Opened in shared mode.");
                            }
                        }
                        else
                        {
                            Device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.ShareRead | ShareMode.ShareWrite);
                            Console.WriteLine("Opened in shared mode.");
                        }
                    }

                    byte[] Vibration = { 0x20, 0x00, 0x00 };
                    if (Device.WriteFeatureData(Vibration) == false)
                    {
                        Device.CloseDevice();
                        continue;
                    }

                    byte[] serialNumber;
                    byte[] product;
                    Device.ReadSerialNumber(out serialNumber);
                    Device.ReadProduct(out product);

                    gamepads[index - 1] = new Xiaomi_gamepad(Device, scpBus, index);
                    ++index;

                    Console.WriteLine(deviceInstance);
                    Console.WriteLine("Added new device.");
                    connectedDevices[index - 1] = deviceInstance.DevicePath;
                }

                Thread.Sleep(5000);
            }
        }
Exemplo n.º 25
0
        public static void Run(BackgroundWorker bw)
        {
            ScpBus scpBus = new ScpBus();

            scpBus.UnplugAll();
            _globalScpBus = scpBus;

            _handler = ConsoleEventCallback;
            SetConsoleCtrlHandler(_handler, true);

            Thread.Sleep(400);

            XiaomiGamepad[] gamepads          = new XiaomiGamepad[4];
            int             index             = 1;
            var             compatibleDevices = HidDevices.Enumerate(0x2717, 0x3144).ToList();

            foreach (var deviceInstance in compatibleDevices)
            {
                Console.WriteLine(deviceInstance);
                HidDevice device = deviceInstance;
                try
                {
                    device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.ShareRead | ShareMode.ShareWrite);
                }
                catch
                {
                    bw.ReportProgress(0, "Could not open gamepad in exclusive mode. Try re-enable device.");
                    var instanceId = DevicePathToInstanceId(deviceInstance.DevicePath);
                    if (TryReEnableDevice(instanceId))
                    {
                        try
                        {
                            device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.Exclusive);
                            bw.ReportProgress(0, "Opened in exclusive mode.");
                        }
                        catch
                        {
                            device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.ShareRead | ShareMode.ShareWrite);
                            bw.ReportProgress(0, "Opened in shared mode.");
                        }
                    }
                    else
                    {
                        device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.ShareRead | ShareMode.ShareWrite);
                        bw.ReportProgress(0, "Opened in shared mode.");
                    }
                }

                byte[] vibration = { 0x20, 0x00, 0x00 };
                if (device.WriteFeatureData(vibration) == false)
                {
                    bw.ReportProgress(0, "Could not write to gamepad (is it closed?), skipping");
                    device.CloseDevice();
                    continue;
                }

                device.ReadSerialNumber(out _);
                device.ReadProduct(out _);


                gamepads[index - 1] = new XiaomiGamepad(device, scpBus, index);
                ++index;

                if (index >= 5)
                {
                    break;
                }
            }
            bw.ReportProgress(0, $"{index - 1} controllers connected");

            while (!bw.CancellationPending)
            {
                Thread.Sleep(1000);
            }
        }
Exemplo n.º 26
0
 public ControllerManager()
 {
     Bus = new ScpBus();
 }
Exemplo n.º 27
0
        private static void Init()
        {
            ScpBus scpBus = new ScpBus();

            scpBus.UnplugAll();
            global_scpBus = scpBus;

            handler = new ConsoleEventDelegate(ConsoleEventCallback);
            SetConsoleCtrlHandler(handler, true);

            var compatibleDevices = HidDevices.Enumerate(0x79, 0x181c).ToList();

            Thread.Sleep(400);

            FuzeGamepad[] gamepads = new FuzeGamepad[4];
            int           index    = 1;

            //compatibleDevices.RemoveRange(1, compatibleDevices.Count - 1);
            foreach (var deviceInstance in compatibleDevices)
            {
                //Console.WriteLine(deviceInstance);
                HidDevice Device = deviceInstance;
                try
                {
                    Device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.Exclusive);
                }
                catch
                {
                    Log.WriteLine("Could not open gamepad in exclusive mode. Try re-enable device.", Log.LogType.warning);
                    var instanceId = devicePathToInstanceId(deviceInstance.DevicePath);
                    if (TryReEnableDevice(instanceId))
                    {
                        try
                        {
                            Device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.Exclusive);
                            Log.WriteLine("Opened in exclusive mode.");
                        }
                        catch
                        {
                            Device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.ShareRead | ShareMode.ShareWrite);
                            Log.WriteLine("Opened in shared mode.");
                        }
                    }
                    else
                    {
                        Device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.ShareRead | ShareMode.ShareWrite);
                        Log.WriteLine("Opened in shared mode.");
                    }
                }

                //byte[] Vibration = { 0x20, 0x00, 0x00 };
                //if (Device.WriteFeatureData(Vibration) == false)
                //{
                //    Console.WriteLine("Could not write to gamepad (is it closed?), skipping");
                //    Device.CloseDevice();
                //    continue;
                //}

                byte[] serialNumber;
                byte[] product;
                Device.ReadSerialNumber(out serialNumber);
                Device.ReadProduct(out product);


                gamepads[index - 1] = new FuzeGamepad(Device, scpBus, index);
                ++index;

                if (index >= 5)
                {
                    break;
                }
            }

            Log.WriteLine(string.Format("{0} controllers connected", index - 1));

            while (true)
            {
                Thread.Sleep(1000);
            }
        }
Exemplo n.º 28
0
        private static void ManageControllers(ScpBus scpBus)
        {
            var nrConnected = 0;
            //while (true)
            {
                var compatibleDevices = HidDevices.Enumerate(0x18D1, 0x9400).ToList();
                var existingDevices   = Gamepads.Select(g => g.Device).ToList();
                var newDevices        = compatibleDevices.Where(d => !existingDevices.Select(e => e.DevicePath).Contains(d.DevicePath));
                foreach (var gamepad in Gamepads.ToList())
                {
                    if (!gamepad.check_connected())
                    {
                        gamepad.unplug();
                        Gamepads.Remove(gamepad);
                    }
                }
                foreach (var deviceInstance in newDevices)
                {
                    var device = deviceInstance;
                    try
                    {
                        device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.Exclusive);
                    }
                    catch
                    {
                        InformUser("Could not open gamepad in exclusive mode. Try reconnecting the device.");
                        var instanceId = devicePathToInstanceId(deviceInstance.DevicePath);
                        if (TryReEnableDevice(instanceId))
                        {
                            try
                            {
                                device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.Exclusive);
                                InformUser("Opened in exclusive mode.");
                            }
                            catch
                            {
                                device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.ShareRead | ShareMode.ShareWrite);
                                InformUser("Opened in shared mode.");
                            }
                        }
                        else
                        {
                            device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.ShareRead | ShareMode.ShareWrite);
                            InformUser("Opened in shared mode.");
                        }
                    }

                    //byte[] vibration = { 0x05, 0x00, 0x00, 0x00, 0x00 };
                    //if (device.Write(vibration) == false)
                    //{
                    //	InformUser("Could not write to gamepad (is it closed?), skipping");
                    //	device.CloseDevice();
                    //	continue;
                    //}

                    byte[] serialNumber;
                    byte[] product;
                    device.ReadSerialNumber(out serialNumber);
                    device.ReadProduct(out product);


                    var usedIndexes = Gamepads.Select(g => g.Index);
                    var index       = 1;
                    while (usedIndexes.Contains(index))
                    {
                        index++;
                    }
                    Gamepads.Add(new StadiaController(device, scpBus, index));
                }
                if (Gamepads.Count != nrConnected)
                {
                    InformUser($"{Gamepads.Count} controllers connected");
                    nrConnected = Gamepads.Count;
                }
                //Thread.Sleep(1000);
            }
        }
Exemplo n.º 29
0
        private void input_thread(HidDevice Device, ScpBus scpBus, int index)
        {
            scpBus.PlugIn(index);
            X360Controller controller = new X360Controller();
            int            timeout    = 10;
            //long last_changed = 0;
            //long last_mi_button = 0;
            bool ss_button_pressed = false;
            bool ss_button_held    = false;

            while (Running)
            {
                HidDeviceData data         = Device.Read(timeout);
                var           currentState = data.Data;
                //bool changed = false;
                if (data.Status == HidDeviceData.ReadStatus.Success && currentState.Length >= 10 && currentState[0] == 3)
                {
                    // NOTE: Console.WriteLine is blocking. If main thread sends a WriteLine while we do a WriteLine here, we're boned and will miss reports!
                    //Console.WriteLine(Program.ByteArrayToHexString(currentState));

                    X360Buttons Buttons = X360Buttons.None;
                    if ((currentState[3] & 64) != 0)
                    {
                        Buttons |= X360Buttons.A;
                    }
                    if ((currentState[3] & 32) != 0)
                    {
                        Buttons |= X360Buttons.B;
                    }
                    if ((currentState[3] & 16) != 0)
                    {
                        Buttons |= X360Buttons.X;
                    }
                    if ((currentState[3] & 8) != 0)
                    {
                        Buttons |= X360Buttons.Y;
                    }
                    if ((currentState[3] & 4) != 0)
                    {
                        Buttons |= X360Buttons.LeftBumper;
                    }
                    if ((currentState[3] & 2) != 0)
                    {
                        Buttons |= X360Buttons.RightBumper;
                    }
                    if ((currentState[3] & 1) != 0)
                    {
                        Buttons |= X360Buttons.LeftStick;
                    }
                    if ((currentState[2] & 128) != 0)
                    {
                        Buttons |= X360Buttons.RightStick;
                    }
                    ss_button_pressed = (currentState[2] & 1) != 0;
                    // [2] & 2 == Assistant, [2] & 1 == Screenshot

                    switch (currentState[1])
                    {
                    default:
                        break;

                    case 0:
                        Buttons |= X360Buttons.Up;
                        break;

                    case 1:
                        Buttons |= X360Buttons.UpRight;
                        break;

                    case 2:
                        Buttons |= X360Buttons.Right;
                        break;

                    case 3:
                        Buttons |= X360Buttons.DownRight;
                        break;

                    case 4:
                        Buttons |= X360Buttons.Down;
                        break;

                    case 5:
                        Buttons |= X360Buttons.DownLeft;
                        break;

                    case 6:
                        Buttons |= X360Buttons.Left;
                        break;

                    case 7:
                        Buttons |= X360Buttons.UpLeft;
                        break;
                    }

                    if ((currentState[2] & 32) != 0)
                    {
                        Buttons |= X360Buttons.Start;
                    }
                    if ((currentState[2] & 64) != 0)
                    {
                        Buttons |= X360Buttons.Back;
                    }

                    if ((currentState[2] & 16) != 0)
                    {
                        //last_mi_button = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond);
                        Buttons |= X360Buttons.Logo;
                    }


                    //if (controller.Buttons != Buttons)
                    {
                        //changed = true;
                        controller.Buttons = Buttons;
                    }

                    // 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 (currentState[i] <= 0x7F && currentState[i] > 0x00)
                        {
                            currentState[i] -= 0x01;
                        }
                    }

                    ushort LeftStickXunsigned = (ushort)(currentState[4] << 8 | (currentState[4] << 1 & 255));
                    if (LeftStickXunsigned == 0xFFFE)
                    {
                        LeftStickXunsigned = 0xFFFF;
                    }
                    short LeftStickX = (short)(LeftStickXunsigned - 0x8000);

                    //if (LeftStickX != controller.LeftStickX)
                    {
                        //	changed = true;
                        controller.LeftStickX = LeftStickX;
                    }

                    ushort LeftStickYunsigned = (ushort)(currentState[5] << 8 | (currentState[5] << 1 & 255));
                    if (LeftStickYunsigned == 0xFFFE)
                    {
                        LeftStickYunsigned = 0xFFFF;
                    }
                    short LeftStickY = (short)(-LeftStickYunsigned + 0x7FFF);
                    if (LeftStickY == -1)
                    {
                        LeftStickY = 0;
                    }
                    //if (LeftStickY != controller.LeftStickY)
                    {
                        //	changed = true;
                        controller.LeftStickY = LeftStickY;
                    }

                    ushort RightStickXunsigned = (ushort)(currentState[6] << 8 | (currentState[6] << 1 & 255));
                    if (RightStickXunsigned == 0xFFFE)
                    {
                        RightStickXunsigned = 0xFFFF;
                    }
                    short RightStickX = (short)(RightStickXunsigned - 0x8000);

                    //if (RightStickX != controller.RightStickX)
                    {
                        //	changed = true;
                        controller.RightStickX = RightStickX;
                    }

                    ushort RightStickYunsigned = (ushort)(currentState[7] << 8 | (currentState[7] << 1 & 255));
                    if (RightStickYunsigned == 0xFFFE)
                    {
                        RightStickYunsigned = 0xFFFF;
                    }
                    short RightStickY = (short)(-RightStickYunsigned + 0x7FFF);
                    if (RightStickY == -1)
                    {
                        RightStickY = 0;
                    }

                    //if (RightStickY != controller.RightStickY)
                    {
                        //	changed = true;
                        controller.RightStickY = RightStickY;
                    }

                    //if (controller.LeftTrigger != currentState[8])
                    {
                        //	changed = true;
                        controller.LeftTrigger = currentState[8];
                    }

                    //if (controller.RightTrigger != currentState[9])
                    {
                        //	changed = true;
                        controller.RightTrigger = currentState[9];
                    }
                }

                /*
                 * if (data.Status == HidDeviceData.ReadStatus.WaitTimedOut || (!changed && ((last_changed + timeout) < (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond))))
                 * {
                 *      changed = true;
                 * }*/

                //if (changed)
                {
                    //Console.WriteLine("changed");
                    //Console.WriteLine((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond));
                    byte[] outputReport = new byte[8];
                    scpBus.Report(index, controller.GetReport(), outputReport);

                    if (outputReport[1] == 0x08)
                    {
                        byte bigMotor   = outputReport[3];
                        byte smallMotor = outputReport[4];

                        if (smallMotor != Vibration[3] || Vibration[1] != bigMotor)
                        {
                            // We only need to take the mutex if we're modifying the data
                            rumble_mutex.WaitOne();
                            Vibration[1] = bigMotor;
                            Vibration[3] = smallMotor;
                            rumble_mutex.ReleaseMutex();
                            rumbleWaitHandle.Set();
                        }
                    }

                    //last_changed = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
                }

                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;
                }
            }
        }
Exemplo n.º 30
0
        static void Main(string[] args)
        {
            string newInputEndpoint       = "http://127.0.0.1:5000/gbmode_input_request_bizhawk";
            string doneInputEndpoint      = "http://127.0.0.1:5000/gbmode_input_complete";
            int    controller             = 1;
            int    minHeldFrames          = 1;
            int    maxSleepFrames         = 100;
            int    maxHeldFrames          = 100;
            int    maxHoldFrames          = 0;    //24;
            bool   toggleTriggers         = false;
            bool   eternalHolds           = true; //false;
            string forceFocusProgram      = null;
            int    forceSaveBackupSeconds = 0;
            string saveBackupEndpoint     = "http://127.0.0.1:5000/back_up_savestate";

            try
            {
                for (var i = 0; i < args.Length; i++)
                {
                    switch (args[i].ToLower())
                    {
                    case "-h":
                    case "-help":
                        PrintHelpText();
                        return;

                    case "-inputendpoint":
                        newInputEndpoint = args[i + 1];
                        ConsoleLogger.Info($"Input endpoint: {newInputEndpoint}");
                        break;

                    case "-doneendpoint":
                        doneInputEndpoint = args[i + 1];
                        ConsoleLogger.Info($"Done endpoint: {doneInputEndpoint}");
                        break;

                    case "-savebackupendpoint":
                        saveBackupEndpoint = args[i + 1];
                        ConsoleLogger.Info($"Save Backup endpoint: {saveBackupEndpoint}");
                        break;

                    case "-controller":
                        controller = int.Parse(args[i + 1]);
                        ConsoleLogger.Info($"Simulating controller #{controller}");
                        break;

                    case "-lstickthrow":
                        TPPInput.LThrowGlobalMult = double.Parse(args[i + 1]);
                        ConsoleLogger.Info($"Left Stick max throw set to {(TPPInput.LThrowGlobalMult * 100).ToString("0")}%");
                        break;

                    case "-rstickthrow":
                        TPPInput.RThrowGlobalMult = double.Parse(args[i + 1]);
                        ConsoleLogger.Info($"Right Stick max throw set to {(TPPInput.RThrowGlobalMult * 100).ToString("0")}%");
                        break;

                    case "-toggletriggers":
                        toggleTriggers = true;
                        ConsoleLogger.Info("Left and Right Triggers will be toggled");
                        break;

                    case "-eternalholds":
                        eternalHolds  = true;
                        maxHoldFrames = 0;
                        ConsoleLogger.Info("Held inputs will last until the next held input");
                        break;

                    case "-minheldframes":
                        minHeldFrames = int.Parse(args[i + 1]);
                        ConsoleLogger.Info($"Minimum Held Frames: {minHeldFrames}");
                        break;

                    case "-maxsleepframes":
                        maxSleepFrames = int.Parse(args[i + 1]);
                        ConsoleLogger.Info($"Maximum Sleep Frames: {maxSleepFrames}");
                        break;

                    case "-maxheldframes":
                        maxHeldFrames = int.Parse(args[i + 1]);
                        ConsoleLogger.Info($"Maximum Held Frames: {maxHeldFrames}");
                        break;

                    case "-maxholdframes":
                        maxHoldFrames = int.Parse(args[i + 1]);
                        ConsoleLogger.Info($"Maximum Hold Input Frames: {maxHoldFrames}");
                        break;

                    case "-forcefocus":
                        forceFocusProgram = args[i + 1];
                        ConsoleLogger.Info($"Forcing {forceFocusProgram} to have focus for each input");
                        break;

                    case "-forcesavebackup":
                        forceSaveBackupSeconds = int.Parse(args[i + 1]);
                        ConsoleLogger.Info($"Forcing save backup every {forceSaveBackupSeconds} seconds");
                        break;
                    }
                }
            }
            catch (Exception e)
            {
                ConsoleLogger.Critical(e.Message);
                PrintHelpText();
                return;
            }

            ScpBus scpBus;

            try
            {
                scpBus = new ScpBus();
            }
            catch
            {
                ConsoleLogger.Critical("Could not create virtual controller. Please make sure the SCP Virtual Bus Driver is installed.");
                return;
            }

            scpBus.PlugIn(1);
            ConsoleLogger.Info("Virtual controller connected.");


            Console.CancelKeyPress += delegate {
                scpBus.UnplugAll();
                ConsoleLogger.Info("Virtual controller(s) disconnected.");
                scpBus.Dispose();
            };

            var inputFetcher = new FetchInput(scpBus, controller, minHeldFrames, maxHeldFrames, maxSleepFrames, maxHoldFrames, toggleTriggers, eternalHolds, newInputEndpoint, doneInputEndpoint, forceFocusProgram);

            var worker = new Worker(() => inputFetcher.Frame());

            worker.Start();

            var willBackupSave = forceSaveBackupSeconds > 0 && !string.IsNullOrWhiteSpace(saveBackupEndpoint);

            while (true)
            {
                for (var i = 0; i < forceSaveBackupSeconds; i += forceSaveBackupSeconds / 10)
                {
                    if (willBackupSave)
                    {
                        ConsoleLogger.Info($"{forceSaveBackupSeconds - i} seconds until save backup...");
                    }
                    Thread.Sleep(forceSaveBackupSeconds * 100);
                }
                if (willBackupSave)
                {
                    using (var webClient = new ImpatientWebClient(forceSaveBackupSeconds * 1000))
                    {
                        ConsoleLogger.Info("Backing up save...");
                        webClient.DownloadStringAsync(new Uri(saveBackupEndpoint));
                    }
                }
            }
        }