[Win] Do not re-query caps in ProcessEvents

We just do that once when a device is opened.
This commit is contained in:
thefiddler 2014-07-31 22:50:33 +02:00
parent 15a79e5213
commit dd0f622670

View file

@ -46,6 +46,11 @@ namespace OpenTK.Platform.Windows
JoystickState State; JoystickState State;
Guid Guid; Guid Guid;
internal readonly List<HidProtocolValueCaps> AxisCaps =
new List<HidProtocolValueCaps>();
internal readonly List<HidProtocolButtonCaps> ButtonCaps =
new List<HidProtocolButtonCaps>();
readonly Dictionary<int, JoystickAxis> axes = readonly Dictionary<int, JoystickAxis> axes =
new Dictionary<int,JoystickAxis>(); new Dictionary<int,JoystickAxis>();
readonly Dictionary<int, JoystickButton> buttons = readonly Dictionary<int, JoystickButton> buttons =
@ -169,8 +174,6 @@ namespace OpenTK.Platform.Windows
byte[] HIDData = new byte[1024]; byte[] HIDData = new byte[1024];
byte[] PreparsedData = new byte[1024]; byte[] PreparsedData = new byte[1024];
HidProtocolValueCaps[] AxisCaps = new HidProtocolValueCaps[4];
HidProtocolButtonCaps[] ButtonCaps = new HidProtocolButtonCaps[4];
HidProtocolData[] DataBuffer = new HidProtocolData[16]; HidProtocolData[] DataBuffer = new HidProtocolData[16];
public WinRawJoystick(IntPtr window) public WinRawJoystick(IntPtr window)
@ -279,17 +282,6 @@ namespace OpenTK.Platform.Windows
return false; return false;
} }
// Detect which axes / buttons are contained in this report
HidProtocolCaps caps;
int axis_caps_count;
int button_caps_count;
if (!GetDeviceCaps(PreparsedData, out caps,
ref AxisCaps, out axis_caps_count,
ref ButtonCaps, out button_caps_count))
{
return false;
}
// Query current state // Query current state
// Allocate enough storage to hold the data of the current report // Allocate enough storage to hold the data of the current report
int report_count = HidProtocol.MaxDataListLength(HidProtocolReportType.Input, PreparsedData); int report_count = HidProtocol.MaxDataListLength(HidProtocolReportType.Input, PreparsedData);
@ -318,19 +310,19 @@ namespace OpenTK.Platform.Windows
} }
*/ */
UpdateButtons(rin, stick, button_caps_count); UpdateButtons(rin, stick);
for (int i = 0; i < axis_caps_count; i++) for (int i = 0; i < stick.AxisCaps.Count; i++)
{ {
if (AxisCaps[i].IsRange) if (stick.AxisCaps[i].IsRange)
{ {
Debug.Print("[{0}] Axis range collections not implemented. Please report your controller type at http://www.opentk.com", Debug.Print("[{0}] Axis range collections not implemented. Please report your controller type at http://www.opentk.com",
GetType().Name); GetType().Name);
continue; continue;
} }
HIDPage page = AxisCaps[i].UsagePage; HIDPage page = stick.AxisCaps[i].UsagePage;
short usage = AxisCaps[i].NotRange.Usage; short usage = stick.AxisCaps[i].NotRange.Usage;
uint value = 0; uint value = 0;
HidProtocolStatus status = HidProtocol.GetUsageValue( HidProtocolStatus status = HidProtocol.GetUsageValue(
@ -349,13 +341,13 @@ namespace OpenTK.Platform.Windows
if (page == HIDPage.GenericDesktop && (HIDUsageGD)usage == HIDUsageGD.Hatswitch) if (page == HIDPage.GenericDesktop && (HIDUsageGD)usage == HIDUsageGD.Hatswitch)
{ {
stick.SetHat(page, usage, GetHatPosition(value, AxisCaps[i])); stick.SetHat(page, usage, GetHatPosition(value, stick.AxisCaps[i]));
} }
else else
{ {
short scaled_value = (short)HidHelper.ScaleValue( short scaled_value = (short)HidHelper.ScaleValue(
(int)((long)value + AxisCaps[i].LogicalMin), (int)((long)value + stick.AxisCaps[i].LogicalMin),
AxisCaps[i].LogicalMin, AxisCaps[i].LogicalMax, stick.AxisCaps[i].LogicalMin, stick.AxisCaps[i].LogicalMax,
Int16.MinValue, Int16.MaxValue); Int16.MinValue, Int16.MaxValue);
stick.SetAxis(page, usage, scaled_value); stick.SetAxis(page, usage, scaled_value);
} }
@ -376,15 +368,15 @@ namespace OpenTK.Platform.Windows
return HatPosition.Centered; return HatPosition.Centered;
} }
unsafe void UpdateButtons(RawInput* rin, Device stick, int button_caps_count) unsafe void UpdateButtons(RawInput* rin, Device stick)
{ {
stick.ClearButtons(); stick.ClearButtons();
for (int i = 0; i < button_caps_count; i++) for (int i = 0; i < stick.ButtonCaps.Count; i++)
{ {
short* usage_list = stackalloc short[(int)JoystickButton.Last + 1]; short* usage_list = stackalloc short[(int)JoystickButton.Last + 1];
int usage_length = (int)JoystickButton.Last; int usage_length = (int)JoystickButton.Last;
HIDPage page = ButtonCaps[i].UsagePage; HIDPage page = stick.ButtonCaps[i].UsagePage;
HidProtocolStatus status = HidProtocol.GetUsages( HidProtocolStatus status = HidProtocol.GetUsages(
HidProtocolReportType.Input, HidProtocolReportType.Input,
@ -446,8 +438,6 @@ namespace OpenTK.Platform.Windows
void QueryDeviceCaps(Device stick) void QueryDeviceCaps(Device stick)
{ {
HidProtocolCaps caps; HidProtocolCaps caps;
int axis_count;
int button_count;
// Discovered elements // Discovered elements
int axes = 0; int axes = 0;
@ -455,23 +445,21 @@ namespace OpenTK.Platform.Windows
int buttons = 0; int buttons = 0;
if (GetPreparsedData(stick.Handle, ref PreparsedData) && if (GetPreparsedData(stick.Handle, ref PreparsedData) &&
GetDeviceCaps(PreparsedData, out caps, GetDeviceCaps(stick, PreparsedData, out caps))
ref AxisCaps, out axis_count,
ref ButtonCaps, out button_count))
{ {
for (int i = 0; i < axis_count; i++) for (int i = 0; i < stick.AxisCaps.Count; i++)
{ {
if (AxisCaps[i].IsRange) if (stick.AxisCaps[i].IsRange)
{ {
Debug.Print("[WinRawJoystick] Range axis elements not implemented."); Debug.Print("[WinRawJoystick] Range axis elements not implemented.");
continue; continue;
} }
HIDPage page = AxisCaps[i].UsagePage; HIDPage page = stick.AxisCaps[i].UsagePage;
switch (page) switch (page)
{ {
case HIDPage.GenericDesktop: case HIDPage.GenericDesktop:
switch ((HIDUsageGD)AxisCaps[i].NotRange.Usage) switch ((HIDUsageGD)stick.AxisCaps[i].NotRange.Usage)
{ {
case HIDUsageGD.X: case HIDUsageGD.X:
case HIDUsageGD.Y: case HIDUsageGD.Y:
@ -482,37 +470,37 @@ namespace OpenTK.Platform.Windows
case HIDUsageGD.Slider: case HIDUsageGD.Slider:
case HIDUsageGD.Dial: case HIDUsageGD.Dial:
case HIDUsageGD.Wheel: case HIDUsageGD.Wheel:
stick.SetAxis(page, AxisCaps[i].NotRange.Usage, 0); stick.SetAxis(page, stick.AxisCaps[i].NotRange.Usage, 0);
break; break;
case HIDUsageGD.Hatswitch: case HIDUsageGD.Hatswitch:
stick.SetHat(page, AxisCaps[i].NotRange.Usage, HatPosition.Centered); stick.SetHat(page, stick.AxisCaps[i].NotRange.Usage, HatPosition.Centered);
break; break;
} }
break; break;
case HIDPage.Simulation: case HIDPage.Simulation:
switch ((HIDUsageSim)AxisCaps[i].NotRange.Usage) switch ((HIDUsageSim)stick.AxisCaps[i].NotRange.Usage)
{ {
case HIDUsageSim.Rudder: case HIDUsageSim.Rudder:
case HIDUsageSim.Throttle: case HIDUsageSim.Throttle:
stick.SetAxis(page, AxisCaps[i].NotRange.Usage, 0); stick.SetAxis(page, stick.AxisCaps[i].NotRange.Usage, 0);
break; break;
} }
break; break;
} }
} }
for (int i = 0; i < button_count; i++) for (int i = 0; i < stick.ButtonCaps.Count; i++)
{ {
bool is_range = ButtonCaps[i].IsRange; bool is_range = stick.ButtonCaps[i].IsRange;
HIDPage page = ButtonCaps[i].UsagePage; HIDPage page = stick.ButtonCaps[i].UsagePage;
switch (page) switch (page)
{ {
case HIDPage.Button: case HIDPage.Button:
if (is_range) if (is_range)
{ {
for (short usage = ButtonCaps[i].Range.UsageMin; usage <= ButtonCaps[i].Range.UsageMax; usage++) for (short usage = stick.ButtonCaps[i].Range.UsageMin; usage <= stick.ButtonCaps[i].Range.UsageMax; usage++)
{ {
buttons++; buttons++;
stick.SetButton(page, usage, false); stick.SetButton(page, usage, false);
@ -521,7 +509,7 @@ namespace OpenTK.Platform.Windows
else else
{ {
buttons++; buttons++;
stick.SetButton(page, ButtonCaps[i].NotRange.Usage, false); stick.SetButton(page, stick.ButtonCaps[i].NotRange.Usage, false);
} }
break; break;
@ -535,12 +523,10 @@ namespace OpenTK.Platform.Windows
stick.SetCapabilities(new JoystickCapabilities(axes, buttons, dpads, true)); stick.SetCapabilities(new JoystickCapabilities(axes, buttons, dpads, true));
} }
static bool GetDeviceCaps(byte[] preparsed_data, out HidProtocolCaps caps, static bool GetDeviceCaps(Device stick, byte[] preparsed_data, out HidProtocolCaps caps)
ref HidProtocolValueCaps[] axis_caps, out int axis_caps_count,
ref HidProtocolButtonCaps[] button_caps, out int button_caps_count)
{ {
axis_caps_count = 0; int axis_caps_count = 0;
button_caps_count = 0; int button_caps_count = 0;
// Query joystick capabilities // Query joystick capabilities
caps = new HidProtocolCaps(); caps = new HidProtocolCaps();
@ -552,14 +538,8 @@ namespace OpenTK.Platform.Windows
} }
// Make sure our caps arrays are big enough // Make sure our caps arrays are big enough
if (axis_caps.Length < caps.NumberInputValueCaps) HidProtocolValueCaps[] axis_caps = new HidProtocolValueCaps[caps.NumberInputValueCaps];
{ HidProtocolButtonCaps[] button_caps = new HidProtocolButtonCaps[caps.NumberInputButtonCaps];
Array.Resize(ref axis_caps, caps.NumberInputValueCaps);
}
if (button_caps.Length < caps.NumberInputButtonCaps)
{
Array.Resize(ref button_caps, caps.NumberInputButtonCaps);
}
// Axis capabilities // Axis capabilities
ushort axis_count = (ushort)axis_caps.Length; ushort axis_count = (ushort)axis_caps.Length;
@ -585,6 +565,12 @@ namespace OpenTK.Platform.Windows
} }
button_caps_count = (int)button_count; button_caps_count = (int)button_count;
stick.AxisCaps.Clear();
stick.AxisCaps.AddRange(axis_caps);
stick.ButtonCaps.Clear();
stick.ButtonCaps.AddRange(button_caps);
return true; return true;
} }