Input: DirectInput support - most controllers/gamepads should now work. XInput is still prioritized when available.

This commit is contained in:
Souryo 2016-07-16 16:25:57 -04:00
parent 50a3d16bf0
commit 726d72c103
19 changed files with 697 additions and 411 deletions

View file

@ -213,6 +213,9 @@ void ControlManager::WriteRAM(uint16_t addr, uint8_t value)
void ControlManager::Reset(bool softReset) void ControlManager::Reset(bool softReset)
{ {
if(_keyManager != nullptr) {
_keyManager->UpdateDevices();
}
} }
void ControlManager::StreamState(bool saving) void ControlManager::StreamState(bool saving)

View file

@ -13,6 +13,7 @@ class IKeyManager
{ {
public: public:
virtual void RefreshState() = 0; virtual void RefreshState() = 0;
virtual void UpdateDevices() = 0;
virtual bool IsMouseButtonPressed(MouseButton button) = 0; virtual bool IsMouseButtonPressed(MouseButton button) = 0;
virtual bool IsKeyPressed(uint32_t keyCode) = 0; virtual bool IsKeyPressed(uint32_t keyCode) = 0;
virtual uint32_t GetPressedKey() = 0; virtual uint32_t GetPressedKey() = 0;

View file

@ -42,6 +42,7 @@ namespace Mesen.GUI.Config
TurboA = "Z"; TurboA = "Z";
TurboB = "X"; TurboB = "X";
} else if(keySetIndex == 1) { } else if(keySetIndex == 1) {
//XInput Default (Xbox controllers)
A = "Pad1 A"; A = "Pad1 A";
B = "Pad1 X"; B = "Pad1 X";
Select = "Pad1 Back"; Select = "Pad1 Back";
@ -53,6 +54,19 @@ namespace Mesen.GUI.Config
TurboA = "Pad1 B"; TurboA = "Pad1 B";
TurboB = "Pad1 Y"; TurboB = "Pad1 Y";
} else if(keySetIndex == 2) {
//DirectInput Default (Used PS4 controller as a default)
A = "Joy1 But2";
B = "Joy1 But1";
Select = "Joy1 But9";
Start = "Joy1 But10";
Up = "Joy1 DPad Up";
Down = "Joy1 DPad Down";
Left = "Joy1 DPad Left";
Right = "Joy1 DPad Right";
TurboA = "Joy1 But3";
TurboB = "Joy1 But4";
} }
} else if(controllerIndex == 1) { } else if(controllerIndex == 1) {
if(keySetIndex == 0) { if(keySetIndex == 0) {
@ -68,6 +82,7 @@ namespace Mesen.GUI.Config
TurboA = "B"; TurboA = "B";
TurboB = "N"; TurboB = "N";
} else if(keySetIndex == 1) { } else if(keySetIndex == 1) {
//XInput Default (Xbox controllers)
A = "Pad2 A"; A = "Pad2 A";
B = "Pad2 X"; B = "Pad2 X";
Select = "Pad2 Back"; Select = "Pad2 Back";
@ -79,6 +94,19 @@ namespace Mesen.GUI.Config
TurboA = "Pad2 B"; TurboA = "Pad2 B";
TurboB = "Pad2 Y"; TurboB = "Pad2 Y";
} else if(keySetIndex == 2) {
//DirectInput Default (Used PS4 controller as a default)
A = "Joy2 But2";
B = "Joy2 But1";
Select = "Joy2 But9";
Start = "Joy2 But10";
Up = "Joy2 DPad Up";
Down = "Joy2 DPad Down";
Left = "Joy2 DPad Left";
Right = "Joy2 DPad Right";
TurboA = "Joy2 But3";
TurboB = "Joy2 But4";
} }
} }
} }
@ -144,6 +172,7 @@ namespace Mesen.GUI.Config
if(Controllers.Count <= 1) { if(Controllers.Count <= 1) {
controllerInfo.Keys.Add(new KeyMappings(Controllers.Count, 0)); controllerInfo.Keys.Add(new KeyMappings(Controllers.Count, 0));
controllerInfo.Keys.Add(new KeyMappings(Controllers.Count, 1)); controllerInfo.Keys.Add(new KeyMappings(Controllers.Count, 1));
controllerInfo.Keys.Add(new KeyMappings(Controllers.Count, 2));
} }
Controllers.Add(controllerInfo); Controllers.Add(controllerInfo);
} }

View file

