/// <summary> /// Function to perform the creation of the DirectInput joystick object. /// </summary> /// <param name="directInput">The direct input interface.</param> /// <param name="deviceInfo">The device information for the gaming device to use.</param> /// <returns>The DirectInput joystick object.</returns> private DI.Joystick CreateJoystick(DI.DirectInput directInput, DirectInputDeviceInfo deviceInfo) { var result = new DI.Joystick(directInput, deviceInfo.InstanceGuid); IntPtr mainWindow = FindMainApplicationWindow(); if (mainWindow == IntPtr.Zero) { // We have no main window, and DI requires one, so we need to kill this. throw new InvalidOperationException(Resources.GORINP_ERR_DI_COULD_NOT_FIND_APP_WINDOW); } result.SetCooperativeLevel(mainWindow, DI.CooperativeLevel.Foreground | DI.CooperativeLevel.NonExclusive); result.Properties.AxisMode = DI.DeviceAxisMode.Absolute; // Set up dead zones. foreach (GorgonGamingDeviceAxis axis in Axis) { // Skip the throttle. Dead zones on the throttle don't work too well for regular joysticks. // Game pads may be another story, but the user can manage those settings if required. if (axis.Axis == GamingDeviceAxis.Throttle) { continue; } GorgonGamingDeviceAxisInfo info = Info.AxisInfo[axis.Axis]; DI.ObjectProperties properties = result.GetObjectPropertiesById(_info.AxisMappings[axis.Axis]); if (properties == null) { continue; } // Set a 0 dead zone. properties.DeadZone = 0; // Make the dead zone 10% of the range for all axes. float deadZone = axis.Axis == GamingDeviceAxis.Throttle ? 0.02f : 0.10f; int deadZoneActual = (int)(info.Range.Range * deadZone); axis.DeadZone = new GorgonRange(info.DefaultValue - deadZoneActual, info.DefaultValue + deadZoneActual); } return(result); }
/// <summary> /// Function to retrieve the capabilities from the DirectInput joystick. /// </summary> /// <param name="joystick">The DirectInput joystick to evaluate.</param> public void GetDeviceCaps(DI.Joystick joystick) { var defaults = new Dictionary <GamingDeviceAxis, int>(new GorgonGamingDeviceAxisEqualityComparer()); var axisRanges = new Dictionary <GamingDeviceAxis, GorgonRange>(new GorgonGamingDeviceAxisEqualityComparer()); ProductID = joystick.Properties.ProductId; ManufacturerID = joystick.Properties.VendorId; ButtonCount = joystick.Capabilities.ButtonCount; POVCount = joystick.Capabilities.PovCount; Capabilities = POVCount > 0 ? GamingDeviceCapabilityFlags.SupportsPOV : GamingDeviceCapabilityFlags.None; IList <DI.DeviceObjectInstance> axisInfo = joystick.GetObjects(DI.DeviceObjectTypeFlags.Axis); foreach (DI.DeviceObjectInstance axis in axisInfo) { var usage = (HIDUsage)axis.Usage; DI.ObjectProperties properties = joystick.GetObjectPropertiesById(axis.ObjectId); // Skip this axis if retrieving the properties results in failure. if (properties == null) { continue; } var range = new GorgonRange(properties.Range.Minimum, properties.Range.Maximum); int midPoint = ((range.Range + 1) / 2) + range.Minimum; switch (usage) { case HIDUsage.X: AxisMappings[GamingDeviceAxis.XAxis] = axis.ObjectId; axisRanges[GamingDeviceAxis.XAxis] = range; defaults[GamingDeviceAxis.XAxis] = range.Minimum < 0 ? 0 : midPoint; break; case HIDUsage.Y: AxisMappings[GamingDeviceAxis.YAxis] = axis.ObjectId; axisRanges[GamingDeviceAxis.YAxis] = range; defaults[GamingDeviceAxis.YAxis] = range.Minimum < 0 ? 0 : midPoint; break; case HIDUsage.Slider: AxisMappings[GamingDeviceAxis.Throttle] = axis.ObjectId; axisRanges[GamingDeviceAxis.Throttle] = range; defaults[GamingDeviceAxis.Throttle] = 0; Capabilities |= GamingDeviceCapabilityFlags.SupportsThrottle; break; case HIDUsage.Z: AxisMappings[GamingDeviceAxis.ZAxis] = axis.ObjectId; axisRanges[GamingDeviceAxis.ZAxis] = range; defaults[GamingDeviceAxis.ZAxis] = range.Minimum < 0 ? 0 : midPoint; Capabilities |= GamingDeviceCapabilityFlags.SupportsZAxis; break; case HIDUsage.RelativeX: AxisMappings[GamingDeviceAxis.XAxis2] = axis.ObjectId; axisRanges[GamingDeviceAxis.XAxis2] = range; Capabilities |= GamingDeviceCapabilityFlags.SupportsSecondaryXAxis; defaults[GamingDeviceAxis.XAxis2] = midPoint; break; case HIDUsage.RelativeY: AxisMappings[GamingDeviceAxis.YAxis2] = axis.ObjectId; axisRanges[GamingDeviceAxis.YAxis2] = range; Capabilities |= GamingDeviceCapabilityFlags.SupportsSecondaryYAxis; defaults[GamingDeviceAxis.YAxis2] = midPoint; break; case HIDUsage.RelativeZ: AxisMappings[GamingDeviceAxis.ZAxis2] = axis.ObjectId; axisRanges[GamingDeviceAxis.ZAxis2] = range; Capabilities |= GamingDeviceCapabilityFlags.SupportsRudder; defaults[GamingDeviceAxis.ZAxis2] = 0; break; } } AxisInfo = new GorgonGamingDeviceAxisList <GorgonGamingDeviceAxisInfo>( axisRanges.Select(item => new GorgonGamingDeviceAxisInfo(item.Key, item.Value, defaults[item.Key]))); }