/// <summary> /// http://wiibrew.org/index.php?title=Wiimote#Extended_Mode /// </summary> protected static bool ParseExtendedBeacon(byte[] buff, int offset, ExtendedIRBeacon irBeacon) { if (buff[offset + 0] == 0xff && buff[offset + 1] == 0xff && buff[offset + 2] == 0xff) { return(false); } irBeacon.X = buff[offset + 0] | ((buff[offset + 2] >> 4) & 0x03) << 8; irBeacon.Y = buff[offset + 1] | ((buff[offset + 2] >> 6) & 0x03) << 8; irBeacon.Size = buff[offset + 2] & 0x0f; return(true); }
protected override bool ParseReport(byte[] report) { if (report[0] < 0x20) throw new InvalidOperationException("Received an output report!"); InputReport type = (InputReport)report[0]; if (type >= InputReport.Buttons && type <= InputReport.ButtonsAccelerometer36IrB) { if (type == InputReport.ButtonsAccelerometer36IrB) ReportingMode = ReportingMode.ButtonsAccelerometer36Ir; else ReportingMode = (ReportingMode)type; IRMode irMode = GetIrMode(type); if (this._IrMode != irMode) { for (int i = 0; i < _CachedIRBeacons.Length; i++) { BasicIRBeacon newBeacon = null; switch (irMode) { case IRMode.Basic: newBeacon = new BasicIRBeacon(); break; case IRMode.Extended: newBeacon = new ExtendedIRBeacon(); break; case IRMode.Full: newBeacon = new FullIRBeacon(); break; } _CachedIRBeacons[i] = newBeacon; _IRBeacons[i] = null; } this._IrMode = irMode; } } switch (type) { case InputReport.Buttons: ParseButtons(report, 1); break; case InputReport.ButtonsAccelerometer: ParseButtons(report, 1); ParseAccelerometer(report, 3); break; case InputReport.Buttons8Extension: ParseButtons(report, 1); ParseExtension(report, 3, 8); break; case InputReport.ButtonsAccelerometer12Ir: { ParseButtons(report, 1); ParseAccelerometer(report, 3); ExtendedIRBeacon irBeacon; // Parse beacon 0. irBeacon = (ExtendedIRBeacon)_CachedIRBeacons[0]; _IRBeacons[0] = ParseExtendedBeacon(report, 6, irBeacon) ? irBeacon : null; // Parse beacon 1. irBeacon = (ExtendedIRBeacon)_CachedIRBeacons[1]; _IRBeacons[1] = ParseExtendedBeacon(report, 9, irBeacon) ? irBeacon : null; // Parse beacon 2. irBeacon = (ExtendedIRBeacon)_CachedIRBeacons[2]; _IRBeacons[2] = ParseExtendedBeacon(report, 12, irBeacon) ? irBeacon : null; // Parse beacon 3. irBeacon = (ExtendedIRBeacon)_CachedIRBeacons[3]; _IRBeacons[3] = ParseExtendedBeacon(report, 15, irBeacon) ? irBeacon : null; } break; case InputReport.Buttons19Extension: ParseButtons(report, 1); ParseExtension(report, 3, 19); break; case InputReport.ButtonsAccelerometer16Extension: ParseButtons(report, 1); ParseAccelerometer(report, 3); ParseExtension(report, 6, 16); break; case InputReport.Buttons10Ir9Extension: case InputReport.ButtonsAccelerometer10Ir6Extension: { int offset = 1; offset += ParseButtons(report, offset); if (type == InputReport.ButtonsAccelerometer10Ir6Extension) offset += ParseAccelerometer(report, offset); BasicIRBeacon irBeacon; // Parse beacon 0. irBeacon = _CachedIRBeacons[0]; _IRBeacons[0] = ParseBasicBeacon(report, offset, 0, irBeacon) ? irBeacon : null; // Parse beacon 1. irBeacon = _CachedIRBeacons[1]; _IRBeacons[1] = ParseBasicBeacon(report, offset, 1, irBeacon) ? irBeacon : null; // Parse beacon 2. irBeacon = _CachedIRBeacons[2]; _IRBeacons[2] = ParseBasicBeacon(report, offset + 5, 0, irBeacon) ? irBeacon : null; // Parse beacon 3. irBeacon = _CachedIRBeacons[3]; _IRBeacons[3] = ParseBasicBeacon(report, offset + 5, 1, irBeacon) ? irBeacon : null; offset += 10; // Each pair of IR-beacons is 5 bytes. if (type == InputReport.ButtonsAccelerometer10Ir6Extension) ParseExtension(report, offset, 6); else ParseExtension(report, offset, 9); } break; case InputReport.Extension: ParseExtension(report, 1, 21); break; case InputReport.ButtonsAccelerometer36IrA: { ParseButtons(report, 1); // since button information is complete on both the interlaced reports it needs no temporary storage _PartialAccelerometerX = report[3]; _PartialAccelerometerZ = (ushort)(((report[2] & 0x60) << 1) | ((report[1] & 0x60) >> 1)); _PartialIRBeaconOneResult = ParseFullBeacon(report, 4, (FullIRBeacon)_CachedIRBeacons[0]); _PartialIRBeaconTwoResult = ParseFullBeacon(report, 13, (FullIRBeacon)_CachedIRBeacons[1]); } break; case InputReport.ButtonsAccelerometer36IrB: { ParseButtons(report, 1); // Complete the _PartialAccelerometerZ field _PartialAccelerometerZ = (ushort)(_PartialAccelerometerZ | ((report[2] & 60) >> 3) | ((report[1] & 60) >> 5)); // Initialize the accelerometer if it was not yet initialized (should never happen). if (Accelerometer == null) ReadCalibrationData(); // Construct the new accelerometer-values from now completed data Accelerometer.Raw.X = _PartialAccelerometerX; Accelerometer.Raw.Y = report[3]; Accelerometer.Raw.Z = _PartialAccelerometerZ; UpdateCalibratedAccelerometer(); FullIRBeacon irBeacon; // Commit partial irbeacon from 'a' report IRBeacons[0] = _PartialIRBeaconOneResult ? _CachedIRBeacons[0] : null; // Commit partial irbeacon from 'a' report IRBeacons[1] = _PartialIRBeaconTwoResult ? _CachedIRBeacons[1] : null; // Parse beacon 2. irBeacon = (FullIRBeacon)_CachedIRBeacons[2]; IRBeacons[2] = ParseFullBeacon(report, 4, irBeacon) ? irBeacon : null; // Parse beacon 3. irBeacon = (FullIRBeacon)_CachedIRBeacons[3]; IRBeacons[3] = ParseFullBeacon(report, 13, irBeacon) ? irBeacon : null; } break; case InputReport.GetStatusResult: ParseButtons(report, 1); ParseStatus(report); break; case InputReport.ReadDataResult: ParseButtons(report, 1); // The rest is handled by the ReadData method (waiting for the report). break; case InputReport.WriteDataResult: // The rest is handled by the WriteData method (waiting for the report). break; default: Debug.WriteLine("Unknown report type: " + type.ToString("x")); return false; } if ((type >= InputReport.Buttons || type == InputReport.GetStatusResult) && (type != InputReport.ButtonsAccelerometer36IrA)) OnUpdated(); return true; }
protected override bool ParseReport(byte[] report) { if (report[0] < 0x20) { throw new InvalidOperationException("Received an output report!"); } InputReport type = (InputReport)report[0]; if (type >= InputReport.Buttons && type <= InputReport.ButtonsAccelerometer36IrB) { if (type == InputReport.ButtonsAccelerometer36IrB) { ReportingMode = ReportingMode.ButtonsAccelerometer36Ir; } else { ReportingMode = (ReportingMode)type; } IRMode irMode = GetIrMode(type); if (this._IrMode != irMode) { for (int i = 0; i < _CachedIRBeacons.Length; i++) { BasicIRBeacon newBeacon = null; switch (irMode) { case IRMode.Basic: newBeacon = new BasicIRBeacon(); break; case IRMode.Extended: newBeacon = new ExtendedIRBeacon(); break; case IRMode.Full: newBeacon = new FullIRBeacon(); break; } _CachedIRBeacons[i] = newBeacon; _IRBeacons[i] = null; } this._IrMode = irMode; } } switch (type) { case InputReport.Buttons: ParseButtons(report, 1); break; case InputReport.ButtonsAccelerometer: ParseButtons(report, 1); ParseAccelerometer(report, 3); break; case InputReport.Buttons8Extension: ParseButtons(report, 1); ParseExtension(report, 3, 8); break; case InputReport.ButtonsAccelerometer12Ir: { ParseButtons(report, 1); ParseAccelerometer(report, 3); ExtendedIRBeacon irBeacon; // Parse beacon 0. irBeacon = (ExtendedIRBeacon)_CachedIRBeacons[0]; _IRBeacons[0] = ParseExtendedBeacon(report, 6, irBeacon) ? irBeacon : null; // Parse beacon 1. irBeacon = (ExtendedIRBeacon)_CachedIRBeacons[1]; _IRBeacons[1] = ParseExtendedBeacon(report, 9, irBeacon) ? irBeacon : null; // Parse beacon 2. irBeacon = (ExtendedIRBeacon)_CachedIRBeacons[2]; _IRBeacons[2] = ParseExtendedBeacon(report, 12, irBeacon) ? irBeacon : null; // Parse beacon 3. irBeacon = (ExtendedIRBeacon)_CachedIRBeacons[3]; _IRBeacons[3] = ParseExtendedBeacon(report, 15, irBeacon) ? irBeacon : null; } break; case InputReport.Buttons19Extension: ParseButtons(report, 1); ParseExtension(report, 3, 19); break; case InputReport.ButtonsAccelerometer16Extension: ParseButtons(report, 1); ParseAccelerometer(report, 3); ParseExtension(report, 6, 16); break; case InputReport.Buttons10Ir9Extension: case InputReport.ButtonsAccelerometer10Ir6Extension: { int offset = 1; offset += ParseButtons(report, offset); if (type == InputReport.ButtonsAccelerometer10Ir6Extension) { offset += ParseAccelerometer(report, offset); } BasicIRBeacon irBeacon; // Parse beacon 0. irBeacon = _CachedIRBeacons[0]; _IRBeacons[0] = ParseBasicBeacon(report, offset, 0, irBeacon) ? irBeacon : null; // Parse beacon 1. irBeacon = _CachedIRBeacons[1]; _IRBeacons[1] = ParseBasicBeacon(report, offset, 1, irBeacon) ? irBeacon : null; // Parse beacon 2. irBeacon = _CachedIRBeacons[2]; _IRBeacons[2] = ParseBasicBeacon(report, offset + 5, 0, irBeacon) ? irBeacon : null; // Parse beacon 3. irBeacon = _CachedIRBeacons[3]; _IRBeacons[3] = ParseBasicBeacon(report, offset + 5, 1, irBeacon) ? irBeacon : null; offset += 10; // Each pair of IR-beacons is 5 bytes. if (type == InputReport.ButtonsAccelerometer10Ir6Extension) { ParseExtension(report, offset, 6); } else { ParseExtension(report, offset, 9); } } break; case InputReport.Extension: ParseExtension(report, 1, 21); break; case InputReport.ButtonsAccelerometer36IrA: { ParseButtons(report, 1); // since button information is complete on both the interlaced reports it needs no temporary storage _PartialAccelerometerX = report[3]; _PartialAccelerometerZ = (ushort)(((report[2] & 0x60) << 1) | ((report[1] & 0x60) >> 1)); _PartialIRBeaconOneResult = ParseFullBeacon(report, 4, (FullIRBeacon)_CachedIRBeacons[0]); _PartialIRBeaconTwoResult = ParseFullBeacon(report, 13, (FullIRBeacon)_CachedIRBeacons[1]); } break; case InputReport.ButtonsAccelerometer36IrB: { ParseButtons(report, 1); // Complete the _PartialAccelerometerZ field _PartialAccelerometerZ = (ushort)(_PartialAccelerometerZ | ((report[2] & 60) >> 3) | ((report[1] & 60) >> 5)); // Initialize the accelerometer if it was not yet initialized (should never happen). if (Accelerometer == null) { ReadCalibrationData(); } // Construct the new accelerometer-values from now completed data Accelerometer.Raw.X = _PartialAccelerometerX; Accelerometer.Raw.Y = report[3]; Accelerometer.Raw.Z = _PartialAccelerometerZ; UpdateCalibratedAccelerometer(); FullIRBeacon irBeacon; // Commit partial irbeacon from 'a' report IRBeacons[0] = _PartialIRBeaconOneResult ? _CachedIRBeacons[0] : null; // Commit partial irbeacon from 'a' report IRBeacons[1] = _PartialIRBeaconTwoResult ? _CachedIRBeacons[1] : null; // Parse beacon 2. irBeacon = (FullIRBeacon)_CachedIRBeacons[2]; IRBeacons[2] = ParseFullBeacon(report, 4, irBeacon) ? irBeacon : null; // Parse beacon 3. irBeacon = (FullIRBeacon)_CachedIRBeacons[3]; IRBeacons[3] = ParseFullBeacon(report, 13, irBeacon) ? irBeacon : null; } break; case InputReport.GetStatusResult: ParseButtons(report, 1); ParseStatus(report); break; case InputReport.ReadDataResult: ParseButtons(report, 1); // The rest is handled by the ReadData method (waiting for the report). break; case InputReport.WriteDataResult: // The rest is handled by the WriteData method (waiting for the report). break; default: Debug.WriteLine("Unknown report type: " + type.ToString("x")); return(false); } if ((type >= InputReport.Buttons || type == InputReport.GetStatusResult) && (type != InputReport.ButtonsAccelerometer36IrA)) { OnUpdated(); } return(true); }
/// <summary> /// http://wiibrew.org/index.php?title=Wiimote#Extended_Mode /// </summary> protected static bool ParseExtendedBeacon(byte[] buff, int offset, ExtendedIRBeacon irBeacon) { if (buff[offset + 0] == 0xff && buff[offset + 1] == 0xff && buff[offset + 2] == 0xff) return false; irBeacon.X = buff[offset + 0] | ((buff[offset + 2] >> 4) & 0x03) << 8; irBeacon.Y = buff[offset + 1] | ((buff[offset + 2] >> 6) & 0x03) << 8; irBeacon.Size = buff[offset + 2] & 0x0f; return true; }