예제 #1
0
        /// <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])));
        }