void UpdateDiStates(UserGame game, DeviceDetector detector) { // Get all mapped user instances. var instanceGuids = SettingsManager.UserSettings.Items .Where(x => x.MapTo > (int)MapTo.None) .Select(x => x.InstanceGuid).ToArray(); // Get all connected devices. var userDevices = SettingsManager.UserDevices.Items .Where(x => instanceGuids.Contains(x.InstanceGuid) && x.IsOnline) .ToArray(); // Acquire copy of feedbacks for processing. var feedbacks = CopyAndClearFeedbacks(); for (int i = 0; i < userDevices.Count(); i++) { // Update direct input form and return actions (pressed Buttons/DPads, turned Axis/Sliders). var ud = userDevices[i]; JoystickState state = null; // Allow if not testing or testing with option enabled. var o = SettingsManager.Options; var allow = !o.TestEnabled || o.TestGetDInputStates; var isOnline = ud != null && ud.IsOnline; if (isOnline && allow) { var device = ud.Device; if (device != null) { var exceptionData = new System.Text.StringBuilder(); try { var isVirtual = ((EmulationType)game.EmulationType).HasFlag(EmulationType.Virtual); var hasForceFeedback = device.Capabilities.Flags.HasFlag(DeviceFlags.ForceFeedback); // Exclusive mode required only if force feedback is available and device is virtual there are no info about effects. var exclusiveRequired = hasForceFeedback && (isVirtual || ud.DeviceEffects == null); // If exclusive mode is required and mode is unknown or not exclusive then... if (exclusiveRequired && (!ud.IsExclusiveMode.HasValue || !ud.IsExclusiveMode.Value)) { var flags = CooperativeLevel.Background | CooperativeLevel.Exclusive; // Reacquire device in exclusive mode. exceptionData.AppendLine("Unacquire (Exclusive)..."); device.Unacquire(); exceptionData.AppendLine("SetCooperativeLevel (Exclusive)..."); device.SetCooperativeLevel(detector.DetectorForm.Handle, flags); exceptionData.AppendLine("Acquire (Exclusive)..."); device.Acquire(); ud.IsExclusiveMode = true; } // If current mode must be non exclusive and mode is unknown or exclusive then... else if (!exclusiveRequired && (!ud.IsExclusiveMode.HasValue || ud.IsExclusiveMode.Value)) { var flags = CooperativeLevel.Background | CooperativeLevel.NonExclusive; // Reacquire device in non exclusive mode so that xinput.dll can control force feedback. exceptionData.AppendLine("Unacquire (NonExclusive)..."); device.Unacquire(); exceptionData.AppendLine("SetCooperativeLevel (Exclusive)..."); device.SetCooperativeLevel(detector.DetectorForm.Handle, flags); exceptionData.AppendLine("Acquire (Acquire)..."); device.Acquire(); ud.IsExclusiveMode = false; } exceptionData.AppendFormat("device.GetCurrentState() // ud.IsExclusiveMode = {0}", ud.IsExclusiveMode).AppendLine(); // Polling - Retrieves data from polled objects on a DirectInput device. // Some devices require pooling (For example original "Xbox Controller S" with XBCD drivers). // If the device does not require polling, calling this method has no effect. // If a device that requires polling is not polled periodically, no new data is received from the device. // Calling this method causes DirectInput to update the device state, generate input // events (if buffered data is enabled), and set notification events (if notification is enabled). device.Poll(); // Get device state. state = device.GetCurrentState(); // Fill device objects. if (ud.DeviceObjects == null) { exceptionData.AppendFormat("AppHelper.GetDeviceObjects(device) // ud.IsExclusiveMode = {0}", ud.IsExclusiveMode).AppendLine(); var dos = AppHelper.GetDeviceObjects(device); ud.DeviceObjects = dos; // Update masks. int axisMask = 0; int actuatorMask = 0; int actuatorCount = 0; if (ud.CapType == (int)SharpDX.DirectInput.DeviceType.Mouse) { CustomDiState.GetMouseAxisMask(dos, device, out axisMask); } else { CustomDiState.GetJoystickAxisMask(dos, device, out axisMask, out actuatorMask, out actuatorCount); } ud.DiAxeMask = axisMask; // Contains information about which axis have force feedback actuator attached. ud.DiActuatorMask = actuatorMask; ud.DiActuatorCount = actuatorCount; CustomDiState.GetJoystickSlidersMask(dos, device); } if (ud.DeviceEffects == null) { exceptionData.AppendFormat("AppHelper.GetDeviceEffects(device) // ud.IsExclusiveMode = {0}", ud.IsExclusiveMode).AppendLine(); ud.DeviceEffects = AppHelper.GetDeviceEffects(device); } // Get PAD index this device is mapped to. var userIndex = SettingsManager.UserSettings.Items .Where(x => x.MapTo > (int)MapTo.None) .Where(x => x.InstanceGuid == ud.InstanceGuid) .Select(x => x.MapTo).First(); // If device support force feedback then... if (hasForceFeedback) { // Get setting related to user device. var setting = SettingsManager.UserSettings.Items .FirstOrDefault(x => x.MapTo == userIndex && x.InstanceGuid == ud.InstanceGuid); if (setting != null) { // Get pad setting attached to device. var ps = SettingsManager.GetPadSetting(setting.PadSettingChecksum); if (ps != null) { // If force is enabled then... if (ps.ForceEnable == "1") { if (ud.FFState == null) { ud.FFState = new Engine.ForceFeedbackState(); } // If force update supplied then... var force = feedbacks[userIndex - 1]; if (force != null || ud.FFState.Changed(ps)) { var v = new Vibration(); if (force == null) { v.LeftMotorSpeed = short.MinValue; v.RightMotorSpeed = short.MinValue; } else { v.LeftMotorSpeed = (short)ConvertHelper.ConvertRange(byte.MinValue, byte.MaxValue, short.MinValue, short.MaxValue, force.LargeMotor); v.RightMotorSpeed = (short)ConvertHelper.ConvertRange(byte.MinValue, byte.MaxValue, short.MinValue, short.MaxValue, force.SmallMotor); } // For the future: Investigate device states if force feedback is not working. // var st = ud.Device.GetForceFeedbackState(); //st == SharpDX.DirectInput.ForceFeedbackState // ud.Device.SendForceFeedbackCommand(ForceFeedbackCommand.SetActuatorsOn); exceptionData.AppendFormat("ud.FFState.SetDeviceForces(device) // ud.IsExclusiveMode = {0}", ud.IsExclusiveMode).AppendLine(); ud.FFState.SetDeviceForces(ud, device, ps, v); } } // If force state was created then... else if (ud.FFState != null) { // Stop device forces. exceptionData.AppendFormat("ud.FFState.StopDeviceForces(device) // ud.IsExclusiveMode = {0}", ud.IsExclusiveMode).AppendLine(); ud.FFState.StopDeviceForces(device); ud.FFState = null; } } } } } catch (Exception ex) { var cx = new DInputException("UpdateDiStates Exception", ex); cx.Data.Add("FFInfo", exceptionData.ToString()); JocysCom.ClassLibrary.Runtime.LogHelper.Current.WriteException(cx); ud.IsExclusiveMode = null; } } // If this is test device then... else if (TestDeviceHelper.ProductGuid.Equals(ud.ProductGuid)) { // Fill device objects. if (ud.DeviceObjects == null) { var dos = TestDeviceHelper.GetDeviceObjects(); ud.DeviceObjects = dos; // Update masks. ud.DiAxeMask = 0x1 | 0x2 | 0x4 | 0x8; ud.DiSliderMask = 0; } if (ud.DeviceEffects == null) { ud.DeviceEffects = new DeviceEffectItem[0]; } state = TestDeviceHelper.GetCurrentState(ud); } } ud.JoState = state ?? new JoystickState(); var newState = new CustomDiState(ud.JoState); var newTime = watch.ElapsedTicks; // Mouse needs special update. if (ud.Device != null && ud.Device.Information.Type == SharpDX.DirectInput.DeviceType.Mouse) { if (ud.DiState == null) { ud.DiState = new CustomDiState(new JoystickState()); } var mouseState = ud.DiState; if (ud.OldDiState == null) { ud.DiState = mouseState; // Make sure new state have zero values. for (int a = 0; a < newState.Axis.Length; a++) { mouseState.Axis[a] = -short.MinValue; } // Update sliders with delta. for (int s = 0; s < newState.Sliders.Length; s++) { mouseState.Sliders[s] = -short.MinValue; } } else { //-------------------------------------------------------- // Map mouse acceleration to axis position. Good for FPS control. //-------------------------------------------------------- // This parts needs to be worked on. //var ticks = (int)(newTime - ud.DiStateTime); // Update axis with delta. //for (int a = 0; a < newState.Axis.Length; a++) // mouseState.Axis[a] = ticks * (newState.Axis[a] - ud.OldDiState.Axis[a]) - short.MinValue; // Update sliders with delta. //for (int s = 0; s < newState.Sliders.Length; s++) // mouseState.Sliders[s] = ticks * (newState.Sliders[s] - ud.OldDiState.Sliders[s]) - short.MinValue; //-------------------------------------------------------- // Map mouse position to axis position. Good for car wheel controls. //-------------------------------------------------------- var sensitivity = 10; for (int a = 0; a < newState.Axis.Length; a++) { // Get delta from last state. var delta = newState.Axis[a] - ud.OldDiState.Axis[a]; var newValue = mouseState.Axis[a] + (delta * sensitivity); newValue = Math.Min(newValue, ushort.MaxValue); newValue = Math.Max(newValue, ushort.MinValue); mouseState.Axis[a] = newValue; } for (int a = 0; a < newState.Sliders.Length; a++) { // Get delta from last state. var delta = newState.Sliders[a] - ud.OldDiState.Sliders[a]; var newValue = mouseState.Sliders[a] + (delta * sensitivity); newValue = Math.Min(newValue, ushort.MaxValue); newValue = Math.Max(newValue, ushort.MinValue); mouseState.Sliders[a] = newValue; } } // Assign unmodified state. ud.OldDiState = newState; ud.OldDiStateTime = ud.DiStateTime; } else { // Update state. ud.DiState = newState; } ud.DiStateTime = newTime; } }
void UpdateDiStates(UserGame game) { // Get all mapped user instances. var instanceGuids = SettingsManager.Settings.Items .Where(x => x.MapTo > (int)MapTo.None) .Select(x => x.InstanceGuid).ToArray(); // Get all connected devices. var userDevices = SettingsManager.UserDevices.Items .Where(x => instanceGuids.Contains(x.InstanceGuid) && x.IsOnline) .ToArray(); // Acquire copy of feedbacks for processing. var feedbacks = CopyAndClearFeedbacks(); for (int i = 0; i < userDevices.Count(); i++) { // Update direct input form and return actions (pressed Buttons/DPads, turned Axis/Sliders). var ud = userDevices[i]; JoystickState state = null; // Allow if not testing or testing with option enabled. var o = SettingsManager.Options; var allow = !o.TestEnabled || o.TestGetDInputStates; var isOnline = ud != null && ud.IsOnline; if (isOnline && allow) { var device = ud.Device; if (device != null) { try { var isVirtual = ((EmulationType)game.EmulationType).HasFlag(EmulationType.Virtual); var hasForceFeedback = device.Capabilities.Flags.HasFlag(DeviceFlags.ForceFeedback); // Exclusive mode required only if force feedback is available and device is virtual there are no info about effects. var exclusiveRequired = hasForceFeedback && (isVirtual || ud.DeviceEffects == null); // If exclusive mode is required and mode is not exclusive then... if (exclusiveRequired && (!ud.IsExclusiveMode.HasValue || !ud.IsExclusiveMode.Value)) { var flags = CooperativeLevel.Background | CooperativeLevel.Exclusive; // Reacquire device in exclusive mode. device.Unacquire(); device.SetCooperativeLevel(detector.DetectorForm.Handle, flags); device.Acquire(); ud.IsExclusiveMode = true; } // If current mode must be non exclusive... else if (!exclusiveRequired && (!ud.IsExclusiveMode.HasValue || ud.IsExclusiveMode.Value)) { var flags = CooperativeLevel.Background | CooperativeLevel.NonExclusive; // Reacquire device in non exclusive mode so that xinput.dll can control force feedback. device.Unacquire(); device.SetCooperativeLevel(detector.DetectorForm.Handle, flags); device.Acquire(); ud.IsExclusiveMode = false; } state = device.GetCurrentState(); // Fill device objects. if (ud.DeviceObjects == null) { var dos = AppHelper.GetDeviceObjects(device); ud.DeviceObjects = dos; // Update masks. ud.DiAxeMask = CustomDiState.GetJoystickAxisMask(dos, device); ud.DiSliderMask = CustomDiState.GetJoystickSlidersMask(dos, device); } if (ud.DeviceEffects == null) { ud.DeviceEffects = AppHelper.GetDeviceEffects(device); } // Get PAD index this device is mapped to. var userIndex = SettingsManager.Settings.Items .Where(x => x.MapTo > (int)MapTo.None) .Where(x => x.InstanceGuid == ud.InstanceGuid) .Select(x => x.MapTo).First(); if (hasForceFeedback) { // Get setting related to user device. var setting = SettingsManager.Settings.Items .FirstOrDefault(x => x.MapTo == userIndex && x.InstanceGuid == ud.InstanceGuid); if (setting != null) { // Get pad setting attached to device. var ps = SettingsManager.GetPadSetting(setting.PadSettingChecksum); if (ps != null) { // If force is enabled then... if (ps.ForceEnable == "1") { if (ud.FFState == null) { ud.FFState = new Engine.ForceFeedbackState(); } // If force update supplied then... var force = feedbacks[userIndex - 1]; if (force != null || ud.FFState.Changed(ps)) { var v = new Vibration(); if (force == null) { v.LeftMotorSpeed = short.MinValue; v.RightMotorSpeed = short.MinValue; } else { v.LeftMotorSpeed = (short)ConvertHelper.ConvertRange(byte.MinValue, byte.MaxValue, short.MinValue, short.MaxValue, force.LargeMotor); v.RightMotorSpeed = (short)ConvertHelper.ConvertRange(byte.MinValue, byte.MaxValue, short.MinValue, short.MaxValue, force.SmallMotor); } // For teh future: Investigate device states if force feedback is not working. // var st = ud.Device.GetForceFeedbackState(); //st == SharpDX.DirectInput.ForceFeedbackState // ud.Device.SendForceFeedbackCommand(ForceFeedbackCommand.SetActuatorsOn); ud.FFState.SetDeviceForces(ud, ud.Device, ps, v); } } // If force state was created then... else if (ud.FFState != null) { // Stop device forces. ud.FFState.StopDeviceForces(ud.Device); ud.FFState = null; } } } } } catch (Exception ex) { JocysCom.ClassLibrary.Runtime.LogHelper.Current.WriteException(ex); ud.IsExclusiveMode = null; var error = ex; } } // If this is test device then... else if (TestDeviceHelper.ProductGuid.Equals(ud.ProductGuid)) { // Fill device objects. if (ud.DeviceObjects == null) { var dos = TestDeviceHelper.GetDeviceObjects(); ud.DeviceObjects = dos; // Update masks. ud.DiAxeMask = 0x1 | 0x2 | 0x4 | 0x8; ud.DiSliderMask = 0; } if (ud.DeviceEffects == null) { ud.DeviceEffects = new DeviceEffectItem[0]; } state = TestDeviceHelper.GetCurrentState(ud); } } ud.JoState = state ?? new JoystickState(); var newState = new CustomDiState(ud.JoState); var newTime = watch.ElapsedTicks; // Mouse needs special update. if (ud.Device != null && ud.Device.Information.Type == SharpDX.DirectInput.DeviceType.Mouse) { var mouseState = new CustomDiState(ud.JoState); if (ud.OldDiState == null) { // Make sure new state have zero values. for (int a = 0; a < newState.Axis.Length; a++) { mouseState.Axis[a] = -short.MinValue; } // Update sliders with delta. for (int s = 0; s < newState.Sliders.Length; s++) { mouseState.Sliders[s] = -short.MinValue; } } else { // This parts needs to be worked on. var ticks = (int)(newTime - ud.DiStateTime); // Update axis with delta. for (int a = 0; a < newState.Axis.Length; a++) { mouseState.Axis[a] = ticks * (newState.Axis[a] - ud.OldDiState.Axis[a]) - short.MinValue; } // Update sliders with delta. for (int s = 0; s < newState.Sliders.Length; s++) { mouseState.Sliders[s] = ticks * (newState.Sliders[s] - ud.OldDiState.Sliders[s]) - short.MinValue; } } // Assign unmodified state. ud.OldDiState = newState; ud.OldDiStateTime = ud.DiStateTime; ud.DiState = mouseState; } else { // Update state. ud.DiState = newState; } ud.DiStateTime = newTime; } }
void UpdateDiStates(UserGame game, DeviceDetector detector) { // Get all mapped user devices. var userDevices = SettingsManager.GetMappedDevices(game?.FileName); // Acquire copy of feedbacks for processing. var feedbacks = CopyAndClearFeedbacks(); for (int i = 0; i < userDevices.Count(); i++) { // Update direct input form and return actions (pressed Buttons/DPads, turned Axis/Sliders). var ud = userDevices[i]; //JoystickState state = null; CustomDiState newState = null; CustomDiUpdate[] newUpdates = null; // Allow if not testing or testing with option enabled. var o = SettingsManager.Options; var allow = !o.TestEnabled || o.TestGetDInputStates; // Note: manager.IsDeviceAttached() use a lot of CPU resources. var isAttached = ud != null && ud.IsOnline; // && manager.IsDeviceAttached(ud.InstanceGuid); if (isAttached && allow) { var useData = false; var device = ud.Device; if (device != null) { var exceptionData = new System.Text.StringBuilder(); try { if (o.UseDeviceBufferedData && device.Properties.BufferSize == 0) { // Set BufferSize in order to use buffered data. device.Properties.BufferSize = 128; useData = true; } var isVirtual = ((EmulationType)game.EmulationType).HasFlag(EmulationType.Virtual); var hasForceFeedback = device.Capabilities.Flags.HasFlag(DeviceFlags.ForceFeedback); // Original device will be hidden from the game when acquired in exclusive mode. var acquireMappedDevicesInExclusiveMode = false; // If device is not keyboard or mouse then apply AcquireMappedDevicesInExclusiveMode option. if (device.Information.Type != SharpDX.DirectInput.DeviceType.Keyboard && device.Information.Type != SharpDX.DirectInput.DeviceType.Mouse) { acquireMappedDevicesInExclusiveMode = o.AcquireMappedDevicesInExclusiveMode; } // Exclusive mode required only if force feedback is available and device is virtual there are no info about effects. var exclusiveRequired = acquireMappedDevicesInExclusiveMode || hasForceFeedback && (isVirtual || ud.DeviceEffects == null); // If exclusive mode is required and mode is unknown or not exclusive then... if (exclusiveRequired && (!ud.IsExclusiveMode.HasValue || !ud.IsExclusiveMode.Value)) { var flags = CooperativeLevel.Background | CooperativeLevel.Exclusive; // Reacquire device in exclusive mode. exceptionData.AppendLine("UnAcquire (Exclusive)..."); device.Unacquire(); exceptionData.AppendLine("SetCooperativeLevel (Exclusive)..."); device.SetCooperativeLevel(detector.DetectorForm.Handle, flags); exceptionData.AppendLine("Acquire (Exclusive)..."); device.Acquire(); ud.IsExclusiveMode = true; } // If current mode must be non exclusive and mode is unknown or exclusive then... else if (!exclusiveRequired && (!ud.IsExclusiveMode.HasValue || ud.IsExclusiveMode.Value)) { var flags = CooperativeLevel.Background | CooperativeLevel.NonExclusive; // Reacquire device in non exclusive mode so that xinput.dll can control force feedback. exceptionData.AppendLine("UnAcquire (NonExclusive)..."); device.Unacquire(); exceptionData.AppendLine("SetCooperativeLevel (Exclusive)..."); device.SetCooperativeLevel(detector.DetectorForm.Handle, flags); exceptionData.AppendLine("Acquire (Acquire)..."); device.Acquire(); ud.IsExclusiveMode = false; } exceptionData.AppendFormat("device.GetCurrentState() // ud.IsExclusiveMode = {0}", ud.IsExclusiveMode).AppendLine(); // Polling - Retrieves data from polled objects on a DirectInput device. // Some devices require pooling (For example original "XBOX Controller S" with XBCD drivers). // If the device does not require polling, calling this method has no effect. // If a device that requires polling is not polled periodically, no new data is received from the device. // Calling this method causes DirectInput to update the device state, generate input // events (if buffered data is enabled), and set notification events (if notification is enabled). device.Poll(); // Get device states as buffered data. if (device is Mouse mDevice) { if (useData) { var data = mDevice.GetBufferedData(); newUpdates = data?.Select(x => new CustomDiUpdate(x)).ToArray(); } var state = mDevice.GetCurrentState(); newState = new CustomDiState(state); ud.DeviceState = state; } else if (device is Keyboard kDevice) { if (useData) { var data = kDevice.GetBufferedData(); newUpdates = data?.Select(x => new CustomDiUpdate(x)).ToArray(); } var state = kDevice.GetCurrentState(); newState = new CustomDiState(state); ud.DeviceState = state; } else if (device is Joystick jDevice) { if (useData) { var data = jDevice.GetBufferedData(); newUpdates = data?.Select(x => new CustomDiUpdate(x)).ToArray(); } var state = jDevice.GetCurrentState(); newState = new CustomDiState(state); ud.DeviceState = state; } else { throw new Exception(string.Format("Unknown device: {0}", device)); } // Fill device objects. if (ud.DeviceObjects == null) { exceptionData.AppendFormat("AppHelper.GetDeviceObjects(device) // ud.IsExclusiveMode = {0}", ud.IsExclusiveMode).AppendLine(); var dos = AppHelper.GetDeviceObjects(device); ud.DeviceObjects = dos; // Update masks. int axisMask = 0; int actuatorMask = 0; int actuatorCount = 0; if (device is Mouse mDevice2) { CustomDiState.GetMouseAxisMask(dos, mDevice2, out axisMask); } else if (device is Joystick jDevice) { CustomDiState.GetJoystickAxisMask(dos, jDevice, out axisMask, out actuatorMask, out actuatorCount); //CustomDiState.GetJoystickSlidersMask(dos, (Joystick) device, out slidersMask); } ud.DiAxeMask = axisMask; // Contains information about which axis have force feedback actuator attached. ud.DiActuatorMask = actuatorMask; ud.DiActuatorCount = actuatorCount; } if (ud.DeviceEffects == null) { exceptionData.AppendFormat("AppHelper.GetDeviceEffects(device) // ud.IsExclusiveMode = {0}", ud.IsExclusiveMode).AppendLine(); ud.DeviceEffects = AppHelper.GetDeviceEffects(device); } // If device support force feedback then... if (hasForceFeedback) { // Get setting related to user device. var setting = SettingsManager.UserSettings.ItemsToArraySynchronized() .FirstOrDefault(x => x.InstanceGuid == ud.InstanceGuid); // If device is mapped to controller then... if (setting != null && setting.MapTo > (int)MapTo.None) { // Get pad setting attached to device. var ps = SettingsManager.GetPadSetting(setting.PadSettingChecksum); if (ps != null) { // If force is enabled then... if (ps.ForceEnable == "1") { if (ud.FFState == null) { ud.FFState = new Engine.ForceFeedbackState(); } // If force update supplied then... var force = feedbacks[setting.MapTo - 1]; if (force != null || ud.FFState.Changed(ps)) { var v = new Vibration(); if (force == null) { v.LeftMotorSpeed = short.MinValue; v.RightMotorSpeed = short.MinValue; } else { v.LeftMotorSpeed = (short)ConvertHelper.ConvertRange(byte.MinValue, byte.MaxValue, short.MinValue, short.MaxValue, force.LargeMotor); v.RightMotorSpeed = (short)ConvertHelper.ConvertRange(byte.MinValue, byte.MaxValue, short.MinValue, short.MaxValue, force.SmallMotor); } // For the future: Investigate device states if force feedback is not working. // var st = ud.Device.GetForceFeedbackState(); //st == SharpDX.DirectInput.ForceFeedbackState // ud.Device.SendForceFeedbackCommand(ForceFeedbackCommand.SetActuatorsOn); exceptionData.AppendFormat("ud.FFState.SetDeviceForces(device) // ud.IsExclusiveMode = {0}", ud.IsExclusiveMode).AppendLine(); ud.FFState.SetDeviceForces(ud, device, ps, v); } } // If force state was created then... else if (ud.FFState != null) { // Stop device forces. exceptionData.AppendFormat("ud.FFState.StopDeviceForces(device) // ud.IsExclusiveMode = {0}", ud.IsExclusiveMode).AppendLine(); ud.FFState.StopDeviceForces(device); ud.FFState = null; } } } } } catch (Exception ex) { var dex = ex as SharpDXException; if (dex != null && dex.ResultCode == SharpDX.DirectInput.ResultCode.InputLost) { // Ignore error. } else if (dex != null && dex.ResultCode == SharpDX.DirectInput.ResultCode.NotAcquired) { // Ignore error } else if (dex != null && dex.ResultCode == SharpDX.DirectInput.ResultCode.Unplugged) { // Ignore error } else { var cx = new DInputException("UpdateDiStates Exception", ex); cx.Data.Add("FFInfo", exceptionData.ToString()); JocysCom.ClassLibrary.Runtime.LogHelper.Current.WriteException(cx); } ud.IsExclusiveMode = null; } } // If this is test device then... else if (TestDeviceHelper.ProductGuid.Equals(ud.ProductGuid)) { // Fill device objects. if (ud.DeviceObjects == null) { var dos = TestDeviceHelper.GetDeviceObjects(); ud.DeviceObjects = dos; // Update masks. ud.DiAxeMask = 0x1 | 0x2 | 0x4 | 0x8; ud.DiSliderMask = 0; } if (ud.DeviceEffects == null) { ud.DeviceEffects = new DeviceEffectItem[0]; } var state = TestDeviceHelper.GetCurrentState(ud); newState = new CustomDiState(state); ud.DeviceState = state; } } if (newState != null) { // If updates from buffer supplied and old state is available then... if (newUpdates != null && newUpdates.Count(x => x.Type == MapType.Button) > 1 && ud.DiState != null) { // Analyse if state must be modified. for (int b = 0; b < newState.Buttons.Length; b++) { var oldPresseed = ud.DiState.Buttons[b]; var newPresseed = newState.Buttons[b]; // If button state was not changed. if (oldPresseed == newPresseed) { // But buffer contains press then... var wasPressed = newUpdates.Count(x => x.Type == MapType.Button && x.Index == b) > 1; if (wasPressed) { // Invert state and give chance for the game to recognize the press. newState.Buttons[b] = !newState.Buttons[b]; } } } } var newTime = watch.ElapsedTicks; // Remember old state. ud.OldDiState = ud.DiState; ud.OldDiUpdates = ud.DiUpdates; ud.OldDiStateTime = ud.DiStateTime; // Update state. ud.DiState = newState; ud.DiUpdates = newUpdates; ud.DiStateTime = newTime; // Mouse needs special update. if (ud.Device != null && ud.Device.Information.Type == SharpDX.DirectInput.DeviceType.Mouse) { // If original state is missing then... if (ud.OrgDiState == null) { // Store current values. ud.OrgDiState = newState; ud.OrgDiStateTime = newTime; // Make sure new states have zero values. for (int a = 0; a < newState.Axis.Length; a++) { newState.Axis[a] = -short.MinValue; } for (int s = 0; s < newState.Sliders.Length; s++) { newState.Sliders[s] = -short.MinValue; } } var mouseState = new CustomDiState(new JoystickState()); // Clone button values. Array.Copy(newState.Buttons, mouseState.Buttons, mouseState.Buttons.Length); // //-------------------------------------------------------- // // Map mouse acceleration to axis position. Good for FPS control. // //-------------------------------------------------------- // // This parts needs to be worked on. // //var ticks = (int)(newTime - ud.DiStateTime); // // Update axis with delta. // //for (int a = 0; a < newState.Axis.Length; a++) // // mouseState.Axis[a] = ticks * (newState.Axis[a] - ud.OldDiState.Axis[a]) - short.MinValue; // // Update sliders with delta. // //for (int s = 0; s < newState.Sliders.Length; s++) // // mouseState.Sliders[s] = ticks * (newState.Sliders[s] - ud.OldDiState.Sliders[s]) - short.MinValue; //-------------------------------------------------------- // Map mouse position to axis position. Good for car wheel controls. //-------------------------------------------------------- Calc(ud.OrgDiState.Axis, newState.Axis, mouseState.Axis); Calc(ud.OrgDiState.Sliders, newState.Sliders, mouseState.Sliders); ud.DiState = mouseState; } } } }