protected override unsafe void OnUpdateEffectTypeSpecificParameters() { base.OnUpdateEffectTypeSpecificParameters(); if (directInputEffect != null) { DICONDITION diCondition = new DICONDITION(); diCondition.lOffset = (int)(Offset * DInput.DI_FFNOMINALMAX); diCondition.lNegativeCoefficient = (int)(NegativeCoefficient * DInput.DI_FFNOMINALMAX); diCondition.lPositiveCoefficient = (int)(PositiveCoefficient * DInput.DI_FFNOMINALMAX); diCondition.dwNegativeSaturation = (uint)(NegativeSaturation * DInput.DI_FFNOMINALMAX); diCondition.dwPositiveSaturation = (uint)(PositiveSaturation * DInput.DI_FFNOMINALMAX); diCondition.lDeadBand = (int)(DeadBand * DInput.DI_FFNOMINALMAX); DIEFFECT diEffect = new DIEFFECT(); diEffect.dwSize = (uint)sizeof(DIEFFECT); diEffect.dwFlags = DInput.DIEFF_CARTESIAN | DInput.DIEFF_OBJECTOFFSETS; diEffect.cbTypeSpecificParams = (uint)sizeof(DICONDITION); diEffect.lpvTypeSpecificParams = &diCondition; int hr = IDirectInputEffect.SetParameters(directInputEffect, ref diEffect, DInput.DIEP_TYPESPECIFICPARAMS); if (Wrapper.FAILED(hr)) { Log.Warning("DirectInputForceFeedbackConditionEffect: " + "Cannot update Condition effect parameters ({0}).", DInput.GetOutString(DInput.DXGetErrorStringW(hr))); return; } } }
protected override unsafe void OnUpdateEffectTypeSpecificParameters() { base.OnUpdateEffectTypeSpecificParameters(); if (directInputEffect != null) { DIRAMPFORCE diRamp = new DIRAMPFORCE(); diRamp.lStart = (int)(StartForce * DInput.DI_FFNOMINALMAX); diRamp.lEnd = (int)(EndForce * DInput.DI_FFNOMINALMAX); DIEFFECT diEffect = new DIEFFECT(); diEffect.dwSize = (uint)sizeof(DIEFFECT); diEffect.dwFlags = DInput.DIEFF_CARTESIAN | DInput.DIEFF_OBJECTOFFSETS; diEffect.cbTypeSpecificParams = (uint)sizeof(DIRAMPFORCE); diEffect.lpvTypeSpecificParams = &diRamp; int hr = IDirectInputEffect.SetParameters(directInputEffect, ref diEffect, DInput.DIEP_TYPESPECIFICPARAMS); if (Wrapper.FAILED(hr)) { Log.Warning("DirectInputForceFeedbackRampEffect: " + "Cannot update Ramp effect parameters ({0}).", DInput.GetOutString(DInput.DXGetErrorStringW(hr))); return; } } }
protected override unsafe void OnUpdateEffectTypeSpecificParameters() { base.OnUpdateEffectTypeSpecificParameters(); if (directInputEffect != null) { DIPERIODIC diPeriodic = new DIPERIODIC(); diPeriodic.dwMagnitude = (uint)(10000.0f * Magnitude); diPeriodic.lOffset = (int)((float)diPeriodic.dwMagnitude * Offset); diPeriodic.dwPhase = (uint)(36000.0f * Phase); diPeriodic.dwPeriod = (uint)(Period * DInput.DI_SECONDS); DIEFFECT diEffect = new DIEFFECT(); diEffect.dwSize = (uint)sizeof(DIEFFECT); diEffect.dwFlags = DInput.DIEFF_CARTESIAN | DInput.DIEFF_OBJECTOFFSETS; diEffect.cbTypeSpecificParams = (uint)sizeof(DIPERIODIC); diEffect.lpvTypeSpecificParams = &diPeriodic; int hr = IDirectInputEffect.SetParameters(directInputEffect, ref diEffect, DInput.DIEP_TYPESPECIFICPARAMS); if (Wrapper.FAILED(hr)) { Log.Warning("DirectInputForceFeedbackPeriodicEffect: " + "Cannot update Periodic effect parameters ({0}).", DInput.GetOutString(DInput.DXGetErrorStringW(hr))); return; } } }
public static unsafe void UpdateEffectDirection(ForceFeedbackEffect effect, IDirectInputEffect *directInputEffect) { if (effect.Direction != null) { int *pDirections = stackalloc int[effect.Direction.Count]; for (int n = 0; n < effect.Direction.Count; n++) { pDirections[n] = (int)(effect.Direction[n] * DInput.DI_FFNOMINALMAX); } uint dwFlags = DInput.DIEP_DIRECTION; DIEFFECT diEffect = new DIEFFECT(); diEffect.dwSize = (uint)sizeof(DIEFFECT); diEffect.dwFlags = DInput.DIEFF_CARTESIAN | DInput.DIEFF_OBJECTOFFSETS; diEffect.cAxes = (uint)effect.Axes.Count; diEffect.rglDirection = pDirections; int hr = IDirectInputEffect.SetParameters(directInputEffect, ref diEffect, dwFlags); if (Wrapper.FAILED(hr)) { Log.Warning("DirectInputForceFeedbackEffect: " + "Cannot update direction ({0}).", DInput.GetOutString(DInput.DXGetErrorStringW(hr))); return; } } }
public unsafe DirectInputForceFeedbackController(IDirectInputDevice8 *directInputDevice, JoystickInputDevice joystick) : base(joystick) { int hr = IDirectInputDevice8.EnumEffects(directInputDevice, EnumEffectHandler, null, DInput.DIEFT_ALL); if (Wrapper.FAILED(hr)) { Log.Warning("DirectInputForceFeedbackController: " + "Cannot enum ForceFeedbackEffects for \"{0}\" ({1}).", Device.Name, DInput.GetOutString(DInput.DXGetErrorStringW(hr))); } }
protected override unsafe void OnStart() { base.OnStart(); OnUpdateDirection(); OnUpdateEffectTypeSpecificParameters(); int hr = IDirectInputEffect.Start(directInputEffect, 1, 0); if (Wrapper.FAILED(hr)) { Log.Warning("DirectInputForceFeedbackRampEffect: " + "Cannot start Ramp force feedback effect ({0}).", DInput.GetOutString(DInput.DXGetErrorStringW(hr))); return; } }
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); }
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); }
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 }