相关
Related in langs
Represents a joystick device and provides methods to query its status.
Inheritance:
IInputDevice
HMI Programming for Pack & Coun...
void RefreshJoysticks()
joysticks.Clear();
int count = SDL.NumJoysticks();
for (int i = 0; i < count; i++)
JoystickDevice<Sdl2JoystickDetails> joystick = null;
int num_axes = 0;
int num_buttons = 0;
int num_hats = 0;
int num_balls = 0;
IntPtr handle = SDL.JoystickOpen(i);
if (handle != IntPtr.Zero)
num_axes = SDL.JoystickNumAxes(handle);
num_buttons = SDL.JoystickNumButtons(handle);
num_hats = SDL.JoystickNumHats(handle);
num_balls = SDL.JoystickNumBalls(handle);
joystick = new JoystickDevice<Sdl2JoystickDetails>(i, num_axes, num_buttons);
joystick.Description = SDL.JoystickName(handle);
joystick.Details.Handle = handle;
joystick.Details.HatCount = num_hats;
joystick.Details.BallCount = num_balls;
joysticks.Add(joystick);
}
public JoystickControl(JoystickDevice joystick, PoincareWindow poincareWindow)
Joystick = joystick;
PoincareWindow = poincareWindow;
Joystick.ButtonDown += Joystick_ButtonDown;
Joystick.ButtonUp += Joystick_ButtonUp;
}
JoystickDevice<WinMMJoyDetails> OpenJoystick(int number)
JoystickDevice<WinMMJoyDetails> stick = null;
JoyCaps caps;
JoystickError result = UnsafeNativeMethods.joyGetDevCaps(number, out caps, JoyCaps.SizeInBytes);
if (result != JoystickError.NoError)
return null;
int num_axes = caps.NumAxes;
if ((caps.Capabilities & JoystCapsFlags.HasPov) != 0)
num_axes += 2;
stick = new JoystickDevice<WinMMJoyDetails>(number, num_axes, caps.NumButtons);
stick.Details = new WinMMJoyDetails(num_axes);
// Make sure to reverse the vertical axes, so that +1 points up and -1 points down.
int axis = 0;
if (axis < caps.NumAxes)
{ stick.Details.Min[axis] = caps.XMin; stick.Details.Max[axis] = caps.XMax; axis++; }
if (axis < caps.NumAxes)
{ stick.Details.Min[axis] = caps.YMax; stick.Details.Max[axis] = caps.YMin; axis++; }
if (axis < caps.NumAxes)
{ stick.Details.Min[axis] = caps.ZMax; stick.Details.Max[axis] = caps.ZMin; axis++; }
if (axis < caps.NumAxes)
{ stick.Details.Min[axis] = caps.RMin; stick.Details.Max[axis] = caps.RMax; axis++; }
if (axis < caps.NumAxes)
{ stick.Details.Min[axis] = caps.UMin; stick.Details.Max[axis] = caps.UMax; axis++; }
if (axis < caps.NumAxes)
{ stick.Details.Min[axis] = caps.VMax; stick.Details.Max[axis] = caps.VMin; axis++; }
if ((caps.Capabilities & JoystCapsFlags.HasPov) != 0)
stick.Details.PovType = PovType.Exists;
if ((caps.Capabilities & JoystCapsFlags.HasPov4Dir) != 0)
stick.Details.PovType |= PovType.Discrete;
if ((caps.Capabilities & JoystCapsFlags.HasPovContinuous) != 0)
stick.Details.PovType |= PovType.Continuous;
#warning "Implement joystick name detection for WinMM."
stick.Description = String.Format("Joystick/Joystick #{0} ({1} axes, {2} buttons)", number, stick.Axis.Count, stick.Button.Count);
// Todo: Try to get the device name from the registry. Oh joy!
//string key_path = String.Format("{0}\\{1}\\{2}", RegistryJoyConfig, caps.RegKey, RegstryJoyCurrent);
//RegistryKey key = Registry.LocalMachine.OpenSubKey(key_path, false);
//if (key == null)
// key = Registry.CurrentUser.OpenSubKey(key_path, false);
//if (key == null)
// stick.Description = String.Format("USB Joystick {0} ({1} axes, {2} buttons)", number, stick.Axis.Count, stick.Button.Count);
//else
// key.Close();
if (stick != null)
Debug.Print("Found joystick on device number {0}", number);
return stick;
}
JoystickDevice<LinuxJoyDetails> OpenJoystick(string path)
JoystickDevice<LinuxJoyDetails> stick = null;
int number = GetJoystickNumber(Path.GetFileName(path));
if (number >= 0)
int fd = -1;
fd = Libc.open(path, OpenFlags.NonBlock);
if (fd == -1)
return null;
// Check joystick driver version (must be 1.0+)
int driver_version = 0x00000800;
Libc.ioctl(fd, JoystickIoctlCode.Version, ref driver_version);
if (driver_version < 0x00010000)
return null;
// Get number of joystick axes
int axes = 0;
Libc.ioctl(fd, JoystickIoctlCode.Axes, ref axes);
// Get number of joystick buttons
int buttons = 0;
Libc.ioctl(fd, JoystickIoctlCode.Buttons, ref buttons);
stick = new JoystickDevice<LinuxJoyDetails>(number, axes, buttons);
StringBuilder sb = new StringBuilder(128);
Libc.ioctl(fd, JoystickIoctlCode.Name128, sb);
stick.Description = sb.ToString();
stick.Details.FileDescriptor = fd;
stick.Details.State.SetIsConnected(true);
stick.Details.Guid = CreateGuid(stick, path, number);
// Find the first disconnected joystick (if any)
int i;
for (i = 0; i < sticks.Count; i++)
if (!sticks[i].Details.State.IsConnected)
break;
// If no disconnected joystick exists, append a new slot
if (i == sticks.Count)
sticks.Add(stick);
sticks[i] = stick;
// Map player index to joystick
index_to_stick.Add(index_to_stick.Count, i);
Debug.Print("Found joystick on path {0}", path);
finally
if (stick == null && fd != -1)
Libc.close(fd);
return stick;
}
JoystickDevice<Sdl2JoystickDetails> OpenJoystick(int id)
JoystickDevice<Sdl2JoystickDetails> joystick = null;
int num_axes = 0;
int num_buttons = 0;
int num_hats = 0;
int num_balls = 0;
IntPtr handle = SDL.JoystickOpen(id);
if (handle != IntPtr.Zero)
num_axes = SDL.JoystickNumAxes(handle);
num_buttons = SDL.JoystickNumButtons(handle);
num_hats = SDL.JoystickNumHats(handle);
num_balls = SDL.JoystickNumBalls(handle);
joystick = new JoystickDevice<Sdl2JoystickDetails>(id, num_axes, num_buttons);
joystick.Description = SDL.JoystickName(handle);
joystick.Details.Handle = handle;
joystick.Details.Guid = SDL.JoystickGetGUID(handle).ToGuid();
joystick.Details.HatCount = num_hats;
joystick.Details.BallCount = num_balls;
Debug.Print("[SDL2] Joystick device {0} opened successfully. ", id);
Debug.Print("\t\t'{0}' has {1} axes, {2} buttons, {3} hats, {4} balls",
joystick.Description, joystick.Axis.Count, joystick.Button.Count,
joystick.Details.HatCount, joystick.Details.BallCount);
Debug.Print("[SDL2] Failed to open joystick device {0}", id);
return joystick;
}
Guid CreateGuid(JoystickDevice<LinuxJoyDetails> js, string path, int number)
byte[] bytes = new byte[16];
for (int i = 0; i < Math.Min(bytes.Length, js.Description.Length); i++)
bytes[i] = (byte)js.Description[i];
return new Guid(bytes);
#if false // Todo: move to /dev/input/event* from /dev/input/js*
string evdev_path = Path.Combine(Path.GetDirectoryName(path), "event" + number);
if (!File.Exists(evdev_path))
return new Guid();
int event_fd = UnsafeNativeMethods.open(evdev_path, OpenFlags.NonBlock);
if (event_fd < 0)
return new Guid();
EventInputId id;
if (UnsafeNativeMethods.ioctl(event_fd, EvdevInputId.Id, out id) < 0)
return new Guid();
int i = 0;
byte[] bus = BitConverter.GetBytes(id.BusType);
bytes[i++] = bus[0];
bytes[i++] = bus[1];
bytes[i++] = 0;
bytes[i++] = 0;
if (id.Vendor != 0 && id.Product != 0 && id.Version != 0)
byte[] vendor = BitConverter.GetBytes(id.Vendor);
byte[] product = BitConverter.GetBytes(id.Product);
byte[] version = BitConverter.GetBytes(id.Version);
bytes[i++] = vendor[0];
bytes[i++] = vendor[1];
bytes[i++] = 0;
bytes[i++] = 0;
bytes[i++] = product[0];
bytes[i++] = product[1];
bytes[i++] = 0;
bytes[i++] = 0;
bytes[i++] = version[0];
bytes[i++] = version[1];
bytes[i++] = 0;
bytes[i++] = 0;
for (; i < bytes.Length; i++)
bytes[i] = (byte)js.Description[i];
return new Guid(bytes);
finally
UnsafeNativeMethods.close(event_fd);
#endif
}
JoystickDevice<WinMMJoyDetails> OpenJoystick(int number)
lock (sync)
JoystickDevice<WinMMJoyDetails> stick = null;
JoyCaps caps;
JoystickError result = UnsafeNativeMethods.joyGetDevCaps(number, out caps, JoyCaps.SizeInBytes);
if (result == JoystickError.NoError)
if (caps.NumAxes > JoystickState.MaxAxes)
Debug.Print("[Input] Device has {0} axes, which is higher than OpenTK maximum {1}. Please report a bug at http://www.opentk.com",
caps.NumAxes, JoystickState.MaxAxes);
caps.NumAxes = JoystickState.MaxAxes;
if (caps.NumAxes > JoystickState.MaxButtons)
Debug.Print("[Input] Device has {0} buttons, which is higher than OpenTK maximum {1}. Please report a bug at http://www.opentk.com",
caps.NumButtons, JoystickState.MaxButtons);
caps.NumButtons = JoystickState.MaxButtons;
JoystickCapabilities joycaps = new JoystickCapabilities(
caps.NumAxes,
caps.NumButtons,
(caps.Capabilities & JoystCapsFlags.HasPov) != 0 ? 1 : 0,
true);
int num_axes = caps.NumAxes;
if ((caps.Capabilities & JoystCapsFlags.HasPov) != 0)
num_axes += 2;
stick = new JoystickDevice<WinMMJoyDetails>(number, num_axes, caps.NumButtons);
stick.Details = new WinMMJoyDetails(joycaps);
// Make sure to reverse the vertical axes, so that +1 points up and -1 points down.
for (int axis = 0; axis < caps.NumAxes; axis++)
stick.Details.Min[axis] = caps.GetMin(axis);
stick.Details.Max[axis] = caps.GetMax(axis);
if ((caps.Capabilities & JoystCapsFlags.HasPov) != 0)
stick.Details.PovType = PovType.Exists;
if ((caps.Capabilities & JoystCapsFlags.HasPov4Dir) != 0)
stick.Details.PovType |= PovType.Discrete;
if ((caps.Capabilities & JoystCapsFlags.HasPovContinuous) != 0)
stick.Details.PovType |= PovType.Continuous;
// Todo: Implement joystick name detection for WinMM.
stick.Description = String.Format("Joystick/Joystick #{0} ({1} axes, {2} buttons)", number, stick.Axis.Count, stick.Button.Count);
// Todo: Try to get the device name from the registry. Oh joy!
//string key_path = String.Format("{0}\\{1}\\{2}", RegistryJoyConfig, caps.RegKey, RegstryJoyCurrent);
//RegistryKey key = Registry.LocalMachine.OpenSubKey(key_path, false);
//if (key == null)
// key = Registry.CurrentUser.OpenSubKey(key_path, false);
//if (key == null)
// stick.Description = String.Format("USB Joystick {0} ({1} axes, {2} buttons)", number, stick.Axis.Count, stick.Button.Count);
//else
// key.Close();
Debug.Print("Found joystick on device number {0}", number);
index_to_stick.Add(number, sticks.Count);
player_to_index.Add(player_to_index.Count, number);
sticks.Add(stick);
return stick;
}
JoystickDevice<X11JoyDetails> OpenJoystick(string base_path, int number)
string path = base_path + number.ToString();
JoystickDevice<X11JoyDetails> stick = null;
int fd = -1;
fd = UnsafeNativeMethods.open(path, OpenFlags.NonBlock);
if (fd == -1)
return null;
// Check joystick driver version (must be 1.0+)
int driver_version = 0x00000800;
UnsafeNativeMethods.ioctl(fd, JoystickIoctlCode.Version, ref driver_version);
if (driver_version < 0x00010000)
return null;
// Get number of joystick axes
int axes = 0;
UnsafeNativeMethods.ioctl(fd, JoystickIoctlCode.Axes, ref axes);
// Get number of joystick buttons
int buttons = 0;
UnsafeNativeMethods.ioctl(fd, JoystickIoctlCode.Buttons, ref buttons);
stick = new JoystickDevice<X11JoyDetails>(fd, axes, buttons);
Debug.Print("Found joystick on path {0}", path);
finally
if (stick == null && fd != -1)
UnsafeNativeMethods.close(fd);
return stick;
}
JoystickDevice<SDL2JoyDetails> OpenJoystick (int number)
JoystickDevice<SDL2JoyDetails> stick = null;
int num_axes, num_buttons;
IntPtr joystick;
lock (API.sdl_api_lock) {
joystick = API.JoystickOpen (number);
num_axes = API.JoystickNumAxes (joystick);
num_buttons = API.JoystickNumButtons (joystick);
stick = new JoystickDevice<SDL2JoyDetails>(number, num_axes, num_buttons);
joystickHandles.Add(joystick);
return stick;
}
JoystickDevice<Sdl2JoystickDetails> OpenJoystick(int id)
JoystickDevice<Sdl2JoystickDetails> joystick = null;
int num_axes = 0;
int num_buttons = 0;
int num_hats = 0;
int num_balls = 0;
int is_haptic = 0;
IntPtr handle = SDL.JoystickOpen(id);
if (handle != IntPtr.Zero)
num_axes = SDL.JoystickNumAxes(handle);
num_buttons = SDL.JoystickNumButtons(handle);
num_hats = SDL.JoystickNumHats(handle);
num_balls = SDL.JoystickNumBalls(handle);
is_haptic = SDL.JoystickIsHaptic(handle);
joystick = new JoystickDevice<Sdl2JoystickDetails>(id, num_axes, num_buttons);
joystick.Description = SDL.JoystickName(handle);
joystick.Details.Handle = handle;
joystick.Details.Guid = SDL.JoystickGetGUID(handle).ToGuid();
joystick.Details.HatCount = num_hats;
joystick.Details.BallCount = num_balls;
joystick.Details.IsHaptic = is_haptic > 0;
if (is_haptic > 0)
Debug.Print("[SDL2] Joystick device {0} supports haptics", id);
IntPtr haptic = SDL.HapticOpenFromJoystick(handle);
if (haptic != IntPtr.Zero)
joystick.Details.Haptic = haptic;
if (SDL.HapticEffectSupported(haptic, ref leftRightHapticEffect) == 1)
supportedHapticEffect = HapticEffectType.LeftAndRightMotor;
SDL.HapticNewEffect(haptic, ref leftRightHapticEffect);
else if (SDL.HapticRumbleSupported(haptic) == 1)
supportedHapticEffect = HapticEffectType.Simple;
if (SDL.HapticRumbleInit(haptic) < 0)
Debug.Print("[SDL2] Couldn't initialize rumble for joystick device {0}", id);
SDL.HapticClose(haptic);
joystick.Details.IsHaptic = false;
Debug.Print("[SDL2] Joystick device {0} opened successfully. ", id);
Debug.Print("\t\t'{0}' has {1} axes, {2} buttons, {3} hats, {4} balls",
joystick.Description, joystick.Axis.Count, joystick.Button.Count,
joystick.Details.HatCount, joystick.Details.BallCount);
Debug.Print("[SDL2] Failed to open joystick device {0}", id);
return joystick;
}
public WindowJoystickInput(JoystickDevice device) this.device = device; }
void CloseJoystick(JoystickDevice<LinuxJoyDetails> js)
Libc.close(js.Details.FileDescriptor);
js.Details.State = new JoystickState(); // clear joystick state
js.Details.FileDescriptor = -1;
// find and remove the joystick index from index_to_stick
int key = -1;
foreach (int i in index_to_stick.Keys)
if (sticks[index_to_stick[i]] == js)
key = i;
break;
if (index_to_stick.ContainsKey(key))
index_to_stick.Remove(key);
}
private JoystickDevice<WinMMJoystick.WinMMJoyDetails> OpenJoystick(int number)
WinMMJoystick.JoyCaps pjc;
if (WinMMJoystick.UnsafeNativeMethods.joyGetDevCaps(number, out pjc, WinMMJoystick.JoyCaps.SizeInBytes) != WinMMJoystick.JoystickError.NoError)
return (JoystickDevice<WinMMJoystick.WinMMJoyDetails>) null;
int num1 = pjc.NumAxes;
if ((pjc.Capabilities & WinMMJoystick.JoystCapsFlags.HasPov) != (WinMMJoystick.JoystCapsFlags) 0)
num1 += 2;
JoystickDevice<WinMMJoystick.WinMMJoyDetails> joystickDevice = new JoystickDevice<WinMMJoystick.WinMMJoyDetails>(number, num1, pjc.NumButtons);
joystickDevice.Details = new WinMMJoystick.WinMMJoyDetails(num1);
int index = 0;
if (index < pjc.NumAxes)
joystickDevice.Details.Min[index] = (float) pjc.XMin;
joystickDevice.Details.Max[index] = (float) pjc.XMax;
++index;
if (index < pjc.NumAxes)
joystickDevice.Details.Min[index] = (float) pjc.YMax;
joystickDevice.Details.Max[index] = (float) pjc.YMin;
++index;
if (index < pjc.NumAxes)
joystickDevice.Details.Min[index] = (float) pjc.ZMax;
joystickDevice.Details.Max[index] = (float) pjc.ZMin;
++index;
if (index < pjc.NumAxes)
joystickDevice.Details.Min[index] = (float) pjc.RMin;
joystickDevice.Details.Max[index] = (float) pjc.RMax;
++index;
if (index < pjc.NumAxes)
joystickDevice.Details.Min[index] = (float) pjc.UMin;
joystickDevice.Details.Max[index] = (float) pjc.UMax;
++index;
if (index < pjc.NumAxes)
joystickDevice.Details.Min[index] = (float) pjc.VMax;
joystickDevice.Details.Max[index] = (float) pjc.VMin;
int num2 = index + 1;
if ((pjc.Capabilities & WinMMJoystick.JoystCapsFlags.HasPov) != (WinMMJoystick.JoystCapsFlags) 0)
joystickDevice.Details.PovType = WinMMJoystick.PovType.Exists;
if ((pjc.Capabilities & WinMMJoystick.JoystCapsFlags.HasPov4Dir) != (WinMMJoystick.JoystCapsFlags) 0)
joystickDevice.Details.PovType |= WinMMJoystick.PovType.Discrete;
if ((pjc.Capabilities & WinMMJoystick.JoystCapsFlags.HasPovContinuous) != (WinMMJoystick.JoystCapsFlags) 0)
joystickDevice.Details.PovType |= WinMMJoystick.PovType.Continuous;
joystickDevice.Description = string.Format("Joystick/Joystick #{0} ({1} axes, {2} buttons)", (object) number, (object) joystickDevice.Axis.Count, (object) joystickDevice.Button.Count);
return joystickDevice;
}
void PollJoystick(JoystickDevice<LinuxJoyDetails> js)
JoystickEvent e;
unsafe
while ((long)Libc.read(js.Details.FileDescriptor, (void*)&e, (UIntPtr)sizeof(JoystickEvent)) > 0)
e.Type &= ~JoystickEventType.Init;
switch (e.Type)
case JoystickEventType.Axis:
// Flip vertical axes so that +1 point up.
if (e.Number % 2 == 0)
js.Details.State.SetAxis((JoystickAxis)e.Number, e.Value);
js.Details.State.SetAxis((JoystickAxis)e.Number, unchecked((short)-e.Value));
break;
case JoystickEventType.Button:
js.Details.State.SetButton((JoystickButton)e.Number, e.Value != 0);
break;
js.Details.State.SetPacketNumber(unchecked((int)e.Time));
}
private JoystickDevice<X11JoyDetails> OpenJoystick(string base_path, int number)
string pathname = base_path + number.ToString();
JoystickDevice<X11JoyDetails> joystickDevice = (JoystickDevice<X11JoyDetails>) null;
int num = -1;
num = X11Joystick.UnsafeNativeMethods.open(pathname, X11Joystick.OpenFlags.NonBlock);
if (num == -1)
return (JoystickDevice<X11JoyDetails>) null;
int data1 = 2048;
X11Joystick.UnsafeNativeMethods.ioctl(num, X11Joystick.JoystickIoctlCode.Version, ref data1);
if (data1 < 65536)
return (JoystickDevice<X11JoyDetails>) null;
int data2 = 0;
X11Joystick.UnsafeNativeMethods.ioctl(num, X11Joystick.JoystickIoctlCode.Axes, ref data2);
int data3 = 0;
X11Joystick.UnsafeNativeMethods.ioctl(num, X11Joystick.JoystickIoctlCode.Buttons, ref data3);
joystickDevice = new JoystickDevice<X11JoyDetails>(num, data2, data3);
return joystickDevice;
finally
if (joystickDevice == null && num != -1)
X11Joystick.UnsafeNativeMethods.close(num);
}
public OpenTKJoystickInputSource(JoystickDevice device) this.device = device; }