Ejemplo n.º 1
0
        protected override unsafe bool OnCreateRealEffect()
        {
            base.OnCreateRealEffect();

            DirectInputJoystickInputDevice device = (DirectInputJoystickInputDevice)Owner.Device;

            directInputEffect = DirectInputForceFeedbackEffectUtils.CreateEffect(device, EffectType, Axes);
            return(directInputEffect != null);
        }
        internal unsafe bool Init()
        {
            GUID devGuid = deviceGuid;

            void */*IDirectInputDevice8*/ directInputDeviceTemp = null;

            int hr = IDirectInput.CreateDevice(
                WindowsInputDeviceManager.Instance.DirectInput,
                ref devGuid, out directInputDeviceTemp, null);

            if (Wrapper.FAILED(hr))
            {
                Log.Warning("DirectInputJoystickDevice: Cannot create device \"{0}\" ({1}).",
                            Name, DInput.GetOutString(DInput.DXGetErrorStringW(hr)));
                return(false);
            }

            directInputDevice = (IDirectInputDevice8 *)directInputDeviceTemp;

            // get capabilities

            DIDEVCAPS caps = new DIDEVCAPS();

            caps.dwSize = (uint)sizeof(DIDEVCAPS);

            hr = IDirectInputDevice8.GetCapabilities(directInputDevice, ref caps);
            if (Wrapper.FAILED(hr))
            {
                Log.Warning("DirectInputJoystickDevice: Cannot get device capabilities \"{0}\".", Name);
                return(false);
            }

            //buttons
            Button[] buttons = new Button[caps.dwButtons];
            for (int n = 0; n < buttons.Length; n++)
            {
                buttons[n] = new Button((JoystickButtons)n, n);
            }

            //povs
            POV[] povs = new POV[caps.dwPOVs];
            for (int n = 0; n < povs.Length; n++)
            {
                povs[n] = new JoystickInputDevice.POV((JoystickPOVs)n);
            }

            // setup

            hr = IDirectInputDevice8.SetDataFormat(directInputDevice, DInput.Get_c_dfDIJoystick2());

            if (Wrapper.FAILED(hr))
            {
                Log.Warning("DirectInputJoystickDevice: Cannot set device data format \"{0}\".", Name);
                return(false);
            }

            hr = IDirectInputDevice8.SetCooperativeLevel(directInputDevice,
                                                         WindowsInputDeviceManager.Instance.WindowHandle,
                                                         DInput.DISCL_EXCLUSIVE | DInput.DISCL_FOREGROUND);

            if (Wrapper.FAILED(hr))
            {
                Log.Warning("DirectInputJoystickDevice: Cannot set device " +
                            "cooperative level \"{0}\".", Name);
                return(false);
            }

            //-------------------------------------------------------------------
            // setup size for buffered input

            DIPROPDWORD dibuf = new DIPROPDWORD();

            dibuf.diph.dwSize       = (uint)sizeof(DIPROPDWORD);
            dibuf.diph.dwHeaderSize = (uint)sizeof(DIPROPHEADER);
            dibuf.diph.dwHow        = DInput.DIPH_DEVICE;
            dibuf.diph.dwObj        = 0;
            dibuf.dwData            = BufferSize;

            GUID *bufferSizeGuid = (GUID *)DInput.getDIPROP_BUFFERSIZE();

            hr = IDirectInputDevice8.SetProperty(directInputDevice, bufferSizeGuid, ref dibuf.diph);
            if (Wrapper.FAILED(hr))
            {
                Log.Warning("DirectInputJoystickDevice: Cannot set device buffer size \"{0}\".",
                            Name);
                return(false);
            }

            deviceDataBuffer = NativeUtility.Alloc(NativeUtility.MemoryAllocationType.Utility,
                                                   sizeof(DIDEVICEOBJECTDATA) * BufferSize);

            //--------------------------------------------------------------------

            temporarySliderCount = 0;

            temporaryAxisList = new List <JoystickInputDevice.Axis>();

            tempDeviceForEnumerate = this;
            hr = IDirectInputDevice8.EnumObjects(directInputDevice, EnumDeviceObjectsHandler,
                                                 null, DInput.DIDFT_ALL);
            tempDeviceForEnumerate = null;

            if (Wrapper.FAILED(hr))
            {
                Log.Warning("DirectInputJoystickDevice: Cannot enumerate device objects \"{0}\".",
                            Name);
                return(false);
            }

            //axes
            Axis[] axes = temporaryAxisList.ToArray();
            temporaryAxisList = null;

            //sliders
            Slider[] sliders = new Slider[temporarySliderCount];
            for (int n = 0; n < sliders.Length; n++)
            {
                sliders[n] = new JoystickInputDevice.Slider((JoystickSliders)n);
            }

            //forceFeedbackController
            ForceFeedbackController forceFeedbackController = null;

            if ((caps.dwFlags & DInput.DIDC_FORCEFEEDBACK) != 0)
            {
                forceFeedbackController = new DirectInputForceFeedbackController(directInputDevice, this);
            }

            //initialize data
            InitDeviceData(buttons, axes, povs, sliders, forceFeedbackController);

            return(true);
        }
