Skip to content

Instantly share code, notes, and snippets.

@InvoxiPlayGames
Created January 12, 2022 08:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save InvoxiPlayGames/184b967f1d4c9e5419493bdc77d1bf6a to your computer and use it in GitHub Desktop.
Save InvoxiPlayGames/184b967f1d4c9e5419493bdc77d1bf6a to your computer and use it in GitHub Desktop.
RBWiiKeytarUnderstander.cs - Basic Rock Band 3 Wii Keyboard / Keytar Parser in C#
/*
RBWiiKeytarUnderstander.cs by InvoxiPlayGames 2022
Licensed under WTFPL
Requires LibUsbDotNet NuGet package, licensed under LGPLv3
Use Zadig to install WinUSB or LibUSB drivers for the device
*/
using LibUsbDotNet;
using LibUsbDotNet.Main;
using LibUsbDotNet.WinUsb;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RBWiiKeytarUnderstander
{
internal class Program
{
[Flags]
public enum FaceButtons
{
None,
Key1 = 1,
A = 2,
B = 4,
Key2 = 8
}
[Flags]
public enum SysButtons
{
None = 0,
Minus = 1,
Plus = 2,
Guide = 0x10 // not actually a guide button but idfk what it is
}
public enum DPad
{
North = 0,
NorthEast = 1,
East = 2,
SouthEast = 3,
South = 4,
SouthWest = 5,
West = 6,
NorthWest = 7,
None = 8
}
static void Main(string[] args)
{
UsbDevice keytar = null;
foreach (UsbRegistry device in UsbDevice.AllDevices)
{
// USB\VID_1BAD&PID_3330
if (device.Vid == 0x1BAD && device.Pid == 0x3330)
{
keytar = device.Device;
}
}
if (keytar == null)
{
Console.WriteLine("Could not find Harmonix RB3 Keyboard for Nintendo Wii.");
Console.WriteLine("Press any key to exit...");
Console.ReadKey(true);
return;
}
var reader = keytar.OpenEndpointReader(ReadEndpointID.Ep01);
byte[] readBuffer = new byte[27];
while (true)
{
int bytesRead;
Console.SetCursorPosition(0, 1);
reader.Read(readBuffer, 27, out bytesRead);
Console.WriteLine("Raw Data: " + BitConverter.ToString(readBuffer));
FaceButtons faceButtons = (FaceButtons)readBuffer[0];
Console.WriteLine("Buttons (1): " + faceButtons + " ");
SysButtons systemButtons = (SysButtons)readBuffer[1];
Console.WriteLine("Buttons (2): " + systemButtons + " ");
DPad dpad = (DPad)readBuffer[2];
Console.WriteLine("D-Pad: " + dpad + " ");
bool[] keys = new bool[25];
int appended = (readBuffer[5] << 17) | (readBuffer[6] << 9) | (readBuffer[7] << 1) | (readBuffer[8] >> 7);
int test = 1 << 24;
int key = 0;
for (var i = 0; i < 25; i++)
{
int mask = test >> i;
keys[key++] = (appended & mask) == mask;
}
Console.WriteLine("Keys: " + Convert.ToString(appended, 2).PadLeft(25, '0'));
byte[] velocities = new byte[]
{
(byte)(readBuffer[8] & 0x7F),
(byte)(readBuffer[9] & 0x7F),
(byte)(readBuffer[10] & 0x7F),
(byte)(readBuffer[11] & 0x7F),
(byte)(readBuffer[12] & 0x7F)
};
Console.WriteLine("Velocities: " + velocities.Select(x => x.ToString().PadLeft(3)).Aggregate((x, y) => x + " " + y));
bool overdrive = (readBuffer[13] & 0x80) == 0x80;
Console.WriteLine("Overdrive: " + overdrive);
bool connected = readBuffer[14] > 0; // is this right?
Console.WriteLine("Connected: " + connected);
byte touchStrip = readBuffer[15];
Console.WriteLine("Touch Strip: " + touchStrip.ToString().PadLeft(3));
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment