我还没有找到任何文章或教程,可以吗? 它试图调用 Effect 类,但我得到的只是
E_INVALIDARG:向返回函数传递了无效参数(-2147024809)
代码
[TestClass]
public class ForceFeedbackTest
{
[TestMethod]
public void Test()
{
using (var form = new Form())
{
var directInput = new DirectInput();
foreach (var device in directInput.GetDevices(DeviceClass.GameController, DeviceEnumerationFlags.AttachedOnly))
{
var controller = new Joystick(directInput, device.InstanceGuid);
controller.SetCooperativeLevel(form.Handle, CooperativeLevel.Exclusive | CooperativeLevel.Background);
controller.Acquire();
int xAxisOffset = 0, yAxisOffset = 0;
int nextOffset = 0;
foreach (DeviceObjectInstance d in controller.GetObjects())
{
if ((d.ObjectType & ObjectDeviceType.ForceFeedbackActuator)
!= 0)
{
if (nextOffset == 0)
xAxisOffset = d.Offset;
else
yAxisOffset = d.Offset;
nextOffset++;
}
}
int[] offsets = new int[2];
offsets[0] = xAxisOffset;
offsets[1] = yAxisOffset;
int[] coords = { 0, 0 };
var info = controller.GetEffects(EffectType.All).First();
var args = new EffectParameters();
args.Flags = EffectFlags.ObjectOffsets | EffectFlags.Cartesian;
var typeSpec = new ConstantForce();
args.Duration = 1000;
args.SamplePeriod = controller.Capabilities.ForceFeedbackSamplePeriod;
args.Parameters = typeSpec;
args.Gain = 5000;
args.SetAxes(offsets, coords);
args.StartDelay = 500;
var effect = new Effect(controller, info.Guid);
effect.SetParameters(args); //This is the line i get the error on.
effect.Start();
}
}
}
}
您不能将从
DeviceObjectInstance
获得的偏移量用于 SetAxes
。 MSDN 提到了这一点,但有点粗略:
设备本机数据格式中的偏移。本机数据格式对应于原始设备数据。 dwOfs 成员不对应于该对象的设备常量,例如 DIJOFS_BUTTON0。
您可以使用
EffectFlags.ObjectIds
代替 EffectFlags.ObjectOffsets
并从 ObjectType
传入 DeviceObjectInstance
来识别轴。
据我记得,如果您知道哪些轴有执行器,您还可以使用
JoystickObjects
类的静态成员之一作为 SetAxes
的偏移量。
如果您使用的是 Xbox 360 控制器或任何支持 XInput 的控制器,我会使用它而不是 DirectInput。使用 IMO 更容易,而且强制反馈也很简单。查看 SlimDX.XInput。过去几年大多数较新的游戏手柄都支持 XInput。
VB.net 代码:
Dim player As Integer = 1 'Player can be 1-4
Dim gamePad As SlimDX.XInput.Controller = New SlimDX.XInput.Controller(player)
Public Sub VibrateController(ByVal rSpeed As Short, ByVal lSpeed As Short)
Dim vibSettings As New SlimDX.XInput.Vibration()
vibSettings.LeftMotorSpeed = lSpeed
vibSettings.RightMotorSpeed = rSpeed
gamePad.SetVibration(vibSettings)
End Sub
对于像我一样想要使用它的人,我在 https://github.com/walbourn/directx-sdk-samples/blob/main/DirectInput/FFConst/ffconst.cpp
中找到了工作示例这就是我如何让它在 C# 中工作:
var directInput = new DirectInput();
JoystickState joys = new JoystickState();
var joy = new Joystick(directInput, dev.InstanceGuid);
joy.SetCooperativeLevel(Process.GetCurrentProcess().MainWindowHandle, CooperativeLevel.Exclusive | CooperativeLevel.Background);
joy.Acquire();
joy.GetCurrentState(ref joys);
joy.Properties.SetRange(0, short.MaxValue);
int[] offsets = { 0 };
int[] coords = { 0 };
var info = joy.GetEffects(EffectType.ConstantForce).First();
var args = new EffectParameters();
args.Flags = EffectFlags.Cartesian | EffectFlags.ObjectOffsets;
args.Duration = -1;
args.SamplePeriod = 0;
args.Gain = 10000;
args.TriggerButton = -1;
args.TriggerRepeatInterval = 0;
args.Envelope = null;
args.SetAxes(offsets, coords);
var typeSpec = new ConstantForce();
typeSpec.Magnitude = 0;
args.Parameters = typeSpec;
var effect = new Effect(joy, info.Guid, args);
effect.Start(1, EffectPlayFlags.None);
while (true)
{
var mouse = Cursor.Position;
var x = mouse.X - 2560 / 2;
args.Parameters = new ConstantForce() { Magnitude = x * 10 };
effect.SetParameters(args, EffectParameterFlags.Start | EffectParameterFlags.TypeSpecificParameters | EffectParameterFlags.Direction);
effect.Start(1, EffectPlayFlags.None);
Thread.Sleep(10);
}