Skip to content

Commit 1ab05fd

Browse files
committed
Add Guide button support (thanks benblo), and various fixes.
1 parent b169811 commit 1ab05fd

File tree

19 files changed

+120
-37
lines changed

19 files changed

+120
-37
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
*.xcuserdatad
2626
*.orig
2727
*.meta
28+
*.unityPackage
2829
obj/
2930
Binaries/
3031
XInputUnity/Library/

Build/UpdateUnityProject.bat

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ if not exist ..\XInputUnity\Assets\Plugins\x86 md ..\XInputUnity\Assets\Plugins\
77
if not exist ..\XInputUnity\Assets\Plugins\x86_64 md ..\XInputUnity\Assets\Plugins\x86_64
88

99
copy ..\BinariesX86\Release\XInputInterface.dll ..\XInputUnity\Assets\Plugins\x86\
10+
copy ..\BinariesX86\Release\XInputInterface.dll ..\XInputUnity\
1011
copy ..\BinariesX86\Release\XInputDotNetPure.dll ..\XInputUnity\Assets\Plugins\x86\
1112

1213
copy ..\BinariesX64\Release\XInputInterface.dll ..\XInputUnity\Assets\Plugins\x86_64\

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ Some examples are available in this repository :
4242
* Copy `[Project Folder]\Assets\Plugins\x86\XInputInterface.dll` to `[Project Folder]\XInputInterface.dll`
4343
* **Making a Build does NOT require to copy `XInputInterface.dll` in the same folder the your game .exe file**
4444

