├── .gitignore
├── LICENSE
├── README.md
├── XOutput.sln
├── XOutput.v12.suo
└── XOutput
├── App.config
├── ControllerDevice.cs
├── ControllerManager.cs
├── ControllerOptions.Designer.cs
├── ControllerOptions.cs
├── Logger.cs
├── MultiLevelComboBox.cs
├── Program.cs
├── Properties
├── AssemblyInfo.cs
├── Resources.Designer.cs
├── Resources.resx
├── Settings.Designer.cs
└── Settings.settings
├── Resources
├── arrow_Down.png
├── arrow_Up.png
└── gear.png
├── SaveManager.cs
├── ScpDevice.cs
├── XOut.Designer.cs
├── XOut.cs
├── XOut.resx
├── XOutput.csproj
├── XOutput.csproj.user
└── XOutput_Icon.ico
/.gitignore:
--------------------------------------------------------------------------------
1 | XOutput/bin/
2 | XOutput/obj/
3 | .vs/
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
167 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | XOutput is a simple DirectInput to XInput wrapper made in C#. It uses the SCPDriver has a backend.
2 | Now modified by me to take input from Steam Controller
3 |
4 | #Building
5 |
6 | XOutput can be built in Visual Studio 2013+. It depends on the SlimDX developer SDK which can be found [here](http://slimdx.org/)
7 |
8 | #How to Set Up
9 |
10 | 1. Download and install the official Xbox 360 Controller driver [here](http://www.microsoft.com/hardware/en-us/d/xbox-360-controller-for-windows)
11 | 2. Run ScpDriver.exe
12 | 3. Click install, wait until it finishes to close it
13 | 4. Run XOutput and set up your controller mappings
14 | 5. Click "Start"
15 |
--------------------------------------------------------------------------------
/XOutput.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Express 14 for Windows Desktop
4 | VisualStudioVersion = 14.0.24720.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XOutput", "XOutput\XOutput.csproj", "{3FA04C64-23DE-4294-B9D7-47BBFFB57539}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Debug|x86 = Debug|x86
12 | Release|Any CPU = Release|Any CPU
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {3FA04C64-23DE-4294-B9D7-47BBFFB57539}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {3FA04C64-23DE-4294-B9D7-47BBFFB57539}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {3FA04C64-23DE-4294-B9D7-47BBFFB57539}.Debug|x86.ActiveCfg = Debug|x86
19 | {3FA04C64-23DE-4294-B9D7-47BBFFB57539}.Debug|x86.Build.0 = Debug|x86
20 | {3FA04C64-23DE-4294-B9D7-47BBFFB57539}.Release|Any CPU.ActiveCfg = Release|Any CPU
21 | {3FA04C64-23DE-4294-B9D7-47BBFFB57539}.Release|Any CPU.Build.0 = Release|Any CPU
22 | {3FA04C64-23DE-4294-B9D7-47BBFFB57539}.Release|x86.ActiveCfg = Release|x86
23 | {3FA04C64-23DE-4294-B9D7-47BBFFB57539}.Release|x86.Build.0 = Release|x86
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | EndGlobal
29 |
--------------------------------------------------------------------------------
/XOutput.v12.suo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mintos5/XOutput/c878b3c3b6c5e1714d300f630c4fb2cddc32374a/XOutput.v12.suo
--------------------------------------------------------------------------------
/XOutput/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/XOutput/ControllerDevice.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using SlimDX.DirectInput;
3 | using SlimDX.XInput;
4 |
5 | namespace XOutput
6 | {
7 |
8 | public struct OutputState
9 | {
10 | public byte LX, LY, RX, RY, L2, R2;
11 | public bool A, B, X, Y, Start, Back, L1, R1, L3, R3, Home;
12 | public bool DpadUp, DpadRight, DpadDown, DpadLeft;
13 | }
14 |
15 | public class ControllerDevice
16 | {
17 | public Joystick joystick;
18 | int deviceNumber;
19 | public string name;
20 | public bool enabled = true;
21 |
22 | public OutputState cOutput;
23 | public byte[] mapping = new byte[42];
24 | bool[] buttons;
25 | int[] dPads;
26 | int[] analogs;
27 |
28 |
29 | delegate byte input(byte subType, byte num);
30 |
31 | public ControllerDevice(Joystick joy, int num)
32 | {
33 | joystick = joy;
34 | deviceNumber = num;
35 | name = joystick.Information.InstanceName;
36 | cOutput = new OutputState();
37 | for (int i = 0; i < 42; i++)
38 | {
39 | mapping[i] = 255; //Changed default mapping to blank
40 | }
41 | byte[] saveData = SaveManager.Load(joy.Information.ProductName.ToString());
42 | if (saveData != null)
43 | mapping = saveData;
44 | }
45 |
46 | #region Utility Functions
47 |
48 | public void Save()
49 | {
50 | SaveManager.Save(joystick.Information.ProductName, mapping);
51 | }
52 |
53 | private int XinputLT()
54 | {
55 | byte lt = new Controller(0).GetState().Gamepad.LeftTrigger;
56 | return lt * 256;
57 | }
58 |
59 | private int XinputRT()
60 | {
61 | byte rt = new Controller(0).GetState().Gamepad.RightTrigger;
62 | return rt * 256;
63 | }
64 |
65 | private int[] GetAxes(JoystickState jstate)
66 | {
67 | return new int[] { jstate.X, jstate.Y, XinputLT(), jstate.RotationX, jstate.RotationY, XinputRT() };
68 | }
69 |
70 | private unsafe byte toByte(bool n)
71 | {
72 | return *((byte*)(&n));
73 | }
74 |
75 | private bool[] getPov(byte n)
76 | {
77 | bool[] b = new bool[4];
78 | int i = dPads[n];
79 | switch (i)
80 | {
81 | case -1: b[0] = false; b[1] = false; b[2] = false; b[3] = false; break;
82 | case 0: b[0] = true; b[1] = false; b[2] = false; b[3] = false; break;
83 | case 4500: b[0] = true; b[1] = false; b[2] = false; b[3] = true; break;
84 | case 9000: b[0] = false; b[1] = false; b[2] = false; b[3] = true; break;
85 | case 13500: b[0] = false; b[1] = true; b[2] = false; b[3] = true; break;
86 | case 18000: b[0] = false; b[1] = true; b[2] = false; b[3] = false; break;
87 | case 22500: b[0] = false; b[1] = true; b[2] = true; b[3] = false; break;
88 | case 27000: b[0] = false; b[1] = false; b[2] = true; b[3] = false; break;
89 | case 31500: b[0] = true; b[1] = false; b[2] = true; b[3] = false; break;
90 | }
91 | return b;
92 | }
93 |
94 | public void changeNumber(int n)
95 | {
96 | deviceNumber = n;
97 | }
98 |
99 | #endregion
100 |
101 | #region Input Types
102 |
103 | byte Button(byte subType, byte num)
104 | {
105 | int i = (int)toByte(buttons[num]) * 255;
106 | return (byte)i;
107 | }
108 |
109 | byte Analog(byte subType, byte num)
110 | {
111 | int p = analogs[num];
112 | switch (subType)
113 | {
114 | case 0: //Normal
115 | return (byte)(p / 256);
116 | case 1: //Inverted
117 | return (byte)((65535 - p) / 256);
118 | case 2: //Half
119 | int m = (p - 32767) / 129;
120 | if (m < 0)
121 | {
122 | m = 0;
123 | }
124 | return (byte)m;
125 | case 3: //Inverted Half
126 | m = (p - 32767) / 129;
127 | if (-m < 0)
128 | {
129 | m = 0;
130 | }
131 | return (byte)-m;
132 | }
133 | return 0;
134 | }
135 |
136 | byte DPad(byte subType, byte num)
137 | {
138 | int i = (int)toByte(getPov(num)[subType]) * 255;
139 | return (byte)i;
140 | }
141 |
142 | #endregion
143 |
144 | private void updateInput()
145 | {
146 | joystick.Poll();
147 | JoystickState jState = joystick.GetCurrentState();
148 | buttons = jState.GetButtons();
149 | dPads = jState.GetPointOfViewControllers();
150 | analogs = GetAxes(jState);
151 |
152 | input funcButton = Button;
153 | input funcAnalog = Analog;
154 | input funcDPad = DPad;
155 | input[] funcArray = new input[] { funcButton, funcAnalog, funcDPad };
156 |
157 | byte[] output = new byte[21];
158 | for (int i = 0; i < 21; i++)
159 | {
160 | if (mapping[i * 2] == 255)
161 | {
162 | continue;
163 | }
164 | byte subtype = (byte)(mapping[i * 2] & 0x0F);
165 | byte type = (byte)((mapping[i * 2] & 0xF0) >> 4);
166 | byte num = mapping[(i * 2) + 1];
167 | output[i] = funcArray[type](subtype, num);
168 | }
169 |
170 | cOutput.A = output[0] != 0;
171 | cOutput.B = output[1] != 0;
172 | cOutput.X = output[2] != 0;
173 | cOutput.Y = output[3] != 0;
174 |
175 | cOutput.DpadUp = output[4] != 0;
176 | cOutput.DpadDown = output[5] != 0;
177 | cOutput.DpadLeft = output[6] != 0;
178 | cOutput.DpadRight = output[7] != 0;
179 |
180 | cOutput.L2 = output[9];
181 | cOutput.R2 = output[8];
182 |
183 | cOutput.L1 = output[10] != 0;
184 | cOutput.R1 = output[11] != 0;
185 |
186 | cOutput.L3 = output[12] != 0;
187 | cOutput.R3 = output[13] != 0;
188 |
189 | cOutput.Home = output[14] != 0;
190 | cOutput.Start = output[15] != 0;
191 | cOutput.Back = output[16] != 0;
192 |
193 | cOutput.LY = output[17];
194 | cOutput.LX = output[18];
195 | cOutput.RY = output[19];
196 | cOutput.RX = output[20];
197 |
198 | }
199 |
200 |
201 | public byte[] getoutput()
202 | {
203 | updateInput();
204 | byte[] Report = new byte[64];
205 | Report[1] = 0x02;
206 | Report[2] = 0x05;
207 | Report[3] = 0x12;
208 |
209 | Report[10] = (byte)(
210 | ((cOutput.Back ? 1 : 0) << 0) |
211 | ((cOutput.L3 ? 1 : 0) << 1) |
212 | ((cOutput.R3 ? 1 : 0) << 2) |
213 | ((cOutput.Start ? 1 : 0) << 3) |
214 | ((cOutput.DpadUp ? 1 : 0) << 4) |
215 | ((cOutput.DpadRight ? 1 : 0) << 5) |
216 | ((cOutput.DpadDown ? 1 : 0) << 6) |
217 | ((cOutput.DpadLeft ? 1 : 0) << 7));
218 |
219 | Report[11] = (byte)(
220 | ((cOutput.L1 ? 1 : 0) << 2) |
221 | ((cOutput.R1 ? 1 : 0) << 3) |
222 | ((cOutput.Y ? 1 : 0) << 4) |
223 | ((cOutput.B ? 1 : 0) << 5) |
224 | ((cOutput.A ? 1 : 0) << 6) |
225 | ((cOutput.X ? 1 : 0) << 7));
226 |
227 | //Guide
228 | Report[12] = (byte)(cOutput.Home ? 0xFF : 0x00);
229 |
230 |
231 | Report[14] = cOutput.LX; //Left Stick X
232 |
233 |
234 | Report[15] = cOutput.LY; //Left Stick Y
235 |
236 |
237 | Report[16] = cOutput.RX; //Right Stick X
238 |
239 |
240 | Report[17] = cOutput.RY; //Right Stick Y
241 |
242 | Report[26] = cOutput.R2;
243 | Report[27] = cOutput.L2;
244 |
245 | return Report;
246 | }
247 |
248 |
249 | }
250 | }
251 |
--------------------------------------------------------------------------------
/XOutput/ControllerManager.cs:
--------------------------------------------------------------------------------
1 | using SlimDX.DirectInput;
2 | using System;
3 | using System.Diagnostics;
4 | using System.Threading;
5 | using System.Windows.Forms;
6 |
7 |
8 | namespace XOutput
9 | {
10 |
11 | class ControllerManager : ScpDevice
12 | {
13 | private class ContData
14 | {
15 | public byte[] parsedData = new byte[28];
16 | public byte[] output = new byte[8];
17 | }
18 |
19 | private DirectInput directInput;
20 | private ControllerDevice[] devices;
21 | public bool running = false;
22 | private Thread[] workers = new Thread[4];
23 | public const String BUS_CLASS_GUID = "{F679F562-3164-42CE-A4DB-E7DDBE723909}";
24 | private ContData[] processingData = new ContData[4];
25 | private Control handle;
26 | public bool isExclusive = false;
27 |
28 |
29 | private object[] ds4locks = new object[4];
30 |
31 | public ControllerManager(Control _handle)
32 | : base(BUS_CLASS_GUID)
33 | {
34 | directInput = new DirectInput();
35 | devices = new ControllerDevice[4];
36 | handle = _handle;
37 | ds4locks[0] = new object();
38 | ds4locks[1] = new object();
39 | ds4locks[2] = new object();
40 | ds4locks[3] = new object();
41 | }
42 |
43 | #region Utility Functions
44 |
45 | public void changeExclusive(bool e)
46 | {
47 | isExclusive = e;
48 | for (int i = 0; i < 4; i++)
49 | {
50 | if (devices[i] != null)
51 | {
52 | if (isExclusive)
53 | {
54 | devices[i].joystick.Unacquire();
55 | devices[i].joystick.SetCooperativeLevel(handle, CooperativeLevel.Exclusive | CooperativeLevel.Background);
56 | devices[i].joystick.Acquire();
57 | }
58 | else
59 | {
60 | devices[i].joystick.Unacquire();
61 | devices[i].joystick.SetCooperativeLevel(handle, CooperativeLevel.Nonexclusive | CooperativeLevel.Background);
62 | devices[i].joystick.Acquire();
63 | }
64 | }
65 | }
66 | }
67 |
68 | public ControllerDevice getController(int n)
69 | {
70 | return devices[n];
71 |
72 | }
73 |
74 | public void Swap(int i, int p)
75 | {
76 | if (true)//devices[i - 1] != null && devices[p - 1] != null)
77 | {
78 |
79 | ControllerDevice s = devices[i - 1];
80 | devices[i - 1] = devices[p - 1];
81 | devices[p - 1] = s;
82 | devices[p - 1].changeNumber(p);
83 |
84 | if (devices[i - 1] != null)
85 | devices[i - 1].changeNumber(i);
86 |
87 | }
88 | }
89 |
90 | public void setControllerEnable(int i, bool b)
91 | {
92 | devices[i].enabled = b;
93 | }
94 |
95 | private Int32 Scale(Int32 Value, Boolean Flip)
96 | {
97 | Value -= 0x80;
98 |
99 | if (Value == -128) Value = -127;
100 | if (Flip) Value *= -1;
101 |
102 | return (Int32)((float)Value * 258.00787401574803149606299212599f);
103 | }
104 |
105 | #endregion
106 |
107 | public override Boolean Open(int Instance = 0)
108 | {
109 | return base.Open(Instance);
110 | }
111 |
112 | public override Boolean Open(String DevicePath)
113 | {
114 | m_Path = DevicePath;
115 | m_WinUsbHandle = (IntPtr)INVALID_HANDLE_VALUE;
116 |
117 | if (GetDeviceHandle(m_Path))
118 | {
119 |
120 | m_IsActive = true;
121 |
122 | }
123 | return true;
124 | }
125 |
126 | public override bool Start()
127 | {
128 | Console.WriteLine(Process.GetCurrentProcess().MainWindowHandle);
129 | Open();
130 | detectControllers();
131 | running = true;
132 | for (int i = 0; i < 4; i++)
133 | {
134 | if (devices[i] != null && devices[i].enabled)
135 | {
136 | running = true;
137 | processingData[i] = new ContData();
138 | Console.WriteLine("Plug " + i);
139 | Plugin(i + 1);
140 | int t = i;
141 | workers[i] = new Thread(() =>
142 | { ProcessData(t); });
143 | workers[i].Start();
144 | }
145 | }
146 |
147 | return running;
148 | }
149 |
150 | public ControllerDevice[] detectControllers()
151 | {
152 | //for (int i = 0; i < 4; i++) //Remove disconnected controllers
153 | //{
154 | // if (devices[i] != null && !directInput.IsDeviceAttached(devices[i].joystick.Information.InstanceGuid))
155 | // {
156 | // Console.WriteLine(devices[i].joystick.Properties.InstanceName + " Removed");
157 | // devices[i] = null;
158 | // workers[i].Abort();
159 | // workers[i] = null;
160 | // Unplug(i + 1);
161 | // }
162 | //}
163 |
164 | foreach (var deviceInstance in directInput.GetDevices(DeviceClass.GameController, DeviceEnumerationFlags.AttachedOnly))
165 | {
166 | Joystick joystick = new Joystick(directInput, deviceInstance.InstanceGuid);
167 |
168 | if (joystick.Information.ProductGuid.ToString() == "028e045e-0000-0000-0000-504944564944") //If its an emulated controller skip it
169 | continue;
170 |
171 | if (joystick.Capabilities.ButtonCount < 1 && joystick.Capabilities.AxesCount < 1) //Skip if it doesn't have any button and axes
172 | continue;
173 |
174 | int spot = -1;
175 | for (int i = 0; i < 4; i++)
176 | {
177 | if (devices[i] == null)
178 | {
179 | if (spot == -1)
180 | {
181 | spot = i;
182 | Console.WriteLine("Open Spot " + i.ToString());
183 | }
184 | }
185 | else if (devices[i] != null && devices[i].joystick.Information.InstanceGuid == deviceInstance.InstanceGuid) //If the device is already initialized skip it
186 | {
187 | Console.WriteLine("Controller Already Acquired " + i.ToString() + " " + deviceInstance.InstanceName);
188 | spot = -1;
189 | break;
190 | }
191 | }
192 |
193 | if (spot == -1)
194 | continue;
195 |
196 | if (isExclusive)
197 | {
198 | joystick.SetCooperativeLevel(handle, CooperativeLevel.Exclusive | CooperativeLevel.Background);
199 | }
200 | else
201 | {
202 | joystick.SetCooperativeLevel(handle, CooperativeLevel.Nonexclusive | CooperativeLevel.Background);
203 | }
204 | joystick.Properties.BufferSize = 128;
205 | joystick.Acquire();
206 |
207 | devices[spot] = new ControllerDevice(joystick, spot + 1);
208 | if (IsActive)
209 | {
210 | processingData[spot] = new ContData();
211 | Console.WriteLine("Plug " + spot);
212 | Plugin(spot + 1);
213 | int t = spot;
214 | workers[spot] = new Thread(() =>
215 | { ProcessData(t); });
216 | workers[spot].Start();
217 | }
218 | }
219 | return devices;
220 | }
221 |
222 | public override bool Stop()
223 | {
224 | if (running)
225 | {
226 | running = false;
227 | for (int i = 0; i < 4; i++)
228 | {
229 | if (devices[i] != null && devices[i].enabled)
230 | {
231 | Console.WriteLine(i);
232 | workers[i].Abort();
233 | workers[i] = null;
234 | Unplug(i + 1);
235 | }
236 | }
237 |
238 | }
239 | return base.Stop();
240 | }
241 |
242 | public Boolean Plugin(Int32 Serial)
243 | {
244 | if (IsActive)
245 | {
246 | Int32 Transfered = 0;
247 | Byte[] Buffer = new Byte[16];
248 |
249 | Buffer[0] = 0x10;
250 | Buffer[1] = 0x00;
251 | Buffer[2] = 0x00;
252 | Buffer[3] = 0x00;
253 |
254 | Buffer[4] = (Byte)((Serial >> 0) & 0xFF);
255 | Buffer[5] = (Byte)((Serial >> 8) & 0xFF);
256 | Buffer[6] = (Byte)((Serial >> 16) & 0xFF);
257 | Buffer[7] = (Byte)((Serial >> 24) & 0xFF);
258 |
259 | return DeviceIoControl(m_FileHandle, 0x2A4000, Buffer, Buffer.Length, null, 0, ref Transfered, IntPtr.Zero);
260 | }
261 |
262 | return false;
263 | }
264 |
265 | public Boolean Unplug(Int32 Serial)
266 | {
267 | if (IsActive)
268 | {
269 | Int32 Transfered = 0;
270 | Byte[] Buffer = new Byte[16];
271 |
272 | Buffer[0] = 0x10;
273 | Buffer[1] = 0x00;
274 | Buffer[2] = 0x00;
275 | Buffer[3] = 0x00;
276 |
277 | Buffer[4] = (Byte)((Serial >> 0) & 0xFF);
278 | Buffer[5] = (Byte)((Serial >> 8) & 0xFF);
279 | Buffer[6] = (Byte)((Serial >> 16) & 0xFF);
280 | Buffer[7] = (Byte)((Serial >> 24) & 0xFF);
281 |
282 | return DeviceIoControl(m_FileHandle, 0x2A4004, Buffer, Buffer.Length, null, 0, ref Transfered, IntPtr.Zero);
283 | }
284 |
285 | return false;
286 | }
287 |
288 | private void ProcessData(int n)
289 | {
290 | while (IsActive)
291 | {
292 | lock (ds4locks[n])
293 | {
294 | if (devices[n] == null)
295 | {
296 | //Console.WriteLine("die" + n.ToString());
297 | //continue;
298 | }
299 | byte[] data = devices[n].getoutput();
300 | if (data != null && devices[n].enabled)
301 | {
302 |
303 | data[0] = (byte)n;
304 | Parse(data, processingData[n].parsedData);
305 | Report(processingData[n].parsedData, processingData[n].output);
306 | }
307 | Thread.Sleep(1);
308 | }
309 | }
310 | }
311 |
312 | public Boolean Report(Byte[] Input, Byte[] Output)
313 | {
314 | if (IsActive)
315 | {
316 | Int32 Transfered = 0;
317 |
318 |
319 | bool result = DeviceIoControl(m_FileHandle, 0x2A400C, Input, Input.Length, Output, Output.Length, ref Transfered, IntPtr.Zero) && Transfered > 0;
320 | int deviceInd = Input[4] - 1;
321 | return result;
322 |
323 | }
324 | return false;
325 | }
326 |
327 | public void Parse(Byte[] Input, Byte[] Output)
328 | {
329 | Byte Serial = (Byte)(Input[0] + 1);
330 |
331 | for (Int32 Index = 0; Index < 28; Index++) Output[Index] = 0x00;
332 |
333 | Output[0] = 0x1C;
334 | Output[4] = (Byte)(Input[0] + 1);
335 | Output[9] = 0x14;
336 |
337 | if (true)//Input[1] == 0x02) // Pad is active
338 | {
339 |
340 | UInt32 Buttons = (UInt32)((Input[10] << 0) | (Input[11] << 8) | (Input[12] << 16) | (Input[13] << 24));
341 |
342 | if ((Buttons & (0x1 << 0)) > 0) Output[10] |= (Byte)(1 << 5); // Back
343 | if ((Buttons & (0x1 << 1)) > 0) Output[10] |= (Byte)(1 << 6); // Left Thumb
344 | if ((Buttons & (0x1 << 2)) > 0) Output[10] |= (Byte)(1 << 7); // Right Thumb
345 | if ((Buttons & (0x1 << 3)) > 0) Output[10] |= (Byte)(1 << 4); // Start
346 |
347 | if ((Buttons & (0x1 << 4)) > 0) Output[10] |= (Byte)(1 << 0); // Up
348 | if ((Buttons & (0x1 << 5)) > 0) Output[10] |= (Byte)(1 << 3); // Down
349 | if ((Buttons & (0x1 << 6)) > 0) Output[10] |= (Byte)(1 << 1); // Right
350 | if ((Buttons & (0x1 << 7)) > 0) Output[10] |= (Byte)(1 << 2); // Left
351 |
352 | if ((Buttons & (0x1 << 10)) > 0) Output[11] |= (Byte)(1 << 0); // Left Shoulder
353 | if ((Buttons & (0x1 << 11)) > 0) Output[11] |= (Byte)(1 << 1); // Right Shoulder
354 |
355 | if ((Buttons & (0x1 << 12)) > 0) Output[11] |= (Byte)(1 << 7); // Y
356 | if ((Buttons & (0x1 << 13)) > 0) Output[11] |= (Byte)(1 << 5); // B
357 | if ((Buttons & (0x1 << 14)) > 0) Output[11] |= (Byte)(1 << 4); // A
358 | if ((Buttons & (0x1 << 15)) > 0) Output[11] |= (Byte)(1 << 6); // X
359 |
360 | if ((Buttons & (0x1 << 16)) > 16) Output[11] |= (Byte)(1 << 2); // Guide
361 |
362 | Output[12] = Input[26]; // Left Trigger
363 | Output[13] = Input[27]; // Right Trigger
364 |
365 | Int32 ThumbLX = Scale(Input[14], false);
366 | Int32 ThumbLY = -Scale(Input[15], false);
367 | Int32 ThumbRX = Scale(Input[16], false);
368 | Int32 ThumbRY = -Scale(Input[17], false);
369 |
370 | Output[14] = (Byte)((ThumbLX >> 0) & 0xFF); // LX
371 | Output[15] = (Byte)((ThumbLX >> 8) & 0xFF);
372 |
373 | Output[16] = (Byte)((ThumbLY >> 0) & 0xFF); // LY
374 | Output[17] = (Byte)((ThumbLY >> 8) & 0xFF);
375 |
376 | Output[18] = (Byte)((ThumbRX >> 0) & 0xFF); // RX
377 | Output[19] = (Byte)((ThumbRX >> 8) & 0xFF);
378 |
379 | Output[20] = (Byte)((ThumbRY >> 0) & 0xFF); // RY
380 | Output[21] = (Byte)((ThumbRY >> 8) & 0xFF);
381 | }
382 | }
383 |
384 | }
385 | }
386 |
--------------------------------------------------------------------------------
/XOutput/ControllerOptions.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace XOutput
2 | {
3 | partial class ControllerOptions
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(XOut));
32 | this.labelA = new System.Windows.Forms.Label();
33 | this.labelB = new System.Windows.Forms.Label();
34 | this.labelX = new System.Windows.Forms.Label();
35 | this.labelY = new System.Windows.Forms.Label();
36 | this.labelUp = new System.Windows.Forms.Label();
37 | this.labelDown = new System.Windows.Forms.Label();
38 | this.labelLeft = new System.Windows.Forms.Label();
39 | this.labelRight = new System.Windows.Forms.Label();
40 | this.dropRight = new XOutput.MultiLevelComboBox();
41 | this.dropLeft = new XOutput.MultiLevelComboBox();
42 | this.dropDown = new XOutput.MultiLevelComboBox();
43 | this.dropUp = new XOutput.MultiLevelComboBox();
44 | this.dropY = new XOutput.MultiLevelComboBox();
45 | this.dropX = new XOutput.MultiLevelComboBox();
46 | this.dropB = new XOutput.MultiLevelComboBox();
47 | this.dropA = new XOutput.MultiLevelComboBox();
48 | this.dropRT = new XOutput.MultiLevelComboBox();
49 | this.dropLT = new XOutput.MultiLevelComboBox();
50 | this.dropRB = new XOutput.MultiLevelComboBox();
51 | this.dropLB = new XOutput.MultiLevelComboBox();
52 | this.dropBack = new XOutput.MultiLevelComboBox();
53 | this.dropStart = new XOutput.MultiLevelComboBox();
54 | this.dropHome = new XOutput.MultiLevelComboBox();
55 | this.labelRT = new System.Windows.Forms.Label();
56 | this.labelLT = new System.Windows.Forms.Label();
57 | this.labelRB = new System.Windows.Forms.Label();
58 | this.labelLB = new System.Windows.Forms.Label();
59 | this.labelBack = new System.Windows.Forms.Label();
60 | this.labelStart = new System.Windows.Forms.Label();
61 | this.labelHome = new System.Windows.Forms.Label();
62 | this.dropRA = new XOutput.MultiLevelComboBox();
63 | this.dropLA = new XOutput.MultiLevelComboBox();
64 | this.dropRX = new XOutput.MultiLevelComboBox();
65 | this.dropRY = new XOutput.MultiLevelComboBox();
66 | this.dropLX = new XOutput.MultiLevelComboBox();
67 | this.dropLY = new XOutput.MultiLevelComboBox();
68 | this.labelRA = new System.Windows.Forms.Label();
69 | this.labelLA = new System.Windows.Forms.Label();
70 | this.labelLX = new System.Windows.Forms.Label();
71 | this.labelRX = new System.Windows.Forms.Label();
72 | this.labelLY = new System.Windows.Forms.Label();
73 | this.labelRY = new System.Windows.Forms.Label();
74 | this.SuspendLayout();
75 | //
76 | // labelA
77 | //
78 | this.labelA.AutoSize = true;
79 | this.labelA.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
80 | this.labelA.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
81 | this.labelA.Location = new System.Drawing.Point(609, 290);
82 | this.labelA.Name = "labelA";
83 | this.labelA.Size = new System.Drawing.Size(20, 20);
84 | this.labelA.TabIndex = 0;
85 | this.labelA.Text = "A";
86 | //
87 | // labelB
88 | //
89 | this.labelB.AutoSize = true;
90 | this.labelB.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
91 | this.labelB.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
92 | this.labelB.Location = new System.Drawing.Point(609, 340);
93 | this.labelB.Name = "labelB";
94 | this.labelB.Size = new System.Drawing.Size(20, 20);
95 | this.labelB.TabIndex = 7;
96 | this.labelB.Text = "B";
97 | //
98 | // labelX
99 | //
100 | this.labelX.AutoSize = true;
101 | this.labelX.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
102 | this.labelX.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
103 | this.labelX.Location = new System.Drawing.Point(609, 390);
104 | this.labelX.Name = "labelX";
105 | this.labelX.Size = new System.Drawing.Size(20, 20);
106 | this.labelX.TabIndex = 8;
107 | this.labelX.Text = "X";
108 | //
109 | // labelY
110 | //
111 | this.labelY.AutoSize = true;
112 | this.labelY.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
113 | this.labelY.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
114 | this.labelY.Location = new System.Drawing.Point(609, 440);
115 | this.labelY.Name = "labelY";
116 | this.labelY.Size = new System.Drawing.Size(20, 20);
117 | this.labelY.TabIndex = 9;
118 | this.labelY.Text = "Y";
119 | //
120 | // labelUp
121 | //
122 | this.labelUp.AutoSize = true;
123 | this.labelUp.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
124 | this.labelUp.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
125 | this.labelUp.Location = new System.Drawing.Point(167, 290);
126 | this.labelUp.Name = "labelUp";
127 | this.labelUp.Size = new System.Drawing.Size(30, 20);
128 | this.labelUp.TabIndex = 14;
129 | this.labelUp.Text = "Up";
130 | //
131 | // labelDown
132 | //
133 | this.labelDown.AutoSize = true;
134 | this.labelDown.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
135 | this.labelDown.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
136 | this.labelDown.Location = new System.Drawing.Point(167, 340);
137 | this.labelDown.Name = "labelDown";
138 | this.labelDown.Size = new System.Drawing.Size(50, 20);
139 | this.labelDown.TabIndex = 15;
140 | this.labelDown.Text = "Down";
141 | //
142 | // labelLeft
143 | //
144 | this.labelLeft.AutoSize = true;
145 | this.labelLeft.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
146 | this.labelLeft.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
147 | this.labelLeft.Location = new System.Drawing.Point(167, 390);
148 | this.labelLeft.Name = "labelLeft";
149 | this.labelLeft.Size = new System.Drawing.Size(37, 20);
150 | this.labelLeft.TabIndex = 16;
151 | this.labelLeft.Text = "Left";
152 | //
153 | // labelRight
154 | //
155 | this.labelRight.AutoSize = true;
156 | this.labelRight.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
157 | this.labelRight.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
158 | this.labelRight.Location = new System.Drawing.Point(167, 440);
159 | this.labelRight.Name = "labelRight";
160 | this.labelRight.Size = new System.Drawing.Size(47, 20);
161 | this.labelRight.TabIndex = 17;
162 | this.labelRight.Text = "Right";
163 | //
164 | // dropRight
165 | //
166 | this.dropRight.FormattingEnabled = true;
167 | this.dropRight.ImeMode = System.Windows.Forms.ImeMode.NoControl;
168 | this.dropRight.Items.AddRange(new object[] {
169 | ""});
170 | this.dropRight.Location = new System.Drawing.Point(40, 440);
171 | this.dropRight.Name = "dropRight";
172 | this.dropRight.Size = new System.Drawing.Size(121, 21);
173 | this.dropRight.TabIndex = 13;
174 | //
175 | // dropLeft
176 | //
177 | this.dropLeft.FormattingEnabled = true;
178 | this.dropLeft.ImeMode = System.Windows.Forms.ImeMode.NoControl;
179 | this.dropLeft.Items.AddRange(new object[] {
180 | ""});
181 | this.dropLeft.Location = new System.Drawing.Point(40, 390);
182 | this.dropLeft.Name = "dropLeft";
183 | this.dropLeft.Size = new System.Drawing.Size(121, 21);
184 | this.dropLeft.TabIndex = 12;
185 | //
186 | // dropDown
187 | //
188 | this.dropDown.FormattingEnabled = true;
189 | this.dropDown.ImeMode = System.Windows.Forms.ImeMode.NoControl;
190 | this.dropDown.Items.AddRange(new object[] {
191 | ""});
192 | this.dropDown.Location = new System.Drawing.Point(40, 340);
193 | this.dropDown.Name = "dropDown";
194 | this.dropDown.Size = new System.Drawing.Size(121, 21);
195 | this.dropDown.TabIndex = 11;
196 | //
197 | // dropUp
198 | //
199 | this.dropUp.FormattingEnabled = true;
200 | this.dropUp.ImeMode = System.Windows.Forms.ImeMode.NoControl;
201 | this.dropUp.Items.AddRange(new object[] {
202 | ""});
203 | this.dropUp.Location = new System.Drawing.Point(40, 290);
204 | this.dropUp.Name = "dropUp";
205 | this.dropUp.Size = new System.Drawing.Size(121, 21);
206 | this.dropUp.TabIndex = 10;
207 | //
208 | // dropY
209 | //
210 | this.dropY.FormattingEnabled = true;
211 | this.dropY.ImeMode = System.Windows.Forms.ImeMode.NoControl;
212 | this.dropY.Items.AddRange(new object[] {
213 | ""});
214 | this.dropY.Location = new System.Drawing.Point(482, 440);
215 | this.dropY.Name = "dropY";
216 | this.dropY.Size = new System.Drawing.Size(121, 21);
217 | this.dropY.TabIndex = 6;
218 | //
219 | // dropX
220 | //
221 | this.dropX.FormattingEnabled = true;
222 | this.dropX.ImeMode = System.Windows.Forms.ImeMode.NoControl;
223 | this.dropX.Items.AddRange(new object[] {
224 | ""});
225 | this.dropX.Location = new System.Drawing.Point(482, 390);
226 | this.dropX.Name = "dropX";
227 | this.dropX.Size = new System.Drawing.Size(121, 21);
228 | this.dropX.TabIndex = 5;
229 | //
230 | // dropB
231 | //
232 | this.dropB.FormattingEnabled = true;
233 | this.dropB.ImeMode = System.Windows.Forms.ImeMode.NoControl;
234 | this.dropB.Items.AddRange(new object[] {
235 | ""});
236 | this.dropB.Location = new System.Drawing.Point(482, 340);
237 | this.dropB.Name = "dropB";
238 | this.dropB.Size = new System.Drawing.Size(121, 21);
239 | this.dropB.TabIndex = 4;
240 | //
241 | // dropA
242 | //
243 | this.dropA.FormattingEnabled = true;
244 | this.dropA.ImeMode = System.Windows.Forms.ImeMode.NoControl;
245 | this.dropA.Items.AddRange(new object[] {
246 | ""});
247 | this.dropA.Location = new System.Drawing.Point(482, 290);
248 | this.dropA.Name = "dropA";
249 | this.dropA.Size = new System.Drawing.Size(121, 21);
250 | this.dropA.TabIndex = 3;
251 | //
252 | // dropRT
253 | //
254 | this.dropRT.FormattingEnabled = true;
255 | this.dropRT.ImeMode = System.Windows.Forms.ImeMode.NoControl;
256 | this.dropRT.Items.AddRange(new object[] {
257 | ""});
258 | this.dropRT.Location = new System.Drawing.Point(482, 40);
259 | this.dropRT.Name = "dropRT";
260 | this.dropRT.Size = new System.Drawing.Size(121, 21);
261 | this.dropRT.TabIndex = 18;
262 | //
263 | // dropLT
264 | //
265 | this.dropLT.FormattingEnabled = true;
266 | this.dropLT.ImeMode = System.Windows.Forms.ImeMode.NoControl;
267 | this.dropLT.Items.AddRange(new object[] {
268 | ""});
269 | this.dropLT.Location = new System.Drawing.Point(40, 40);
270 | this.dropLT.Name = "dropLT";
271 | this.dropLT.Size = new System.Drawing.Size(121, 21);
272 | this.dropLT.TabIndex = 19;
273 | //
274 | // dropRB
275 | //
276 | this.dropRB.FormattingEnabled = true;
277 | this.dropRB.ImeMode = System.Windows.Forms.ImeMode.NoControl;
278 | this.dropRB.Items.AddRange(new object[] {
279 | ""});
280 | this.dropRB.Location = new System.Drawing.Point(482, 90);
281 | this.dropRB.Name = "dropRB";
282 | this.dropRB.Size = new System.Drawing.Size(121, 21);
283 | this.dropRB.TabIndex = 20;
284 | //
285 | // dropLB
286 | //
287 | this.dropLB.FormattingEnabled = true;
288 | this.dropLB.ImeMode = System.Windows.Forms.ImeMode.NoControl;
289 | this.dropLB.Items.AddRange(new object[] {
290 | ""});
291 | this.dropLB.Location = new System.Drawing.Point(40, 90);
292 | this.dropLB.Name = "dropLB";
293 | this.dropLB.Size = new System.Drawing.Size(121, 21);
294 | this.dropLB.TabIndex = 21;
295 | //
296 | // dropBack
297 | //
298 | this.dropBack.FormattingEnabled = true;
299 | this.dropBack.ImeMode = System.Windows.Forms.ImeMode.NoControl;
300 | this.dropBack.Items.AddRange(new object[] {
301 | ""});
302 | this.dropBack.Location = new System.Drawing.Point(40, 490);
303 | this.dropBack.Name = "dropBack";
304 | this.dropBack.Size = new System.Drawing.Size(121, 21);
305 | this.dropBack.TabIndex = 22;
306 | //
307 | // dropStart
308 | //
309 | this.dropStart.FormattingEnabled = true;
310 | this.dropStart.ImeMode = System.Windows.Forms.ImeMode.NoControl;
311 | this.dropStart.Items.AddRange(new object[] {
312 | ""});
313 | this.dropStart.Location = new System.Drawing.Point(482, 490);
314 | this.dropStart.Name = "dropStart";
315 | this.dropStart.Size = new System.Drawing.Size(121, 21);
316 | this.dropStart.TabIndex = 23;
317 | //
318 | // dropHome
319 | //
320 | this.dropHome.FormattingEnabled = true;
321 | this.dropHome.ImeMode = System.Windows.Forms.ImeMode.NoControl;
322 | this.dropHome.Items.AddRange(new object[] {
323 | ""});
324 | this.dropHome.Location = new System.Drawing.Point(264, 490);
325 | this.dropHome.Name = "dropHome";
326 | this.dropHome.Size = new System.Drawing.Size(121, 21);
327 | this.dropHome.TabIndex = 24;
328 | //
329 | // labelRT
330 | //
331 | this.labelRT.AutoSize = true;
332 | this.labelRT.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
333 | this.labelRT.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
334 | this.labelRT.Location = new System.Drawing.Point(609, 40);
335 | this.labelRT.Name = "labelRT";
336 | this.labelRT.Size = new System.Drawing.Size(100, 20);
337 | this.labelRT.TabIndex = 25;
338 | this.labelRT.Text = "Right Trigger";
339 | //
340 | // labelLT
341 | //
342 | this.labelLT.AutoSize = true;
343 | this.labelLT.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
344 | this.labelLT.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
345 | this.labelLT.Location = new System.Drawing.Point(167, 40);
346 | this.labelLT.Name = "labelLT";
347 | this.labelLT.Size = new System.Drawing.Size(90, 20);
348 | this.labelLT.TabIndex = 26;
349 | this.labelLT.Text = "Left Trigger";
350 | //
351 | // labelRB
352 | //
353 | this.labelRB.AutoSize = true;
354 | this.labelRB.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
355 | this.labelRB.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
356 | this.labelRB.Location = new System.Drawing.Point(609, 90);
357 | this.labelRB.Name = "labelRB";
358 | this.labelRB.Size = new System.Drawing.Size(107, 20);
359 | this.labelRB.TabIndex = 27;
360 | this.labelRB.Text = "Right Bumper";
361 | //
362 | // labelLB
363 | //
364 | this.labelLB.AutoSize = true;
365 | this.labelLB.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
366 | this.labelLB.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
367 | this.labelLB.Location = new System.Drawing.Point(167, 90);
368 | this.labelLB.Name = "labelLB";
369 | this.labelLB.Size = new System.Drawing.Size(97, 20);
370 | this.labelLB.TabIndex = 28;
371 | this.labelLB.Text = "Left Bumper";
372 | //
373 | // labelBack
374 | //
375 | this.labelBack.AutoSize = true;
376 | this.labelBack.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
377 | this.labelBack.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
378 | this.labelBack.Location = new System.Drawing.Point(167, 490);
379 | this.labelBack.Name = "labelBack";
380 | this.labelBack.Size = new System.Drawing.Size(45, 20);
381 | this.labelBack.TabIndex = 29;
382 | this.labelBack.Text = "Back";
383 | //
384 | // labelStart
385 | //
386 | this.labelStart.AutoSize = true;
387 | this.labelStart.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
388 | this.labelStart.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
389 | this.labelStart.Location = new System.Drawing.Point(609, 490);
390 | this.labelStart.Name = "labelStart";
391 | this.labelStart.Size = new System.Drawing.Size(44, 20);
392 | this.labelStart.TabIndex = 30;
393 | this.labelStart.Text = "Start";
394 | //
395 | // labelHome
396 | //
397 | this.labelHome.AutoSize = true;
398 | this.labelHome.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
399 | this.labelHome.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
400 | this.labelHome.Location = new System.Drawing.Point(391, 490);
401 | this.labelHome.Name = "labelHome";
402 | this.labelHome.Size = new System.Drawing.Size(52, 20);
403 | this.labelHome.TabIndex = 31;
404 | this.labelHome.Text = "Home";
405 | //
406 | // dropRA
407 | //
408 | this.dropRA.FormattingEnabled = true;
409 | this.dropRA.ImeMode = System.Windows.Forms.ImeMode.NoControl;
410 | this.dropRA.Items.AddRange(new object[] {
411 | ""});
412 | this.dropRA.Location = new System.Drawing.Point(482, 140);
413 | this.dropRA.Name = "dropRA";
414 | this.dropRA.Size = new System.Drawing.Size(121, 21);
415 | this.dropRA.TabIndex = 32;
416 | //
417 | // dropLA
418 | //
419 | this.dropLA.FormattingEnabled = true;
420 | this.dropLA.ImeMode = System.Windows.Forms.ImeMode.NoControl;
421 | this.dropLA.Items.AddRange(new object[] {
422 | ""});
423 | this.dropLA.Location = new System.Drawing.Point(40, 140);
424 | this.dropLA.Name = "dropLA";
425 | this.dropLA.Size = new System.Drawing.Size(121, 21);
426 | this.dropLA.TabIndex = 33;
427 | //
428 | // dropRX
429 | //
430 | this.dropRX.FormattingEnabled = true;
431 | this.dropRX.ImeMode = System.Windows.Forms.ImeMode.NoControl;
432 | this.dropRX.Items.AddRange(new object[] {
433 | ""});
434 | this.dropRX.Location = new System.Drawing.Point(482, 190);
435 | this.dropRX.Name = "dropRX";
436 | this.dropRX.Size = new System.Drawing.Size(121, 21);
437 | this.dropRX.TabIndex = 34;
438 | //
439 | // dropRY
440 | //
441 | this.dropRY.FormattingEnabled = true;
442 | this.dropRY.ImeMode = System.Windows.Forms.ImeMode.NoControl;
443 | this.dropRY.Items.AddRange(new object[] {
444 | ""});
445 | this.dropRY.Location = new System.Drawing.Point(482, 240);
446 | this.dropRY.Name = "dropRY";
447 | this.dropRY.Size = new System.Drawing.Size(121, 21);
448 | this.dropRY.TabIndex = 35;
449 | //
450 | // dropLX
451 | //
452 | this.dropLX.FormattingEnabled = true;
453 | this.dropLX.ImeMode = System.Windows.Forms.ImeMode.NoControl;
454 | this.dropLX.Items.AddRange(new object[] {
455 | ""});
456 | this.dropLX.Location = new System.Drawing.Point(40, 190);
457 | this.dropLX.Name = "dropLX";
458 | this.dropLX.Size = new System.Drawing.Size(121, 21);
459 | this.dropLX.TabIndex = 36;
460 | //
461 | // dropLY
462 | //
463 | this.dropLY.FormattingEnabled = true;
464 | this.dropLY.ImeMode = System.Windows.Forms.ImeMode.NoControl;
465 | this.dropLY.Items.AddRange(new object[] {
466 | ""});
467 | this.dropLY.Location = new System.Drawing.Point(40, 240);
468 | this.dropLY.Name = "dropLY";
469 | this.dropLY.Size = new System.Drawing.Size(121, 21);
470 | this.dropLY.TabIndex = 37;
471 | //
472 | // labelRA
473 | //
474 | this.labelRA.AutoSize = true;
475 | this.labelRA.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
476 | this.labelRA.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
477 | this.labelRA.Location = new System.Drawing.Point(609, 140);
478 | this.labelRA.Name = "labelRA";
479 | this.labelRA.Size = new System.Drawing.Size(153, 20);
480 | this.labelRA.TabIndex = 38;
481 | this.labelRA.Text = "Right Analog Button";
482 | //
483 | // labelLA
484 | //
485 | this.labelLA.AutoSize = true;
486 | this.labelLA.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
487 | this.labelLA.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
488 | this.labelLA.Location = new System.Drawing.Point(167, 140);
489 | this.labelLA.Name = "labelLA";
490 | this.labelLA.Size = new System.Drawing.Size(143, 20);
491 | this.labelLA.TabIndex = 39;
492 | this.labelLA.Text = "Left Analog Button";
493 | //
494 | // labelLX
495 | //
496 | this.labelLX.AutoSize = true;
497 | this.labelLX.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
498 | this.labelLX.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
499 | this.labelLX.Location = new System.Drawing.Point(167, 190);
500 | this.labelLX.Name = "labelLX";
501 | this.labelLX.Size = new System.Drawing.Size(106, 20);
502 | this.labelLX.TabIndex = 40;
503 | this.labelLX.Text = "Left Analog X";
504 | //
505 | // labelRX
506 | //
507 | this.labelRX.AutoSize = true;
508 | this.labelRX.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
509 | this.labelRX.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
510 | this.labelRX.Location = new System.Drawing.Point(609, 190);
511 | this.labelRX.Name = "labelRX";
512 | this.labelRX.Size = new System.Drawing.Size(116, 20);
513 | this.labelRX.TabIndex = 41;
514 | this.labelRX.Text = "Right Analog X";
515 | //
516 | // labelLY
517 | //
518 | this.labelLY.AutoSize = true;
519 | this.labelLY.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
520 | this.labelLY.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
521 | this.labelLY.Location = new System.Drawing.Point(167, 240);
522 | this.labelLY.Name = "labelLY";
523 | this.labelLY.Size = new System.Drawing.Size(106, 20);
524 | this.labelLY.TabIndex = 42;
525 | this.labelLY.Text = "Left Analog Y";
526 | //
527 | // labelRY
528 | //
529 | this.labelRY.AutoSize = true;
530 | this.labelRY.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
531 | this.labelRY.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
532 | this.labelRY.Location = new System.Drawing.Point(609, 240);
533 | this.labelRY.Name = "labelRY";
534 | this.labelRY.Size = new System.Drawing.Size(116, 20);
535 | this.labelRY.TabIndex = 43;
536 | this.labelRY.Text = "Right Analog Y";
537 | //
538 | // ControllerOptions
539 | //
540 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
541 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
542 | this.ClientSize = new System.Drawing.Size(814, 561);
543 | this.Controls.Add(this.labelRY);
544 | this.Controls.Add(this.labelLY);
545 | this.Controls.Add(this.labelRX);
546 | this.Controls.Add(this.labelLX);
547 | this.Controls.Add(this.labelLA);
548 | this.Controls.Add(this.labelRA);
549 | this.Controls.Add(this.labelHome);
550 | this.Controls.Add(this.labelStart);
551 | this.Controls.Add(this.labelBack);
552 | this.Controls.Add(this.labelLB);
553 | this.Controls.Add(this.labelRB);
554 | this.Controls.Add(this.labelLT);
555 | this.Controls.Add(this.labelRT);
556 | this.Controls.Add(this.labelRight);
557 | this.Controls.Add(this.labelLeft);
558 | this.Controls.Add(this.labelDown);
559 | this.Controls.Add(this.labelUp);
560 | this.Controls.Add(this.labelY);
561 | this.Controls.Add(this.labelX);
562 | this.Controls.Add(this.labelB);
563 | this.Controls.Add(this.labelA);
564 | this.Controls.Add(this.dropA);
565 | this.Controls.Add(this.dropB);
566 | this.Controls.Add(this.dropX);
567 | this.Controls.Add(this.dropY);
568 | this.Controls.Add(this.dropUp);
569 | this.Controls.Add(this.dropDown);
570 | this.Controls.Add(this.dropLeft);
571 | this.Controls.Add(this.dropRight);
572 | this.Controls.Add(this.dropLT);
573 | this.Controls.Add(this.dropRT);
574 | this.Controls.Add(this.dropLB);
575 | this.Controls.Add(this.dropRB);
576 | this.Controls.Add(this.dropLA);
577 | this.Controls.Add(this.dropRA);
578 | this.Controls.Add(this.dropHome);
579 | this.Controls.Add(this.dropStart);
580 | this.Controls.Add(this.dropBack);
581 | this.Controls.Add(this.dropLY);
582 | this.Controls.Add(this.dropLX);
583 | this.Controls.Add(this.dropRY);
584 | this.Controls.Add(this.dropRX);
585 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
586 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
587 | this.MaximizeBox = false;
588 | this.MinimizeBox = false;
589 | this.Name = "ControllerOptions";
590 | this.Text = "Controller Options";
591 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.onClose);
592 | this.ResumeLayout(false);
593 | this.PerformLayout();
594 |
595 | }
596 |
597 | #endregion
598 |
599 | private System.Windows.Forms.Label labelA;
600 | private MultiLevelComboBox dropA;
601 | private MultiLevelComboBox dropB;
602 | private MultiLevelComboBox dropX;
603 | private MultiLevelComboBox dropY;
604 | private System.Windows.Forms.Label labelB;
605 | private System.Windows.Forms.Label labelX;
606 | private System.Windows.Forms.Label labelY;
607 | private MultiLevelComboBox dropUp;
608 | private MultiLevelComboBox dropDown;
609 | private MultiLevelComboBox dropLeft;
610 | private MultiLevelComboBox dropRight;
611 | private System.Windows.Forms.Label labelUp;
612 | private System.Windows.Forms.Label labelDown;
613 | private System.Windows.Forms.Label labelLeft;
614 | private System.Windows.Forms.Label labelRight;
615 | private MultiLevelComboBox dropRT;
616 | private MultiLevelComboBox dropLT;
617 | private MultiLevelComboBox dropRB;
618 | private MultiLevelComboBox dropLB;
619 | private MultiLevelComboBox dropBack;
620 | private MultiLevelComboBox dropStart;
621 | private MultiLevelComboBox dropHome;
622 | private System.Windows.Forms.Label labelRT;
623 | private System.Windows.Forms.Label labelLT;
624 | private System.Windows.Forms.Label labelRB;
625 | private System.Windows.Forms.Label labelLB;
626 | private System.Windows.Forms.Label labelBack;
627 | private System.Windows.Forms.Label labelStart;
628 | private System.Windows.Forms.Label labelHome;
629 | private MultiLevelComboBox dropRA;
630 | private MultiLevelComboBox dropLA;
631 | private MultiLevelComboBox dropRX;
632 | private MultiLevelComboBox dropRY;
633 | private MultiLevelComboBox dropLX;
634 | private MultiLevelComboBox dropLY;
635 | private System.Windows.Forms.Label labelRA;
636 | private System.Windows.Forms.Label labelLA;
637 | private System.Windows.Forms.Label labelLX;
638 | private System.Windows.Forms.Label labelRX;
639 | private System.Windows.Forms.Label labelLY;
640 | private System.Windows.Forms.Label labelRY;
641 |
642 | }
643 | }
--------------------------------------------------------------------------------
/XOutput/ControllerOptions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Threading;
4 | using System.Windows.Forms;
5 |
6 | namespace XOutput
7 | {
8 | public partial class ControllerOptions : Form
9 | {
10 | ControllerDevice dev;
11 | private Thread detectThread;
12 | public ControllerOptions(ControllerDevice device)
13 | {
14 | InitializeComponent();
15 | dev = device;
16 | int ind = 0;
17 |
18 | foreach (MultiLevelComboBox m in this.Controls.OfType()) {
19 | //Tag structure: [Type, Number, Index]
20 | m.Items[0] = getBindingText(ind); //Change combobox text according to saved binding
21 | m.addOption("Disabled",
22 | tag: new byte[] { 255, 0, (byte)ind });
23 | m.addOption("Detect",
24 | tag: new byte[] { 254, 0, (byte)ind });
25 | ToolStripMenuItem axes = m.addMenu("Axes");
26 | ToolStripMenuItem buttons = m.addMenu("Buttons");
27 | ToolStripMenuItem dpads = m.addMenu("D-Pads");
28 | ToolStripMenuItem iaxes = m.addMenu("Inverted Axes", axes);
29 | ToolStripMenuItem haxes = m.addMenu("Half Axes", axes);
30 | ToolStripMenuItem ihaxes = m.addMenu("Inverted Half Axes", axes);
31 | for (int i = 1; i <= dev.joystick.Capabilities.ButtonCount; i++)
32 | {
33 | m.addOption("Button " + i.ToString(), buttons,
34 | new byte[] { 0, (byte)(i - 1), (byte)ind });
35 | }
36 | for (int i = 1; i <= dev.joystick.Capabilities.PovCount; i++)
37 | {
38 | m.addOption("D-Pad " + i.ToString() + " Up", dpads,
39 | new byte[] { 32, (byte)(i - 1), (byte)ind });
40 | m.addOption("D-Pad " + i.ToString() + " Down", dpads,
41 | new byte[] { 33, (byte)(i - 1), (byte)ind });
42 | m.addOption("D-Pad " + i.ToString() + " Left", dpads,
43 | new byte[] { 34, (byte)(i - 1), (byte)ind });
44 | m.addOption("D-Pad " + i.ToString() + " Right", dpads,
45 | new byte[] { 35, (byte)(i - 1), (byte)ind });
46 | }
47 | for (int i = 1; i <= dev.joystick.Capabilities.AxesCount; i++)
48 | {
49 | m.addOption("Axis " + i.ToString(), axes,
50 | new byte[] { 16, (byte)(i - 1), (byte)ind });
51 | m.addOption("IAxis " + i.ToString(), iaxes,
52 | new byte[] { 17, (byte)(i - 1), (byte)ind });
53 | m.addOption("HAxis" + i.ToString(), haxes,
54 | new byte[] { 18, (byte)(i - 1), (byte)ind });
55 | m.addOption("IHAxis" + i.ToString(), ihaxes,
56 | new byte[] { 19, (byte)(i - 1), (byte)ind });
57 | }
58 | m.SelectionChangeCommitted += new System.EventHandler(SelectionChanged);
59 | ind++;
60 | }
61 | }
62 |
63 | private string getBindingText(int i)
64 | {
65 | if (dev.mapping[i * 2] == 255) {
66 | return "Disabled";
67 | }
68 | byte subType = (byte)(dev.mapping[i * 2] & 0x0F);
69 | byte type = (byte)((dev.mapping[i * 2] & 0xF0) >> 4);
70 | byte num = (byte)(dev.mapping[(i * 2) + 1] + 1);
71 | string[] typeString = new string[] { "Button {0}", "{1}Axis {0}", "D-Pad {0} {2}" };
72 | string[] axesString = new string[] { "", "I", "H", "IH" };
73 | string[] dpadString = new string[] { "Up", "Down", "Left", "Right" };
74 | return string.Format(typeString[type], num, axesString[subType], dpadString[subType]);
75 | }
76 |
77 | private void SelectionChanged(object sender, EventArgs e) {
78 | ToolStripMenuItem i = (ToolStripMenuItem)sender;
79 | byte[] b = (byte[])i.Tag;
80 | if (b[0] == 254) {
81 | //start thread
82 | return;
83 | }
84 | dev.mapping[b[2] * 2] = b[0];
85 | dev.mapping[(b[2] * 2) + 1] = b[1];
86 | dev.Save();
87 | }
88 |
89 | private void onClose(object sender, EventArgs e) {
90 | dev.Save();
91 | }
92 |
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/XOutput/Logger.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 |
4 |
5 | namespace XOutput {
6 | static class Logger {
7 | static private string fileName = @"XOutput.log";
8 |
9 | public static void Log(string s) {
10 | Console.WriteLine(s);
11 | if (File.Exists(fileName)) {
12 | string l = File.ReadAllText(fileName);
13 | l += "\r\n" + s;
14 | File.WriteAllText(fileName, l);
15 | } else {
16 | File.Create(fileName); // If the file doesn't exist create it
17 | }
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/XOutput/MultiLevelComboBox.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Drawing;
4 | using System.Windows.Forms;
5 |
6 | namespace XOutput
7 | {
8 | class MultiLevelComboBox : ComboBox {
9 | ContextMenuStrip menu;
10 |
11 | public new event EventHandler DropDown;
12 | public new event EventHandler DropDownClosed;
13 | public new event EventHandler SelectionChangeCommitted;
14 |
15 | private bool _DroppedDown;
16 |
17 | public MultiLevelComboBox()
18 | : base()
19 | {
20 | base.DropDownStyle = ComboBoxStyle.DropDownList;
21 | menu = new ContextMenuStrip();
22 | base.Items.Add("");
23 | base.SelectedItem = "";
24 | }
25 |
26 | public ToolStripMenuItem addMenu(string name, ToolStripMenuItem parent = null) {
27 | ToolStripMenuItem item = new ToolStripMenuItem();
28 | item.Text = name;
29 | if (parent != null) {
30 | parent.DropDownItems.Add(item);
31 | } else {
32 | menu.Items.Add(item);
33 | }
34 | return item;
35 | }
36 |
37 | public ToolStripMenuItem addOption(string name, ToolStripMenuItem parent = null, object tag = null) {
38 | ToolStripMenuItem item = new ToolStripMenuItem();
39 | item.Text = name;
40 | item.Tag = tag;
41 | item.Click += (sender, e) => selectValue(item);
42 | if (parent != null)
43 | {
44 | parent.DropDownItems.Add(item);
45 | }
46 | else
47 | {
48 | menu.Items.Add(item);
49 | }
50 | return parent;
51 | }
52 |
53 | private void selectValue(ToolStripMenuItem m) {
54 | Items[0] = m.Text;
55 | DroppedDown = false;
56 | if (SelectionChangeCommitted != null)
57 | SelectionChangeCommitted(m, EventArgs.Empty);
58 | }
59 |
60 | private void showDropDown() {
61 | menu.Show(this, new Point(0, Height));
62 | menu.AutoSize = false;
63 | menu.Width = Width;
64 | if (DropDown != null)
65 | DropDown(this, EventArgs.Empty);
66 | }
67 |
68 | private void hideDropDown() {
69 | menu.Hide();
70 | if (DropDownClosed != null)
71 | DropDownClosed(this, EventArgs.Empty);
72 | }
73 |
74 | protected override void WndProc(ref Message m)
75 | {
76 | switch (m.Msg)
77 | {
78 | case 0x87: //WM_GETDLGCODE
79 | break;//Block key down messages
80 | case 0x201: //WM_LBUTTONDOWN
81 | DroppedDown = !DroppedDown;
82 | break;
83 | case 0x203: //WM_LBUTTONDBLCLK
84 | DroppedDown = !DroppedDown;
85 | break;
86 | default:
87 | base.WndProc(ref m);
88 | break;
89 | }
90 | }
91 |
92 | public new bool DroppedDown {
93 | get { return _DroppedDown; }
94 | set { _DroppedDown = value;
95 | if (value) { showDropDown(); } else { hideDropDown(); }
96 | }
97 | }
98 |
99 | [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
100 | [Browsable(false), ReadOnly(true)]
101 | public new ComboBoxStyle DropDownStyle
102 | {
103 | get { return base.DropDownStyle; }
104 | set { }
105 | }
106 |
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/XOutput/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using System.Windows.Forms;
6 |
7 | namespace XOutput
8 | {
9 | static class Program
10 | {
11 | ///
12 | /// The main entry point for the application.
13 | ///
14 | [STAThread]
15 | static void Main()
16 | {
17 | Application.EnableVisualStyles();
18 | Application.SetCompatibleTextRenderingDefault(false);
19 | Application.Run(new XOut());
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/XOutput/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("XOutput")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Eric Barrett")]
12 | [assembly: AssemblyProduct("XOutput")]
13 | [assembly: AssemblyCopyright("Copyright © Eric Barrett 2014")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("e39d3ad7-5d65-44e9-b0c1-58c1dc2e5f5f")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("0.1.0.0")]
36 | [assembly: AssemblyFileVersion("0.1.0.0")]
37 |
--------------------------------------------------------------------------------
/XOutput/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.34014
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace XOutput.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("XOutput.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized resource of type System.Drawing.Bitmap.
65 | ///
66 | internal static System.Drawing.Bitmap arrow_Down {
67 | get {
68 | object obj = ResourceManager.GetObject("arrow_Down", resourceCulture);
69 | return ((System.Drawing.Bitmap)(obj));
70 | }
71 | }
72 |
73 | ///
74 | /// Looks up a localized resource of type System.Drawing.Bitmap.
75 | ///
76 | internal static System.Drawing.Bitmap arrow_Up {
77 | get {
78 | object obj = ResourceManager.GetObject("arrow_Up", resourceCulture);
79 | return ((System.Drawing.Bitmap)(obj));
80 | }
81 | }
82 |
83 | ///
84 | /// Looks up a localized resource of type System.Drawing.Bitmap.
85 | ///
86 | internal static System.Drawing.Bitmap gear {
87 | get {
88 | object obj = ResourceManager.GetObject("gear", resourceCulture);
89 | return ((System.Drawing.Bitmap)(obj));
90 | }
91 | }
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/XOutput/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 | ..\Resources\arrow_Down.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
123 |
124 |
125 | ..\Resources\arrow_Up.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
126 |
127 |
128 | ..\Resources\gear.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
129 |
130 |
--------------------------------------------------------------------------------
/XOutput/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.34014
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace XOutput.Properties
12 | {
13 |
14 |
15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
18 | {
19 |
20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
21 |
22 | public static Settings Default
23 | {
24 | get
25 | {
26 | return defaultInstance;
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/XOutput/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/XOutput/Resources/arrow_Down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mintos5/XOutput/c878b3c3b6c5e1714d300f630c4fb2cddc32374a/XOutput/Resources/arrow_Down.png
--------------------------------------------------------------------------------
/XOutput/Resources/arrow_Up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mintos5/XOutput/c878b3c3b6c5e1714d300f630c4fb2cddc32374a/XOutput/Resources/arrow_Up.png
--------------------------------------------------------------------------------
/XOutput/Resources/gear.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mintos5/XOutput/c878b3c3b6c5e1714d300f630c4fb2cddc32374a/XOutput/Resources/gear.png
--------------------------------------------------------------------------------
/XOutput/SaveManager.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 |
4 | namespace XOutput
5 | {
6 | static class SaveManager {
7 | static string[] properties = new string[] {"button_a", "button_b", "button_x", "button_y",
8 | "dpad_up", "dpad_down", "dpad_left", "dpad_right",
9 | "left_trigger", "right_trigger", "left_bumper", "right_bumper", "left_axebutton", "right_axebutton",
10 | "home", "start", "back", "left_y", "left_x", "right_y", "right_x"};
11 | static private string dirName = @"configs";
12 |
13 | private static byte[] parseLine(string line) { //This needs better error hadnling
14 | int i; //The index of the control in the map array
15 | byte type = 255, subType = 255, num = 255;
16 | for (i = 0; i < 21; i++) { //find which button this is for
17 | if (line.StartsWith(properties[i])) {
18 | break;
19 | }
20 | if (i == 20) {
21 | Logger.Log("Error parsing: Could not identify property");
22 | return new byte[] { 255, 255, 255};
23 | }
24 | }
25 | if (properties[i].Length + 1 > line.Length) {
26 | Logger.Log("Error parsing: No assignment");
27 | return new byte[] { 255, 255, 255 };
28 | }
29 | string val = line.Remove(0, properties[i].Length + 1); //remove up to the = sign
30 | if (val.StartsWith("btn")) {
31 | type = 0;
32 | subType = 0;
33 | num = byte.Parse(val.Remove(0, 3));
34 | } else if (val.Contains("axis")) {
35 | type = 1;
36 | if (val.StartsWith("ih")) {
37 | num = byte.Parse(val.Remove(0, 6));
38 | subType = 3;
39 | } else if (val.StartsWith("h")) {
40 | subType = 2;
41 | num = byte.Parse(val.Remove(0, 5));
42 | } else if (val.StartsWith("i")) {
43 | subType = 1;
44 | num = byte.Parse(val.Remove(0, 5));
45 | } else {
46 | subType = 0;
47 | num = byte.Parse(val.Remove(0, 4));
48 | }
49 | } else if (val.StartsWith("dpad")) {
50 | type = 2;
51 | val = val.Remove(0, 4);
52 | if (val.EndsWith("up")) {
53 | subType = 0;
54 | num = byte.Parse(val.Remove(val.Length - 2));
55 | } else if (val.EndsWith("down")) {
56 | subType = 1;
57 | num = byte.Parse(val.Remove(val.Length - 4));
58 | } else if (val.EndsWith("left")) {
59 | subType = 2;
60 | num = byte.Parse(val.Remove(val.Length - 4));
61 | } else if (val.EndsWith("right")) {
62 | subType = 3;
63 | num = byte.Parse(val.Remove(val.Length - 5));
64 | }
65 | } else if (val == "disabled") {
66 | } else {
67 | Logger.Log("Error parsing: Could not identify value");
68 | return new byte[] { 255, 255, 255 };
69 | }
70 | num -= 1;
71 | byte l = (byte)(type << 4 | subType);
72 | return new byte[] { (byte)(i * 2), l, num};
73 | }
74 |
75 | public static byte[] Load(string devName) {
76 | if (!Directory.Exists(dirName)) {
77 | Directory.CreateDirectory(dirName);
78 | return null;
79 | }
80 | string path = dirName + "\\" + devName + ".ini";
81 | if (!File.Exists(path)) {
82 | File.Create(path);
83 | return null;
84 | }
85 | byte[] mapping = new byte[42];
86 | string[] config = File.ReadAllLines(path);
87 | for (int i = 0; i < config.Length; i++) {
88 | byte[] data = parseLine(config[i]);
89 | Console.Write(data[0]);
90 | if (data[0] > 40) {
91 | continue;
92 | }
93 | mapping[data[0]] = data[1];
94 | mapping[data[0] + 1] = data[2];
95 | }
96 | return mapping;
97 | }
98 |
99 | public static void Save(string devName, byte[] mapping) {
100 | if (!Directory.Exists(dirName)) {
101 | Directory.CreateDirectory(dirName);
102 | }
103 | string path = dirName + "\\" + devName + ".ini";
104 | if (!File.Exists(path)) {
105 | File.Create(path);
106 | }
107 | File.WriteAllText(path, generateSaveString(mapping));
108 | }
109 |
110 | private static string generateSaveString(byte[] Mapping) {
111 | string[] typeString = new string[] { "btn{0}", "{1}axis{0}", "dpad{0}{2}" };
112 | string[] axesString = new string[] { "", "i", "h", "ih" };
113 | string[] dpadString = new string[] { "up", "down", "left", "right" };
114 |
115 | string saveString = "";
116 | for (int i = 0; i < 21; i++) {
117 | saveString += properties[i] + "=";
118 | if (Mapping[i * 2] == 255) {
119 | saveString += "disabled\r\n";
120 | continue;
121 | }
122 | byte subType = (byte)(Mapping[i * 2] & 0x0F);
123 | byte type = (byte)((Mapping[i * 2] & 0xF0) >> 4);
124 | byte num = (byte)(Mapping[i * 2 + 1] + 1);
125 | saveString += string.Format(typeString[type], num, axesString[subType], dpadString[subType]) + "\r\n";
126 | }
127 | return saveString;
128 | }
129 |
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/XOutput/ScpDevice.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Windows.Forms;
5 |
6 | using System.Runtime.InteropServices;
7 | using Microsoft.Win32.SafeHandles;
8 |
9 | namespace XOutput
10 | {
11 | public partial class ScpDevice
12 | {
13 | public virtual Boolean IsActive
14 | {
15 | get { return m_IsActive; }
16 | }
17 |
18 | public virtual String Path
19 | {
20 | get { return m_Path; }
21 | }
22 |
23 | public ScpDevice(String Class)
24 | {
25 | this.m_Class = new Guid(Class);
26 | }
27 |
28 |
29 | public virtual Boolean Open(Int32 Instance = 0)
30 | {
31 | String DevicePath = String.Empty;
32 | m_WinUsbHandle = (IntPtr)INVALID_HANDLE_VALUE;
33 |
34 | if (Find(m_Class, ref DevicePath, Instance))
35 | {
36 | Open(DevicePath);
37 | }
38 |
39 | return m_IsActive;
40 | }
41 |
42 | public virtual Boolean Open(String DevicePath)
43 | {
44 | m_Path = DevicePath.ToUpper();
45 | m_WinUsbHandle = (IntPtr)INVALID_HANDLE_VALUE;
46 |
47 | if (GetDeviceHandle(m_Path))
48 | {
49 | if (WinUsb_Initialize(m_FileHandle, ref m_WinUsbHandle))
50 | {
51 | if (InitializeDevice())
52 | {
53 |
54 | m_IsActive = true;
55 | }
56 | else
57 | {
58 | WinUsb_Free(m_WinUsbHandle);
59 | m_WinUsbHandle = (IntPtr)INVALID_HANDLE_VALUE;
60 | }
61 | }
62 | else
63 | {
64 | m_FileHandle.Close();
65 | }
66 | }
67 |
68 | return m_IsActive;
69 | }
70 |
71 | public virtual Boolean Start()
72 | {
73 | return m_IsActive;
74 | }
75 |
76 | public virtual Boolean Stop()
77 | {
78 | m_IsActive = false;
79 |
80 | if (!(m_WinUsbHandle == (IntPtr)INVALID_HANDLE_VALUE))
81 | {
82 | WinUsb_AbortPipe(m_WinUsbHandle, m_IntIn);
83 | WinUsb_AbortPipe(m_WinUsbHandle, m_BulkIn);
84 | WinUsb_AbortPipe(m_WinUsbHandle, m_BulkOut);
85 |
86 | WinUsb_Free(m_WinUsbHandle);
87 | m_WinUsbHandle = (IntPtr)INVALID_HANDLE_VALUE;
88 | }
89 |
90 | if (m_FileHandle != null && !m_FileHandle.IsInvalid && !m_FileHandle.IsClosed)
91 | {
92 | m_FileHandle.Close();
93 | m_FileHandle = null;
94 | }
95 |
96 | return true;
97 | }
98 |
99 | public virtual Boolean Close()
100 | {
101 | return Stop();
102 | }
103 |
104 |
105 |
106 |
107 | #region Constant and Structure Definitions
108 | public const Int32 SERVICE_CONTROL_STOP = 0x00000001;
109 | public const Int32 SERVICE_CONTROL_SHUTDOWN = 0x00000005;
110 | public const Int32 SERVICE_CONTROL_DEVICEEVENT = 0x0000000B;
111 | public const Int32 SERVICE_CONTROL_POWEREVENT = 0x0000000D;
112 |
113 | public const Int32 DBT_DEVICEARRIVAL = 0x8000;
114 | public const Int32 DBT_DEVICEQUERYREMOVE = 0x8001;
115 | public const Int32 DBT_DEVICEREMOVECOMPLETE = 0x8004;
116 | public const Int32 DBT_DEVTYP_DEVICEINTERFACE = 0x0005;
117 | public const Int32 DBT_DEVTYP_HANDLE = 0x0006;
118 |
119 | public const Int32 PBT_APMRESUMEAUTOMATIC = 0x0012;
120 | public const Int32 PBT_APMSUSPEND = 0x0004;
121 |
122 | public const Int32 DEVICE_NOTIFY_WINDOW_HANDLE = 0x0000;
123 | public const Int32 DEVICE_NOTIFY_SERVICE_HANDLE = 0x0001;
124 | public const Int32 DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = 0x0004;
125 |
126 | public const Int32 WM_DEVICECHANGE = 0x0219;
127 |
128 | public const Int32 DIGCF_PRESENT = 0x0002;
129 | public const Int32 DIGCF_DEVICEINTERFACE = 0x0010;
130 |
131 | public delegate Int32 ServiceControlHandlerEx(Int32 Control, Int32 Type, IntPtr Data, IntPtr Context);
132 |
133 | [StructLayout(LayoutKind.Sequential)]
134 | public class DEV_BROADCAST_DEVICEINTERFACE
135 | {
136 | internal Int32 dbcc_size;
137 | internal Int32 dbcc_devicetype;
138 | internal Int32 dbcc_reserved;
139 | internal Guid dbcc_classguid;
140 | internal Int16 dbcc_name;
141 | }
142 |
143 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
144 | public class DEV_BROADCAST_DEVICEINTERFACE_M
145 | {
146 | public Int32 dbcc_size;
147 | public Int32 dbcc_devicetype;
148 | public Int32 dbcc_reserved;
149 |
150 | [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 16)]
151 | public Byte[] dbcc_classguid;
152 |
153 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 255)]
154 | public Char[] dbcc_name;
155 | }
156 |
157 | [StructLayout(LayoutKind.Sequential)]
158 | public class DEV_BROADCAST_HDR
159 | {
160 | public Int32 dbch_size;
161 | public Int32 dbch_devicetype;
162 | public Int32 dbch_reserved;
163 | }
164 |
165 | [StructLayout(LayoutKind.Sequential)]
166 | protected struct SP_DEVICE_INTERFACE_DATA
167 | {
168 | internal Int32 cbSize;
169 | internal Guid InterfaceClassGuid;
170 | internal Int32 Flags;
171 | internal IntPtr Reserved;
172 | }
173 |
174 | protected const UInt32 FILE_ATTRIBUTE_NORMAL = 0x80;
175 | protected const UInt32 FILE_FLAG_OVERLAPPED = 0x40000000;
176 | protected const UInt32 FILE_SHARE_READ = 1;
177 | protected const UInt32 FILE_SHARE_WRITE = 2;
178 | protected const UInt32 GENERIC_READ = 0x80000000;
179 | protected const UInt32 GENERIC_WRITE = 0x40000000;
180 | protected const Int32 INVALID_HANDLE_VALUE = -1;
181 | protected const UInt32 OPEN_EXISTING = 3;
182 | protected const UInt32 DEVICE_SPEED = 1;
183 | protected const Byte USB_ENDPOINT_DIRECTION_MASK = 0x80;
184 |
185 | protected enum POLICY_TYPE
186 | {
187 | SHORT_PACKET_TERMINATE = 1,
188 | AUTO_CLEAR_STALL = 2,
189 | PIPE_TRANSFER_TIMEOUT = 3,
190 | IGNORE_SHORT_PACKETS = 4,
191 | ALLOW_PARTIAL_READS = 5,
192 | AUTO_FLUSH = 6,
193 | RAW_IO = 7,
194 | }
195 |
196 | protected enum USBD_PIPE_TYPE
197 | {
198 | UsbdPipeTypeControl = 0,
199 | UsbdPipeTypeIsochronous = 1,
200 | UsbdPipeTypeBulk = 2,
201 | UsbdPipeTypeInterrupt = 3,
202 | }
203 |
204 | protected enum USB_DEVICE_SPEED
205 | {
206 | UsbLowSpeed = 1,
207 | UsbFullSpeed = 2,
208 | UsbHighSpeed = 3,
209 | }
210 |
211 | [StructLayout(LayoutKind.Sequential)]
212 | protected struct USB_CONFIGURATION_DESCRIPTOR
213 | {
214 | internal Byte bLength;
215 | internal Byte bDescriptorType;
216 | internal UInt16 wTotalLength;
217 | internal Byte bNumInterfaces;
218 | internal Byte bConfigurationValue;
219 | internal Byte iConfiguration;
220 | internal Byte bmAttributes;
221 | internal Byte MaxPower;
222 | }
223 |
224 | [StructLayout(LayoutKind.Sequential)]
225 | protected struct USB_INTERFACE_DESCRIPTOR
226 | {
227 | internal Byte bLength;
228 | internal Byte bDescriptorType;
229 | internal Byte bInterfaceNumber;
230 | internal Byte bAlternateSetting;
231 | internal Byte bNumEndpoints;
232 | internal Byte bInterfaceClass;
233 | internal Byte bInterfaceSubClass;
234 | internal Byte bInterfaceProtocol;
235 | internal Byte iInterface;
236 | }
237 |
238 | [StructLayout(LayoutKind.Sequential)]
239 | protected struct WINUSB_PIPE_INFORMATION
240 | {
241 | internal USBD_PIPE_TYPE PipeType;
242 | internal Byte PipeId;
243 | internal UInt16 MaximumPacketSize;
244 | internal Byte Interval;
245 | }
246 |
247 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
248 | protected struct WINUSB_SETUP_PACKET
249 | {
250 | internal Byte RequestType;
251 | internal Byte Request;
252 | internal UInt16 Value;
253 | internal UInt16 Index;
254 | internal UInt16 Length;
255 | }
256 |
257 | protected const Int32 DIF_PROPERTYCHANGE = 0x12;
258 | protected const Int32 DICS_ENABLE = 1;
259 | protected const Int32 DICS_DISABLE = 2;
260 | protected const Int32 DICS_PROPCHANGE = 3;
261 | protected const Int32 DICS_FLAG_GLOBAL = 1;
262 |
263 | [StructLayout(LayoutKind.Sequential)]
264 | protected struct SP_CLASSINSTALL_HEADER
265 | {
266 | internal Int32 cbSize;
267 | internal Int32 InstallFunction;
268 | }
269 |
270 | [StructLayout(LayoutKind.Sequential)]
271 | protected struct SP_PROPCHANGE_PARAMS
272 | {
273 | internal SP_CLASSINSTALL_HEADER ClassInstallHeader;
274 | internal Int32 StateChange;
275 | internal Int32 Scope;
276 | internal Int32 HwProfile;
277 | }
278 | #endregion
279 |
280 | #region Protected Data Members
281 | protected Guid m_Class = Guid.Empty;
282 | protected String m_Path = String.Empty;
283 |
284 | protected SafeFileHandle m_FileHandle = null;
285 | protected IntPtr m_WinUsbHandle = IntPtr.Zero;
286 |
287 | protected Byte m_IntIn = 0xFF;
288 | protected Byte m_IntOut = 0xFF;
289 | protected Byte m_BulkIn = 0xFF;
290 | protected Byte m_BulkOut = 0xFF;
291 |
292 | protected Boolean m_IsActive = false;
293 | #endregion
294 |
295 | #region Static Helper Methods
296 | public enum Notified { Ignore = 0x0000, Arrival = 0x8000, QueryRemove = 0x8001, Removal = 0x8004 };
297 |
298 | public static Boolean RegisterNotify(IntPtr Form, Guid Class, ref IntPtr Handle, Boolean Window = true)
299 | {
300 | IntPtr devBroadcastDeviceInterfaceBuffer = IntPtr.Zero;
301 |
302 | try
303 | {
304 | DEV_BROADCAST_DEVICEINTERFACE devBroadcastDeviceInterface = new DEV_BROADCAST_DEVICEINTERFACE();
305 | Int32 Size = Marshal.SizeOf(devBroadcastDeviceInterface);
306 |
307 | devBroadcastDeviceInterface.dbcc_size = Size;
308 | devBroadcastDeviceInterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
309 | devBroadcastDeviceInterface.dbcc_reserved = 0;
310 | devBroadcastDeviceInterface.dbcc_classguid = Class;
311 |
312 | devBroadcastDeviceInterfaceBuffer = Marshal.AllocHGlobal(Size);
313 | Marshal.StructureToPtr(devBroadcastDeviceInterface, devBroadcastDeviceInterfaceBuffer, true);
314 |
315 | Handle = RegisterDeviceNotification(Form, devBroadcastDeviceInterfaceBuffer, Window ? DEVICE_NOTIFY_WINDOW_HANDLE : DEVICE_NOTIFY_SERVICE_HANDLE);
316 |
317 | Marshal.PtrToStructure(devBroadcastDeviceInterfaceBuffer, devBroadcastDeviceInterface);
318 |
319 | return Handle != IntPtr.Zero;
320 | }
321 | catch (Exception ex)
322 | {
323 | Console.WriteLine("{0} {1}", ex.HelpLink, ex.Message);
324 | throw;
325 | }
326 | finally
327 | {
328 | if (devBroadcastDeviceInterfaceBuffer != IntPtr.Zero)
329 | {
330 | Marshal.FreeHGlobal(devBroadcastDeviceInterfaceBuffer);
331 | }
332 | }
333 | }
334 |
335 | public static Boolean UnregisterNotify(IntPtr Handle)
336 | {
337 | try
338 | {
339 | return UnregisterDeviceNotification(Handle);
340 | }
341 | catch (Exception ex)
342 | {
343 | Console.WriteLine("{0} {1}", ex.HelpLink, ex.Message);
344 | throw;
345 | }
346 | }
347 | #endregion
348 |
349 | #region Protected Methods
350 | protected virtual Boolean Find(Guid Target, ref String Path, Int32 Instance = 0)
351 | {
352 | IntPtr detailDataBuffer = IntPtr.Zero;
353 | IntPtr deviceInfoSet = IntPtr.Zero;
354 |
355 | try
356 | {
357 | SP_DEVICE_INTERFACE_DATA DeviceInterfaceData = new SP_DEVICE_INTERFACE_DATA(), da = new SP_DEVICE_INTERFACE_DATA();
358 | Int32 bufferSize = 0, memberIndex = 0;
359 |
360 | deviceInfoSet = SetupDiGetClassDevs(ref Target, IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
361 |
362 | DeviceInterfaceData.cbSize = da.cbSize = Marshal.SizeOf(DeviceInterfaceData);
363 |
364 | while (SetupDiEnumDeviceInterfaces(deviceInfoSet, IntPtr.Zero, ref Target, memberIndex, ref DeviceInterfaceData))
365 | {
366 | SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref DeviceInterfaceData, IntPtr.Zero, 0, ref bufferSize, ref da);
367 | {
368 | detailDataBuffer = Marshal.AllocHGlobal(bufferSize);
369 |
370 | Marshal.WriteInt32(detailDataBuffer, (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8);
371 |
372 | if (SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref DeviceInterfaceData, detailDataBuffer, bufferSize, ref bufferSize, ref da))
373 | {
374 | IntPtr pDevicePathName = new IntPtr(IntPtr.Size == 4 ? detailDataBuffer.ToInt32() + 4 : detailDataBuffer.ToInt64() + 4);
375 |
376 | Path = Marshal.PtrToStringAuto(pDevicePathName).ToUpper();
377 | Marshal.FreeHGlobal(detailDataBuffer);
378 |
379 | if (memberIndex == Instance) return true;
380 | }
381 | else Marshal.FreeHGlobal(detailDataBuffer);
382 | }
383 |
384 | memberIndex++;
385 | }
386 | }
387 | catch (Exception ex)
388 | {
389 | Console.WriteLine("{0} {1}", ex.HelpLink, ex.Message);
390 | throw;
391 | }
392 | finally
393 | {
394 | if (deviceInfoSet != IntPtr.Zero)
395 | {
396 | SetupDiDestroyDeviceInfoList(deviceInfoSet);
397 | }
398 | }
399 |
400 | return false;
401 | }
402 |
403 |
404 | protected virtual Boolean GetDeviceHandle(String Path)
405 | {
406 | m_FileHandle = CreateFile(Path, (GENERIC_WRITE | GENERIC_READ), FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 0);
407 |
408 | return !m_FileHandle.IsInvalid;
409 | }
410 |
411 | protected virtual Boolean UsbEndpointDirectionIn(Int32 addr)
412 | {
413 | return (addr & 0x80) == 0x80;
414 | }
415 |
416 | protected virtual Boolean UsbEndpointDirectionOut(Int32 addr)
417 | {
418 | return (addr & 0x80) == 0x00;
419 | }
420 |
421 | protected virtual Boolean InitializeDevice()
422 | {
423 | try
424 | {
425 | USB_INTERFACE_DESCRIPTOR ifaceDescriptor = new USB_INTERFACE_DESCRIPTOR();
426 | WINUSB_PIPE_INFORMATION pipeInfo = new WINUSB_PIPE_INFORMATION();
427 |
428 | if (WinUsb_QueryInterfaceSettings(m_WinUsbHandle, 0, ref ifaceDescriptor))
429 | {
430 | for (Int32 i = 0; i < ifaceDescriptor.bNumEndpoints; i++)
431 | {
432 | WinUsb_QueryPipe(m_WinUsbHandle, 0, System.Convert.ToByte(i), ref pipeInfo);
433 |
434 | if (((pipeInfo.PipeType == USBD_PIPE_TYPE.UsbdPipeTypeBulk) & UsbEndpointDirectionIn(pipeInfo.PipeId)))
435 | {
436 | m_BulkIn = pipeInfo.PipeId;
437 | WinUsb_FlushPipe(m_WinUsbHandle, m_BulkIn);
438 | }
439 | else if (((pipeInfo.PipeType == USBD_PIPE_TYPE.UsbdPipeTypeBulk) & UsbEndpointDirectionOut(pipeInfo.PipeId)))
440 | {
441 | m_BulkOut = pipeInfo.PipeId;
442 | WinUsb_FlushPipe(m_WinUsbHandle, m_BulkOut);
443 | }
444 | else if ((pipeInfo.PipeType == USBD_PIPE_TYPE.UsbdPipeTypeInterrupt) & UsbEndpointDirectionIn(pipeInfo.PipeId))
445 | {
446 | m_IntIn = pipeInfo.PipeId;
447 | WinUsb_FlushPipe(m_WinUsbHandle, m_IntIn);
448 | }
449 | else if ((pipeInfo.PipeType == USBD_PIPE_TYPE.UsbdPipeTypeInterrupt) & UsbEndpointDirectionOut(pipeInfo.PipeId))
450 | {
451 | m_IntOut = pipeInfo.PipeId;
452 | WinUsb_FlushPipe(m_WinUsbHandle, m_IntOut);
453 | }
454 | }
455 |
456 | return true;
457 | }
458 |
459 | return false;
460 | }
461 | catch (Exception ex)
462 | {
463 | Console.WriteLine("{0} {1}", ex.HelpLink, ex.Message);
464 | throw;
465 | }
466 | }
467 |
468 | #endregion
469 |
470 | #region Interop Definitions
471 | [DllImport("setupapi.dll", SetLastError = true)]
472 | protected static extern Int32 SetupDiCreateDeviceInfoList(ref System.Guid ClassGuid, Int32 hwndParent);
473 |
474 | [DllImport("setupapi.dll", SetLastError = true)]
475 | protected static extern Int32 SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);
476 |
477 | [DllImport("setupapi.dll", SetLastError = true)]
478 | protected static extern Boolean SetupDiEnumDeviceInterfaces(IntPtr DeviceInfoSet, IntPtr DeviceInfoData, ref System.Guid InterfaceClassGuid, Int32 MemberIndex, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
479 |
480 | [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
481 | protected static extern IntPtr SetupDiGetClassDevs(ref System.Guid ClassGuid, IntPtr Enumerator, IntPtr hwndParent, Int32 Flags);
482 |
483 | [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
484 | protected static extern Boolean SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, IntPtr DeviceInterfaceDetailData, Int32 DeviceInterfaceDetailDataSize, ref Int32 RequiredSize, IntPtr DeviceInfoData);
485 |
486 | [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
487 | protected static extern Boolean SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, IntPtr DeviceInterfaceDetailData, Int32 DeviceInterfaceDetailDataSize, ref Int32 RequiredSize, ref SP_DEVICE_INTERFACE_DATA DeviceInfoData);
488 |
489 | [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
490 | protected static extern IntPtr RegisterDeviceNotification(IntPtr hRecipient, IntPtr NotificationFilter, Int32 Flags);
491 |
492 | [DllImport("user32.dll", SetLastError = true)]
493 | protected static extern Boolean UnregisterDeviceNotification(IntPtr Handle);
494 |
495 | [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
496 | protected static extern SafeFileHandle CreateFile(String lpFileName, UInt32 dwDesiredAccess, UInt32 dwShareMode, IntPtr lpSecurityAttributes, UInt32 dwCreationDisposition, UInt32 dwFlagsAndAttributes, UInt32 hTemplateFile);
497 |
498 | [DllImport("winusb.dll", SetLastError = true)]
499 | protected static extern Boolean WinUsb_Initialize(SafeFileHandle DeviceHandle, ref IntPtr InterfaceHandle);
500 |
501 | [DllImport("winusb.dll", SetLastError = true)]
502 | protected static extern Boolean WinUsb_QueryInterfaceSettings(IntPtr InterfaceHandle, Byte AlternateInterfaceNumber, ref USB_INTERFACE_DESCRIPTOR UsbAltInterfaceDescriptor);
503 |
504 | [DllImport("winusb.dll", SetLastError = true)]
505 | protected static extern Boolean WinUsb_QueryPipe(IntPtr InterfaceHandle, Byte AlternateInterfaceNumber, Byte PipeIndex, ref WINUSB_PIPE_INFORMATION PipeInformation);
506 |
507 | [DllImport("winusb.dll", SetLastError = true)]
508 | protected static extern Boolean WinUsb_AbortPipe(IntPtr InterfaceHandle, Byte PipeID);
509 |
510 | [DllImport("winusb.dll", SetLastError = true)]
511 | protected static extern Boolean WinUsb_FlushPipe(IntPtr InterfaceHandle, Byte PipeID);
512 |
513 | [DllImport("winusb.dll", SetLastError = true)]
514 | protected static extern Boolean WinUsb_ControlTransfer(IntPtr InterfaceHandle, WINUSB_SETUP_PACKET SetupPacket, Byte[] Buffer, Int32 BufferLength, ref Int32 LengthTransferred, IntPtr Overlapped);
515 |
516 | [DllImport("winusb.dll", SetLastError = true)]
517 | protected static extern Boolean WinUsb_ReadPipe(IntPtr InterfaceHandle, Byte PipeID, Byte[] Buffer, Int32 BufferLength, ref Int32 LengthTransferred, IntPtr Overlapped);
518 |
519 | [DllImport("winusb.dll", SetLastError = true)]
520 | protected static extern Boolean WinUsb_WritePipe(IntPtr InterfaceHandle, Byte PipeID, Byte[] Buffer, Int32 BufferLength, ref Int32 LengthTransferred, IntPtr Overlapped);
521 |
522 | [DllImport("winusb.dll", SetLastError = true)]
523 | protected static extern Boolean WinUsb_Free(IntPtr InterfaceHandle);
524 |
525 | [DllImport("advapi32.dll", SetLastError = true)]
526 | public static extern IntPtr RegisterServiceCtrlHandlerEx(String ServiceName, ServiceControlHandlerEx Callback, IntPtr Context);
527 |
528 | [DllImport("kernel32.dll", SetLastError = true)]
529 | protected static extern Boolean DeviceIoControl(SafeFileHandle DeviceHandle, Int32 IoControlCode, Byte[] InBuffer, Int32 InBufferSize, Byte[] OutBuffer, Int32 OutBufferSize, ref Int32 BytesReturned, IntPtr Overlapped);
530 |
531 | [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
532 | protected static extern Int32 CM_Get_Device_ID(Int32 dnDevInst, IntPtr Buffer, Int32 BufferLen, Int32 ulFlags);
533 |
534 | [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
535 | protected static extern Boolean SetupDiOpenDeviceInfo(IntPtr DeviceInfoSet, String DeviceInstanceId, IntPtr hwndParent, Int32 Flags, ref SP_DEVICE_INTERFACE_DATA DeviceInfoData);
536 |
537 | [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
538 | protected static extern Boolean SetupDiChangeState(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
539 |
540 | [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
541 | protected static extern Boolean SetupDiSetClassInstallParams(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, ref SP_PROPCHANGE_PARAMS ClassInstallParams, Int32 ClassInstallParamsSize);
542 | #endregion
543 | }
544 | }
545 |
--------------------------------------------------------------------------------
/XOutput/XOut.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace XOutput
2 | {
3 | partial class XOut
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(XOut));
32 | this.StartStopBtn = new System.Windows.Forms.Button();
33 | this.controllerBoxOne = new System.Windows.Forms.GroupBox();
34 | this.optionsOne = new System.Windows.Forms.Button();
35 | this.moveOneDown = new System.Windows.Forms.Button();
36 | this.enabledTwo = new System.Windows.Forms.CheckBox();
37 | this.enabledOne = new System.Windows.Forms.CheckBox();
38 | this.controllerBoxTwo = new System.Windows.Forms.GroupBox();
39 | this.optionsTwo = new System.Windows.Forms.Button();
40 | this.moveTwoUp = new System.Windows.Forms.Button();
41 | this.moveTwoDown = new System.Windows.Forms.Button();
42 | this.controllerBoxThree = new System.Windows.Forms.GroupBox();
43 | this.optionsThree = new System.Windows.Forms.Button();
44 | this.moveThreeUp = new System.Windows.Forms.Button();
45 | this.moveThreeDown = new System.Windows.Forms.Button();
46 | this.enabledThree = new System.Windows.Forms.CheckBox();
47 | this.controllerBoxFour = new System.Windows.Forms.GroupBox();
48 | this.optionsFour = new System.Windows.Forms.Button();
49 | this.moveFourUp = new System.Windows.Forms.Button();
50 | this.enabledFour = new System.Windows.Forms.CheckBox();
51 | this.isExclusive = new System.Windows.Forms.CheckBox();
52 | this.controllerBoxOne.SuspendLayout();
53 | this.controllerBoxTwo.SuspendLayout();
54 | this.controllerBoxThree.SuspendLayout();
55 | this.controllerBoxFour.SuspendLayout();
56 | this.SuspendLayout();
57 | //
58 | // StartStopBtn
59 | //
60 | this.StartStopBtn.Location = new System.Drawing.Point(397, 316);
61 | this.StartStopBtn.Name = "StartStopBtn";
62 | this.StartStopBtn.Size = new System.Drawing.Size(75, 23);
63 | this.StartStopBtn.TabIndex = 0;
64 | this.StartStopBtn.Text = "Start";
65 | this.StartStopBtn.UseVisualStyleBackColor = true;
66 | this.StartStopBtn.Click += new System.EventHandler(this.StartStopBtn_Click);
67 | //
68 | // controllerBoxOne
69 | //
70 | this.controllerBoxOne.Controls.Add(this.optionsOne);
71 | this.controllerBoxOne.Controls.Add(this.moveOneDown);
72 | this.controllerBoxOne.Location = new System.Drawing.Point(12, 12);
73 | this.controllerBoxOne.Name = "controllerBoxOne";
74 | this.controllerBoxOne.Size = new System.Drawing.Size(460, 70);
75 | this.controllerBoxOne.TabIndex = 1;
76 | this.controllerBoxOne.TabStop = false;
77 | this.controllerBoxOne.Text = "`";
78 | //
79 | // optionsOne
80 | //
81 | this.optionsOne.Image = global::XOutput.Properties.Resources.gear;
82 | this.optionsOne.Location = new System.Drawing.Point(6, 41);
83 | this.optionsOne.Name = "optionsOne";
84 | this.optionsOne.Size = new System.Drawing.Size(27, 23);
85 | this.optionsOne.TabIndex = 7;
86 | this.optionsOne.UseVisualStyleBackColor = true;
87 | //
88 | // moveOneDown
89 | //
90 | this.moveOneDown.Image = global::XOutput.Properties.Resources.arrow_Down;
91 | this.moveOneDown.Location = new System.Drawing.Point(427, 41);
92 | this.moveOneDown.Name = "moveOneDown";
93 | this.moveOneDown.Size = new System.Drawing.Size(27, 23);
94 | this.moveOneDown.TabIndex = 1;
95 | this.moveOneDown.UseVisualStyleBackColor = true;
96 | //
97 | // enabledTwo
98 | //
99 | this.enabledTwo.AutoSize = true;
100 | this.enabledTwo.Checked = true;
101 | this.enabledTwo.CheckState = System.Windows.Forms.CheckState.Checked;
102 | this.enabledTwo.Location = new System.Drawing.Point(51, 133);
103 | this.enabledTwo.Name = "enabledTwo";
104 | this.enabledTwo.Size = new System.Drawing.Size(65, 17);
105 | this.enabledTwo.TabIndex = 8;
106 | this.enabledTwo.Text = "Enabled";
107 | this.enabledTwo.UseVisualStyleBackColor = true;
108 | //
109 | // enabledOne
110 | //
111 | this.enabledOne.AutoSize = true;
112 | this.enabledOne.Checked = true;
113 | this.enabledOne.CheckState = System.Windows.Forms.CheckState.Checked;
114 | this.enabledOne.Location = new System.Drawing.Point(51, 56);
115 | this.enabledOne.Name = "enabledOne";
116 | this.enabledOne.Size = new System.Drawing.Size(65, 17);
117 | this.enabledOne.TabIndex = 6;
118 | this.enabledOne.Text = "Enabled";
119 | this.enabledOne.UseVisualStyleBackColor = true;
120 | //
121 | // controllerBoxTwo
122 | //
123 | this.controllerBoxTwo.Controls.Add(this.optionsTwo);
124 | this.controllerBoxTwo.Controls.Add(this.moveTwoUp);
125 | this.controllerBoxTwo.Controls.Add(this.moveTwoDown);
126 | this.controllerBoxTwo.Location = new System.Drawing.Point(12, 88);
127 | this.controllerBoxTwo.Name = "controllerBoxTwo";
128 | this.controllerBoxTwo.Size = new System.Drawing.Size(460, 70);
129 | this.controllerBoxTwo.TabIndex = 2;
130 | this.controllerBoxTwo.TabStop = false;
131 | //
132 | // optionsTwo
133 | //
134 | this.optionsTwo.Image = global::XOutput.Properties.Resources.gear;
135 | this.optionsTwo.Location = new System.Drawing.Point(6, 41);
136 | this.optionsTwo.Name = "optionsTwo";
137 | this.optionsTwo.Size = new System.Drawing.Size(27, 23);
138 | this.optionsTwo.TabIndex = 7;
139 | this.optionsTwo.UseVisualStyleBackColor = true;
140 | //
141 | // moveTwoUp
142 | //
143 | this.moveTwoUp.Image = global::XOutput.Properties.Resources.arrow_Up;
144 | this.moveTwoUp.Location = new System.Drawing.Point(427, 12);
145 | this.moveTwoUp.Name = "moveTwoUp";
146 | this.moveTwoUp.Size = new System.Drawing.Size(27, 23);
147 | this.moveTwoUp.TabIndex = 3;
148 | this.moveTwoUp.UseVisualStyleBackColor = true;
149 | //
150 | // moveTwoDown
151 | //
152 | this.moveTwoDown.Image = global::XOutput.Properties.Resources.arrow_Down;
153 | this.moveTwoDown.Location = new System.Drawing.Point(427, 41);
154 | this.moveTwoDown.Name = "moveTwoDown";
155 | this.moveTwoDown.Size = new System.Drawing.Size(27, 23);
156 | this.moveTwoDown.TabIndex = 2;
157 | this.moveTwoDown.UseVisualStyleBackColor = true;
158 | //
159 | // controllerBoxThree
160 | //
161 | this.controllerBoxThree.Controls.Add(this.optionsThree);
162 | this.controllerBoxThree.Controls.Add(this.moveThreeUp);
163 | this.controllerBoxThree.Controls.Add(this.moveThreeDown);
164 | this.controllerBoxThree.Location = new System.Drawing.Point(12, 164);
165 | this.controllerBoxThree.Name = "controllerBoxThree";
166 | this.controllerBoxThree.Size = new System.Drawing.Size(460, 70);
167 | this.controllerBoxThree.TabIndex = 3;
168 | this.controllerBoxThree.TabStop = false;
169 | //
170 | // optionsThree
171 | //
172 | this.optionsThree.Image = global::XOutput.Properties.Resources.gear;
173 | this.optionsThree.Location = new System.Drawing.Point(6, 41);
174 | this.optionsThree.Name = "optionsThree";
175 | this.optionsThree.Size = new System.Drawing.Size(27, 23);
176 | this.optionsThree.TabIndex = 6;
177 | this.optionsThree.UseVisualStyleBackColor = true;
178 | //
179 | // moveThreeUp
180 | //
181 | this.moveThreeUp.Image = global::XOutput.Properties.Resources.arrow_Up;
182 | this.moveThreeUp.Location = new System.Drawing.Point(427, 12);
183 | this.moveThreeUp.Name = "moveThreeUp";
184 | this.moveThreeUp.Size = new System.Drawing.Size(27, 23);
185 | this.moveThreeUp.TabIndex = 4;
186 | this.moveThreeUp.UseVisualStyleBackColor = true;
187 | //
188 | // moveThreeDown
189 | //
190 | this.moveThreeDown.Image = global::XOutput.Properties.Resources.arrow_Down;
191 | this.moveThreeDown.Location = new System.Drawing.Point(427, 41);
192 | this.moveThreeDown.Name = "moveThreeDown";
193 | this.moveThreeDown.Size = new System.Drawing.Size(27, 23);
194 | this.moveThreeDown.TabIndex = 3;
195 | this.moveThreeDown.UseVisualStyleBackColor = true;
196 | //
197 | // enabledThree
198 | //
199 | this.enabledThree.AutoSize = true;
200 | this.enabledThree.Checked = true;
201 | this.enabledThree.CheckState = System.Windows.Forms.CheckState.Checked;
202 | this.enabledThree.Location = new System.Drawing.Point(51, 209);
203 | this.enabledThree.Name = "enabledThree";
204 | this.enabledThree.Size = new System.Drawing.Size(65, 17);
205 | this.enabledThree.TabIndex = 7;
206 | this.enabledThree.Text = "Enabled";
207 | this.enabledThree.UseVisualStyleBackColor = true;
208 | //
209 | // controllerBoxFour
210 | //
211 | this.controllerBoxFour.Controls.Add(this.optionsFour);
212 | this.controllerBoxFour.Controls.Add(this.moveFourUp);
213 | this.controllerBoxFour.Location = new System.Drawing.Point(12, 240);
214 | this.controllerBoxFour.Name = "controllerBoxFour";
215 | this.controllerBoxFour.Size = new System.Drawing.Size(460, 70);
216 | this.controllerBoxFour.TabIndex = 4;
217 | this.controllerBoxFour.TabStop = false;
218 | //
219 | // optionsFour
220 | //
221 | this.optionsFour.Image = global::XOutput.Properties.Resources.gear;
222 | this.optionsFour.Location = new System.Drawing.Point(6, 41);
223 | this.optionsFour.Name = "optionsFour";
224 | this.optionsFour.Size = new System.Drawing.Size(27, 23);
225 | this.optionsFour.TabIndex = 5;
226 | this.optionsFour.UseVisualStyleBackColor = true;
227 | //
228 | // moveFourUp
229 | //
230 | this.moveFourUp.Image = global::XOutput.Properties.Resources.arrow_Up;
231 | this.moveFourUp.Location = new System.Drawing.Point(427, 12);
232 | this.moveFourUp.Name = "moveFourUp";
233 | this.moveFourUp.Size = new System.Drawing.Size(27, 23);
234 | this.moveFourUp.TabIndex = 4;
235 | this.moveFourUp.UseVisualStyleBackColor = true;
236 | //
237 | // enabledFour
238 | //
239 | this.enabledFour.AutoSize = true;
240 | this.enabledFour.Checked = true;
241 | this.enabledFour.CheckState = System.Windows.Forms.CheckState.Checked;
242 | this.enabledFour.Location = new System.Drawing.Point(51, 285);
243 | this.enabledFour.Name = "enabledFour";
244 | this.enabledFour.Size = new System.Drawing.Size(65, 17);
245 | this.enabledFour.TabIndex = 7;
246 | this.enabledFour.Text = "Enabled";
247 | this.enabledFour.UseVisualStyleBackColor = true;
248 | //
249 | // isExclusive
250 | //
251 | this.isExclusive.AutoSize = true;
252 | this.isExclusive.Location = new System.Drawing.Point(18, 320);
253 | this.isExclusive.Name = "isExclusive";
254 | this.isExclusive.Size = new System.Drawing.Size(75, 17);
255 | this.isExclusive.TabIndex = 9;
256 | this.isExclusive.Text = "Exclusivity";
257 | this.isExclusive.UseVisualStyleBackColor = true;
258 | this.isExclusive.CheckedChanged += new System.EventHandler(this.isExclusive_CheckedChanged);
259 | //
260 | // XOut
261 | //
262 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
263 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
264 | this.ClientSize = new System.Drawing.Size(484, 351);
265 | this.Controls.Add(this.isExclusive);
266 | this.Controls.Add(this.enabledOne);
267 | this.Controls.Add(this.enabledTwo);
268 | this.Controls.Add(this.enabledThree);
269 | this.Controls.Add(this.enabledFour);
270 | this.Controls.Add(this.controllerBoxOne);
271 | this.Controls.Add(this.controllerBoxTwo);
272 | this.Controls.Add(this.controllerBoxThree);
273 | this.Controls.Add(this.controllerBoxFour);
274 | this.Controls.Add(this.StartStopBtn);
275 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
276 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
277 | this.MaximizeBox = false;
278 | this.Name = "XOut";
279 | this.Text = "XOutput";
280 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.XOut_Closing);
281 | this.Load += new System.EventHandler(this.XOut_Load);
282 | this.Shown += new System.EventHandler(this.XOut_Shown);
283 | this.controllerBoxOne.ResumeLayout(false);
284 | this.controllerBoxTwo.ResumeLayout(false);
285 | this.controllerBoxThree.ResumeLayout(false);
286 | this.controllerBoxFour.ResumeLayout(false);
287 | this.ResumeLayout(false);
288 | this.PerformLayout();
289 |
290 | }
291 |
292 | #endregion
293 |
294 | private System.Windows.Forms.Button StartStopBtn;
295 |
296 | private System.Windows.Forms.GroupBox[] boxes;
297 | private System.Windows.Forms.CheckBox[] checks;
298 | private System.Windows.Forms.Button[] options;
299 | private ControllerOptions optionsWindow;
300 | private ControllerManager controllerManager;
301 | private System.Windows.Forms.GroupBox controllerBoxOne;
302 | private System.Windows.Forms.GroupBox controllerBoxTwo;
303 | private System.Windows.Forms.GroupBox controllerBoxThree;
304 | private System.Windows.Forms.GroupBox controllerBoxFour;
305 | private System.Windows.Forms.Button moveOneDown;
306 | private System.Windows.Forms.Button moveTwoUp;
307 | private System.Windows.Forms.Button moveTwoDown;
308 | private System.Windows.Forms.Button moveThreeUp;
309 | private System.Windows.Forms.Button moveThreeDown;
310 | private System.Windows.Forms.Button moveFourUp;
311 | private System.Windows.Forms.Button optionsOne;
312 | private System.Windows.Forms.Button optionsTwo;
313 | private System.Windows.Forms.Button optionsThree;
314 | private System.Windows.Forms.Button optionsFour;
315 | private System.Windows.Forms.CheckBox enabledOne;
316 | private System.Windows.Forms.CheckBox enabledTwo;
317 | private System.Windows.Forms.CheckBox enabledThree;
318 | private System.Windows.Forms.CheckBox enabledFour;
319 | private System.Windows.Forms.CheckBox isExclusive;
320 | }
321 | }
--------------------------------------------------------------------------------
/XOutput/XOut.cs:
--------------------------------------------------------------------------------
1 | using SlimDX.DirectInput;
2 | using System;
3 | using System.Windows.Forms;
4 |
5 | namespace XOutput
6 | {
7 | public partial class XOut : Form
8 | {
9 |
10 | public XOut()
11 | {
12 | InitializeComponent();
13 | this.moveOneDown.Click += (sender, e) => Swap(1, 2);
14 | this.moveTwoUp.Click += (sender, e) => Swap(2, 1);
15 | this.moveTwoDown.Click += (sender, e) => Swap(2, 3);
16 | this.moveThreeUp.Click += (sender, e) => Swap(3, 2);
17 | this.moveThreeDown.Click += (sender, e) => Swap(3, 4);
18 | this.moveFourUp.Click += (sender, e) => Swap(4, 3);
19 | this.enabledOne.CheckedChanged += (sender, e) => enabledChanged(0);
20 | this.enabledTwo.CheckedChanged += (sender, e) => enabledChanged(1);
21 | this.enabledThree.CheckedChanged += (sender, e) => enabledChanged(2);
22 | this.enabledFour.CheckedChanged += (sender, e) => enabledChanged(3);
23 | this.optionsOne.Click += (sender, e) => openOptions(0);
24 | this.optionsTwo.Click += (sender, e) => openOptions(1);
25 | this.optionsThree.Click += (sender, e) => openOptions(2);
26 | this.optionsFour.Click += (sender, e) => openOptions(3);
27 |
28 | boxes = new System.Windows.Forms.GroupBox[4] { controllerBoxOne, controllerBoxTwo, controllerBoxThree, controllerBoxFour };
29 | checks = new System.Windows.Forms.CheckBox[4] { enabledOne, enabledTwo, enabledThree, enabledFour };
30 | options = new System.Windows.Forms.Button[4] { optionsOne, optionsTwo, optionsThree, optionsFour };
31 | }
32 |
33 | private void XOut_Load(object sender, EventArgs e)
34 | {
35 | controllerManager = new ControllerManager(this);
36 | }
37 |
38 | private void XOut_Shown(object sender, EventArgs e)
39 | {
40 | UpdateInfo(controllerManager.detectControllers());
41 | }
42 |
43 | private void XOut_Closing(object sender, FormClosingEventArgs e)
44 | {
45 | if (controllerManager.IsActive)
46 | {
47 | controllerManager.Stop();
48 | }
49 | }
50 |
51 | private void StartStopBtn_Click(object sender, EventArgs e)
52 | {
53 | if (StartStopBtn.Text == "Start")
54 | {
55 | if (optionsWindow != null)
56 | {
57 | System.Media.SystemSounds.Asterisk.Play();
58 | optionsWindow.Focus();
59 | return;
60 | }
61 | if (controllerManager.Start())
62 | {
63 | StartStopBtn.Text = "Stop";
64 | for (int i = 0; i < 4; i++)
65 | {
66 | checks[i].Enabled = false;
67 | isExclusive.Enabled = false;
68 | foreach (Control con in boxes[i].Controls)
69 | {
70 | con.Enabled = false;
71 | }
72 | }
73 | }
74 | }
75 | else
76 | {
77 | if (controllerManager.Stop())
78 | {
79 | StartStopBtn.Text = "Start";
80 | for (int i = 0; i < 4; i++)
81 | {
82 | checks[i].Enabled = true;
83 | isExclusive.Enabled = true;
84 | foreach (Control con in boxes[i].Controls)
85 | {
86 | con.Enabled = true;
87 | }
88 | }
89 | }
90 | }
91 | }
92 |
93 | private void UpdateInfo(ControllerDevice[] dev)
94 | {
95 | for (int i = 0; i < 4; i++)
96 | {
97 | if (dev[i] != null)
98 | {
99 | boxes[i].Visible = true;
100 | boxes[i].Text = (i + 1).ToString() + ": " + dev[i].name;
101 | checks[i].Visible = true;
102 | }
103 | else
104 | {
105 | boxes[i].Visible = false;
106 | checks[i].Visible = false;
107 | }
108 | }
109 | }
110 |
111 | private void Swap(int i, int p)
112 | {
113 | bool s = checks[i - 1].Checked;
114 | checks[i- 1].Checked = checks[p - 1].Checked;
115 | checks[p - 1].Checked = s;
116 | controllerManager.Swap(i, p);
117 |
118 | UpdateInfo(controllerManager.detectControllers());
119 | }
120 |
121 |
122 |
123 | private void enabledChanged(int i)
124 | {
125 | boxes[i].Enabled = checks[i].Checked;
126 | controllerManager.setControllerEnable(i, checks[i].Checked);
127 | }
128 |
129 | private void openOptions(int i)
130 | {
131 | if (optionsWindow == null)
132 | {
133 | optionsWindow = new ControllerOptions(controllerManager.getController(i));
134 | optionsWindow.Show();
135 | optionsWindow.Activate();
136 | optionsWindow.FormClosed += (sender, e) => { optionsWindow = null; };
137 | }
138 | else
139 | {
140 | System.Media.SystemSounds.Asterisk.Play();
141 | optionsWindow.Focus();
142 | }
143 | }
144 |
145 | protected override void WndProc(ref Message m)
146 | {
147 | try
148 | {
149 | if (m.Msg == 0x0219)
150 | {
151 | lock (this)
152 | {
153 | UpdateInfo(controllerManager.detectControllers());
154 | }
155 | }
156 | }
157 | catch { }
158 |
159 | base.WndProc(ref m);
160 | }
161 |
162 | private void isExclusive_CheckedChanged(object sender, EventArgs e)
163 | {
164 | controllerManager.changeExclusive(!controllerManager.isExclusive);
165 | }
166 |
167 |
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/XOutput/XOutput.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {3FA04C64-23DE-4294-B9D7-47BBFFB57539}
8 | WinExe
9 | Properties
10 | XOutput
11 | XOutput
12 | v4.5
13 | 512
14 | false
15 | publish\
16 | true
17 | Disk
18 | false
19 | Foreground
20 | 7
21 | Days
22 | false
23 | false
24 | true
25 | 0
26 | 1.0.0.%2a
27 | false
28 | true
29 |
30 |
31 | x86
32 | true
33 | full
34 | false
35 | bin\Debug\
36 | DEBUG;TRACE
37 | prompt
38 | 4
39 | true
40 |
41 |
42 | AnyCPU
43 | pdbonly
44 | true
45 | bin\Release\
46 | TRACE
47 | prompt
48 | 4
49 | true
50 |
51 |
52 |
53 |
54 |
55 |
56 | XOutput_Icon.ico
57 |
58 |
59 | true
60 |
61 |
62 | false
63 |
64 |
65 | x86
66 | bin\x86\Debug\
67 |
68 |
69 | x86
70 | bin\x86\Release\
71 |
72 |
73 |
74 | False
75 | ..\..\..\..\..\..\..\Windows\Microsoft.NET\assembly\GAC_32\SlimDX\v4.0_4.0.13.43__b1b0c32fd1ffe4f9\SlimDX.dll
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 | Form
93 |
94 |
95 | ControllerOptions.cs
96 |
97 |
98 |
99 | Component
100 |
101 |
102 |
103 |
104 |
105 |
106 | Form
107 |
108 |
109 | XOut.cs
110 |
111 |
112 | ResXFileCodeGenerator
113 | Resources.Designer.cs
114 | Designer
115 |
116 |
117 | True
118 | Resources.resx
119 | True
120 |
121 |
122 | XOut.cs
123 |
124 |
125 | SettingsSingleFileGenerator
126 | Settings.Designer.cs
127 |
128 |
129 | True
130 | Settings.settings
131 | True
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 | False
140 | Microsoft .NET Framework 4.5 %28x86 and x64%29
141 | true
142 |
143 |
144 | False
145 | .NET Framework 3.5 SP1 Client Profile
146 | false
147 |
148 |
149 | False
150 | .NET Framework 3.5 SP1
151 | false
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
177 |
--------------------------------------------------------------------------------
/XOutput/XOutput.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | publish\
5 |
6 |
7 |
8 |
9 |
10 | en-US
11 | false
12 |
13 |
--------------------------------------------------------------------------------
/XOutput/XOutput_Icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mintos5/XOutput/c878b3c3b6c5e1714d300f630c4fb2cddc32374a/XOutput/XOutput_Icon.ico
--------------------------------------------------------------------------------