@ -29,17 +29,17 @@
{ {
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ctrlStandardController)); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ctrlStandardController));
this.panel2 = new System.Windows.Forms.Panel(); this.panel2 = new System.Windows.Forms.Panel();
this.picControllerLayout = new System.Windows.Forms.PictureBox();
this.btnA = new System.Windows.Forms.Button();
this.btnDown = new System.Windows.Forms.Button();
this.btnUp = new System.Windows.Forms.Button();
this.btnStart = new System.Windows.Forms.Button();
this.btnB = new System.Windows.Forms.Button();
this.btnTurboA = new System.Windows.Forms.Button();
this.btnLeft = new System.Windows.Forms.Button();
this.btnSelect = new System.Windows.Forms.Button();
this.btnRight = new System.Windows.Forms.Button();
this.btnTurboB = new System.Windows.Forms.Button(); this.btnTurboB = new System.Windows.Forms.Button();
this.btnRight = new System.Windows.Forms.Button();
this.btnSelect = new System.Windows.Forms.Button();
this.btnLeft = new System.Windows.Forms.Button();
this.btnTurboA = new System.Windows.Forms.Button();
this.btnB = new System.Windows.Forms.Button();
this.btnStart = new System.Windows.Forms.Button();
this.btnUp = new System.Windows.Forms.Button();
this.btnDown = new System.Windows.Forms.Button();
this.btnA = new System.Windows.Forms.Button();
this.picControllerLayout = new System.Windows.Forms.PictureBox();
this.panel2.SuspendLayout(); this.panel2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.picControllerLayout)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.picControllerLayout)).BeginInit();
this.SuspendLayout(); this.SuspendLayout();
@ -64,64 +64,45 @@
this.panel2.Size = new System.Drawing.Size(585, 210); this.panel2.Size = new System.Drawing.Size(585, 210);
this.panel2.TabIndex = 3; this.panel2.TabIndex = 3;
// //
// picControllerLayout // btnTurboB
// //
this.picControllerLayout.Image = ((System.Drawing.Image)(resources.GetObject("picControllerLayout.Image"))); this.btnTurboB.Location = new System.Drawing.Point(417, 17);
this.picControllerLayout.Location = new System.Drawing.Point(0, 0); this.btnTurboB.Name = "btnTurboB";
this.picControllerLayout.Name = "picControllerLayout"; this.btnTurboB.Size = new System.Drawing.Size(61, 59);
this.picControllerLayout.Size = new System.Drawing.Size(615, 211); this.btnTurboB.TabIndex = 21;
this.picControllerLayout.TabIndex = 11; this.btnTurboB.Text = "B";
this.picControllerLayout.TabStop = false; this.btnTurboB.UseVisualStyleBackColor = true;
this.btnTurboB.Click += new System.EventHandler(this.btnMapping_Click);
// //
// btnA // btnRight
// //
this.btnA.Location = new System.Drawing.Point(499, 105); this.btnRight.Location = new System.Drawing.Point(105, 90);
this.btnA.Name = "btnA"; this.btnRight.Name = "btnRight";
this.btnA.Size = new System.Drawing.Size(61, 59); this.btnRight.Size = new System.Drawing.Size(69, 35);
this.btnA.TabIndex = 14; this.btnRight.TabIndex = 16;
this.btnA.Text = "A"; this.btnRight.Text = "Right";
this.btnA.UseVisualStyleBackColor = true; this.btnRight.UseVisualStyleBackColor = true;
this.btnA.Click += new System.EventHandler(this.btnMapping_Click); this.btnRight.Click += new System.EventHandler(this.btnMapping_Click);
// //
// btnDown // btnSelect
// //
this.btnDown.Location = new System.Drawing.Point(68, 141); this.btnSelect.Location = new System.Drawing.Point(228, 131);
this.btnDown.Name = "btnDown"; this.btnSelect.Name = "btnSelect";
this.btnDown.Size = new System.Drawing.Size(64, 35); this.btnSelect.Size = new System.Drawing.Size(73, 37);
this.btnDown.TabIndex = 19; this.btnSelect.TabIndex = 12;
this.btnDown.Text = "Down"; this.btnSelect.Text = "Q";
this.btnDown.UseVisualStyleBackColor = true; this.btnSelect.UseVisualStyleBackColor = true;
this.btnDown.Click += new System.EventHandler(this.btnMapping_Click); this.btnSelect.Click += new System.EventHandler(this.btnMapping_Click);
// //
// btnUp // btnLeft
// //
this.btnUp.Location = new System.Drawing.Point(68, 34); this.btnLeft.Location = new System.Drawing.Point(27, 90);
this.btnUp.Name = "btnUp"; this.btnLeft.Name = "btnLeft";
this.btnUp.Size = new System.Drawing.Size(64, 35); this.btnLeft.Size = new System.Drawing.Size(69, 35);
this.btnUp.TabIndex = 18; this.btnLeft.TabIndex = 17;
this.btnUp.Text = "Up"; this.btnLeft.Text = "Left";
this.btnUp.UseVisualStyleBackColor = true; this.btnLeft.UseVisualStyleBackColor = true;
this.btnUp.Click += new System.EventHandler(this.btnMapping_Click); this.btnLeft.Click += new System.EventHandler(this.btnMapping_Click);
//
// btnStart
//
this.btnStart.Location = new System.Drawing.Point(316, 131);
this.btnStart.Name = "btnStart";
this.btnStart.Size = new System.Drawing.Size(61, 37);
this.btnStart.TabIndex = 13;
this.btnStart.Text = "W";
this.btnStart.UseVisualStyleBackColor = true;
this.btnStart.Click += new System.EventHandler(this.btnMapping_Click);
//
// btnB
//
this.btnB.Location = new System.Drawing.Point(417, 105);
this.btnB.Name = "btnB";
this.btnB.Size = new System.Drawing.Size(61, 59);
this.btnB.TabIndex = 15;
this.btnB.Text = "B";
this.btnB.UseVisualStyleBackColor = true;
this.btnB.Click += new System.EventHandler(this.btnMapping_Click);
// //
// btnTurboA // btnTurboA
// //
@ -133,45 +114,64 @@
this.btnTurboA.UseVisualStyleBackColor = true; this.btnTurboA.UseVisualStyleBackColor = true;
this.btnTurboA.Click += new System.EventHandler(this.btnMapping_Click); this.btnTurboA.Click += new System.EventHandler(this.btnMapping_Click);
// //
// btnLeft // btnB
// //
this.btnLeft.Location = new System.Drawing.Point(29, 90); this.btnB.Location = new System.Drawing.Point(417, 105);
this.btnLeft.Name = "btnLeft"; this.btnB.Name = "btnB";
this.btnLeft.Size = new System.Drawing.Size(64, 35); this.btnB.Size = new System.Drawing.Size(61, 59);
this.btnLeft.TabIndex = 17; this.btnB.TabIndex = 15;
this.btnLeft.Text = "Left"; this.btnB.Text = "B";
this.btnLeft.UseVisualStyleBackColor = true; this.btnB.UseVisualStyleBackColor = true;
this.btnLeft.Click += new System.EventHandler(this.btnMapping_Click); this.btnB.Click += new System.EventHandler(this.btnMapping_Click);
// //
// btnSelect // btnStart
// //
this.btnSelect.Location = new System.Drawing.Point(234, 131); this.btnStart.Location = new System.Drawing.Point(310, 131);
this.btnSelect.Name = "btnSelect"; this.btnStart.Name = "btnStart";
this.btnSelect.Size = new System.Drawing.Size(61, 37); this.btnStart.Size = new System.Drawing.Size(73, 37);
this.btnSelect.TabIndex = 12; this.btnStart.TabIndex = 13;
this.btnSelect.Text = "Q"; this.btnStart.Text = "W";
this.btnSelect.UseVisualStyleBackColor = true; this.btnStart.UseVisualStyleBackColor = true;
this.btnSelect.Click += new System.EventHandler(this.btnMapping_Click); this.btnStart.Click += new System.EventHandler(this.btnMapping_Click);
// //
// btnRight // btnUp
// //
this.btnRight.Location = new System.Drawing.Point(108, 90); this.btnUp.Location = new System.Drawing.Point(61, 34);
this.btnRight.Name = "btnRight"; this.btnUp.Name = "btnUp";
this.btnRight.Size = new System.Drawing.Size(64, 35); this.btnUp.Size = new System.Drawing.Size(79, 35);
this.btnRight.TabIndex = 16; this.btnUp.TabIndex = 18;
this.btnRight.Text = "Right"; this.btnUp.Text = "Up";
this.btnRight.UseVisualStyleBackColor = true; this.btnUp.UseVisualStyleBackColor = true;
this.btnRight.Click += new System.EventHandler(this.btnMapping_Click); this.btnUp.Click += new System.EventHandler(this.btnMapping_Click);
// //
// btnTurboB // btnDown
// //
this.btnTurboB.Location = new System.Drawing.Point(417, 17); this.btnDown.Location = new System.Drawing.Point(61, 141);
this.btnTurboB.Name = "btnTurboB"; this.btnDown.Name = "btnDown";
this.btnTurboB.Size = new System.Drawing.Size(61, 59); this.btnDown.Size = new System.Drawing.Size(79, 35);
this.btnTurboB.TabIndex = 21; this.btnDown.TabIndex = 19;
this.btnTurboB.Text = "B"; this.btnDown.Text = "Down";
this.btnTurboB.UseVisualStyleBackColor = true; this.btnDown.UseVisualStyleBackColor = true;
this.btnTurboB.Click += new System.EventHandler(this.btnMapping_Click); this.btnDown.Click += new System.EventHandler(this.btnMapping_Click);
//
// btnA
//
this.btnA.Location = new System.Drawing.Point(499, 105);
this.btnA.Name = "btnA";
this.btnA.Size = new System.Drawing.Size(61, 59);
this.btnA.TabIndex = 14;
this.btnA.Text = "A";
this.btnA.UseVisualStyleBackColor = true;
this.btnA.Click += new System.EventHandler(this.btnMapping_Click);
//
// picControllerLayout
//
this.picControllerLayout.Image = ((System.Drawing.Image)(resources.GetObject("picControllerLayout.Image")));
this.picControllerLayout.Location = new System.Drawing.Point(0, 0);
this.picControllerLayout.Name = "picControllerLayout";
this.picControllerLayout.Size = new System.Drawing.Size(615, 211);
this.picControllerLayout.TabIndex = 11;
this.picControllerLayout.TabStop = false;
// //
// ctrlStandardController // ctrlStandardController
// //
@ -192,7 +192,6 @@
private System.Windows.Forms.Button btnTurboB; private System.Windows.Forms.Button btnTurboB;
private System.Windows.Forms.Button btnRight; private System.Windows.Forms.Button btnRight;
private System.Windows.Forms.Button btnSelect; private System.Windows.Forms.Button btnSelect;
private System.Windows.Forms.Button btnLeft;
private System.Windows.Forms.Button btnTurboA; private System.Windows.Forms.Button btnTurboA;
private System.Windows.Forms.Button btnB; private System.Windows.Forms.Button btnB;
private System.Windows.Forms.Button btnStart; private System.Windows.Forms.Button btnStart;
@ -200,5 +199,6 @@
private System.Windows.Forms.Button btnDown; private System.Windows.Forms.Button btnDown;
private System.Windows.Forms.Button btnA; private System.Windows.Forms.Button btnA;
private System.Windows.Forms.PictureBox picControllerLayout; private System.Windows.Forms.PictureBox picControllerLayout;
private System.Windows.Forms.Button btnLeft;
} }
} }

View file

@ -121,7 +121,7 @@
<data name="picControllerLayout.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> <data name="picControllerLayout.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value> <value>
iVBORw0KGgoAAAANSUhEUgAAAkkAAADQCAYAAAATdvWWAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO iVBORw0KGgoAAAANSUhEUgAAAkkAAADQCAYAAAATdvWWAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
vQAADr0BR/uQrQAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC41ZYUyZQAAJNpJREFUeF7t3Qm0 vAAADrwBlbxySQAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC41ZYUyZQAAJNpJREFUeF7t3Qm0
LFtd33EH1Cc85IHMM4iC+hhEoqBomFTCEEFBEUGJosKKWWGtkKwMJpiY2aVkxQEFFAgODBGCKIoI7ykR LFtd33EH1Cc85IHMM4iC+hhEoqBomFTCEEFBEUGJosKKWWGtkKwMJpiY2aVkxQEFFAgODBGCKIoI7ykR
UVRQEGWeZZ4RNCjk9+3ade3bd29ud93d53RVf39rfQ69e3efc26dXW//qV1d9Wmf/OQnJUmStKH6pCRJ UVRQEGWeZZ4RNCjk9+3ade3bd29ud93d53RVf39rfQ69e3efc26dXW//qV1d9Wmf/OQnJUmStKH6pCRJ
0rH7uwd5KEmSdOwskiRJkiqaRdLYliRJOiabtVCzQ5Ik6Zhs1kLNDkmSpGOyWQs1OyRJko7JZi3U7JAk 0rH7uwd5KEmSdOwskiRJkiqaRdLYliRJOiabtVCzQ5Ik6Zhs1kLNDkmSpGOyWQs1OyRJko7JZi3U7JAk

View file

@ -15,6 +15,7 @@ namespace Mesen.GUI.Forms.Config
public frmGetKey() public frmGetKey()
{ {
InitializeComponent(); InitializeComponent();
InteropEmu.UpdateInputDevices();
} }
public string BindedKey { get; set; } public string BindedKey { get; set; }

View file

@ -232,7 +232,7 @@
this.btnSetupP1.AutoSize = true; this.btnSetupP1.AutoSize = true;
this.btnSetupP1.Location = new System.Drawing.Point(282, 55); this.btnSetupP1.Location = new System.Drawing.Point(282, 55);
this.btnSetupP1.Name = "btnSetupP1"; this.btnSetupP1.Name = "btnSetupP1";
this.btnSetupP1.Size = new System.Drawing.Size(45, 23); this.btnSetupP1.Size = new System.Drawing.Size(56, 23);
this.btnSetupP1.TabIndex = 9; this.btnSetupP1.TabIndex = 9;
this.btnSetupP1.Text = "Setup"; this.btnSetupP1.Text = "Setup";
this.btnSetupP1.UseVisualStyleBackColor = true; this.btnSetupP1.UseVisualStyleBackColor = true;
@ -243,7 +243,7 @@
this.btnSetupP2.AutoSize = true; this.btnSetupP2.AutoSize = true;
this.btnSetupP2.Location = new System.Drawing.Point(282, 84); this.btnSetupP2.Location = new System.Drawing.Point(282, 84);
this.btnSetupP2.Name = "btnSetupP2"; this.btnSetupP2.Name = "btnSetupP2";
this.btnSetupP2.Size = new System.Drawing.Size(45, 23); this.btnSetupP2.Size = new System.Drawing.Size(56, 23);
this.btnSetupP2.TabIndex = 10; this.btnSetupP2.TabIndex = 10;
this.btnSetupP2.Text = "Setup"; this.btnSetupP2.Text = "Setup";
this.btnSetupP2.UseVisualStyleBackColor = true; this.btnSetupP2.UseVisualStyleBackColor = true;