45+
**NOTE** : you may see this error message but it should still work as expected, the message won't appear in a Build
46+
47+
![License Error Message](https://raw.github.com/speps/XInputDotNet/master/XInputUnity/LicenseError.jpg)
48+
4549
### Notes
4650

4751
* Under Windows XP, you'll need special drivers for your Xbox 360 Controller. You can find them at this address : [XBox 360 Controller for Windows Software](http://www.microsoft.com/en-us/download/details.aspx?id=34001)

XInputDemo/Program.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ static void Main(string[] args)
1414
Console.WriteLine("IsConnected {0} Packet #{1}", state.IsConnected, state.PacketNumber);
1515
Console.WriteLine("\tTriggers {0} {1}", state.Triggers.Left, state.Triggers.Right);
1616
Console.WriteLine("\tD-Pad {0} {1} {2} {3}", state.DPad.Up, state.DPad.Right, state.DPad.Down, state.DPad.Left);
17-
Console.WriteLine("\tButtons Start {0} Back {1} LeftStick {2} RightStick {3} LeftShoulder {4} RightShoulder {5} A {6} B {7} X {8} Y {9}", state.Buttons.Start, state.Buttons.Back, state.Buttons.LeftStick, state.Buttons.RightStick, state.Buttons.LeftShoulder, state.Buttons.RightShoulder, state.Buttons.A, state.Buttons.B, state.Buttons.X, state.Buttons.Y);
17+
Console.WriteLine("\tButtons Start {0} Back {1} LeftStick {2} RightStick {3} LeftShoulder {4} RightShoulder {5} Guide {6} A {7} B {9} X {9} Y {10}",
18+
state.Buttons.Start, state.Buttons.Back, state.Buttons.LeftStick, state.Buttons.RightStick, state.Buttons.LeftShoulder, state.Buttons.RightShoulder,
19+
state.Buttons.Guide, state.Buttons.A, state.Buttons.B, state.Buttons.X, state.Buttons.Y);
1820
Console.WriteLine("\tSticks Left {0} {1} Right {2} {3}", state.ThumbSticks.Left.X, state.ThumbSticks.Left.Y, state.ThumbSticks.Right.X, state.ThumbSticks.Right.Y);
1921
GamePad.SetVibration(PlayerIndex.One, state.Triggers.Left, state.Triggers.Right);
2022
Thread.Sleep(16);

XInputDotNetPure/GamePad.cs

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@
33

44
namespace XInputDotNetPure
55
{
6-
76
class Imports
87
{
98
internal const string DLLName = "XInputInterface";
109

1110
[DllImport(DLLName)]
12-
public static extern uint XInputGamePadGetState(uint playerIndex, IntPtr state);
11+
public static extern uint XInputGamePadGetState(uint playerIndex, out GamePadState.RawState state);
1312
[DllImport(DLLName)]
1413
public static extern void XInputGamePadSetState(uint playerIndex, float leftMotor, float rightMotor);
1514
}
@@ -22,18 +21,19 @@ public enum ButtonState
2221

2322
public struct GamePadButtons
2423
{
25-
ButtonState start, back, leftStick, rightStick, leftShoulder, rightShoulder, a, b, x, y;
24+
ButtonState start, back, leftStick, rightStick, leftShoulder, rightShoulder, guide, a, b, x, y;
2625

2726
internal GamePadButtons(ButtonState start, ButtonState back, ButtonState leftStick, ButtonState rightStick,
28-
ButtonState leftShoulder, ButtonState rightShoulder, ButtonState a, ButtonState b,
29-
ButtonState x, ButtonState y)
27+
ButtonState leftShoulder, ButtonState rightShoulder, ButtonState guide,
28+
ButtonState a, ButtonState b, ButtonState x, ButtonState y)
3029
{
3130
this.start = start;
3231
this.back = back;
3332
this.leftStick = leftStick;
3433
this.rightStick = rightStick;
3534
this.leftShoulder = leftShoulder;
3635
this.rightShoulder = rightShoulder;
36+
this.guide = guide;
3737
this.a = a;
3838
this.b = b;
3939
this.x = x;
@@ -70,6 +70,11 @@ public ButtonState RightShoulder
7070
get { return rightShoulder; }
7171
}
7272

73+
public ButtonState Guide
74+
{
75+
get { return guide; }
76+
}
77+
7378
public ButtonState A
7479
{
7580
get { return a; }
@@ -190,14 +195,16 @@ public float Right
190195

191196
public struct GamePadState
192197
{
198+
[StructLayout(LayoutKind.Sequential)]
193199
internal struct RawState
194200
{
195201
public uint dwPacketNumber;
196202
public GamePad Gamepad;
197203

204+
[StructLayout(LayoutKind.Sequential)]
198205
public struct GamePad
199206
{
200-
public ushort dwButtons;
207+
public ushort wButtons;
201208
public byte bLeftTrigger;
202209
public byte bRightTrigger;
203210
public short sThumbLX;
@@ -226,6 +233,7 @@ enum ButtonsConstants
226233
RightThumb = 0x00000080,
227234
LeftShoulder = 0x0100,
228235
RightShoulder = 0x0200,
236+
Guide = 0x0400,
229237
A = 0x1000,
230238
B = 0x2000,
231239
X = 0x4000,
@@ -239,7 +247,7 @@ internal GamePadState(bool isConnected, RawState rawState, GamePadDeadZone deadZ
239247
if (!isConnected)
240248
{
241249
rawState.dwPacketNumber = 0;
242-
rawState.Gamepad.dwButtons = 0;
250+
rawState.Gamepad.wButtons = 0;
243251
rawState.Gamepad.bLeftTrigger = 0;
244252
rawState.Gamepad.bRightTrigger = 0;
245253
rawState.Gamepad.sThumbLX = 0;
@@ -250,22 +258,23 @@ internal GamePadState(bool isConnected, RawState rawState, GamePadDeadZone deadZ
250258

251259
packetNumber = rawState.dwPacketNumber;
252260
buttons = new GamePadButtons(
253-
(rawState.Gamepad.dwButtons & (uint)ButtonsConstants.Start) != 0 ? ButtonState.Pressed : ButtonState.Released,
254-
(rawState.Gamepad.dwButtons & (uint)ButtonsConstants.Back) != 0 ? ButtonState.Pressed : ButtonState.Released,
255-
(rawState.Gamepad.dwButtons & (uint)ButtonsConstants.LeftThumb) != 0 ? ButtonState.Pressed : ButtonState.Released,
256-
(rawState.Gamepad.dwButtons & (uint)ButtonsConstants.RightThumb) != 0 ? ButtonState.Pressed : ButtonState.Released,
257-
(rawState.Gamepad.dwButtons & (uint)ButtonsConstants.LeftShoulder) != 0 ? ButtonState.Pressed : ButtonState.Released,
258-
(rawState.Gamepad.dwButtons & (uint)ButtonsConstants.RightShoulder) != 0 ? ButtonState.Pressed : ButtonState.Released,
259-
(rawState.Gamepad.dwButtons & (uint)ButtonsConstants.A) != 0 ? ButtonState.Pressed : ButtonState.Released,
260-
(rawState.Gamepad.dwButtons & (uint)ButtonsConstants.B) != 0 ? ButtonState.Pressed : ButtonState.Released,
261-
(rawState.Gamepad.dwButtons & (uint)ButtonsConstants.X) != 0 ? ButtonState.Pressed : ButtonState.Released,
262-
(rawState.Gamepad.dwButtons & (uint)ButtonsConstants.Y) != 0 ? ButtonState.Pressed : ButtonState.Released
261+
(rawState.Gamepad.wButtons & (uint)ButtonsConstants.Start) != 0 ? ButtonState.Pressed : ButtonState.Released,
262+
(rawState.Gamepad.wButtons & (uint)ButtonsConstants.Back) != 0 ? ButtonState.Pressed : ButtonState.Released,
263+
(rawState.Gamepad.wButtons & (uint)ButtonsConstants.LeftThumb) != 0 ? ButtonState.Pressed : ButtonState.Released,
264+
(rawState.Gamepad.wButtons & (uint)ButtonsConstants.RightThumb) != 0 ? ButtonState.Pressed : ButtonState.Released,
265+
(rawState.Gamepad.wButtons & (uint)ButtonsConstants.LeftShoulder) != 0 ? ButtonState.Pressed : ButtonState.Released,
266+
(rawState.Gamepad.wButtons & (uint)ButtonsConstants.RightShoulder) != 0 ? ButtonState.Pressed : ButtonState.Released,
267+
(rawState.Gamepad.wButtons & (uint)ButtonsConstants.Guide) != 0 ? ButtonState.Pressed : ButtonState.Released,
268+
(rawState.Gamepad.wButtons & (uint)ButtonsConstants.A) != 0 ? ButtonState.Pressed : ButtonState.Released,
269+
(rawState.Gamepad.wButtons & (uint)ButtonsConstants.B) != 0 ? ButtonState.Pressed : ButtonState.Released,
270+
(rawState.Gamepad.wButtons & (uint)ButtonsConstants.X) != 0 ? ButtonState.Pressed : ButtonState.Released,
271+
(rawState.Gamepad.wButtons & (uint)ButtonsConstants.Y) != 0 ? ButtonState.Pressed : ButtonState.Released
263272
);
264273
dPad = new GamePadDPad(
265-
(rawState.Gamepad.dwButtons & (uint)ButtonsConstants.DPadUp) != 0 ? ButtonState.Pressed : ButtonState.Released,
266-
(rawState.Gamepad.dwButtons & (uint)ButtonsConstants.DPadDown) != 0 ? ButtonState.Pressed : ButtonState.Released,
267-
(rawState.Gamepad.dwButtons & (uint)ButtonsConstants.DPadLeft) != 0 ? ButtonState.Pressed : ButtonState.Released,
268-
(rawState.Gamepad.dwButtons & (uint)ButtonsConstants.DPadRight) != 0 ? ButtonState.Pressed : ButtonState.Released
274+
(rawState.Gamepad.wButtons & (uint)ButtonsConstants.DPadUp) != 0 ? ButtonState.Pressed : ButtonState.Released,
275+
(rawState.Gamepad.wButtons & (uint)ButtonsConstants.DPadDown) != 0 ? ButtonState.Pressed : ButtonState.Released,
276+
(rawState.Gamepad.wButtons & (uint)ButtonsConstants.DPadLeft) != 0 ? ButtonState.Pressed : ButtonState.Released,
277+
(rawState.Gamepad.wButtons & (uint)ButtonsConstants.DPadRight) != 0 ? ButtonState.Pressed : ButtonState.Released
269278
);
270279

271280
thumbSticks = new GamePadThumbSticks(
@@ -333,10 +342,8 @@ public static GamePadState GetState(PlayerIndex playerIndex)
333342

334343
public static GamePadState GetState(PlayerIndex playerIndex, GamePadDeadZone deadZone)
335344
{
336-
IntPtr gamePadStatePointer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(GamePadState.RawState)));
337-
uint result = Imports.XInputGamePadGetState((uint)playerIndex, gamePadStatePointer);
338-
GamePadState.RawState state = (GamePadState.RawState)Marshal.PtrToStructure(gamePadStatePointer, typeof(GamePadState.RawState));
339-
Marshal.FreeHGlobal(gamePadStatePointer);
345+
GamePadState.RawState state;
346+
uint result = Imports.XInputGamePadGetState((uint)playerIndex, out state);
340347
return new GamePadState(result == Utils.Success, state, deadZone);
341348
}
342349

XInputInterface/GamePad.cpp

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,46 @@
11
#include "GamePad.h"
22

3-
DWORD XInputGamePadGetState(DWORD dwUserIndex, XINPUT_STATE *pState)
3+
namespace
44
{
5-
return XInputGetState(dwUserIndex, pState);
5+
typedef DWORD (*XInputGetStatePointer)(DWORD dwUserIndex, XINPUT_STATE* pState);
6+
typedef DWORD (*XInputSetStatePointer)(DWORD dwUserIndex, XINPUT_VIBRATION* pVibration);
7+
8+
class XInputLoader
9+
{
10+
public:
11+
XInputLoader()
12+
: mHandle(0), mGetState(0), mSetState(0)
13+
{
14+
mHandle = LoadLibrary("xinput1_3.dll");
15+
16+
// Ordinal 100 is the same as XInputGetState but supports the Guide button.
17+
mGetState = (XInputGetStatePointer)GetProcAddress(mHandle, (LPCSTR)100);
18+
19+
mSetState = (XInputSetStatePointer)GetProcAddress(mHandle, "XInputSetState");
20+
}
21+
22+
~XInputLoader()
23+
{
24+
FreeLibrary(mHandle);
25+
}
26+
27+
XInputGetStatePointer mGetState;
28+
XInputSetStatePointer mSetState;
29+
30+
private:
31+
HMODULE mHandle;
32+
};
33+
34+
XInputLoader gXInputLoader;
35+
}
36+
37+
DWORD XInputGamePadGetState(DWORD dwUserIndex, XINPUT_STATE* pState)
38+
{
39+
return gXInputLoader.mGetState(dwUserIndex, pState);
640
}
741

842
void XInputGamePadSetState(DWORD dwUserIndex, float leftMotor, float rightMotor)
943
{
10-
XINPUT_VIBRATION vibration = { (int)(leftMotor * 65535), (int)(rightMotor * 65535) };
11-
XInputSetState(dwUserIndex, &vibration);
44+
XINPUT_VIBRATION vibration = { (int)(leftMotor * 65535), (int)(rightMotor * 65535) };
45+
gXInputLoader.mSetState(dwUserIndex, &vibration);
1246
}

XInputInterface/XInputInterface.vcxproj

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@
8787
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
8888
</ClCompile>
8989
<Link>
90-
<AdditionalDependencies>XInput.lib;%(AdditionalDependencies)</AdditionalDependencies>
9190
<GenerateDebugInformation>true</GenerateDebugInformation>
9291
<TargetMachine>MachineX86</TargetMachine>
9392
<ImportLibrary>$(IntDir)\$(TargetName).lib</ImportLibrary>
@@ -103,7 +102,6 @@
103102
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
104103
</ClCompile>
105104
<Link>
106-
<AdditionalDependencies>XInput.lib;%(AdditionalDependencies)</AdditionalDependencies>
107105
<GenerateDebugInformation>true</GenerateDebugInformation>
108106
<ImportLibrary>$(IntDir)\$(TargetName).lib</ImportLibrary>
109107
</Link>
@@ -119,7 +117,6 @@
119117
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
120118
</ClCompile>
121119
<Link>
122-
<AdditionalDependencies>XInput.lib;%(AdditionalDependencies)</AdditionalDependencies>
123120
<GenerateDebugInformation>false</GenerateDebugInformation>
124121
<OptimizeReferences>true</OptimizeReferences>
125122
<EnableCOMDATFolding>true</EnableCOMDATFolding>
@@ -138,7 +135,6 @@
138135
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
139136
</ClCompile>
140137
<Link>
141-
<AdditionalDependencies>XInput.lib;%(AdditionalDependencies)</AdditionalDependencies>
142138
<GenerateDebugInformation>false</GenerateDebugInformation>
143139
<OptimizeReferences>true</OptimizeReferences>
144140
<EnableCOMDATFolding>true</EnableCOMDATFolding>

XInputReporter/MainForm.Designer.cs

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

XInputReporter/MainForm.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ private void UpdateState()
7979
checkY.Checked = reporterState.LastActiveState.Buttons.Y == XInputDotNetPure.ButtonState.Pressed;
8080
checkStart.Checked = reporterState.LastActiveState.Buttons.Start == XInputDotNetPure.ButtonState.Pressed;
8181
checkBack.Checked = reporterState.LastActiveState.Buttons.Back == XInputDotNetPure.ButtonState.Pressed;
82+
checkGuide.Checked = reporterState.LastActiveState.Buttons.Guide == XInputDotNetPure.ButtonState.Pressed;
8283
checkStickLeft.Checked = reporterState.LastActiveState.Buttons.LeftStick == XInputDotNetPure.ButtonState.Pressed;
8384
checkStickRight.Checked = reporterState.LastActiveState.Buttons.RightStick == XInputDotNetPure.ButtonState.Pressed;
8485
checkShoulderLeft.Checked = reporterState.LastActiveState.Buttons.LeftShoulder == XInputDotNetPure.ButtonState.Pressed;

XInputReporter/ReporterState.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,16 @@ public bool Poll()
4444
}
4545
}
4646

47-
GamePad.SetVibration(playerIndices[lastActivePlayerIndex], 0.0f, 0.0f);
48-
4947
lastActivePlayerIndex = activePlayerIndex;
5048

5149
if (LinkTriggersToVibration)
5250
{
5351
GamePad.SetVibration(playerIndices[lastActivePlayerIndex], LastActiveState.Triggers.Left, LastActiveState.Triggers.Right);
5452
}
53+
else
54+
{
55+
GamePad.SetVibration(playerIndices[lastActivePlayerIndex], 0.0f, 0.0f);
56+
}
5557

5658
return changed;
5759
}

0 commit comments

Comments
 (0)