added missing files
This commit is contained in:
1 parent
f577e53925
commit
3941c631a7
5 files changed
+1469
No files matched your search
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
using Vocaluxe.Lib.Input;
|
||||
using Vocaluxe.Lib.Input.WiiMote;
|
||||
|
||||
namespace Vocaluxe.Base
|
||||
{
|
||||
static class CInput
|
||||
{
|
||||
static IInput _Input;
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
_Input = new CWiiMote();
|
||||
|
||||
_Input.Init();
|
||||
}
|
||||
|
||||
public static void Close()
|
||||
{
|
||||
_Input.Close();
|
||||
}
|
||||
|
||||
public static bool Connect()
|
||||
{
|
||||
return _Input.Connect();
|
||||
}
|
||||
|
||||
public static bool Disconnect()
|
||||
{
|
||||
return _Input.Disconnect();
|
||||
}
|
||||
|
||||
public static bool IsConnected()
|
||||
{
|
||||
return _Input.IsConnected();
|
||||
}
|
||||
|
||||
public static void Update()
|
||||
{
|
||||
_Input.Update();
|
||||
}
|
||||
|
||||
public static bool PollKeyEvent(ref KeyEvent KeyEvent)
|
||||
{
|
||||
return _Input.PollKeyEvent(ref KeyEvent);
|
||||
}
|
||||
|
||||
public static bool PollMouseEvent(ref MouseEvent MouseEvent)
|
||||
{
|
||||
return _Input.PollMouseEvent(ref MouseEvent);
|
||||
}
|
||||
|
||||
public static void SetRumble(float Duration)
|
||||
{
|
||||
_Input.SetRumble(Duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,267 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
using Vocaluxe.Base;
|
||||
|
||||
namespace Vocaluxe.Lib.Input
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||
public struct HIDDeviceInfo
|
||||
{
|
||||
[MarshalAsAttribute(UnmanagedType.LPTStr)]
|
||||
public String Path;
|
||||
public ushort VendorString;
|
||||
public ushort ProductID;
|
||||
public String SerialNumber;
|
||||
public ushort ReleaseNumber;
|
||||
public String ManufacturerString;
|
||||
public String ProductString;
|
||||
public ushort UsagePage;
|
||||
public ushort Usage;
|
||||
public int InterfaceNumber;
|
||||
public IntPtr Next;
|
||||
}
|
||||
public static class CHIDAPI
|
||||
{
|
||||
#if ARCH_X86
|
||||
#if WIN
|
||||
private const string HIDapiDll = "x86\\hidapi.dll";
|
||||
#endif
|
||||
|
||||
#if LINUX
|
||||
private const string HIDapiDll = "libhidapi.so";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if ARCH_X64
|
||||
#if WIN
|
||||
private const string HIDapiDll = "x64\\hidapi.dll";
|
||||
#endif
|
||||
|
||||
#if LINUX
|
||||
private const string HIDapiDll = "libhidapi.so";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
[DllImport(HIDapiDll, ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, EntryPoint = "hid_init", CharSet = CharSet.Unicode)]
|
||||
private static extern int hid_init();
|
||||
public static bool Init()
|
||||
{
|
||||
int result = -1;
|
||||
try
|
||||
{
|
||||
result = hid_init();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
CLog.LogError("Error CHIDAPI.Init(): " + e.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (result == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[DllImport(HIDapiDll, ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, EntryPoint = "hid_exit", CharSet = CharSet.Unicode)]
|
||||
private static extern int hid_exit();
|
||||
public static bool Exit()
|
||||
{
|
||||
int result = -1;
|
||||
try
|
||||
{
|
||||
result = hid_exit();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
CLog.LogError("Error CHIDAPI.Exit(): " + e.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (result == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
[DllImport(HIDapiDll, ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, EntryPoint = "hid_enumerate", CharSet = CharSet.Ansi)]
|
||||
private static extern IntPtr hid_enumerate(ushort VendorID, ushort ProductID); //HIDDeviceInfo
|
||||
public static IntPtr Enumerate(ushort VendorID, ushort ProductID) //HIDDeviceInfo
|
||||
{
|
||||
return hid_enumerate(VendorID, ProductID);
|
||||
}
|
||||
|
||||
[DllImport(HIDapiDll, ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, EntryPoint = "hid_free_enumeration", CharSet = CharSet.Unicode)]
|
||||
private static extern void hid_free_enumeration(HIDDeviceInfo devs);
|
||||
public static void FreeEnumeration(HIDDeviceInfo devs)
|
||||
{
|
||||
hid_free_enumeration(devs);
|
||||
}
|
||||
|
||||
[DllImport(HIDapiDll, ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, EntryPoint = "hid_open", CharSet = CharSet.Unicode)]
|
||||
private static extern IntPtr hid_open(ushort VendorID, ushort ProductID, IntPtr SerialNumber);
|
||||
public static bool Open(ushort VendorID, ushort ProductID, out IntPtr Handle)
|
||||
{
|
||||
Handle = IntPtr.Zero;
|
||||
try
|
||||
{
|
||||
Handle = hid_open(VendorID, ProductID, IntPtr.Zero);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
CLog.LogError("Error CHIDAPI.Open(): " + e.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Handle != IntPtr.Zero)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
[DllImport(HIDapiDll, ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, EntryPoint = "hid_open_path", CharSet = CharSet.Unicode)]
|
||||
private static extern IntPtr hid_open_path(string Path);
|
||||
public static IntPtr OpenPath(string Path)
|
||||
{
|
||||
return hid_open_path(Path);
|
||||
}
|
||||
|
||||
[DllImport(HIDapiDll, ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, EntryPoint = "hid_write", CharSet = CharSet.Unicode)]
|
||||
private static extern int hid_write(IntPtr device, byte[] data, int length);
|
||||
public static int Write(IntPtr Device, byte[] Data)
|
||||
{
|
||||
return hid_write(Device, Data, Data.Length);
|
||||
}
|
||||
|
||||
[DllImport(HIDapiDll, ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, EntryPoint = "hid_read_timeout", CharSet = CharSet.Unicode)]
|
||||
private static extern int hid_read_timeout(IntPtr device, IntPtr data, int length, int milliseconds);
|
||||
public static int ReadTimeout(IntPtr Device, out byte[] Data, int length, int milliseconds)
|
||||
{
|
||||
Data = new byte[length];
|
||||
IntPtr data = Marshal.AllocHGlobal(length);
|
||||
|
||||
int result = -1;
|
||||
try
|
||||
{
|
||||
result = hid_read_timeout(Device, data, length, milliseconds);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
result = -1;
|
||||
CLog.LogError("Error CHIDAPI.ReadTimeout(): " + e.ToString());
|
||||
}
|
||||
|
||||
if (result != -1)
|
||||
Marshal.Copy(data, Data, 0, result);
|
||||
else
|
||||
Data = null;
|
||||
|
||||
Marshal.FreeHGlobal(data);
|
||||
return result;
|
||||
}
|
||||
|
||||
[DllImport(HIDapiDll, ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, EntryPoint = "hid_read", CharSet = CharSet.Unicode)]
|
||||
private static extern int hid_read(IntPtr device, IntPtr data, int length);
|
||||
public static int Read(IntPtr Device, out byte[] Data, int length)
|
||||
{
|
||||
Data = new byte[length];
|
||||
IntPtr data = Marshal.AllocHGlobal(length);
|
||||
|
||||
int result = -1;
|
||||
try
|
||||
{
|
||||
result = hid_read(Device, data, length);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
result = -1;
|
||||
CLog.LogError("Error CHIDAPI.Read(): " + e.ToString());
|
||||
}
|
||||
|
||||
if (result != -1)
|
||||
Marshal.Copy(data, Data, 0, result);
|
||||
else
|
||||
Data = null;
|
||||
|
||||
Marshal.FreeHGlobal(data);
|
||||
return result;
|
||||
}
|
||||
|
||||
[DllImport(HIDapiDll, ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, EntryPoint = "hid_set_nonblocking", CharSet = CharSet.Unicode)]
|
||||
private static extern int hid_set_nonblocking(IntPtr device, bool nonblock);
|
||||
public static int Read(IntPtr Device, bool Nonblocking)
|
||||
{
|
||||
return hid_set_nonblocking(Device, Nonblocking);
|
||||
}
|
||||
|
||||
[DllImport(HIDapiDll, ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, EntryPoint = "hid_send_feature_report", CharSet = CharSet.Unicode)]
|
||||
private static extern int hid_send_feature_report(IntPtr device, string data, int length);
|
||||
public static int SendFeatureReport(IntPtr Device, string Data)
|
||||
{
|
||||
return hid_send_feature_report(Device, Data, Data.Length);
|
||||
}
|
||||
|
||||
[DllImport(HIDapiDll, ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, EntryPoint = "hid_get_feature_report", CharSet = CharSet.Unicode)]
|
||||
private static extern int hid_get_feature_report(IntPtr device, string Data, int length);
|
||||
public static int GetFeatureReport(IntPtr Device, string Data)
|
||||
{
|
||||
return hid_get_feature_report(Device, Data, Data.Length);
|
||||
}
|
||||
|
||||
[DllImport(HIDapiDll, ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, EntryPoint = "hid_close", CharSet = CharSet.Unicode)]
|
||||
private static extern void hid_close(IntPtr device);
|
||||
public static bool Close(IntPtr Device)
|
||||
{
|
||||
try
|
||||
{
|
||||
hid_close(Device);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
CLog.LogError("Error CHIDAPI.Close(): " + e.ToString());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
[DllImport(HIDapiDll, ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, EntryPoint = "hid_get_manufacturer_string", CharSet = CharSet.Unicode)]
|
||||
private static extern int hid_get_manufacturer_string(IntPtr device, string Data, int maxlength);
|
||||
public static int GetManufacturerString(IntPtr Device, string Data, int MaxLength)
|
||||
{
|
||||
return hid_get_manufacturer_string(Device, Data, MaxLength);
|
||||
}
|
||||
|
||||
[DllImport(HIDapiDll, ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, EntryPoint = "hid_get_product_string", CharSet = CharSet.Unicode)]
|
||||
private static extern int hid_get_product_string(IntPtr device, string Data, int maxlength);
|
||||
public static int GetProductString(IntPtr Device, string Data, int MaxLength)
|
||||
{
|
||||
return hid_get_product_string(Device, Data, MaxLength);
|
||||
}
|
||||
|
||||
[DllImport(HIDapiDll, ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, EntryPoint = "hid_get_serial_number_string", CharSet = CharSet.Unicode)]
|
||||
private static extern int hid_get_serial_number_string(IntPtr device, string Data, int maxlength);
|
||||
public static int GetSerialNumberString(IntPtr Device, string Data, int MaxLength)
|
||||
{
|
||||
return hid_get_serial_number_string(Device, Data, MaxLength);
|
||||
}
|
||||
|
||||
[DllImport(HIDapiDll, ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, EntryPoint = "hid_get_indexed_string", CharSet = CharSet.Unicode)]
|
||||
private static extern int hid_get_indexed_string(IntPtr device, string Data, int maxlength);
|
||||
public static int GetIndexedString(IntPtr Device, string Data, int MaxLength)
|
||||
{
|
||||
return hid_get_indexed_string(Device, Data, MaxLength);
|
||||
}
|
||||
|
||||
[DllImport(HIDapiDll, ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, EntryPoint = "hid_error", CharSet = CharSet.Unicode)]
|
||||
private static extern string hid_error(IntPtr device);
|
||||
public static string Error(IntPtr Device)
|
||||
{
|
||||
return hid_error(Device);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
|
||||
using Vocaluxe.Base;
|
||||
|
||||
namespace Vocaluxe.Lib.Input
|
||||
{
|
||||
enum EGesture
|
||||
{
|
||||
None,
|
||||
Back,
|
||||
ScrollDown,
|
||||
ScrollUp
|
||||
}
|
||||
|
||||
interface IInput
|
||||
{
|
||||
bool Init();
|
||||
void Close();
|
||||
bool Connect();
|
||||
bool Disconnect();
|
||||
|
||||
bool IsConnected();
|
||||
void Update();
|
||||
|
||||
bool PollKeyEvent(ref KeyEvent KeyEvent);
|
||||
bool PollMouseEvent(ref MouseEvent MouseEvent);
|
||||
|
||||
void SetRumble(float Duration);
|
||||
}
|
||||
|
||||
class RumbleTimer
|
||||
{
|
||||
private Stopwatch _timer;
|
||||
private float _duration;
|
||||
|
||||
public bool ShouldStart
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_timer.IsRunning && _duration != 0f)
|
||||
{
|
||||
_timer.Start();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShouldStop
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_timer.IsRunning && _timer.ElapsedMilliseconds / 1000f >= _duration)
|
||||
{
|
||||
_timer.Reset();
|
||||
_duration = 0f;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public RumbleTimer()
|
||||
{
|
||||
_timer = new Stopwatch();
|
||||
_duration = 0f;
|
||||
}
|
||||
|
||||
public void Set(float Duration)
|
||||
{
|
||||
if (!_timer.IsRunning)
|
||||
{
|
||||
_duration = Duration;
|
||||
_timer.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
_duration = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
class CGesture
|
||||
{
|
||||
Point _Begin;
|
||||
bool _locked;
|
||||
|
||||
public CGesture()
|
||||
{
|
||||
_locked = false;
|
||||
}
|
||||
|
||||
public void SetLockPosition(Point Position)
|
||||
{
|
||||
_locked = true;
|
||||
_Begin = new Point(Position.X, Position.Y);
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
_locked = false;
|
||||
}
|
||||
|
||||
public EGesture GetGesture(Point NewPosition)
|
||||
{
|
||||
if (!_locked)
|
||||
return EGesture.None;
|
||||
|
||||
int dx = NewPosition.X - _Begin.X;
|
||||
int dy = NewPosition.Y - _Begin.Y;
|
||||
|
||||
//Back/Escape
|
||||
if (dx < -150 && Math.Abs(dy) < 150)
|
||||
{
|
||||
_locked = false;
|
||||
return EGesture.Back;
|
||||
}
|
||||
|
||||
//ScrollDown
|
||||
if (Math.Abs(dx) < 150 && dy > 30)
|
||||
{
|
||||
_Begin.Y = NewPosition.Y;
|
||||
_Begin.X = NewPosition.X;
|
||||
return EGesture.ScrollDown;
|
||||
}
|
||||
|
||||
//ScrollUp
|
||||
if (Math.Abs(dx) < 150 && dy < -30)
|
||||
{
|
||||
_Begin.Y = NewPosition.Y;
|
||||
_Begin.X = NewPosition.X;
|
||||
return EGesture.ScrollUp;
|
||||
}
|
||||
|
||||
return EGesture.None;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,327 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
using Vocaluxe.Base;
|
||||
|
||||
namespace Vocaluxe.Lib.Input.WiiMote
|
||||
{
|
||||
class CWiiMote : IInput
|
||||
{
|
||||
WiiMoteLib _WiiMote;
|
||||
|
||||
private List<KeyEvent> _KeysPool;
|
||||
private List<KeyEvent> _CurrentKeysPool;
|
||||
private Object _KeyCopyLock = new Object();
|
||||
|
||||
private List<MouseEvent> _MousePool;
|
||||
private List<MouseEvent> _CurrentMousePool;
|
||||
private Object _MouseCopyLock = new Object();
|
||||
|
||||
private bool[] _ButtonStates;
|
||||
private Point _OldPosition;
|
||||
private bool _Connected;
|
||||
|
||||
private Thread _HandlerThread;
|
||||
private Object _Sync;
|
||||
private bool _Active;
|
||||
private RumbleTimer _RumbleTimer;
|
||||
|
||||
private CGesture _Gesture;
|
||||
|
||||
public bool Init()
|
||||
{
|
||||
_Sync = new Object();
|
||||
_RumbleTimer = new RumbleTimer();
|
||||
_Gesture = new CGesture();
|
||||
|
||||
_Active = true;
|
||||
_HandlerThread = new Thread(MainLoop);
|
||||
_HandlerThread.Priority = ThreadPriority.BelowNormal;
|
||||
|
||||
_KeysPool = new List<KeyEvent>();
|
||||
_CurrentKeysPool = new List<KeyEvent>();
|
||||
|
||||
_MousePool = new List<MouseEvent>();
|
||||
_CurrentMousePool = new List<MouseEvent>();
|
||||
|
||||
_ButtonStates = new bool[11];
|
||||
_OldPosition = new Point();
|
||||
|
||||
_HandlerThread.Start();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
_Active = false;
|
||||
}
|
||||
|
||||
public bool Connect()
|
||||
{
|
||||
if (!_Active)
|
||||
{
|
||||
_Active = true;
|
||||
_HandlerThread.Start();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public bool Disconnect()
|
||||
{
|
||||
_Active = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsConnected()
|
||||
{
|
||||
return _Connected;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
CopyEvents();
|
||||
}
|
||||
|
||||
public bool PollKeyEvent(ref KeyEvent KeyEvent)
|
||||
{
|
||||
if (_CurrentKeysPool.Count > 0)
|
||||
{
|
||||
KeyEvent = _CurrentKeysPool[0];
|
||||
_CurrentKeysPool.RemoveAt(0);
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
public bool PollMouseEvent(ref MouseEvent MouseEvent)
|
||||
{
|
||||
if (_CurrentMousePool.Count > 0)
|
||||
{
|
||||
MouseEvent = _CurrentMousePool[0];
|
||||
_CurrentMousePool.RemoveAt(0);
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
public void SetRumble(float Duration)
|
||||
{
|
||||
lock (_Sync)
|
||||
{
|
||||
_RumbleTimer.Set(Duration);
|
||||
}
|
||||
}
|
||||
|
||||
private void MainLoop()
|
||||
{
|
||||
_WiiMote = new WiiMoteLib();
|
||||
_WiiMote.WiiMoteChanged += wm_WiiMoteChanged;
|
||||
|
||||
while (_Active)
|
||||
{
|
||||
Thread.Sleep(5);
|
||||
|
||||
if (!_WiiMote.Connected)
|
||||
{
|
||||
if (!DoConnect())
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool StartRumble = false;
|
||||
bool StopRumble = false;
|
||||
lock (_Sync)
|
||||
{
|
||||
StartRumble = _RumbleTimer.ShouldStart;
|
||||
StopRumble = _RumbleTimer.ShouldStop;
|
||||
}
|
||||
|
||||
if (StartRumble)
|
||||
_WiiMote.SetRumble(true);
|
||||
|
||||
if (StopRumble)
|
||||
_WiiMote.SetRumble(false);
|
||||
}
|
||||
}
|
||||
|
||||
_WiiMote.SetRumble(false);
|
||||
_WiiMote.Disconnect();
|
||||
_Connected = false;
|
||||
}
|
||||
|
||||
private bool DoConnect()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!_WiiMote.Connect())
|
||||
return false;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false; ;
|
||||
}
|
||||
|
||||
_WiiMote.SetReportType(InputReport.IRAccel, IRSensitivity.Max, false);
|
||||
_WiiMote.SetLEDs(false, false, true, false);
|
||||
|
||||
_WiiMote.SetRumble(true);
|
||||
Thread.Sleep(250);
|
||||
_WiiMote.SetRumble(false);
|
||||
Thread.Sleep(250);
|
||||
_WiiMote.SetRumble(true);
|
||||
Thread.Sleep(250);
|
||||
_WiiMote.SetRumble(false);
|
||||
|
||||
_Connected = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void wm_WiiMoteChanged(object sender, WiiMoteChangedEventArgs args)
|
||||
{
|
||||
if (!_Active)
|
||||
return;
|
||||
|
||||
WiiMoteStatus ws = args.WiiMoteState;
|
||||
|
||||
Point p = ws.IRState.Position;
|
||||
p.X = 1023 - p.X;
|
||||
|
||||
//key events
|
||||
bool alt = false;
|
||||
bool shift = false;
|
||||
bool ctrl = false;
|
||||
bool pressed = false;
|
||||
char unicode = char.MinValue;
|
||||
|
||||
EGesture gesture = _Gesture.GetGesture(p);
|
||||
bool lb = false;
|
||||
bool rb = gesture == EGesture.Back;
|
||||
|
||||
Keys key = Keys.None;
|
||||
|
||||
if (ws.ButtonState.A && !_ButtonStates[0])
|
||||
lb = true;
|
||||
else if (ws.ButtonState.B && !_ButtonStates[1])
|
||||
_Gesture.SetLockPosition(p);
|
||||
else if (!ws.ButtonState.B && _ButtonStates[1])
|
||||
_Gesture.Reset();
|
||||
else if (ws.ButtonState.Down && !_ButtonStates[2])
|
||||
key = Keys.Right;
|
||||
else if (ws.ButtonState.Up && !_ButtonStates[3])
|
||||
key = Keys.Left;
|
||||
else if (ws.ButtonState.Left && !_ButtonStates[4])
|
||||
key = Keys.Down;
|
||||
else if (ws.ButtonState.Right && !_ButtonStates[5])
|
||||
key = Keys.Up;
|
||||
else if (ws.ButtonState.Home && !_ButtonStates[6])
|
||||
key = Keys.Space;
|
||||
else if (ws.ButtonState.Minus && !_ButtonStates[7])
|
||||
key = Keys.PageDown;
|
||||
else if (ws.ButtonState.Plus && !_ButtonStates[8])
|
||||
key = Keys.PageUp;
|
||||
else if (ws.ButtonState.One && !_ButtonStates[9])
|
||||
key = Keys.Enter;
|
||||
else if (ws.ButtonState.Two && !_ButtonStates[10])
|
||||
key = Keys.Escape;
|
||||
|
||||
_ButtonStates[0] = ws.ButtonState.A;
|
||||
_ButtonStates[1] = ws.ButtonState.B;
|
||||
_ButtonStates[2] = ws.ButtonState.Down;
|
||||
_ButtonStates[3] = ws.ButtonState.Up;
|
||||
_ButtonStates[4] = ws.ButtonState.Left;
|
||||
_ButtonStates[5] = ws.ButtonState.Right;
|
||||
_ButtonStates[6] = ws.ButtonState.Home;
|
||||
_ButtonStates[7] = ws.ButtonState.Minus;
|
||||
_ButtonStates[8] = ws.ButtonState.Plus;
|
||||
_ButtonStates[9] = ws.ButtonState.One;
|
||||
_ButtonStates[10] = ws.ButtonState.Two;
|
||||
|
||||
|
||||
if (alt || shift || ctrl || pressed || unicode != char.MinValue || key != Keys.None)
|
||||
{
|
||||
KeyEvent pool = new KeyEvent(ESender.WiiMote, alt, shift, ctrl, pressed, unicode, key);
|
||||
|
||||
lock (_KeyCopyLock)
|
||||
{
|
||||
_KeysPool.Add(pool);
|
||||
}
|
||||
}
|
||||
|
||||
//mouse events
|
||||
float reducing = 0.15f;
|
||||
float factor = 1f / (1f - reducing * 2f);
|
||||
float rx = (((float)p.X / 1024f) - reducing) * factor;
|
||||
float ry = (((float)p.Y / 768f) - reducing) * factor;
|
||||
|
||||
int x = (int)(rx * (float)CSettings.iRenderW);
|
||||
int y = (int)(ry * (float)CSettings.iRenderH);
|
||||
|
||||
|
||||
bool ld = false;
|
||||
bool lbh = !lb && ws.ButtonState.A;
|
||||
bool rbh = false;
|
||||
bool mb = false;
|
||||
bool mbh = false;
|
||||
|
||||
int wheel = 0;
|
||||
if (gesture == EGesture.ScrollUp)
|
||||
wheel = -1;
|
||||
if (gesture == EGesture.ScrollDown)
|
||||
wheel = 1;
|
||||
|
||||
MouseEvent mpool = new MouseEvent();
|
||||
bool trigger = false;
|
||||
|
||||
if (!lb && !rb && (p.X != _OldPosition.X || p.Y != _OldPosition.Y))
|
||||
{
|
||||
mpool = new MouseEvent(ESender.WiiMote, alt, shift, ctrl, x, y, false, false, false, wheel, lbh, rbh, false, mbh);
|
||||
trigger = true;
|
||||
}
|
||||
else if (lb || rb)
|
||||
{
|
||||
mpool = new MouseEvent(ESender.WiiMote, alt, shift, ctrl, x, y, lb, ld, rb, wheel, false, false, mb, false);
|
||||
trigger = true;
|
||||
}
|
||||
|
||||
|
||||
if (trigger)
|
||||
{
|
||||
lock (_MouseCopyLock)
|
||||
{
|
||||
_MousePool.Add(mpool);
|
||||
}
|
||||
}
|
||||
|
||||
_OldPosition.X = p.X;
|
||||
_OldPosition.Y = p.Y;
|
||||
}
|
||||
|
||||
private void CopyEvents()
|
||||
{
|
||||
lock (_KeyCopyLock)
|
||||
{
|
||||
foreach (KeyEvent e in _KeysPool)
|
||||
{
|
||||
_CurrentKeysPool.Add(e);
|
||||
}
|
||||
_KeysPool.Clear();
|
||||
}
|
||||
|
||||
lock (_MouseCopyLock)
|
||||
{
|
||||
foreach (MouseEvent e in _MousePool)
|
||||
{
|
||||
_CurrentMousePool.Add(e);
|
||||
}
|
||||
_MousePool.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,669 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Threading;
|
||||
|
||||
using Vocaluxe.Base;
|
||||
using Vocaluxe.Lib.Draw;
|
||||
using Vocaluxe.Lib.Input;
|
||||
|
||||
namespace Vocaluxe.Lib.Input.WiiMote
|
||||
{
|
||||
#region DataTypes
|
||||
public class WiiMoteStatus
|
||||
{
|
||||
public AccelCalibrationInfo AccelCalibrationInfo = new AccelCalibrationInfo();
|
||||
|
||||
public AccelStatus AccelState = new AccelStatus();
|
||||
|
||||
public Buttons ButtonState = new Buttons();
|
||||
|
||||
public IRState IRState = new IRState();
|
||||
|
||||
public byte Battery;
|
||||
|
||||
public bool Rumble;
|
||||
|
||||
public LEDStatus LEDState;
|
||||
|
||||
public WiiMoteStatus()
|
||||
{
|
||||
IRState.Sensors = new IR[4];
|
||||
}
|
||||
}
|
||||
|
||||
public struct LEDStatus
|
||||
{
|
||||
public bool LED1;
|
||||
public bool LED2;
|
||||
public bool LED3;
|
||||
public bool LED4;
|
||||
}
|
||||
|
||||
public enum IRMode : byte
|
||||
{
|
||||
Off = 0x00,
|
||||
Basic = 0x01, // 10 bytes
|
||||
Extended = 0x03 // 12 bytes
|
||||
};
|
||||
|
||||
public struct IR
|
||||
{
|
||||
public bool Active;
|
||||
public Point Position; // X: 0-1023; Y: 0-767
|
||||
public int Width; // 0-15
|
||||
}
|
||||
|
||||
public struct IRState
|
||||
{
|
||||
public IRMode Mode;
|
||||
public IR[] Sensors;
|
||||
public Point Position; //0..1023, 0..767
|
||||
public Point Distance; //between Point 0 and Point 1
|
||||
}
|
||||
|
||||
public struct AccelStatus
|
||||
{
|
||||
public SPoint3 RawValues; //0-255
|
||||
public SPoint3f Values; //0-3
|
||||
}
|
||||
|
||||
public struct AccelCalibrationInfo
|
||||
{
|
||||
public byte X0, Y0, Z0; //zero point
|
||||
public byte XG, YG, ZG; //gravity
|
||||
}
|
||||
|
||||
public struct Buttons
|
||||
{
|
||||
public bool Up, Down, Left, Right, A, B, Plus, Minus, One, Two, Home;
|
||||
}
|
||||
|
||||
public enum InputReport : byte
|
||||
{
|
||||
Status = 0x20,
|
||||
ReadData = 0x21,
|
||||
Ack = 0x22,
|
||||
Buttons = 0x30,
|
||||
ButtonsAccel = 0x31,
|
||||
Buttons8Bytes = 0x32,
|
||||
IRAccel = 0x33,
|
||||
ButtonsExtension = 0x34,
|
||||
ExtensionAccel = 0x35,
|
||||
IRExtensionAccel = 0x37,
|
||||
};
|
||||
|
||||
public enum IRSensitivity
|
||||
{
|
||||
Level1,
|
||||
Level2,
|
||||
Level3,
|
||||
Level4,
|
||||
Level5,
|
||||
Max
|
||||
}
|
||||
#endregion DataTypes
|
||||
|
||||
#region Events
|
||||
public class WiiMoteChangedEventArgs: EventArgs
|
||||
{
|
||||
public WiiMoteStatus WiiMoteState;
|
||||
|
||||
public WiiMoteChangedEventArgs(WiiMoteStatus ws)
|
||||
{
|
||||
WiiMoteState = ws;
|
||||
}
|
||||
}
|
||||
#endregion Events
|
||||
|
||||
public class WiiMoteLib : IDisposable
|
||||
{
|
||||
private const ushort VID = 0x057e;
|
||||
private const ushort PID = 0x0306; //Wiimotion
|
||||
private const ushort PIDPlus = 0x0330; //Wiimotion Plus
|
||||
|
||||
// registers
|
||||
private const int REGISTER_IR = 0x04b00030;
|
||||
private const int REGISTER_IR_SENSITIVITY_1 = 0x04b00000;
|
||||
private const int REGISTER_IR_SENSITIVITY_2 = 0x04b0001a;
|
||||
private const int REGISTER_IR_MODE = 0x04b00033;
|
||||
|
||||
private const int REPORT_LENGTH = 22;
|
||||
|
||||
// output commands
|
||||
private enum OutputReport : byte
|
||||
{
|
||||
LEDs = 0x11,
|
||||
Type = 0x12,
|
||||
IR = 0x13,
|
||||
Status = 0x15,
|
||||
WriteMemory = 0x16,
|
||||
ReadMemory = 0x17,
|
||||
SpeakerData = 0x18,
|
||||
SpeakerMute = 0x19,
|
||||
IR2 = 0x1a,
|
||||
};
|
||||
|
||||
// data handling
|
||||
private IntPtr _Handle;
|
||||
private readonly byte[] _Buff = new byte[REPORT_LENGTH];
|
||||
private byte[] _ReadBuff;
|
||||
private int _Address;
|
||||
private short _Size;
|
||||
|
||||
private Thread _Reader;
|
||||
private bool _Active;
|
||||
|
||||
private bool _Connected;
|
||||
public bool Connected
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Connected;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly WiiMoteStatus _WiiMoteState = new WiiMoteStatus();
|
||||
private readonly AutoResetEvent _ReadDone = new AutoResetEvent(false);
|
||||
public event EventHandler<WiiMoteChangedEventArgs> WiiMoteChanged;
|
||||
|
||||
#region Interface
|
||||
public WiiMoteLib()
|
||||
{
|
||||
_Connected = false;
|
||||
_Active = true;
|
||||
_Reader = new Thread(ReaderLoop);
|
||||
_Reader.Start();
|
||||
}
|
||||
|
||||
public bool Connect()
|
||||
{
|
||||
_Connected = false;
|
||||
CHIDAPI.Exit();
|
||||
|
||||
if (!CHIDAPI.Init())
|
||||
{
|
||||
CLog.LogError("WiiMoteLib: Can't initialize HID API");
|
||||
return false;
|
||||
}
|
||||
|
||||
//Try WiiMotion
|
||||
if (_Connected = CHIDAPI.Open(VID, PID, out _Handle))
|
||||
{
|
||||
if (!(_Connected = ReadCalibration()))
|
||||
CHIDAPI.Close(_Handle);
|
||||
}
|
||||
|
||||
if (_Connected)
|
||||
return true;
|
||||
|
||||
//Try WiiMotion Plus
|
||||
if (_Connected = CHIDAPI.Open(VID, PIDPlus, out _Handle))
|
||||
{
|
||||
if (!(_Connected = ReadCalibration()))
|
||||
CHIDAPI.Close(_Handle);
|
||||
}
|
||||
|
||||
return _Connected;
|
||||
}
|
||||
|
||||
public void Disconnect()
|
||||
{
|
||||
_Connected = false;
|
||||
_Active = false;
|
||||
CHIDAPI.Exit();
|
||||
}
|
||||
|
||||
public void SetReportType(InputReport type, IRSensitivity irSensitivity, bool continuous)
|
||||
{
|
||||
if (!_Connected)
|
||||
return;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case InputReport.IRAccel:
|
||||
EnableIR(IRMode.Extended, irSensitivity);
|
||||
break;
|
||||
default:
|
||||
DisableIR();
|
||||
break;
|
||||
}
|
||||
|
||||
ClearReport();
|
||||
_Buff[0] = (byte)OutputReport.Type;
|
||||
_Buff[1] = (byte)((continuous ? 0x04 : 0x00) | (byte)(_WiiMoteState.Rumble ? 0x01 : 0x00));
|
||||
_Buff[2] = (byte)type;
|
||||
|
||||
CHIDAPI.Write(_Handle, _Buff);
|
||||
}
|
||||
|
||||
public void SetLEDs(bool led1, bool led2, bool led3, bool led4)
|
||||
{
|
||||
_WiiMoteState.LEDState.LED1 = led1;
|
||||
_WiiMoteState.LEDState.LED2 = led2;
|
||||
_WiiMoteState.LEDState.LED3 = led3;
|
||||
_WiiMoteState.LEDState.LED4 = led4;
|
||||
|
||||
if (!_Connected)
|
||||
return;
|
||||
|
||||
ClearReport();
|
||||
|
||||
_Buff[0] = (byte)OutputReport.LEDs;
|
||||
_Buff[1] = (byte)(
|
||||
(led1 ? 0x10 : 0x00) |
|
||||
(led2 ? 0x20 : 0x00) |
|
||||
(led3 ? 0x40 : 0x00) |
|
||||
(led4 ? 0x80 : 0x00) |
|
||||
RumbleBit);
|
||||
|
||||
CHIDAPI.Write(_Handle, _Buff);
|
||||
}
|
||||
|
||||
public void SetRumble(bool on)
|
||||
{
|
||||
_WiiMoteState.Rumble = on;
|
||||
|
||||
// the LED report also handles rumble
|
||||
SetLEDs(_WiiMoteState.LEDState.LED1,
|
||||
_WiiMoteState.LEDState.LED2,
|
||||
_WiiMoteState.LEDState.LED3,
|
||||
_WiiMoteState.LEDState.LED4);
|
||||
}
|
||||
|
||||
public WiiMoteStatus WiiMoteState
|
||||
{
|
||||
get { return _WiiMoteState; }
|
||||
}
|
||||
#endregion Interface
|
||||
|
||||
#region Private stuff
|
||||
private void ReaderLoop()
|
||||
{
|
||||
while (_Active)
|
||||
{
|
||||
Thread.Sleep(5);
|
||||
|
||||
if (_Handle != IntPtr.Zero && _Connected)
|
||||
{
|
||||
byte[] buff = new byte[REPORT_LENGTH];
|
||||
|
||||
try
|
||||
{
|
||||
CHIDAPI.ReadTimeout(_Handle, out buff, REPORT_LENGTH, 100);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
CLog.LogError("(WiiMoteLib) Error reading from device: " + e.ToString());
|
||||
}
|
||||
|
||||
if (ParseInputReport(buff))
|
||||
{
|
||||
if (WiiMoteChanged != null)
|
||||
WiiMoteChanged(this, new WiiMoteChangedEventArgs(_WiiMoteState));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool ParseInputReport(byte[] buff)
|
||||
{
|
||||
if (buff == null)
|
||||
{
|
||||
_Connected = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
InputReport type = (InputReport)buff[0];
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case InputReport.Buttons:
|
||||
ParseButtons(buff);
|
||||
break;
|
||||
|
||||
case InputReport.ButtonsAccel:
|
||||
ParseButtons(buff);
|
||||
ParseAccel(buff);
|
||||
break;
|
||||
|
||||
case InputReport.IRAccel:
|
||||
ParseButtons(buff);
|
||||
ParseAccel(buff);
|
||||
ParseIR(buff);
|
||||
break;
|
||||
|
||||
case InputReport.ButtonsExtension:
|
||||
ParseButtons(buff);
|
||||
break;
|
||||
|
||||
case InputReport.ExtensionAccel:
|
||||
ParseButtons(buff);
|
||||
ParseAccel(buff);
|
||||
break;
|
||||
|
||||
case InputReport.IRExtensionAccel:
|
||||
ParseButtons(buff);
|
||||
ParseAccel(buff);
|
||||
ParseIR(buff);
|
||||
break;
|
||||
|
||||
case InputReport.Status:
|
||||
ParseButtons(buff);
|
||||
_WiiMoteState.Battery = buff[6];
|
||||
|
||||
_WiiMoteState.LEDState.LED1 = (buff[3] & 0x10) != 0;
|
||||
_WiiMoteState.LEDState.LED2 = (buff[3] & 0x20) != 0;
|
||||
_WiiMoteState.LEDState.LED3 = (buff[3] & 0x40) != 0;
|
||||
_WiiMoteState.LEDState.LED4 = (buff[3] & 0x80) != 0;
|
||||
break;
|
||||
|
||||
case InputReport.ReadData:
|
||||
ParseButtons(buff);
|
||||
ParseReadData(buff);
|
||||
break;
|
||||
|
||||
case InputReport.Ack:
|
||||
return false;
|
||||
|
||||
case InputReport.Buttons8Bytes:
|
||||
break;
|
||||
|
||||
default:
|
||||
CLog.LogError("(WiiMoteLib) Unknown report type: " + type.ToString("x"));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private byte[] DecryptBuffer(byte[] buff)
|
||||
{
|
||||
for(int i = 0; i < buff.Length; i++)
|
||||
buff[i] = (byte)(((buff[i] ^ 0x17) + 0x17) & 0xff);
|
||||
|
||||
return buff;
|
||||
}
|
||||
|
||||
private void ParseButtons(byte[] buff)
|
||||
{
|
||||
_WiiMoteState.ButtonState.A = (buff[2] & 0x08) != 0;
|
||||
_WiiMoteState.ButtonState.B = (buff[2] & 0x04) != 0;
|
||||
_WiiMoteState.ButtonState.Minus = (buff[2] & 0x10) != 0;
|
||||
_WiiMoteState.ButtonState.Home = (buff[2] & 0x80) != 0;
|
||||
_WiiMoteState.ButtonState.Plus = (buff[1] & 0x10) != 0;
|
||||
_WiiMoteState.ButtonState.One = (buff[2] & 0x02) != 0;
|
||||
_WiiMoteState.ButtonState.Two = (buff[2] & 0x01) != 0;
|
||||
_WiiMoteState.ButtonState.Up = (buff[1] & 0x08) != 0;
|
||||
_WiiMoteState.ButtonState.Down = (buff[1] & 0x04) != 0;
|
||||
_WiiMoteState.ButtonState.Left = (buff[1] & 0x01) != 0;
|
||||
_WiiMoteState.ButtonState.Right = (buff[1] & 0x02) != 0;
|
||||
}
|
||||
|
||||
private void ParseAccel(byte[] buff)
|
||||
{
|
||||
_WiiMoteState.AccelState.RawValues.X = buff[3];
|
||||
_WiiMoteState.AccelState.RawValues.Y = buff[4];
|
||||
_WiiMoteState.AccelState.RawValues.Z = buff[5];
|
||||
|
||||
_WiiMoteState.AccelState.Values.X = (float)((float)_WiiMoteState.AccelState.RawValues.X - _WiiMoteState.AccelCalibrationInfo.X0) /
|
||||
((float)_WiiMoteState.AccelCalibrationInfo.XG - _WiiMoteState.AccelCalibrationInfo.X0);
|
||||
_WiiMoteState.AccelState.Values.Y = (float)((float)_WiiMoteState.AccelState.RawValues.Y - _WiiMoteState.AccelCalibrationInfo.Y0) /
|
||||
((float)_WiiMoteState.AccelCalibrationInfo.YG - _WiiMoteState.AccelCalibrationInfo.Y0);
|
||||
_WiiMoteState.AccelState.Values.Z = (float)((float)_WiiMoteState.AccelState.RawValues.Z - _WiiMoteState.AccelCalibrationInfo.Z0) /
|
||||
((float)_WiiMoteState.AccelCalibrationInfo.ZG - _WiiMoteState.AccelCalibrationInfo.Z0);
|
||||
}
|
||||
|
||||
private void ParseIR(byte[] buff)
|
||||
{
|
||||
switch(_WiiMoteState.IRState.Mode)
|
||||
{
|
||||
case IRMode.Basic:
|
||||
if (_WiiMoteState.IRState.Sensors[0].Active = !(buff[6] == 0xff && buff[7] == 0xff))
|
||||
{
|
||||
_WiiMoteState.IRState.Sensors[0].Position.X = buff[6] | ((buff[8] >> 4) & 0x03) << 8;
|
||||
_WiiMoteState.IRState.Sensors[0].Position.Y = buff[7] | ((buff[8] >> 6) & 0x03) << 8;
|
||||
_WiiMoteState.IRState.Sensors[0].Width = 0;
|
||||
}
|
||||
|
||||
if (_WiiMoteState.IRState.Sensors[1].Active = !(buff[9] == 0xff && buff[10] == 0xff))
|
||||
{
|
||||
_WiiMoteState.IRState.Sensors[1].Position.X = buff[9] | ((buff[8] >> 0) & 0x03) << 8;
|
||||
_WiiMoteState.IRState.Sensors[1].Position.Y = buff[10] | ((buff[8] >> 2) & 0x03) << 8;
|
||||
_WiiMoteState.IRState.Sensors[1].Width = 0;
|
||||
}
|
||||
break;
|
||||
case IRMode.Extended:
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (_WiiMoteState.IRState.Sensors[i].Active = !(buff[6 + i * 3] == 0xff && buff[7 + i * 3] == 0xff && buff[8 + i * 3] == 0xff))
|
||||
{
|
||||
_WiiMoteState.IRState.Sensors[i].Position.X = buff[6 + i * 3] | ((buff[8 + i * 3] >> 4) & 0x03) << 8;
|
||||
_WiiMoteState.IRState.Sensors[i].Position.Y = buff[7 + i * 3] | ((buff[8 + i * 3] >> 6) & 0x03) << 8;
|
||||
_WiiMoteState.IRState.Sensors[i].Width = buff[8 + i * 3] & 0x0f;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (_WiiMoteState.IRState.Sensors[0].Active && _WiiMoteState.IRState.Sensors[1].Active)
|
||||
{
|
||||
_WiiMoteState.IRState.Position.X = (_WiiMoteState.IRState.Sensors[1].Position.X + _WiiMoteState.IRState.Sensors[0].Position.X) / 2;
|
||||
_WiiMoteState.IRState.Position.Y = (_WiiMoteState.IRState.Sensors[1].Position.Y + _WiiMoteState.IRState.Sensors[0].Position.Y) / 2;
|
||||
|
||||
_WiiMoteState.IRState.Distance.X = Math.Abs(_WiiMoteState.IRState.Sensors[1].Position.X - _WiiMoteState.IRState.Sensors[0].Position.X);
|
||||
_WiiMoteState.IRState.Distance.Y = Math.Abs(_WiiMoteState.IRState.Sensors[1].Position.Y - _WiiMoteState.IRState.Sensors[0].Position.Y);
|
||||
}
|
||||
else if (_WiiMoteState.IRState.Sensors[0].Active)
|
||||
{
|
||||
if (_WiiMoteState.IRState.Sensors[0].Position.X > 512)
|
||||
_WiiMoteState.IRState.Position.X = _WiiMoteState.IRState.Sensors[0].Position.X - _WiiMoteState.IRState.Distance.X / 2;
|
||||
else
|
||||
_WiiMoteState.IRState.Position.X = _WiiMoteState.IRState.Sensors[0].Position.X + _WiiMoteState.IRState.Distance.X / 2;
|
||||
|
||||
if (_WiiMoteState.IRState.Sensors[0].Position.X < 384)
|
||||
_WiiMoteState.IRState.Position.Y = _WiiMoteState.IRState.Sensors[0].Position.Y - _WiiMoteState.IRState.Distance.Y / 2;
|
||||
else
|
||||
_WiiMoteState.IRState.Position.Y = _WiiMoteState.IRState.Sensors[0].Position.Y + _WiiMoteState.IRState.Distance.Y / 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void ParseReadData(byte[] buff)
|
||||
{
|
||||
if ((buff[3] & 0x08) != 0)
|
||||
{
|
||||
CLog.LogError("Error reading data from WiiMote: Bytes do not exist");
|
||||
_Connected = false;
|
||||
}
|
||||
|
||||
if ((buff[3] & 0x07) != 0)
|
||||
{
|
||||
CLog.LogError("Error reading data from WiiMote: Attempt to read from write-only registers.");
|
||||
_Connected = false;
|
||||
}
|
||||
|
||||
int size = (buff[3] >> 4) + 1;
|
||||
int offset = (buff[4] << 8 | buff[5]);
|
||||
|
||||
Array.Copy(buff, 6, _ReadBuff, offset - _Address, size);
|
||||
|
||||
if(_Address + _Size == offset + size)
|
||||
_ReadDone.Set();
|
||||
}
|
||||
|
||||
private byte RumbleBit
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_WiiMoteState.Rumble)
|
||||
return (byte)0x1;
|
||||
return (byte)0x0;
|
||||
}
|
||||
}
|
||||
|
||||
private bool ReadCalibration()
|
||||
{
|
||||
// this appears to change the report type to 0x31
|
||||
byte[] buff = ReadData(0x0016, 7);
|
||||
if (buff == null)
|
||||
return false;
|
||||
|
||||
_WiiMoteState.AccelCalibrationInfo.X0 = buff[0];
|
||||
_WiiMoteState.AccelCalibrationInfo.Y0 = buff[1];
|
||||
_WiiMoteState.AccelCalibrationInfo.Z0 = buff[2];
|
||||
_WiiMoteState.AccelCalibrationInfo.XG = buff[4];
|
||||
_WiiMoteState.AccelCalibrationInfo.YG = buff[5];
|
||||
_WiiMoteState.AccelCalibrationInfo.ZG = buff[6];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void EnableIR(IRMode mode, IRSensitivity Sensitivity)
|
||||
{
|
||||
_WiiMoteState.IRState.Mode = mode;
|
||||
|
||||
ClearReport();
|
||||
_Buff[0] = (byte)OutputReport.IR;
|
||||
_Buff[1] = (byte)(0x04 | RumbleBit);
|
||||
CHIDAPI.Write(_Handle, _Buff);
|
||||
Thread.Sleep(50);
|
||||
|
||||
ClearReport();
|
||||
_Buff[0] = (byte)OutputReport.IR2;
|
||||
_Buff[1] = (byte)(0x04 | RumbleBit);
|
||||
CHIDAPI.Write(_Handle, _Buff);
|
||||
Thread.Sleep(50);
|
||||
|
||||
WriteData(REGISTER_IR, 0x08);
|
||||
Thread.Sleep(50);
|
||||
|
||||
switch(Sensitivity)
|
||||
{
|
||||
case IRSensitivity.Level1:
|
||||
WriteData(REGISTER_IR_SENSITIVITY_1, 9, new byte[] {0x02, 0x00, 0x00, 0x71, 0x01, 0x00, 0x64, 0x00, 0xfe});
|
||||
Thread.Sleep(50);
|
||||
WriteData(REGISTER_IR_SENSITIVITY_2, 2, new byte[] {0xfd, 0x05});
|
||||
break;
|
||||
case IRSensitivity.Level2:
|
||||
WriteData(REGISTER_IR_SENSITIVITY_1, 9, new byte[] {0x02, 0x00, 0x00, 0x71, 0x01, 0x00, 0x96, 0x00, 0xb4});
|
||||
Thread.Sleep(50);
|
||||
WriteData(REGISTER_IR_SENSITIVITY_2, 2, new byte[] {0xb3, 0x04});
|
||||
break;
|
||||
case IRSensitivity.Level3:
|
||||
WriteData(REGISTER_IR_SENSITIVITY_1, 9, new byte[] {0x02, 0x00, 0x00, 0x71, 0x01, 0x00, 0xaa, 0x00, 0x64});
|
||||
Thread.Sleep(50);
|
||||
WriteData(REGISTER_IR_SENSITIVITY_2, 2, new byte[] {0x63, 0x03});
|
||||
break;
|
||||
case IRSensitivity.Level4:
|
||||
WriteData(REGISTER_IR_SENSITIVITY_1, 9, new byte[] {0x02, 0x00, 0x00, 0x71, 0x01, 0x00, 0xc8, 0x00, 0x36});
|
||||
Thread.Sleep(50);
|
||||
WriteData(REGISTER_IR_SENSITIVITY_2, 2, new byte[] {0x35, 0x03});
|
||||
break;
|
||||
case IRSensitivity.Level5:
|
||||
WriteData(REGISTER_IR_SENSITIVITY_1, 9, new byte[] {0x07, 0x00, 0x00, 0x71, 0x01, 0x00, 0x72, 0x00, 0x20});
|
||||
Thread.Sleep(50);
|
||||
WriteData(REGISTER_IR_SENSITIVITY_2, 2, new byte[] {0x1, 0x03});
|
||||
break;
|
||||
case IRSensitivity.Max:
|
||||
WriteData(REGISTER_IR_SENSITIVITY_1, 9, new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x41});
|
||||
Thread.Sleep(50);
|
||||
WriteData(REGISTER_IR_SENSITIVITY_2, 2, new byte[] {0x40, 0x00});
|
||||
break;
|
||||
}
|
||||
Thread.Sleep(50);
|
||||
WriteData(REGISTER_IR_MODE, (byte)mode);
|
||||
Thread.Sleep(50);
|
||||
WriteData(REGISTER_IR, 0x08);
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
|
||||
private void DisableIR()
|
||||
{
|
||||
_WiiMoteState.IRState.Mode = IRMode.Off;
|
||||
|
||||
ClearReport();
|
||||
_Buff[0] = (byte)OutputReport.IR;
|
||||
_Buff[1] = RumbleBit;
|
||||
CHIDAPI.Write(_Handle, _Buff);
|
||||
|
||||
ClearReport();
|
||||
_Buff[0] = (byte)OutputReport.IR2;
|
||||
_Buff[1] = RumbleBit;
|
||||
CHIDAPI.Write(_Handle, _Buff);
|
||||
}
|
||||
|
||||
private void ClearReport()
|
||||
{
|
||||
Array.Clear(_Buff, 0, REPORT_LENGTH);
|
||||
}
|
||||
|
||||
private byte[] ReadData(int address, short size)
|
||||
{
|
||||
ClearReport();
|
||||
|
||||
_ReadBuff = new byte[size];
|
||||
_Address = address & 0xffff;
|
||||
_Size = size;
|
||||
|
||||
_Buff[0] = (byte)OutputReport.ReadMemory;
|
||||
_Buff[1] = (byte)(((address & 0xff000000) >> 24) | RumbleBit);
|
||||
_Buff[2] = (byte)((address & 0x00ff0000) >> 16);
|
||||
_Buff[3] = (byte)((address & 0x0000ff00) >> 8);
|
||||
_Buff[4] = (byte)(address & 0x000000ff);
|
||||
|
||||
_Buff[5] = (byte)((size & 0xff00) >> 8);
|
||||
_Buff[6] = (byte)(size & 0xff);
|
||||
|
||||
CHIDAPI.Write(_Handle, _Buff);
|
||||
|
||||
if (!_ReadDone.WaitOne(1000, false))
|
||||
{
|
||||
_Connected = false;
|
||||
return null;
|
||||
}
|
||||
|
||||
return _ReadBuff;
|
||||
}
|
||||
|
||||
private void WriteData(int address, byte data)
|
||||
{
|
||||
WriteData(address, 1, new byte[] { data });
|
||||
}
|
||||
|
||||
private void WriteData(int address, byte size, byte[] buff)
|
||||
{
|
||||
ClearReport();
|
||||
|
||||
_Buff[0] = (byte)OutputReport.WriteMemory;
|
||||
_Buff[1] = (byte)(((address & 0xff000000) >> 24) | RumbleBit);
|
||||
_Buff[2] = (byte)((address & 0x00ff0000) >> 16);
|
||||
_Buff[3] = (byte)((address & 0x0000ff00) >> 8);
|
||||
_Buff[4] = (byte)(address & 0x000000ff);
|
||||
_Buff[5] = size;
|
||||
Array.Copy(buff, 0, _Buff, 6, size);
|
||||
|
||||
CHIDAPI.Write(_Handle, _Buff);
|
||||
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
#endregion Private stuff
|
||||
|
||||
#region IDisposable Members
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if(disposing)
|
||||
Disconnect();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user