|
@@ -4,6 +4,7 @@
|
|
|
#include "config.h"
|
|
#include "config.h"
|
|
|
#include "haptics.h"
|
|
#include "haptics.h"
|
|
|
#include "bonds.h"
|
|
#include "bonds.h"
|
|
|
|
|
+#include "rf_link.h"
|
|
|
#include "usb_mount.h"
|
|
#include "usb_mount.h"
|
|
|
#include "usb_tx.h"
|
|
#include "usb_tx.h"
|
|
|
#include <Adafruit_TinyUSB.h>
|
|
#include <Adafruit_TinyUSB.h>
|
|
@@ -222,6 +223,31 @@ static void jcPackStick(uint8_t s[3], int16_t x, int16_t y)
|
|
|
s[1] = (uint8_t)(((Y & 0x0F) << 4) | ((X >> 8) & 0x0F));
|
|
s[1] = (uint8_t)(((Y & 0x0F) << 4) | ((X >> 8) & 0x0F));
|
|
|
s[2] = (uint8_t)((Y >> 4) & 0xFF);
|
|
s[2] = (uint8_t)((Y >> 4) & 0xFF);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+// The Switch battery/connection byte (bat_con) is NOT a 0..8 value in the high nibble. Per hid-nintendo it is:
|
|
|
|
|
+// bits[7:5] = battery capacity (0=empty .. 4=full), bit4 = charging, bit0 = host_powered (USB-powered).
|
|
|
|
|
+// A genuine pad therefore only ever emits the EVEN high-nibble levels 8/6/4/2/0 (full/medium/low/critical/empty)
|
|
|
|
|
+// -- the odd bit (bit4) is reserved for the charging flag. The old code packed a 0..8 value straight into the
|
|
|
|
|
+// high nibble, so any ODD level (1,3,5,7) set bit4 and the console showed the pad as "charging". Here we round
|
|
|
|
|
+// the percentage onto the genuine 5-level scale and return the ready-to-place EVEN nibble {0,2,4,6,8}.
|
|
|
|
|
+static uint8_t jcBatteryNibble(uint8_t bond)
|
|
|
|
|
+{
|
|
|
|
|
+ if (bond >= NSLOT)
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ uint8_t pct = g_battery[bond];
|
|
|
|
|
+ uint8_t cap; // genuine 0..4 capacity
|
|
|
|
|
+ if (pct >= 70)
|
|
|
|
|
+ cap = 4; // full
|
|
|
|
|
+ else if (pct >= 50)
|
|
|
|
|
+ cap = 3; // medium
|
|
|
|
|
+ else if (pct >= 30)
|
|
|
|
|
+ cap = 2; // low
|
|
|
|
|
+ else if (pct >= 10)
|
|
|
|
|
+ cap = 1; // critical
|
|
|
|
|
+ else
|
|
|
|
|
+ cap = 0; // empty
|
|
|
|
|
+ return (uint8_t)(cap << 1); // -> 0,2,4,6,8 (even; leaves bit4 clear)
|
|
|
|
|
+}
|
|
|
// Standard input-report prefix [0..11] (timer, battery/conn, 3 button bytes, both packed sticks, vibrator),
|
|
// Standard input-report prefix [0..11] (timer, battery/conn, 3 button bytes, both packed sticks, vibrator),
|
|
|
// shared by the streamed 0x30 report and the 0x21 subcommand-reply reports the host reads during init.
|
|
// shared by the streamed 0x30 report and the 0x21 subcommand-reply reports the host reads during init.
|
|
|
static void jcInputPrefix(uint8_t slot, uint8_t *out)
|
|
static void jcInputPrefix(uint8_t slot, uint8_t *out)
|
|
@@ -284,16 +310,16 @@ static void jcInputPrefix(uint8_t slot, uint8_t *out)
|
|
|
jc |= codeToJc(g_qamMap, fA, fB, fX, fY);
|
|
jc |= codeToJc(g_qamMap, fA, fB, fX, fY);
|
|
|
out[0] = g_jcTimer[slot]++;
|
|
out[0] = g_jcTimer[slot]++;
|
|
|
|
|
|
|
|
- // battery full+charging (hi nibble 0x9), connection_info=1 (lo nibble): a wired/charging Pro Controller.
|
|
|
|
|
- // A real Switch reads this to show the pad as connected; Steam/hid-nintendo accept it too.
|
|
|
|
|
- out[1] = 0x91;
|
|
|
|
|
|
|
+ // bat_con byte: [7:5]=capacity, bit4=charging, bit0=host_powered (see jcBatteryNibble). The controllers are
|
|
|
|
|
+ // wireless (battery powered) from the console's view, so host_powered=0 -- setting it pins the pad the console
|
|
|
|
|
+ // treats as the wired/primary device in the charging state (the first-enumerated pad showing "charging, 100%").
|
|
|
|
|
+ // The charging flag reflects the controller's REAL EChargeState (2=charging); wireless pads report discharging
|
|
|
|
|
+ // (1) so it stays clear, but a pad genuinely on a charger will show the bolt correctly.
|
|
|
|
|
+ uint8_t chg = (bond < NSLOT && g_batteryState[bond] == 2) ? 0x10 : 0x00;
|
|
|
|
|
+ out[1] = (uint8_t)((jcBatteryNibble(bond) << 4) | chg);
|
|
|
out[2] = (uint8_t)(jc);
|
|
out[2] = (uint8_t)(jc);
|
|
|
out[3] = (uint8_t)(jc >> 8);
|
|
out[3] = (uint8_t)(jc >> 8);
|
|
|
out[4] = (uint8_t)(jc >> 16);
|
|
out[4] = (uint8_t)(jc >> 16);
|
|
|
-
|
|
|
|
|
- // charging_grip bit (button "common" byte, bit7): genuine Pro Controller always sets it on USB; real
|
|
|
|
|
- // Switch uses it to recognise a wired controller. Not a button, so hid-nintendo ignores it.
|
|
|
|
|
- out[3] |= 0x80;
|
|
|
|
|
jcPackStick(out + 5, g_in[bond].lx, g_in[bond].ly);
|
|
jcPackStick(out + 5, g_in[bond].lx, g_in[bond].ly);
|
|
|
jcPackStick(out + 8, g_in[bond].rx, g_in[bond].ry);
|
|
jcPackStick(out + 8, g_in[bond].rx, g_in[bond].ry);
|
|
|
// rumble_input_report echo: genuine pad emits 0x09..0x0C; some Switch firmware expects this nonzero.
|
|
// rumble_input_report echo: genuine pad emits 0x09..0x0C; some Switch firmware expects this nonzero.
|