View file

@ -17,6 +17,8 @@ namespace Mesen.GUI.Forms.Config
{ {
InitializeComponent(); InitializeComponent();
InteropEmu.UpdateInputDevices();
Entity = ConfigManager.Config.InputInfo; Entity = ConfigManager.Config.InputInfo;
if(ConfigManager.Config.InputInfo.AutoConfigureInput) { if(ConfigManager.Config.InputInfo.AutoConfigureInput) {

View file

@ -46,6 +46,7 @@ namespace Mesen.GUI
[DllImport(DLLPath)] public static extern ExpansionPortDevice GetExpansionDevice(); [DllImport(DLLPath)] public static extern ExpansionPortDevice GetExpansionDevice();
[DllImport(DLLPath)] public static extern ConsoleType GetConsoleType(); [DllImport(DLLPath)] public static extern ConsoleType GetConsoleType();
[DllImport(DLLPath)] public static extern void UpdateInputDevices();
[DllImport(DLLPath)] public static extern UInt32 GetPressedKey(); [DllImport(DLLPath)] public static extern UInt32 GetPressedKey();
[DllImport(DLLPath)] public static extern UInt32 GetKeyCode([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string keyName); [DllImport(DLLPath)] public static extern UInt32 GetKeyCode([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string keyName);
[DllImport(DLLPath, EntryPoint="GetKeyName")] private static extern IntPtr GetKeyNameWrapper(UInt32 key); [DllImport(DLLPath, EntryPoint="GetKeyName")] private static extern IntPtr GetKeyNameWrapper(UInt32 key);

View file

@ -21,6 +21,7 @@
NES::Renderer *_renderer = nullptr; NES::Renderer *_renderer = nullptr;
SoundManager *_soundManager = nullptr; SoundManager *_soundManager = nullptr;
IKeyManager *_keyManager = nullptr;
HWND _windowHandle = nullptr; HWND _windowHandle = nullptr;
HWND _viewerHandle = nullptr; HWND _viewerHandle = nullptr;
string _returnString; string _returnString;
@ -70,8 +71,9 @@ namespace InteropEmu {
_renderer = new NES::Renderer(_viewerHandle); _renderer = new NES::Renderer(_viewerHandle);
_soundManager = new SoundManager(_windowHandle); _soundManager = new SoundManager(_windowHandle);
_keyManager = new WindowsKeyManager(_windowHandle);
ControlManager::RegisterKeyManager(new WindowsKeyManager(_windowHandle)); ControlManager::RegisterKeyManager(_keyManager);
} }
} }
@ -105,6 +107,7 @@ namespace InteropEmu {
DllExport void __stdcall SetMousePosition(double x, double y) { ControlManager::SetMousePosition(x, y); } DllExport void __stdcall SetMousePosition(double x, double y) { ControlManager::SetMousePosition(x, y); }
DllExport void __stdcall UpdateInputDevices() { _keyManager->UpdateDevices(); }
DllExport uint32_t __stdcall GetPressedKey() { return ControlManager::GetPressedKey(); } DllExport uint32_t __stdcall GetPressedKey() { return ControlManager::GetPressedKey(); }
DllExport const char* __stdcall GetKeyName(uint32_t keyCode) DllExport const char* __stdcall GetKeyName(uint32_t keyCode)
{ {

View file

@ -187,7 +187,7 @@
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Xinput9_1_0.lib;d3d11.lib;d3dcompiler.lib;dxguid.lib;winmm.lib;comctl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib</AdditionalDependencies> <AdditionalDependencies>dinput8.lib;Xinput9_1_0.lib;d3d11.lib;d3dcompiler.lib;dxguid.lib;winmm.lib;comctl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@ -207,7 +207,7 @@
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Xinput9_1_0.lib;d3d11.lib;d3dcompiler.lib;dxguid.lib;winmm.lib;comctl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;</AdditionalDependencies> <AdditionalDependencies>dinput8.lib;Xinput9_1_0.lib;d3d11.lib;d3dcompiler.lib;dxguid.lib;winmm.lib;comctl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@ -230,7 +230,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>Xinput9_1_0.lib;d3d11.lib;d3dcompiler.lib;dxguid.lib;winmm.lib;comctl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;</AdditionalDependencies> <AdditionalDependencies>dinput8.lib;Xinput9_1_0.lib;d3d11.lib;d3dcompiler.lib;dxguid.lib;winmm.lib;comctl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@ -253,7 +253,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>Xinput9_1_0.lib;d3d11.lib;d3dcompiler.lib;dxguid.lib;winmm.lib;comctl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;</AdditionalDependencies> <AdditionalDependencies>dinput8.lib;Xinput9_1_0.lib;d3d11.lib;d3dcompiler.lib;dxguid.lib;winmm.lib;comctl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;</AdditionalDependencies>
<LinkTimeCodeGeneration>PGInstrument</LinkTimeCodeGeneration> <LinkTimeCodeGeneration>PGInstrument</LinkTimeCodeGeneration>
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link> </Link>
@ -276,7 +276,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>Xinput9_1_0.lib;d3d11.lib;d3dcompiler.lib;dxguid.lib;winmm.lib;comctl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;</AdditionalDependencies> <AdditionalDependencies>dinput8.lib;Xinput9_1_0.lib;d3d11.lib;d3dcompiler.lib;dxguid.lib;winmm.lib;comctl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;</AdditionalDependencies>
<LinkTimeCodeGeneration>PGOptimization</LinkTimeCodeGeneration> <LinkTimeCodeGeneration>PGOptimization</LinkTimeCodeGeneration>
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link> </Link>
@ -300,7 +300,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>Xinput9_1_0.lib;d3d11.lib;d3dcompiler.lib;dxguid.lib;winmm.lib;comctl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;</AdditionalDependencies> <AdditionalDependencies>dinput8.lib;Xinput9_1_0.lib;d3d11.lib;d3dcompiler.lib;dxguid.lib;winmm.lib;comctl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@ -323,7 +323,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>Xinput9_1_0.lib;d3d11.lib;d3dcompiler.lib;dxguid.lib;winmm.lib;comctl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;</AdditionalDependencies> <AdditionalDependencies>dinput8.lib;Xinput9_1_0.lib;d3d11.lib;d3dcompiler.lib;dxguid.lib;winmm.lib;comctl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;</AdditionalDependencies>
<LinkTimeCodeGeneration>PGInstrument</LinkTimeCodeGeneration> <LinkTimeCodeGeneration>PGInstrument</LinkTimeCodeGeneration>
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link> </Link>
@ -346,7 +346,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>Xinput9_1_0.lib;d3d11.lib;d3dcompiler.lib;dxguid.lib;winmm.lib;comctl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;</AdditionalDependencies> <AdditionalDependencies>dinput8.lib;Xinput9_1_0.lib;d3d11.lib;d3dcompiler.lib;dxguid.lib;winmm.lib;comctl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;</AdditionalDependencies>
<LinkTimeCodeGeneration>PGOptimization</LinkTimeCodeGeneration> <LinkTimeCodeGeneration>PGOptimization</LinkTimeCodeGeneration>
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link> </Link>

View file

@ -0,0 +1,235 @@
#include "stdafx.h"
#define DIRECTINPUT_VERSION 0x0800
#include <thread>
#include <windows.h>
#include <dinput.h>
#include <dinputd.h>
#include "DirectInputManager.h"
LPDIRECTINPUT8 DirectInputManager::_directInput = nullptr;
vector<DirectInputData> DirectInputManager::_joysticks;
bool DirectInputManager::Initialize()
{
HRESULT hr;
// Register with the DirectInput subsystem and get a pointer to a IDirectInput interface we can use.
// Create a DInput object
if(FAILED(hr = DirectInput8Create(GetModuleHandle(nullptr), DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&_directInput, nullptr))) {
return false;
}
IDirectInputJoyConfig8* pJoyConfig = nullptr;
if(FAILED(hr = _directInput->QueryInterface(IID_IDirectInputJoyConfig8, (void**)&pJoyConfig))) {
return false;
}
if(pJoyConfig) {
pJoyConfig->Release();
}
return UpdateDeviceList();
}
bool DirectInputManager::UpdateDeviceList()
{
HRESULT hr;
for(DirectInputData &data : _joysticks) {
data.joystick->Unacquire();
data.joystick->Release();
}
_joysticks.clear();
// Enumerate devices
if(FAILED(hr = _directInput->EnumDevices(DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, nullptr, DIEDFL_ALLDEVICES))) {
return false;
}
// Make sure we got a joystick
if(_joysticks.empty()) {
return false;
}
for(DirectInputData& data : _joysticks) {
// Set the data format to "simple joystick" - a predefined data format
// A data format specifies which controls on a device we are interested in, and how they should be reported.
// This tells DInput that we will be passing a DIJOYSTATE2 structure to IDirectInputDevice::GetDeviceState().
if(FAILED(hr = data.joystick->SetDataFormat(&c_dfDIJoystick2))) {
return false;
}
// Set the cooperative level to let DInput know how this device should interact with the system and with other DInput applications.
if(FAILED(hr = data.joystick->SetCooperativeLevel(_hWnd, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND))) {
return false;
}
// Enumerate the joystick objects. The callback function enabled user interface elements for objects that are found, and sets the min/max values property for discovered axes.
if(FAILED(hr = data.joystick->EnumObjects(EnumObjectsCallback, data.joystick, DIDFT_ALL))) {
return false;
}
}
//Sleeping apparently lets us read accurate "default" values, otherwise a PS4 controller returns all 0s, despite not doing so normally
RefreshState();
std::this_thread::sleep_for(std::chrono::duration<int, std::milli>(100));
RefreshState();
for(DirectInputData &joystick : _joysticks) {
joystick.defaultState = joystick.state;
}
return true;
}
//-----------------------------------------------------------------------------
// Name: EnumJoysticksCallback()
// Desc: Called once for each enumerated joystick. If we find one, create a
// device interface on it so we can play with it.
//-----------------------------------------------------------------------------
int DirectInputManager::EnumJoysticksCallback(const DIDEVICEINSTANCE* pdidInstance, void* pContext)
{
HRESULT hr;
// Obtain an interface to the enumerated joystick.
LPDIRECTINPUTDEVICE8 pJoystick = nullptr;
hr = _directInput->CreateDevice(pdidInstance->guidInstance, &pJoystick, nullptr);
if(SUCCEEDED(hr)) {
DIJOYSTATE2 state;
memset(&state, 0, sizeof(state));
DirectInputData data{ pJoystick, state, state };
_joysticks.push_back(data);
}
return DIENUM_CONTINUE;
}
//-----------------------------------------------------------------------------
// Name: EnumObjectsCallback()
// Desc: Callback function for enumerating objects (axes, buttons, POVs) on a
// joystick. This function enables user interface elements for objects
// that are found to exist, and scales axes min/max values.
//-----------------------------------------------------------------------------
int DirectInputManager::EnumObjectsCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, void* pContext)
{
LPDIRECTINPUTDEVICE8 joystick = (LPDIRECTINPUTDEVICE8)pContext;
static int nSliderCount = 0; // Number of returned slider controls
static int nPOVCount = 0; // Number of returned POV controls
// For axes that are returned, set the DIPROP_RANGE property for the enumerated axis in order to scale min/max values.
if(pdidoi->dwType & DIDFT_AXIS) {
DIPROPRANGE diprg;
diprg.diph.dwSize = sizeof(DIPROPRANGE);
diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
diprg.diph.dwHow = DIPH_BYID;
diprg.diph.dwObj = pdidoi->dwType; // Specify the enumerated axis
diprg.lMin = -1000;
diprg.lMax = +1000;
// Set the range for the axis
if(FAILED(joystick->SetProperty(DIPROP_RANGE, &diprg.diph))) {
return DIENUM_STOP;
}
}
return DIENUM_CONTINUE;
}
void DirectInputManager::RefreshState()
{
for(DirectInputData &joystick : _joysticks) {
UpdateInputState(joystick);
}
}
int DirectInputManager::GetJoystickCount()
{
return (int)_joysticks.size();
}
bool DirectInputManager::IsPressed(int port, int button)
{
if(port >= _joysticks.size()) {
return false;
}
DIJOYSTATE2& state = _joysticks[port].state;
DIJOYSTATE2& defaultState = _joysticks[port].defaultState;
int deadRange = 500;
bool povCentered = (LOWORD(state.rgdwPOV[0]) == 0xFFFF);
switch(button) {
case 0x00: return state.lY - defaultState.lY < -deadRange;
case 0x01: return state.lY - defaultState.lY > deadRange;
case 0x02: return state.lX - defaultState.lX < -deadRange;
case 0x03: return state.lX - defaultState.lX > deadRange;
case 0x04: return state.lRy - defaultState.lRy < -deadRange;
case 0x05: return state.lRy - defaultState.lRy > deadRange;
case 0x06: return state.lRx - defaultState.lRx < -deadRange;
case 0x07: return state.lRx - defaultState.lRx > deadRange;
case 0x08: return state.lZ - defaultState.lZ < -deadRange;
case 0x09: return state.lZ - defaultState.lZ > deadRange;
case 0x0A: return state.lRz - defaultState.lRz < -deadRange;
case 0x0B: return state.lRz - defaultState.lRz > deadRange;
case 0x0C: return !povCentered && (state.rgdwPOV[0] >= 31500 || state.rgdwPOV[0] <= 4500);
case 0x0D: return !povCentered && state.rgdwPOV[0] >= 13500 && state.rgdwPOV[0] <= 22500;
case 0x0E: return !povCentered && state.rgdwPOV[0] >= 4500 && state.rgdwPOV[0] <= 13500;
case 0x0F: return !povCentered && state.rgdwPOV[0] >= 22500 && state.rgdwPOV[0] <= 31500;
default: return state.rgbButtons[button - 0x10] != 0;
}
return false;
}
bool DirectInputManager::UpdateInputState(DirectInputData &data)
{
HRESULT hr;
// Poll the device to read the current state
hr = data.joystick->Poll();
if(FAILED(hr)) {
// DInput is telling us that the input stream has been interrupted. We aren't tracking any state between polls, so
// we don't have any special reset that needs to be done. We just re-acquire and try again.
hr = data.joystick->Acquire();
while(hr == DIERR_INPUTLOST) {
hr = data.joystick->Acquire();
}
// hr may be DIERR_OTHERAPPHASPRIO or other errors. This may occur when the app is minimized or in the process of
// switching, so just try again later
if(FAILED(hr)) {
return true;
}
}
// Get the input's device state
if(FAILED(hr = data.joystick->GetDeviceState(sizeof(DIJOYSTATE2), &data.state))) {
return false; // The device should have been acquired during the Poll()
}
return true;
}
DirectInputManager::DirectInputManager(HWND hWnd)
{
_hWnd = hWnd;
Initialize();
}
DirectInputManager::~DirectInputManager()
{
for(DirectInputData &data: _joysticks) {
data.joystick->Unacquire();
data.joystick->Release();
}
_joysticks.clear();
if(_directInput) {
_directInput->Release();
_directInput = nullptr;
}
}

View file

@ -0,0 +1,33 @@
#pragma once
#include "stdafx.h"
#include <dinput.h>
#include "../Utilities/SimpleLock.h"
struct DirectInputData
{
LPDIRECTINPUTDEVICE8 joystick;
DIJOYSTATE2 state;
DIJOYSTATE2 defaultState;
};
class DirectInputManager
{
private:
HWND _hWnd;
static LPDIRECTINPUT8 _directInput;
static vector<DirectInputData> _joysticks;
bool Initialize();
bool UpdateInputState(DirectInputData& joystick);
static int __stdcall EnumJoysticksCallback(const DIDEVICEINSTANCE* pdidInstance, void* pContext);
static int __stdcall EnumObjectsCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, void* pContext);
public:
DirectInputManager(HWND window);
~DirectInputManager();
void RefreshState();
bool UpdateDeviceList();
int GetJoystickCount();
bool IsPressed(int port, int button);
};

View file

@ -296,6 +296,7 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="DirectInputManager.h" />
<ClInclude Include="DirectXTK\Audio.h" /> <ClInclude Include="DirectXTK\Audio.h" />
<ClInclude Include="DirectXTK\CommonStates.h" /> <ClInclude Include="DirectXTK\CommonStates.h" />
<ClInclude Include="DirectXTK\DDSTextureLoader.h" /> <ClInclude Include="DirectXTK\DDSTextureLoader.h" />
@ -311,7 +312,7 @@
<ClInclude Include="DirectXTK\VertexTypes.h" /> <ClInclude Include="DirectXTK\VertexTypes.h" />
<ClInclude Include="DirectXTK\WICTextureLoader.h" /> <ClInclude Include="DirectXTK\WICTextureLoader.h" />
<ClInclude Include="DirectXTK\XboxDDSTextureLoader.h" /> <ClInclude Include="DirectXTK\XboxDDSTextureLoader.h" />
<ClInclude Include="GamePad.h" /> <ClInclude Include="XInputManager.h" />
<ClInclude Include="WindowsKeyManager.h" /> <ClInclude Include="WindowsKeyManager.h" />
<ClInclude Include="Renderer.h" /> <ClInclude Include="Renderer.h" />
<ClInclude Include="SoundManager.h" /> <ClInclude Include="SoundManager.h" />
@ -319,7 +320,8 @@
<ClInclude Include="targetver.h" /> <ClInclude Include="targetver.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="GamePad.cpp" /> <ClCompile Include="DirectInputManager.cpp" />
<ClCompile Include="XInputManager.cpp" />
<ClCompile Include="WindowsKeyManager.cpp"> <ClCompile Include="WindowsKeyManager.cpp">
<DeploymentContent>false</DeploymentContent> <DeploymentContent>false</DeploymentContent>
</ClCompile> </ClCompile>

View file

@ -20,9 +20,6 @@
<ClInclude Include="targetver.h"> <ClInclude Include="targetver.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="GamePad.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Renderer.h"> <ClInclude Include="Renderer.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
@ -77,14 +74,17 @@
<ClInclude Include="WindowsKeyManager.h"> <ClInclude Include="WindowsKeyManager.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="XInputManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="DirectInputManager.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="stdafx.cpp"> <ClCompile Include="stdafx.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="GamePad.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Renderer.cpp"> <ClCompile Include="Renderer.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
@ -94,6 +94,12 @@
<ClCompile Include="WindowsKeyManager.cpp"> <ClCompile Include="WindowsKeyManager.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="XInputManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="DirectInputManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="DirectXTK\SimpleMath.inl"> <None Include="DirectXTK\SimpleMath.inl">

View file

@ -2,9 +2,229 @@
#include "WindowsKeyManager.h" #include "WindowsKeyManager.h"
#include "../Core/ControlManager.h" #include "../Core/ControlManager.h"
static vector<KeyDefinition> _keyDefinitions = {
//{ "VK_LBUTTON", 0x01, "Left mouse button" },
//{ "VK_RBUTTON", 0x02, "Right mouse button" },
{ "VK_CANCEL", 0x03, "Control-break processing" },
//{ "VK_MBUTTON", 0x04, "Middle mouse button (three-button mouse)" },
//{ "VK_XBUTTON1", 0x05, "X1 mouse button" },
//{ "VK_XBUTTON2", 0x06, "X2 mouse button" },
{ "-", 0x07, "Undefined" },
{ "VK_BACK", 0x08, "Backspace" },
{ "VK_TAB", 0x09, "Tab" },
//{ "-", 0x0A - 0B, "Reserved" },
{ "VK_CLEAR", 0x0C, "Clear" },
{ "VK_RETURN", 0x0D, "Enter" },
//{ "-", 0x0E - 0F, "Undefined" },
{ "VK_SHIFT", 0x10, "Shift" },
{ "VK_CONTROL", 0x11, "Ctrl" },
{ "VK_MENU", 0x12, "Alt" },
{ "VK_PAUSE", 0x13, "Pause" },
{ "VK_CAPITAL", 0x14, "Caps Lock" },
{ "VK_KANA", 0x15, "IME Kana mode" },
{ "VK_HANGUEL", 0x15, "IME Hanguel mode" },
{ "VK_HANGUL", 0x15, "IME Hangul mode" },
//{ "-", 0x16, "Undefined" },
{ "VK_JUNJA", 0x17, "IME Junja mode" },
{ "VK_FINAL", 0x18, "IME final mode" },
{ "VK_HANJA", 0x19, "IME Hanja mode" },
{ "VK_KANJI", 0x19, "IME Kanji mode" },
//{ "-", 0x1A, "Undefined" },
{ "VK_ESCAPE", 0x1B, "Esc" },
{ "VK_CONVERT", 0x1C, "IME convert" },
{ "VK_NONCONVERT", 0x1D, "IME nonconvert" },
{ "VK_ACCEPT", 0x1E, "IME accept" },
{ "VK_MODECHANGE", 0x1F, "IME mode change request" },
{ "VK_SPACE", 0x20, "Spacebar" },
{ "VK_PRIOR", 0x21, "Page Up" },
{ "VK_NEXT", 0x22, "Page Down" },
{ "VK_END", 0x23, "End" },
{ "VK_HOME", 0x24, "Home" },
{ "VK_LEFT", 0x25, "Left Arrow" },
{ "VK_UP", 0x26, "Up Arrow" },
{ "VK_RIGHT", 0x27, "Right Arrow" },
{ "VK_DOWN", 0x28, "Down Arrow" },
{ "VK_SELECT", 0x29, "Select" },
{ "VK_PRINT", 0x2A, "Print" },
{ "VK_EXECUTE", 0x2B, "Execute" },
{ "VK_SNAPSHOT", 0x2C, "Print Screen" },
{ "VK_INSERT", 0x2D, "Ins" },
{ "VK_DELETE", 0x2E, "Del" },
{ "VK_HELP", 0x2F, "Help" },
{ "0", 0x30, "0" },
{ "1", 0x31, "1" },
{ "2", 0x32, "2" },
{ "3", 0x33, "3" },
{ "4", 0x34, "4" },
{ "5", 0x35, "5" },
{ "6", 0x36, "6" },
{ "7", 0x37, "7" },
{ "8", 0x38, "8" },
{ "9", 0x39, "9" },
//{ "undefined", 0x3A - 40, "undefined" },
{ "A", 0x41, "A" },
{ "B", 0x42, "B" },
{ "C", 0x43, "C" },
{ "D", 0x44, "D" },
{ "E", 0x45, "E" },
{ "F", 0x46, "F" },
{ "G", 0x47, "G" },
{ "H", 0x48, "H" },
{ "I", 0x49, "I" },
{ "J", 0x4A, "J" },
{ "K", 0x4B, "K" },
{ "L", 0x4C, "L" },
{ "M", 0x4D, "M" },
{ "N", 0x4E, "N" },
{ "O", 0x4F, "O" },
{ "P", 0x50, "P" },
{ "Q", 0x51, "Q" },
{ "R", 0x52, "R" },
{ "S", 0x53, "S" },
{ "T", 0x54, "T" },
{ "U", 0x55, "U" },
{ "V", 0x56, "V" },
{ "W", 0x57, "W" },
{ "X", 0x58, "X" },
{ "Y", 0x59, "Y" },
{ "Z", 0x5A, "Z" },
{ "VK_LWIN", 0x5B, "Left Windows" },
{ "VK_RWIN", 0x5C, "Right Windows" },
{ "VK_APPS", 0x5D, "Applications Key" },
//{ "-", 0x5E, "Reserved" },
{ "VK_SLEEP", 0x5F, "Computer Sleep" },
{ "VK_NUMPAD0", 0x60, "Keypad 0" },
{ "VK_NUMPAD1", 0x61, "Keypad 1" },
{ "VK_NUMPAD2", 0x62, "Keypad 2" },
{ "VK_NUMPAD3", 0x63, "Keypad 3" },
{ "VK_NUMPAD4", 0x64, "Keypad 4" },
{ "VK_NUMPAD5", 0x65, "Keypad 5" },
{ "VK_NUMPAD6", 0x66, "Keypad 6" },
{ "VK_NUMPAD7", 0x67, "Keypad 7" },
{ "VK_NUMPAD8", 0x68, "Keypad 8" },
{ "VK_NUMPAD9", 0x69, "Keypad 9" },
{ "VK_MULTIPLY", 0x6A, "Multiply" },
{ "VK_ADD", 0x6B, "Add" },
{ "VK_SEPARATOR", 0x6C, "Separator" },
{ "VK_SUBTRACT", 0x6D, "Subtract" },
{ "VK_DECIMAL", 0x6E, "Decimal" },
{ "VK_DIVIDE", 0x6F, "Divide" },
{ "VK_F1", 0x70, "F1" },
{ "VK_F2", 0x71, "F2" },
{ "VK_F3", 0x72, "F3" },
{ "VK_F4", 0x73, "F4" },
{ "VK_F5", 0x74, "F5" },
{ "VK_F6", 0x75, "F6" },
{ "VK_F7", 0x76, "F7" },
{ "VK_F8", 0x77, "F8" },
{ "VK_F9", 0x78, "F9" },
{ "VK_F10", 0x79, "F10" },
{ "VK_F11", 0x7A, "F11" },
{ "VK_F12", 0x7B, "F12" },
{ "VK_F13", 0x7C, "F13" },
{ "VK_F14", 0x7D, "F14" },
{ "VK_F15", 0x7E, "F15" },
{ "VK_F16", 0x7F, "F16" },
{ "VK_F17", 0x80, "F17" },
{ "VK_F18", 0x81, "F18" },
{ "VK_F19", 0x82, "F19" },
{ "VK_F20", 0x83, "F20" },
{ "VK_F21", 0x84, "F21" },
{ "VK_F22", 0x85, "F22" },
{ "VK_F23", 0x86, "F23" },
{ "VK_F24", 0x87, "F24" },
//{ "-", 0x88 - 8F, "Unassigned" },
{ "VK_NUMLOCK", 0x90, "Num Lock" },
{ "VK_SCROLL", 0x91, "Scroll Lock" },
//{"-", 0x92-96,"OEM specific"},
//{ "-", 0x97 - 9F, "Unassigned" },
{ "VK_LSHIFT", 0xA0, "Left Shift" },
{ "VK_RSHIFT", 0xA1, "Right Shift" },
{ "VK_LCONTROL", 0xA2, "Left Control" },
{ "VK_RCONTROL", 0xA3, "Right Control" },
{ "VK_LMENU", 0xA4, "Left Menu" },
{ "VK_RMENU", 0xA5, "Right Menu" },
{ "VK_BROWSER_BACK", 0xA6, "Browser Back" },
{ "VK_BROWSER_FORWARD", 0xA7, "Browser Forward" },
{ "VK_BROWSER_REFRESH", 0xA8, "Browser Refresh" },
{ "VK_BROWSER_STOP", 0xA9, "Browser Stop" },
{ "VK_BROWSER_SEARCH", 0xAA, "Browser Search" },
{ "VK_BROWSER_FAVORITES", 0xAB, "Browser Favorites" },
{ "VK_BROWSER_HOME", 0xAC, "Browser Start and Home" },
{ "VK_VOLUME_MUTE", 0xAD, "Volume Mute" },
{ "VK_VOLUME_DOWN", 0xAE, "Volume Down" },
{ "VK_VOLUME_UP", 0xAF, "Volume Up" },
{ "VK_MEDIA_NEXT_TRACK", 0xB0, "Next Track" },
{ "VK_MEDIA_PREV_TRACK", 0xB1, "Previous Track" },
{ "VK_MEDIA_STOP", 0xB2, "Stop Media" },
{ "VK_MEDIA_PLAY_PAUSE", 0xB3, "Play/Pause Media" },
{ "VK_LAUNCH_MAIL", 0xB4, "Start Mail" },
{ "VK_LAUNCH_MEDIA_SELECT", 0xB5, "Select Media" },
{ "VK_LAUNCH_APP1", 0xB6, "Start Application 1" },
{ "VK_LAUNCH_APP2", 0xB7, "Start Application 2" },
//{ "-", 0xB8 - B9, "Reserved" },
{ "VK_OEM_1", 0xBA, "Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the \';:\' key VK_OEM_PLUS" },
{ "VK_OEM_PLUS", 0xBB, "+" },
{ "VK_OEM_COMMA", 0xBC, "," },
{ "VK_OEM_MINUS", 0xBD, "-" },
{ "VK_OEM_PERIOD", 0xBE, "." },
{ "VK_OEM_2", 0xBF, "/" },
{ "VK_OEM_3", 0xC0, "`" },
//{ "-", 0xC1 - D7, "Reserved" },
//{ "-", 0xD8 - DA, "Unassigned" },
{ "VK_OEM_4", 0xDB, "[" },
{ "VK_OEM_5", 0xDC, "\\" },
{ "VK_OEM_6", 0xDD, "]" },
{ "VK_OEM_7", 0xDE, "'" },
{ "VK_OEM_8", 0xDF, "Used for miscellaneous characters; it can vary by keyboard." },
//{ "-", 0xE0, "Reserved" },
//{ "-", 0xE1, "OEM specific" },
{ "VK_OEM_102", 0xE2, "Either the angle bracket key or the backslash key on the RT 102-key keyboard" },
//{ "-", 0xE3 - E4, "OEM specific" },
{ "VK_PROCESSKEY", 0xE5, "IME PROCESS" },
//{ "-", 0xE6, "OEM specific" },
{ "VK_PACKET", 0xE7, "Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP" },
//{ "-", 0xE8, "Unassigned" },
// {"-",0xE6,"OEM specific"},
{ "VK_PACKET", 0xE7, "Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP" },
// {"-",0xE8,"Unassigned"},
//{ "-", 0xE9 - F5, "OEM specific" },
{ "VK_ATTN", 0xF6, "Attn" },
{ "VK_CRSEL", 0xF7, "CrSel" },
{ "VK_EXSEL", 0xF8, "ExSel" },
{ "VK_EREOF", 0xF9, "Erase EOF" },
{ "VK_PLAY", 0xFA, "Play" },
{ "VK_ZOOM", 0xFB, "Zoom" },
{ "VK_NONAME", 0xFC, "Reserved" },
{ "VK_PA1", 0xFD, "PA1" },
{ "VK_OEM_CLEAR", 0xFE, "Clear" }
};
WindowsKeyManager::WindowsKeyManager(HWND hWnd) WindowsKeyManager::WindowsKeyManager(HWND hWnd)
{ {
_hWnd = hWnd; _hWnd = hWnd;
//Init XInput buttons
vector<string> buttonNames = { "Up", "Down", "Left", "Right", "Start", "Back", "L3", "R3", "L1", "R1", "?", "?", "A", "B", "X", "Y", "L2", "R2", "RT Up", "RT Down", "RT Up", "RT Left", "RT Right" };
for(int i = 0; i < 4; i++) {
for(int j = 0; j < buttonNames.size(); j++) {
_keyDefinitions.push_back({ "", (uint32_t)(0xFFFF + i * 0x100 + j + 1), "Pad" + std::to_string(i + 1) + " " + buttonNames[j] });
}
}
//Init DirectInput buttons
vector<string> diButtonNames = { "Y+", "Y-", "X-", "X+", "Y2+", "Y2-", "X2-", "X2+", "Z+", "Z-", "Z2+", "Z2-", "DPad Up", "DPad Down", "DPad Right", "DPad Left" };
for(int i = 0; i < 16; i++) {
for(int j = 0; j < diButtonNames.size(); j++) {
_keyDefinitions.push_back({ "", (uint32_t)(0x11000 + i * 0x100 + j), "Joy" + std::to_string(i + 1) + " " + diButtonNames[j] });
}
for(int j = 0; j < 128; j++) {
_keyDefinitions.push_back({ "", (uint32_t)(0x11000 + i * 0x100 + j + 0x10), "Joy" + std::to_string(i + 1) + " But" + std::to_string(j+1)});
}
}
_directInput.reset(new DirectInput(hWnd));
} }
WindowsKeyManager::~WindowsKeyManager() WindowsKeyManager::~WindowsKeyManager()
@ -14,15 +234,23 @@ WindowsKeyManager::~WindowsKeyManager()
void WindowsKeyManager::RefreshState() void WindowsKeyManager::RefreshState()
{ {
_gamePad.RefreshState(); _gamePad.RefreshState();
_directInput->RefreshState();
} }
bool WindowsKeyManager::IsKeyPressed(uint32_t key) bool WindowsKeyManager::IsKeyPressed(uint32_t key)
{ {
if(key >= 0x10000) { if(key >= 0x10000) {
if(key >= 0x11000) {
//Directinput key
uint8_t gamepadPort = (key - 0x11000) / 0x100;
uint8_t gamepadButton = (key - 0x11000) % 0x100;
return _directInput->IsButtonPressed(gamepadPort, gamepadButton);
} else {
//XInput key //XInput key
uint8_t gamepadPort = (key - 0xFFFF) / 0x100; uint8_t gamepadPort = (key - 0xFFFF) / 0x100;
uint8_t gamepadButton = (key - 0xFFFF) % 0x100; uint8_t gamepadButton = (key - 0xFFFF) % 0x100;
return _gamePad.IsPressed(gamepadPort, gamepadButton); return _gamePad.IsPressed(gamepadPort, gamepadButton);
}
} else { } else {
return (GetAsyncKeyState(key) & 0x8000) == 0x8000; return (GetAsyncKeyState(key) & 0x8000) == 0x8000;
} }
@ -44,7 +272,6 @@ bool WindowsKeyManager::IsMouseButtonPressed(MouseButton button)
uint32_t WindowsKeyManager::GetPressedKey() uint32_t WindowsKeyManager::GetPressedKey()
{ {
_gamePad.RefreshState(); _gamePad.RefreshState();
for(int i = 0; i < XUSER_MAX_COUNT; i++) { for(int i = 0; i < XUSER_MAX_COUNT; i++) {
for(int j = 1; j <= 22; j++) { for(int j = 1; j <= 22; j++) {
if(_gamePad.IsPressed(i, j)) { if(_gamePad.IsPressed(i, j)) {
@ -53,6 +280,15 @@ uint32_t WindowsKeyManager::GetPressedKey()
} }
} }
_directInput->RefreshState();
for(int i = _directInput->GetJoystickCount() - 1; i >= 0; i--) {
for(int j = 0; j < 0x29; j++) {
if(_directInput->IsButtonPressed(i, j)) {
return 0x11000 + i * 0x100 + j;
}
}
}
for(int i = 0; i < 0xFF; i++) { for(int i = 0; i < 0xFF; i++) {
if((GetAsyncKeyState(i) & 0x8000) == 0x8000) { if((GetAsyncKeyState(i) & 0x8000) == 0x8000) {
return i; return i;

View file

@ -2,7 +2,9 @@
#include "stdafx.h" #include "stdafx.h"
#include "../Core/IKeyManager.h" #include "../Core/IKeyManager.h"
#include "GamePad.h" #include "../Utilities/Timer.h"
#include "XInputManager.h"
#include "DirectInputManager.h"
struct KeyDefinition { struct KeyDefinition {
string name; string name;
@ -10,293 +12,13 @@ struct KeyDefinition {
string description; string description;
}; };
const KeyDefinition _keyDefinitions[] = {
//{ "VK_LBUTTON", 0x01, "Left mouse button" },
//{ "VK_RBUTTON", 0x02, "Right mouse button" },
{ "VK_CANCEL", 0x03, "Control-break processing" },
//{ "VK_MBUTTON", 0x04, "Middle mouse button (three-button mouse)" },
//{ "VK_XBUTTON1", 0x05, "X1 mouse button" },
//{ "VK_XBUTTON2", 0x06, "X2 mouse button" },
{ "-", 0x07, "Undefined" },
{ "VK_BACK", 0x08, "Backspace" },
{ "VK_TAB", 0x09, "Tab" },
//{ "-", 0x0A - 0B, "Reserved" },
{ "VK_CLEAR", 0x0C, "Clear" },
{ "VK_RETURN", 0x0D, "Enter" },
//{ "-", 0x0E - 0F, "Undefined" },
{ "VK_SHIFT", 0x10, "Shift" },
{ "VK_CONTROL", 0x11, "Ctrl" },
{ "VK_MENU", 0x12, "Alt" },
{ "VK_PAUSE", 0x13, "Pause" },
{ "VK_CAPITAL", 0x14, "Caps Lock" },
{ "VK_KANA", 0x15, "IME Kana mode" },
{ "VK_HANGUEL", 0x15, "IME Hanguel mode" },
{ "VK_HANGUL", 0x15, "IME Hangul mode" },
//{ "-", 0x16, "Undefined" },
{ "VK_JUNJA", 0x17, "IME Junja mode" },
{ "VK_FINAL", 0x18, "IME final mode" },
{ "VK_HANJA", 0x19, "IME Hanja mode" },
{ "VK_KANJI", 0x19, "IME Kanji mode" },
//{ "-", 0x1A, "Undefined" },
{ "VK_ESCAPE", 0x1B, "Esc" },
{ "VK_CONVERT", 0x1C, "IME convert" },
{ "VK_NONCONVERT", 0x1D, "IME nonconvert" },
{ "VK_ACCEPT", 0x1E, "IME accept" },
{ "VK_MODECHANGE", 0x1F, "IME mode change request" },
{ "VK_SPACE", 0x20, "Spacebar" },
{ "VK_PRIOR", 0x21, "Page Up" },
{ "VK_NEXT", 0x22, "Page Down" },
{ "VK_END", 0x23, "End" },
{ "VK_HOME", 0x24, "Home" },
{ "VK_LEFT", 0x25, "Left Arrow" },
{ "VK_UP", 0x26, "Up Arrow" },
{ "VK_RIGHT", 0x27, "Right Arrow" },
{ "VK_DOWN", 0x28, "Down Arrow" },
{ "VK_SELECT", 0x29, "Select" },
{ "VK_PRINT", 0x2A, "Print" },
{ "VK_EXECUTE", 0x2B, "Execute" },
{ "VK_SNAPSHOT", 0x2C, "Print Screen" },
{ "VK_INSERT", 0x2D, "Ins" },
{ "VK_DELETE", 0x2E, "Del" },
{ "VK_HELP", 0x2F, "Help" },
{ "0", 0x30, "0" },
{ "1", 0x31, "1" },
{ "2", 0x32, "2" },
{ "3", 0x33, "3" },
{ "4", 0x34, "4" },
{ "5", 0x35, "5" },
{ "6", 0x36, "6" },
{ "7", 0x37, "7" },
{ "8", 0x38, "8" },
{ "9", 0x39, "9" },
//{ "undefined", 0x3A - 40, "undefined" },
{ "A", 0x41, "A" },
{ "B", 0x42, "B" },
{ "C", 0x43, "C" },
{ "D", 0x44, "D" },
{ "E", 0x45, "E" },
{ "F", 0x46, "F" },
{ "G", 0x47, "G" },
{ "H", 0x48, "H" },
{ "I", 0x49, "I" },
{ "J", 0x4A, "J" },
{ "K", 0x4B, "K" },
{ "L", 0x4C, "L" },
{ "M", 0x4D, "M" },
{ "N", 0x4E, "N" },
{ "O", 0x4F, "O" },
{ "P", 0x50, "P" },
{ "Q", 0x51, "Q" },
{ "R", 0x52, "R" },
{ "S", 0x53, "S" },
{ "T", 0x54, "T" },
{ "U", 0x55, "U" },
{ "V", 0x56, "V" },
{ "W", 0x57, "W" },
{ "X", 0x58, "X" },
{ "Y", 0x59, "Y" },
{ "Z", 0x5A, "Z" },
{ "VK_LWIN", 0x5B, "Left Windows" },
{ "VK_RWIN", 0x5C, "Right Windows" },
{ "VK_APPS", 0x5D, "Applications Key" },
//{ "-", 0x5E, "Reserved" },
{ "VK_SLEEP", 0x5F, "Computer Sleep" },
{ "VK_NUMPAD0", 0x60, "Keypad 0" },
{ "VK_NUMPAD1", 0x61, "Keypad 1" },
{ "VK_NUMPAD2", 0x62, "Keypad 2" },
{ "VK_NUMPAD3", 0x63, "Keypad 3" },
{ "VK_NUMPAD4", 0x64, "Keypad 4" },
{ "VK_NUMPAD5", 0x65, "Keypad 5" },
{ "VK_NUMPAD6", 0x66, "Keypad 6" },
{ "VK_NUMPAD7", 0x67, "Keypad 7" },
{ "VK_NUMPAD8", 0x68, "Keypad 8" },
{ "VK_NUMPAD9", 0x69, "Keypad 9" },
{ "VK_MULTIPLY", 0x6A, "Multiply" },
{ "VK_ADD", 0x6B, "Add" },
{ "VK_SEPARATOR", 0x6C, "Separator" },
{ "VK_SUBTRACT", 0x6D, "Subtract" },
{ "VK_DECIMAL", 0x6E, "Decimal" },
{ "VK_DIVIDE", 0x6F, "Divide" },
{ "VK_F1", 0x70, "F1" },
{ "VK_F2", 0x71, "F2" },
{ "VK_F3", 0x72, "F3" },
{ "VK_F4", 0x73, "F4" },
{ "VK_F5", 0x74, "F5" },
{ "VK_F6", 0x75, "F6" },
{ "VK_F7", 0x76, "F7" },
{ "VK_F8", 0x77, "F8" },
{ "VK_F9", 0x78, "F9" },
{ "VK_F10", 0x79, "F10" },
{ "VK_F11", 0x7A, "F11" },
{ "VK_F12", 0x7B, "F12" },
{ "VK_F13", 0x7C, "F13" },
{ "VK_F14", 0x7D, "F14" },
{ "VK_F15", 0x7E, "F15" },
{ "VK_F16", 0x7F, "F16" },
{ "VK_F17", 0x80, "F17" },
{ "VK_F18", 0x81, "F18" },
{ "VK_F19", 0x82, "F19" },
{ "VK_F20", 0x83, "F20" },
{ "VK_F21", 0x84, "F21" },
{ "VK_F22", 0x85, "F22" },
{ "VK_F23", 0x86, "F23" },
{ "VK_F24", 0x87, "F24" },
//{ "-", 0x88 - 8F, "Unassigned" },
{ "VK_NUMLOCK", 0x90, "Num Lock" },
{ "VK_SCROLL", 0x91, "Scroll Lock" },
//{"-", 0x92-96,"OEM specific"},
//{ "-", 0x97 - 9F, "Unassigned" },
{ "VK_LSHIFT", 0xA0, "Left Shift" },
{ "VK_RSHIFT", 0xA1, "Right Shift" },
{ "VK_LCONTROL", 0xA2, "Left Control" },
{ "VK_RCONTROL", 0xA3, "Right Control" },
{ "VK_LMENU", 0xA4, "Left Menu" },
{ "VK_RMENU", 0xA5, "Right Menu" },
{ "VK_BROWSER_BACK", 0xA6, "Browser Back" },
{ "VK_BROWSER_FORWARD", 0xA7, "Browser Forward" },
{ "VK_BROWSER_REFRESH", 0xA8, "Browser Refresh" },
{ "VK_BROWSER_STOP", 0xA9, "Browser Stop" },
{ "VK_BROWSER_SEARCH", 0xAA, "Browser Search" },
{ "VK_BROWSER_FAVORITES", 0xAB, "Browser Favorites" },
{ "VK_BROWSER_HOME", 0xAC, "Browser Start and Home" },
{ "VK_VOLUME_MUTE", 0xAD, "Volume Mute" },
{ "VK_VOLUME_DOWN", 0xAE, "Volume Down" },
{ "VK_VOLUME_UP", 0xAF, "Volume Up" },
{ "VK_MEDIA_NEXT_TRACK", 0xB0, "Next Track" },
{ "VK_MEDIA_PREV_TRACK", 0xB1, "Previous Track" },
{ "VK_MEDIA_STOP", 0xB2, "Stop Media" },
{ "VK_MEDIA_PLAY_PAUSE", 0xB3, "Play/Pause Media" },
{ "VK_LAUNCH_MAIL", 0xB4, "Start Mail" },
{ "VK_LAUNCH_MEDIA_SELECT", 0xB5, "Select Media" },
{ "VK_LAUNCH_APP1", 0xB6, "Start Application 1" },
{ "VK_LAUNCH_APP2", 0xB7, "Start Application 2" },
//{ "-", 0xB8 - B9, "Reserved" },
{ "VK_OEM_1", 0xBA, "Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the \';:\' key VK_OEM_PLUS" },
{ "VK_OEM_PLUS", 0xBB, "+" },
{ "VK_OEM_COMMA", 0xBC, "," },
{ "VK_OEM_MINUS", 0xBD, "-" },
{ "VK_OEM_PERIOD", 0xBE, "." },
{ "VK_OEM_2", 0xBF, "/" },
{ "VK_OEM_3", 0xC0, "`" },
//{ "-", 0xC1 - D7, "Reserved" },
//{ "-", 0xD8 - DA, "Unassigned" },
{ "VK_OEM_4", 0xDB, "[" },
{ "VK_OEM_5", 0xDC, "\\" },
{ "VK_OEM_6", 0xDD, "]" },
{ "VK_OEM_7", 0xDE, "'" },
{ "VK_OEM_8", 0xDF, "Used for miscellaneous characters; it can vary by keyboard." },
//{ "-", 0xE0, "Reserved" },
//{ "-", 0xE1, "OEM specific" },
{ "VK_OEM_102", 0xE2, "Either the angle bracket key or the backslash key on the RT 102-key keyboard" },
//{ "-", 0xE3 - E4, "OEM specific" },
{ "VK_PROCESSKEY", 0xE5, "IME PROCESS" },
//{ "-", 0xE6, "OEM specific" },
{ "VK_PACKET", 0xE7, "Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP" },
//{ "-", 0xE8, "Unassigned" },
// {"-",0xE6,"OEM specific"},
{ "VK_PACKET", 0xE7, "Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP" },
// {"-",0xE8,"Unassigned"},
//{ "-", 0xE9 - F5, "OEM specific" },
{ "VK_ATTN", 0xF6, "Attn" },
{ "VK_CRSEL", 0xF7, "CrSel" },
{ "VK_EXSEL", 0xF8, "ExSel" },
{ "VK_EREOF", 0xF9, "Erase EOF" },
{ "VK_PLAY", 0xFA, "Play" },
{ "VK_ZOOM", 0xFB, "Zoom" },
{ "VK_NONAME", 0xFC, "Reserved" },
{ "VK_PA1", 0xFD, "PA1" },
{ "VK_OEM_CLEAR", 0xFE, "Clear" },
{ "", 0xFFFF + 0x01, "Pad1 Up" },
{ "", 0xFFFF + 0x02, "Pad1 Down" },
{ "", 0xFFFF + 0x03, "Pad1 Left" },
{ "", 0xFFFF + 0x04, "Pad1 Right" },
{ "", 0xFFFF + 0x05, "Pad1 Start" },
{ "", 0xFFFF + 0x06, "Pad1 Back" },
{ "", 0xFFFF + 0x07, "Pad1 L3" },
{ "", 0xFFFF + 0x08, "Pad1 R3" },
{ "", 0xFFFF + 0x09, "Pad1 L1" },
{ "", 0xFFFF + 0x0A, "Pad1 R1" },
{ "", 0xFFFF + 0x0D, "Pad1 A" },
{ "", 0xFFFF + 0x0E, "Pad1 B" },
{ "", 0xFFFF + 0x0F, "Pad1 X" },
{ "", 0xFFFF + 0x10, "Pad1 Y" },
{ "", 0xFFFF + 0x11, "Pad1 L2" },
{ "", 0xFFFF + 0x12, "Pad1 R2" },
{ "", 0xFFFF + 0x13, "Pad1 RT Up" },
{ "", 0xFFFF + 0x14, "Pad1 RT Down" },
{ "", 0xFFFF + 0x15, "Pad1 RT Left" },
{ "", 0xFFFF + 0x16, "Pad1 RT Right" },
{ "", 0xFFFF + 0x101, "Pad2 Up" },
{ "", 0xFFFF + 0x102, "Pad2 Down" },
{ "", 0xFFFF + 0x103, "Pad2 Left" },
{ "", 0xFFFF + 0x104, "Pad2 Right" },
{ "", 0xFFFF + 0x105, "Pad2 Start" },
{ "", 0xFFFF + 0x106, "Pad2 Back" },
{ "", 0xFFFF + 0x107, "Pad2 Left Thumb" },
{ "", 0xFFFF + 0x108, "Pad2 Right Thumb" },
{ "", 0xFFFF + 0x109, "Pad2 Left Bumper" },
{ "", 0xFFFF + 0x10A, "Pad2 Right Bumper" },
{ "", 0xFFFF + 0x10D, "Pad2 A" },
{ "", 0xFFFF + 0x10E, "Pad2 B" },
{ "", 0xFFFF + 0x10F, "Pad2 X" },
{ "", 0xFFFF + 0x110, "Pad2 Y" },
{ "", 0xFFFF + 0x111, "Pad2 L2" },
{ "", 0xFFFF + 0x112, "Pad2 R2" },
{ "", 0xFFFF + 0x113, "Pad2 RT Up" },
{ "", 0xFFFF + 0x114, "Pad2 RT Down" },
{ "", 0xFFFF + 0x115, "Pad2 RT Left" },
{ "", 0xFFFF + 0x116, "Pad2 RT Right" },
{ "", 0xFFFF + 0x201, "Pad3 Up" },
{ "", 0xFFFF + 0x202, "Pad3 Down" },
{ "", 0xFFFF + 0x203, "Pad3 Left" },
{ "", 0xFFFF + 0x204, "Pad3 Right" },
{ "", 0xFFFF + 0x205, "Pad3 Start" },
{ "", 0xFFFF + 0x206, "Pad3 Back" },
{ "", 0xFFFF + 0x207, "Pad3 Left Thumb" },
{ "", 0xFFFF + 0x208, "Pad3 Right Thumb" },
{ "", 0xFFFF + 0x209, "Pad3 Left Bumper" },
{ "", 0xFFFF + 0x20A, "Pad3 Right Bumper" },
{ "", 0xFFFF + 0x20D, "Pad3 A" },
{ "", 0xFFFF + 0x20E, "Pad3 B" },
{ "", 0xFFFF + 0x20F, "Pad3 X" },
{ "", 0xFFFF + 0x210, "Pad3 Y" },
{ "", 0xFFFF + 0x211, "Pad3 L2" },
{ "", 0xFFFF + 0x212, "Pad3 R2" },
{ "", 0xFFFF + 0x213, "Pad3 RT Up" },
{ "", 0xFFFF + 0x214, "Pad3 RT Down" },
{ "", 0xFFFF + 0x215, "Pad3 RT Left" },
{ "", 0xFFFF + 0x216, "Pad3 RT Right" },
{ "", 0xFFFF + 0x301, "Pad4 Up" },
{ "", 0xFFFF + 0x302, "Pad4 Down" },
{ "", 0xFFFF + 0x303, "Pad4 Left" },
{ "", 0xFFFF + 0x304, "Pad4 Right" },
{ "", 0xFFFF + 0x305, "Pad4 Start" },
{ "", 0xFFFF + 0x306, "Pad4 Back" },
{ "", 0xFFFF + 0x307, "Pad4 Left Thumb" },
{ "", 0xFFFF + 0x308, "Pad4 Right Thumb" },
{ "", 0xFFFF + 0x309, "Pad4 Left Bumper" },
{ "", 0xFFFF + 0x30A, "Pad4 Right Bumper" },
{ "", 0xFFFF + 0x30D, "Pad4 A" },
{ "", 0xFFFF + 0x30E, "Pad4 B" },
{ "", 0xFFFF + 0x30F, "Pad4 X" },
{ "", 0xFFFF + 0x310, "Pad4 Y" },
{ "", 0xFFFF + 0x311, "Pad4 L2" },
{ "", 0xFFFF + 0x312, "Pad4 R2" },
{ "", 0xFFFF + 0x313, "Pad4 RT Up" },
{ "", 0xFFFF + 0x314, "Pad4 RT Down" },
{ "", 0xFFFF + 0x315, "Pad4 RT Left" },
{ "", 0xFFFF + 0x316, "Pad4 RT Right" }
};
class WindowsKeyManager : public IKeyManager class WindowsKeyManager : public IKeyManager
{ {
private: private:
GamePad _gamePad; Timer _timer;
HWND _hWnd; HWND _hWnd;
unique_ptr<DirectInputManager> _directInput;
unique_ptr<XInputManager> _xInput;
public: public:
WindowsKeyManager(HWND hWnd); WindowsKeyManager(HWND hWnd);
@ -308,4 +30,6 @@ class WindowsKeyManager : public IKeyManager
uint32_t GetPressedKey(); uint32_t GetPressedKey();
string GetKeyName(uint32_t key); string GetKeyName(uint32_t key);
uint32_t GetKeyCode(string keyName); uint32_t GetKeyCode(string keyName);
void UpdateDevices();
}; };

View file

@ -1,28 +1,37 @@
#include "stdafx.h" #include "stdafx.h"
#include "GamePad.h" #include "XInputManager.h"
GamePad::GamePad() XInputManager::XInputManager()
{ {
for(int i = 0; i < XUSER_MAX_COUNT; i++) { for(int i = 0; i < XUSER_MAX_COUNT; i++) {
_gamePadStates.push_back(shared_ptr<XINPUT_STATE>(new XINPUT_STATE())); _gamePadStates.push_back(shared_ptr<XINPUT_STATE>(new XINPUT_STATE()));
} }
} }
void GamePad::RefreshState() void XInputManager::RefreshState()
{ {
for(DWORD i = 0; i < XUSER_MAX_COUNT; i++) { for(DWORD i = 0; i < XUSER_MAX_COUNT; i++) {
if(_gamePadStates[i] != nullptr) { if(_gamePadStates[i] != nullptr) {
ZeroMemory(_gamePadStates[i].get(), sizeof(XINPUT_STATE)); ZeroMemory(_gamePadStates[i].get(), sizeof(XINPUT_STATE));
if(XInputGetState(i, _gamePadStates[i].get()) != ERROR_SUCCESS) { if(XInputGetState(i, _gamePadStates[i].get()) != ERROR_SUCCESS) {
//XInputGetState is incredibly slow when no controller is plugged in //XInputGetState is incredibly slow when no controller is plugged in
//TODO: Periodically detect if a controller has been plugged in to allow controllers to be plugged in after the emu is started
_gamePadStates[i] = nullptr; _gamePadStates[i] = nullptr;
} }
} }
} }
} }
bool GamePad::IsPressed(uint8_t gamepadPort, uint8_t button) void XInputManager::UpdateDeviceList()
{
//Periodically detect if a controller has been plugged in to allow controllers to be plugged in after the emu is started
for(int i = 0; i < XUSER_MAX_COUNT; i++) {
if(_gamePadStates[i] == nullptr) {
_gamePadStates[i] = shared_ptr<XINPUT_STATE>(new XINPUT_STATE());
}
}
}
bool XInputManager::IsPressed(uint8_t gamepadPort, uint8_t button)
{ {
if(_gamePadStates[gamepadPort] != nullptr) { if(_gamePadStates[gamepadPort] != nullptr) {
XINPUT_GAMEPAD &gamepad = _gamePadStates[gamepadPort]->Gamepad; XINPUT_GAMEPAD &gamepad = _gamePadStates[gamepadPort]->Gamepad;

View file

@ -3,14 +3,15 @@
#include "stdafx.h" #include "stdafx.h"
#include <Xinput.h> #include <Xinput.h>
class GamePad class XInputManager
{ {
private: private:
vector<shared_ptr<XINPUT_STATE>> _gamePadStates; vector<shared_ptr<XINPUT_STATE>> _gamePadStates;
public: public:
GamePad(); XInputManager();
void UpdateDeviceList();
void RefreshState(); void RefreshState();
bool IsPressed(uint8_t gamepadPort, uint8_t button); bool IsPressed(uint8_t gamepadPort, uint8_t button);
}; };