Ejemplo n.º 3
0
        public unsafe static IDirectInputEffect *CreateEffect(DirectInputJoystickInputDevice device,
                                                              ForceFeedbackEffectTypes effectType, IList <JoystickAxes> axes)
        {
            uint *pAxes       = stackalloc uint[axes.Count];
            int * pDirections = stackalloc int[axes.Count];

            for (int n = 0; n < axes.Count; n++)
            {
                pAxes[n]       = (uint)GetOffsetByAxisType(axes[n]);
                pDirections[n] = 0;
            }

            //

            DICONSTANTFORCE diConstantForce = new DICONSTANTFORCE();
            //DICUSTOMFORCE diCustomForce = new DICUSTOMFORCE();
            DICONDITION diCondition = new DICONDITION();
            DIPERIODIC  diPeriodic  = new DIPERIODIC();
            DIRAMPFORCE diRamp      = new DIRAMPFORCE();

            GUID     effectTypeGuid = new GUID();
            DIEFFECT diEffect       = new DIEFFECT();

            switch (effectType)
            {
            case ForceFeedbackEffectTypes.Spring:
                effectTypeGuid = DInput.GUID_Spring;
                diEffect.cbTypeSpecificParams  = (uint)sizeof(DICONDITION);
                diEffect.lpvTypeSpecificParams = &diCondition;
                break;

            case ForceFeedbackEffectTypes.Damper:
                effectTypeGuid = DInput.GUID_Damper;
                diEffect.cbTypeSpecificParams  = (uint)sizeof(DICONDITION);
                diEffect.lpvTypeSpecificParams = &diCondition;
                break;

            case ForceFeedbackEffectTypes.Friction:
                effectTypeGuid = DInput.GUID_Friction;
                diEffect.cbTypeSpecificParams  = (uint)sizeof(DICONDITION);
                diEffect.lpvTypeSpecificParams = &diCondition;
                break;

            case ForceFeedbackEffectTypes.Inertia:
                effectTypeGuid = DInput.GUID_Inertia;
                diEffect.cbTypeSpecificParams  = (uint)sizeof(DICONDITION);
                diEffect.lpvTypeSpecificParams = &diCondition;
                break;

            case ForceFeedbackEffectTypes.ConstantForce:
                effectTypeGuid = DInput.GUID_ConstantForce;
                diEffect.cbTypeSpecificParams  = (uint)sizeof(DICONSTANTFORCE);
                diEffect.lpvTypeSpecificParams = &diConstantForce;
                break;

            //case ForceFeedbackEffectTypes.CustomForce:
            //   effectTypeGuid = DInput.GUID_CustomForce;
            //   diEffect.cbTypeSpecificParams = (uint)sizeof( DICUSTOMFORCE );
            //   diEffect.lpvTypeSpecificParams = &diCustomForce;
            //   break;

            case ForceFeedbackEffectTypes.SawtoothDown:
                effectTypeGuid = DInput.GUID_SawtoothDown;
                diEffect.cbTypeSpecificParams  = (uint)sizeof(DIPERIODIC);
                diEffect.lpvTypeSpecificParams = &diPeriodic;
                break;

            case ForceFeedbackEffectTypes.SawtoothUp:
                effectTypeGuid = DInput.GUID_SawtoothUp;
                diEffect.cbTypeSpecificParams  = (uint)sizeof(DIPERIODIC);
                diEffect.lpvTypeSpecificParams = &diPeriodic;
                break;

            case ForceFeedbackEffectTypes.Sine:
                effectTypeGuid = DInput.GUID_Sine;
                diEffect.cbTypeSpecificParams  = (uint)sizeof(DIPERIODIC);
                diEffect.lpvTypeSpecificParams = &diPeriodic;
                break;

            case ForceFeedbackEffectTypes.Square:
                effectTypeGuid = DInput.GUID_Square;
                diEffect.cbTypeSpecificParams  = (uint)sizeof(DIPERIODIC);
                diEffect.lpvTypeSpecificParams = &diPeriodic;
                break;

            case ForceFeedbackEffectTypes.Triangle:
                effectTypeGuid = DInput.GUID_Triangle;
                diEffect.cbTypeSpecificParams  = (uint)sizeof(DIPERIODIC);
                diEffect.lpvTypeSpecificParams = &diPeriodic;
                break;

            case ForceFeedbackEffectTypes.Ramp:
                effectTypeGuid = DInput.GUID_RampForce;
                diEffect.cbTypeSpecificParams  = (uint)sizeof(DIRAMPFORCE);
                diEffect.lpvTypeSpecificParams = &diRamp;
                break;
            }

            diEffect.dwSize                  = (uint)sizeof(DIEFFECT);
            diEffect.dwFlags                 = DInput.DIEFF_CARTESIAN | DInput.DIEFF_OBJECTOFFSETS;
            diEffect.dwDuration              = DInput.INFINITE;
            diEffect.dwSamplePeriod          = 0;
            diEffect.dwGain                  = DInput.DI_FFNOMINALMAX;
            diEffect.dwTriggerButton         = DInput.DIEB_NOTRIGGER;
            diEffect.dwTriggerRepeatInterval = 0;
            diEffect.cAxes          = (uint)axes.Count;
            diEffect.rgdwAxes       = pAxes;
            diEffect.rglDirection   = pDirections;
            diEffect.lpEnvelope     = null;
            diEffect.dwStartDelay   = 0;
            diEffect.dwSamplePeriod = 0;

            //

            void */*IDirectInputEffect*/ directInputEffect = null;

            int hr = IDirectInputDevice8.CreateEffect(device.directInputDevice,
                                                      ref effectTypeGuid, ref diEffect, out directInputEffect, null);

            if (Wrapper.FAILED(hr))
            {
                Log.Warning("DirectInputForceFeedbackController: " +
                            "Cannot create ForceFeedbackEffect for \"{0}\" ({1}).", device.Name,
                            DInput.GetOutString(DInput.DXGetErrorStringW(hr)));
                return(null);
            }

            return((IDirectInputEffect *)directInputEffect);
        }
        unsafe static bool EnumDeviceObjectsHandler(IntPtr /*DIDEVICEOBJECTINSTANCE*/ lpddoi, void *pvRef)
        {
            DirectInputJoystickInputDevice device = tempDeviceForEnumerate;

            DIDEVICEOBJECTINSTANCE *deviceObjectInstance = (DIDEVICEOBJECTINSTANCE *)lpddoi;

            if ((deviceObjectInstance->dwType & DInput.DIDFT_AXIS) != 0)
            {
                int hr;

                // set range

                DIPROPRANGE diPropRange = new DIPROPRANGE();
                diPropRange.diph.dwSize       = (uint)sizeof(DIPROPRANGE);
                diPropRange.diph.dwHeaderSize = (uint)sizeof(DIPROPHEADER);
                diPropRange.diph.dwHow        = DInput.DIPH_BYID;
                diPropRange.diph.dwObj        = deviceObjectInstance->dwType;
                diPropRange.lMin = -(int)MaxRange;
                diPropRange.lMax = +(int)MaxRange;

                GUID *propRangeGuid = (GUID *)DInput.getDIPROP_RANGE();

                hr = IDirectInputDevice8.SetProperty_DIPROPRANGE(device.directInputDevice,
                                                                 propRangeGuid, ref diPropRange);
                //hr = IDirectInputDevice8.SetProperty( device.directInputDevice,
                //   propRangeGuid, ref diPropRange.diph );

                if (Wrapper.FAILED(hr))
                {
                    Log.Warning("DirectInputJoystickInputDevice: Cannot set axis range for \"{0}\" ({1}).",
                                device.Name, DInput.GetOutString(DInput.DXGetErrorStringW(hr)));
                }

                // set axis type

                //uint userData = 0xFFFFFFFF;

                if (deviceObjectInstance->guidType == DInput.GUID_Slider)
                {
                    device.temporarySliderCount++;
                }

                if (deviceObjectInstance->guidType == DInput.GUID_XAxis ||
                    deviceObjectInstance->guidType == DInput.GUID_YAxis ||
                    deviceObjectInstance->guidType == DInput.GUID_ZAxis ||
                    deviceObjectInstance->guidType == DInput.GUID_RxAxis ||
                    deviceObjectInstance->guidType == DInput.GUID_RyAxis ||
                    deviceObjectInstance->guidType == DInput.GUID_RzAxis)
                {
                    // set dead zone

                    //DIPROPDWORD deadZone = new DIPROPDWORD();
                    //deadZone.diph.dwSize = (uint)sizeof( DIPROPDWORD );
                    //deadZone.diph.dwHeaderSize = (uint)sizeof( DIPROPHEADER );
                    //deadZone.diph.dwHow = DInput.DIPH_BYID;
                    //deadZone.diph.dwObj = deviceObjectInstance->dwType; // Specify the enumerated axis
                    //deadZone.dwData = 500;	// dead zone of 5%

                    //GUID* propDeadZone = (GUID*)DInput.getDIPROP_DEADZONE();

                    //hr = IDirectInputDevice8.SetProperty( joystickDevice,
                    //   propDeadZone, ref deadZone.diph );
                    //if( Wrapper.FAILED( hr ) )
                    //{
                    //   Log.Error( "Cannot set axis dead zone for '" + Name + "'" );
                    //}

                    // type settings

                    //userData = 0x80000000 | (uint)device.temporaryAxisList.Count;

                    JoystickAxes axisName = GetJoystickAxisNameByGUID(deviceObjectInstance->guidType);

                    RangeF range = new RangeF(-1, 1);

                    bool forceFeedbackSupported =
                        (deviceObjectInstance->dwFlags & DInput.DIDOI_FFACTUATOR) != 0;

                    JoystickInputDevice.Axis axis = new JoystickInputDevice.Axis(
                        axisName, range, forceFeedbackSupported);

                    device.temporaryAxisList.Add(axis);
                }

                //// set user data

                //DIPROPPOINTER diptr = new DIPROPPOINTER();
                //diptr.diph.dwSize = (uint)sizeof( DIPROPPOINTER );
                //diptr.diph.dwHeaderSize = (uint)sizeof( DIPROPHEADER );
                //diptr.diph.dwHow = DInput.DIPH_BYID;
                //diptr.diph.dwObj = deviceObjectInstance->dwType;
                ////if( IntPtr.Size == 8 )
                ////{
                ////   UInt64 v64 = userData;
                ////   NativeUtils.CopyMemory( (IntPtr)( &diptr.uData ), (IntPtr)( &v64 ), IntPtr.Size );
                ////}
                ////else
                ////{
                ////   NativeUtils.CopyMemory( (IntPtr)( &diptr.uData ), (IntPtr)( &userData ), IntPtr.Size );
                ////}
                //diptr.uData = IntPtr.Zero;
                ////diptr.uData = (IntPtr)userData;

                //GUID* appDataGuid = (GUID*)DInput.getDIPROP_APPDATA();

                //hr = IDirectInputDevice8.SetProperty( device.directInputDevice,
                //   appDataGuid, ref diptr.diph );
                //if( Wrapper.FAILED( hr ) )
                //{
                //   Log.InvisibleInfo( "DirectInputJoystickDevice: Cannot set appData for \"{0}\".",
                //      device.Name );
                //   //Log.Warning( "DirectInputJoystickDevice: Cannot set appData for \"{0}\".",
                //   //   device.Name );
                //}
            }
            return(true);            // continue
        }