Skip to content

Commit

Permalink
Added gamecube support for byte sized packets sent by the NicoHood Ni…
Browse files Browse the repository at this point in the history
…ntendo API

This adds support to reads packets in the form of bytes that are sent from the NicoHood Nintendo API at https://github.com/NicoHood/Nintendo

The reason for this is that when using the above API, it's incredibly time sensitive to write data that is read from the controller to the console, so to save time we just call a single write for each packet (and write the whole gamecube report) via Serial.write(report.raw8, sizeof(report.raw8)).

It however is in a different format, thus the need for the NICOHOOD_BUTTONS setup.

Currently this only supports gamecube input but will be extended to N64 in the near future.
  • Loading branch information
robertvanderaarde committed Sep 2, 2019
1 parent 56f7a76 commit 0e557d9
Showing 1 changed file with 50 additions and 18 deletions.
68 changes: 50 additions & 18 deletions Readers/GameCube.cs
Expand Up @@ -9,38 +9,70 @@ namespace NintendoSpy.Readers
static public class GameCube
{
const int PACKET_SIZE = 64;
const int NICOHOOD_PACKET_SIZE = 8;

static readonly string[] BUTTONS = {
null, null, null, "start", "y", "x", "b", "a", null, "l", "r", "z", "up", "down", "right", "left"
};

static float readStick (byte input) {

// Button order for the Nicohood Nintendo API
// https://github.com/NicoHood/Nintendo
// Each byte is reverse from the buttons above
static readonly string[] NICOHOOD_BUTTONS = {
"a", "b", "x", "y", "start", null, null, null, "left", "right", "down", "up", "z", "r", "l", null
};

static float readStick(byte input)
{
return (float)(input - 128) / 128;
}

static float readTrigger (byte input) {
static float readTrigger(byte input)
{
return (float)(input) / 256;
}

static public ControllerState ReadFromPacket (byte[] packet)
static public ControllerState ReadFromPacket(byte[] packet)
{
if (packet.Length < PACKET_SIZE) return null;

var state = new ControllerStateBuilder ();

for (int i = 0 ; i < BUTTONS.Length ; ++i) {
if (string.IsNullOrEmpty (BUTTONS [i])) continue;
state.SetButton (BUTTONS[i], packet[i] != 0x00);
var state = new ControllerStateBuilder();
switch (packet.Length)
{
// Standard 64 bit packet size
case PACKET_SIZE:
for (int i = 0; i < BUTTONS.Length; ++i)
{
if (string.IsNullOrEmpty(BUTTONS[i])) continue;
state.SetButton(BUTTONS[i], packet[i] != 0x00);
Console.WriteLine(i + ": " + packet[i]);
}
state.SetAnalog("lstick_x", readStick(SignalTool.readByte(packet, BUTTONS.Length)));
state.SetAnalog("lstick_y", readStick(SignalTool.readByte(packet, BUTTONS.Length + 8)));
state.SetAnalog("cstick_x", readStick(SignalTool.readByte(packet, BUTTONS.Length + 16)));
state.SetAnalog("cstick_y", readStick(SignalTool.readByte(packet, BUTTONS.Length + 24)));
state.SetAnalog("trig_l", readTrigger(SignalTool.readByte(packet, BUTTONS.Length + 32)));
state.SetAnalog("trig_r", readTrigger(SignalTool.readByte(packet, BUTTONS.Length + 40)));
break;
// Packets are written as bytes when writing from the NicoHood API, so we're looking for a packet size of 8 (interpreted as bytes)
case NICOHOOD_PACKET_SIZE:
for (int i = 0; i < 16; i++)
{
if (string.IsNullOrEmpty(NICOHOOD_BUTTONS[i])) continue;
int bitPacket = (packet[i / 8] >> (i % 8)) & 0x1;
state.SetButton(NICOHOOD_BUTTONS[i], bitPacket != 0x00);
}
state.SetAnalog("lstick_x", readStick(packet[2]));
state.SetAnalog("lstick_y", readStick(packet[3]));
state.SetAnalog("cstick_x", readStick(packet[4]));
state.SetAnalog("cstick_y", readStick(packet[5]));
state.SetAnalog("trig_l", readTrigger(packet[6]));
state.SetAnalog("trig_r", readTrigger(packet[7]));
break;
default:
return null;
}

state.SetAnalog ("lstick_x", readStick (SignalTool.readByte (packet, BUTTONS.Length )));
state.SetAnalog ("lstick_y", readStick (SignalTool.readByte (packet, BUTTONS.Length + 8)));
state.SetAnalog ("cstick_x", readStick (SignalTool.readByte (packet, BUTTONS.Length + 16)));
state.SetAnalog ("cstick_y", readStick (SignalTool.readByte (packet, BUTTONS.Length + 24)));
state.SetAnalog ("trig_l", readTrigger (SignalTool.readByte (packet, BUTTONS.Length + 32)));
state.SetAnalog ("trig_r", readTrigger (SignalTool.readByte (packet, BUTTONS.Length + 40)));

return state.Build ();
return state.Build();
}
}
}

0 comments on commit 0e557d9

Please sign in to comment.