using System;
using System.Drawing;
namespace WiimoteLib.Extensions
{
public class Nunchuk : ExtensionController<NunchukState>
{
internal Nunchuk(Wiimote wm) : base(wm)
{
}
internal override void Initialize()
{
byte[] buff = Wiimote.ReadData(REGISTER_EXTENSION_CALIBRATION, 16);
State.CalibrationInfo.AccelCalibration.X0 = buff[0];
State.CalibrationInfo.AccelCalibration.Y0 = buff[1];
State.CalibrationInfo.AccelCalibration.Z0 = buff[2];
State.CalibrationInfo.AccelCalibration.XG = buff[4];
State.CalibrationInfo.AccelCalibration.YG = buff[5];
State.CalibrationInfo.AccelCalibration.ZG = buff[6];
State.CalibrationInfo.MaxX = buff[8];
State.CalibrationInfo.MinX = buff[9];
State.CalibrationInfo.MidX = buff[10];
State.CalibrationInfo.MaxY = buff[11];
State.CalibrationInfo.MinY = buff[12];
State.CalibrationInfo.MidY = buff[13];
}
internal override void ParseData(byte[] buff, int offset)
{
State.RawJoystick.X = buff[offset];
State.RawJoystick.Y = buff[offset + 1];
State.AccelState.RawValues.X = buff[offset + 2];
State.AccelState.RawValues.Y = buff[offset + 3];
State.AccelState.RawValues.Z = buff[offset + 4];
State.C = (buff[offset + 5] & 0x02) == 0;
State.Z = (buff[offset + 5] & 0x01) == 0;
State.AccelState.Values.X = (float)((float)State.AccelState.RawValues.X - State.CalibrationInfo.AccelCalibration.X0) /
((float)State.CalibrationInfo.AccelCalibration.XG - State.CalibrationInfo.AccelCalibration.X0);
State.AccelState.Values.Y = (float)((float)State.AccelState.RawValues.Y - State.CalibrationInfo.AccelCalibration.Y0) /
((float)State.CalibrationInfo.AccelCalibration.YG - State.CalibrationInfo.AccelCalibration.Y0);
State.AccelState.Values.Z = (float)((float)State.AccelState.RawValues.Z - State.CalibrationInfo.AccelCalibration.Z0) /
((float)State.CalibrationInfo.AccelCalibration.ZG - State.CalibrationInfo.AccelCalibration.Z0);
if(State.CalibrationInfo.MaxX != 0x00)
State.Joystick.X = (float)((float)State.RawJoystick.X - State.CalibrationInfo.MidX) /
((float)State.CalibrationInfo.MaxX - State.CalibrationInfo.MinX);
if(State.CalibrationInfo.MaxY != 0x00)
State.Joystick.Y = (float)((float)State.RawJoystick.Y - State.CalibrationInfo.MidY) /
((float)State.CalibrationInfo.MaxY - State.CalibrationInfo.MinY);
}
public override ExtensionType ExtensionType
{
get { return ExtensionType.Nunchuk; }
}
}
/// <summary>
/// Current state of the Nunchuk extension
/// </summary>
[Serializable]
[DataContract]
public class NunchukState : IExtensionState
{
/// <summary>
/// Calibration data for Nunchuk extension
/// </summary>
[DataMember]
public NunchukCalibrationInfo CalibrationInfo;
/// <summary>
/// State of accelerometers
/// </summary>
[DataMember]
public AccelState AccelState;
/// <summary>
/// Raw joystick position before normalization. Values range between 0 and 255.
/// </summary>
[DataMember]
public Point RawJoystick;
/// <summary>
/// Normalized joystick position. Values range between -0.5 and 0.5
/// </summary>
[DataMember]
public PointF Joystick;
/// <summary>
/// Digital button on Nunchuk extension
/// </summary>
[DataMember]
public bool C, Z;
}
/// <summary>
/// Calibration information stored on the Nunchuk
/// </summary>
[Serializable]
[DataContract]
public struct NunchukCalibrationInfo
{
/// <summary>
/// Accelerometer calibration data
/// </summary>
public AccelCalibrationInfo AccelCalibration;
/// <summary>
/// Joystick X-axis calibration
/// </summary>
[DataMember]
public byte MinX, MidX, MaxX;
/// <summary>
/// Joystick Y-axis calibration
/// </summary>
[DataMember]
public byte MinY, MidY, MaxY;
}
}