bluetooth-mitm: update amplitude lookup table and clean up rumble code

This commit is contained in:
ndeadly 2021-03-16 00:09:21 +01:00
parent 14146e3d30
commit b92d4b588b
10 changed files with 39 additions and 103 deletions

View file

@ -22,11 +22,6 @@ namespace ams::controller {
const constexpr float stick_scale_factor = float(UINT12_MAX) / UINT8_MAX;
constexpr uint8_t min_rumble_lf = 0x01;
constexpr uint8_t max_rumble_lf = 0x5f;
constexpr uint8_t min_rumble_hf = 0x30;
constexpr uint8_t max_rumble_hf = 0xbf;
const uint8_t player_led_flags[] = {
// Mimic the Switch's player LEDs
0x01,
@ -61,9 +56,9 @@ namespace ams::controller {
return ams::ResultSuccess();
}
Result DualsenseController::SetVibration(const SwitchRumbleData *left, const SwitchRumbleData *right) {
m_rumble_state.amp_motor_left = ScaleRumbleAmplitude(left->low_band_amp, min_rumble_lf, max_rumble_lf); //left->low_band_amp; //(left->low_band_amp + left->high_band_amp) >> 1;
m_rumble_state.amp_motor_right = ScaleRumbleAmplitude(left->high_band_amp, min_rumble_hf, max_rumble_hf); //(right->low_band_amp + right->high_band_amp) >> 1;
Result DualsenseController::SetVibration(const SwitchRumbleData *rumble_data) {
m_rumble_state.amp_motor_left = static_cast<uint8_t>(255 * rumble_data->low_band_amp);
m_rumble_state.amp_motor_right = static_cast<uint8_t>(255 * rumble_data->high_band_amp);
return this->PushRumbleLedState();
}

View file

@ -121,7 +121,7 @@ namespace ams::controller {
, m_rumble_state({0, 0}) { };
Result Initialize(void);
Result SetVibration(const SwitchRumbleData *left, const SwitchRumbleData *right);
Result SetVibration(const SwitchRumbleData *rumble_data);
Result CancelVibration(void);
Result SetPlayerLed(uint8_t led_mask);
Result SetLightbarColour(RGBColour colour);

View file

@ -24,11 +24,6 @@ namespace ams::controller {
const constexpr float stick_scale_factor = float(UINT12_MAX) / UINT8_MAX;
constexpr uint8_t min_rumble_lf = 0x01;
constexpr uint8_t max_rumble_lf = 0x5f;
constexpr uint8_t min_rumble_hf = 0x30;
constexpr uint8_t max_rumble_hf = 0xbf;
const RGBColour player_led_colours[] = {
// Same colours used by PS4
{0x00, 0x00, 0x40}, // blue
@ -51,9 +46,9 @@ namespace ams::controller {
return ams::ResultSuccess();
}
Result Dualshock4Controller::SetVibration(const SwitchRumbleData *left, const SwitchRumbleData *right) {
m_rumble_state.amp_motor_left = ScaleRumbleAmplitude(left->low_band_amp, min_rumble_lf, max_rumble_lf); //left->low_band_amp; //(left->low_band_amp + left->high_band_amp) >> 1;
m_rumble_state.amp_motor_right = ScaleRumbleAmplitude(left->high_band_amp, min_rumble_hf, max_rumble_hf); //(right->low_band_amp + right->high_band_amp) >> 1;
Result Dualshock4Controller::SetVibration(const SwitchRumbleData *rumble_data) {
m_rumble_state.amp_motor_left = static_cast<uint8_t>(255 * rumble_data->low_band_amp);
m_rumble_state.amp_motor_right = static_cast<uint8_t>(255 * rumble_data->high_band_amp);
return this->PushRumbleLedState();
}

View file

@ -135,7 +135,7 @@ namespace ams::controller {
, m_rumble_state({0, 0}) { };
Result Initialize(void);
Result SetVibration(const SwitchRumbleData *left, const SwitchRumbleData *right);
Result SetVibration(const SwitchRumbleData *rumble_data);
Result CancelVibration(void);
Result SetPlayerLed(uint8_t led_mask);
Result SetLightbarColour(RGBColour colour);

View file

@ -22,6 +22,7 @@ namespace ams::controller {
namespace {
// Frequency in Hz rounded to nearest int
// https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/rumble_data_table.md#frequency-table
const uint16_t rumble_freq_lut[] = {
0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031,
0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0039, 0x003a, 0x003b,
@ -43,73 +44,26 @@ namespace ams::controller {
0x0464, 0x047d, 0x0496, 0x04af, 0x04ca, 0x04e5
};
// Amplitude range scaled between 0-255
/*
const uint8_t rumble_amp_lut[] = {
0x00, 0x02, 0x03, 0x04, 0x04, 0x05, 0x06, 0x07, 0x09, 0x0a, 0x0c, 0x0e,
0x11, 0x14, 0x18, 0x1d, 0x1e, 0x1f, 0x21, 0x22, 0x24, 0x25, 0x27, 0x29,
0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x35, 0x37, 0x39, 0x3b, 0x3c, 0x3d, 0x3f,
0x40, 0x41, 0x43, 0x44, 0x46, 0x47, 0x49, 0x4a, 0x4c, 0x4e, 0x4f, 0x51,
0x53, 0x55, 0x57, 0x58, 0x5a, 0x5c, 0x5e, 0x60, 0x63, 0x65, 0x67, 0x69,
0x6c, 0x6e, 0x70, 0x73, 0x75, 0x78, 0x7a, 0x7d, 0x80, 0x83, 0x86, 0x88,
0x8b, 0x8e, 0x92, 0x95, 0x98, 0x9b, 0x9f, 0xa2, 0xa6, 0xa9, 0xad, 0xb1,
0xb5, 0xb9, 0xbd, 0xc1, 0xc5, 0xca, 0xce, 0xd2, 0xd7, 0xdc, 0xe1, 0xe5,
0xeb, 0xf0, 0xf5, 0xfa, 0xff
};
*/
// Amplitude range with scaling function applied
// y = static_cast<uint8_t>(((x + powf(x, 0.2)) / 2.0) * 255.0)
const uint8_t rumble_amp_lut[] = {
0x00, 0x31, 0x35, 0x38, 0x3a, 0x3c, 0x3f, 0x41, 0x44, 0x47, 0x4b, 0x4e,
0x52, 0x56, 0x5b, 0x60, 0x61, 0x63, 0x64, 0x66, 0x67, 0x69, 0x6a, 0x6c,
0x6e, 0x6f, 0x71, 0x73, 0x75, 0x77, 0x79, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0x80, 0x81, 0x82, 0x83, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8b, 0x8c, 0x8d,
0x8f, 0x90, 0x91, 0x93, 0x94, 0x96, 0x97, 0x99, 0x9a, 0x9c, 0x9d, 0x9f,
0xa0, 0xa2, 0xa4, 0xa5, 0xa7, 0xa9, 0xab, 0xac, 0xae, 0xb0, 0xb2, 0xb4,
0xb6, 0xb8, 0xba, 0xbc, 0xbe, 0xc0, 0xc3, 0xc5, 0xc7, 0xc9, 0xcc, 0xce,
0xd1, 0xd3, 0xd6, 0xd8, 0xdb, 0xde, 0xe0, 0xe3, 0xe6, 0xe9, 0xec, 0xef,
0xf2, 0xf5, 0xf8, 0xfb, 0xff,
};
// Raw floats from dekunukem github
/*
// Floats from dekunukem repo normalised and scaled by function used by yuzu
// https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/rumble_data_table.md#amplitude-table
// https://github.com/yuzu-emu/yuzu/blob/d3a4a192fe26e251f521f0311b2d712f5db9918e/src/input_common/sdl/sdl_impl.cpp#L429
const float rumble_amp_lut_f[] = {
0.000000, 0.007843, 0.011823, 0.014061, 0.016720, 0.019885, 0.023648,
0.028123, 0.033442, 0.039771, 0.047296, 0.056246, 0.066886, 0.079542,
0.094592, 0.112491, 0.117471, 0.122671, 0.128102, 0.133774, 0.139697,
0.145882, 0.152341, 0.159085, 0.166129, 0.173484, 0.181166, 0.189185,
0.197561, 0.206308, 0.215442, 0.224982, 0.229908, 0.234943, 0.240087,
0.245345, 0.250715, 0.256206, 0.261816, 0.267549, 0.273407, 0.279394,
0.285514, 0.291765, 0.298154, 0.304681, 0.311353, 0.318171, 0.325138,
0.332258, 0.339534, 0.346969, 0.354566, 0.362331, 0.370265, 0.378372,
0.386657, 0.395124, 0.403777, 0.412619, 0.421652, 0.430885, 0.440321,
0.449964, 0.459817, 0.469885, 0.480174, 0.490689, 0.501433, 0.512413,
0.523633, 0.535100, 0.546816, 0.558790, 0.571027, 0.583530, 0.596307,
0.609365, 0.622708, 0.636344, 0.650279, 0.664518, 0.679069, 0.693939,
0.709133, 0.724662, 0.740529, 0.756745, 0.773316, 0.790249, 0.807554,
0.825237, 0.843307, 0.861772, 0.880643, 0.899928, 0.919633, 0.939771,
0.960348, 0.981378, 1.002867
};
*/
0.000000, 0.120576, 0.137846, 0.146006, 0.154745, 0.164139, 0.174246,
0.185147, 0.196927, 0.209703, 0.223587, 0.238723, 0.255268, 0.273420,
0.293398, 0.315462, 0.321338, 0.327367, 0.333557, 0.339913, 0.346441,
0.353145, 0.360034, 0.367112, 0.374389, 0.381870, 0.389564, 0.397476,
0.405618, 0.413996, 0.422620, 0.431501, 0.436038, 0.440644, 0.445318,
0.450062, 0.454875, 0.459764, 0.464726, 0.469763, 0.474876, 0.480068,
0.485342, 0.490694, 0.496130, 0.501649, 0.507256, 0.512950, 0.518734,
0.524609, 0.530577, 0.536639, 0.542797, 0.549055, 0.555413, 0.561872,
0.568436, 0.575106, 0.581886, 0.588775, 0.595776, 0.602892, 0.610127,
0.617482, 0.624957, 0.632556, 0.640283, 0.648139, 0.656126, 0.664248,
0.672507, 0.680906, 0.689447, 0.698135, 0.706971, 0.715957, 0.725098,
0.734398, 0.743857, 0.753481, 0.763273, 0.773235, 0.783370, 0.793684,
0.804178, 0.814858, 0.825726, 0.836787, 0.848044, 0.859502, 0.871165,
0.883035, 0.895119, 0.907420, 0.919943, 0.932693, 0.945673, 0.958889,
0.972345, 0.986048, 1.000000
// Above floats scaled by yuzu function
const float rumble_amp_lut_f[] = {
0.000000, 0.193414, 0.211610, 0.219983, 0.228816, 0.238172, 0.248099,
0.258665, 0.269941, 0.282030, 0.295028, 0.309064, 0.324277, 0.340847,
0.358972, 0.378893, 0.384185, 0.389610, 0.395176, 0.400887, 0.406749,
0.412766, 0.418945, 0.425292, 0.431815, 0.438519, 0.445413, 0.452500,
0.459793, 0.467298, 0.475023, 0.482979, 0.487045, 0.491172, 0.495360,
0.499613, 0.503928, 0.508311, 0.512760, 0.517278, 0.521865, 0.526524,
0.531257, 0.536062, 0.540943, 0.545900, 0.550937, 0.556054, 0.561253,
0.566536, 0.571904, 0.577359, 0.582902, 0.588537, 0.594264, 0.600084,
0.606001, 0.612016, 0.618132, 0.624351, 0.630671, 0.637100, 0.643638,
0.650287, 0.657049, 0.663926, 0.670921, 0.678037, 0.685275, 0.692639,
0.700131, 0.707754, 0.715510, 0.723403, 0.731435, 0.739608, 0.747926,
0.756393, 0.765010, 0.773782, 0.782712, 0.791802, 0.801056, 0.810477,
0.820069, 0.829837, 0.839782, 0.849910, 0.860224, 0.870727, 0.881424,
0.892319, 0.903416, 0.914719, 0.926234, 0.937964, 0.949912, 0.962086,
0.974488, 0.987125, 1.000000
};
inline void DecodeRumbleValues(const uint8_t enc[], SwitchRumbleData *dec) {
@ -240,13 +194,10 @@ namespace ams::controller {
auto report_data = reinterpret_cast<const SwitchReportData *>(report->data);
SwitchRumbleData left_motor;
DecodeRumbleValues(report_data->output0x10.left_motor, &left_motor);
SwitchRumbleData rumble_data;
DecodeRumbleValues(report_data->output0x10.left_motor, &rumble_data);
SwitchRumbleData right_motor;
DecodeRumbleValues(report_data->output0x10.right_motor, &right_motor);
return this->SetVibration(&left_motor, &right_motor);
return this->SetVibration(&rumble_data);
}
Result EmulatedSwitchController::SubCmdRequestDeviceInfo(const bluetooth::HidReport *report) {

View file

@ -36,7 +36,7 @@ namespace ams::controller {
void ClearControllerState(void);
virtual void UpdateControllerState(const bluetooth::HidReport *report) {};
virtual Result SetVibration(const SwitchRumbleData *left, const SwitchRumbleData *right) { return ams::ResultSuccess(); };
virtual Result SetVibration(const SwitchRumbleData *rumble_data) { return ams::ResultSuccess(); };
virtual Result CancelVibration(void) { return ams::ResultSuccess(); };
virtual Result SetPlayerLed(uint8_t led_mask) { return ams::ResultSuccess(); };

View file

@ -347,8 +347,8 @@ namespace ams::controller {
return bluetooth::hid::report::SendHidReport(&m_address, &s_output_report);
}
Result WiiController::SetVibration(const SwitchRumbleData *left, const SwitchRumbleData *right) {
m_rumble_state = left->low_band_amp > 0 || left->high_band_amp > 0;
Result WiiController::SetVibration(const SwitchRumbleData *rumble_data) {
m_rumble_state = rumble_data->low_band_amp > 0 || rumble_data->high_band_amp > 0;
s_output_report.size = sizeof(WiiOutputReport0x10) + 1;
auto report_data = reinterpret_cast<WiiReportData *>(s_output_report.data);

View file

@ -299,7 +299,7 @@ namespace ams::controller {
, m_rumble_state(0) { };
Result Initialize(void);
Result SetVibration(const SwitchRumbleData *left, const SwitchRumbleData *right);
Result SetVibration(const SwitchRumbleData *rumble_data);
Result CancelVibration(void);
Result SetPlayerLed(uint8_t led_mask);
void UpdateControllerState(const bluetooth::HidReport *report);

View file

@ -20,23 +20,18 @@
namespace ams::controller {
namespace {
constexpr float stick_scale_factor = float(UINT12_MAX) / UINT16_MAX;
constexpr uint8_t min_rumble_lf = 0x03;
constexpr uint8_t max_rumble_lf = 0x5f;
constexpr uint8_t min_rumble_hf = 0x10; //0x03;
constexpr uint8_t max_rumble_hf = 0xbf; //0x7f;
constexpr float stick_scale_factor = float(UINT12_MAX) / UINT16_MAX;
}
Result XboxOneController::SetVibration(const SwitchRumbleData *left, const SwitchRumbleData *right) {
Result XboxOneController::SetVibration(const SwitchRumbleData *rumble_data) {
auto report = reinterpret_cast<XboxOneReportData *>(s_output_report.data);
s_output_report.size = sizeof(XboxOneOutputReport0x03) + 1;
report->id = 0x03;
report->output0x03.enable = 0x3;
report->output0x03.magnitude_strong = ScaleRumbleAmplitude(left->low_band_amp, min_rumble_lf, max_rumble_lf); //left->low_band_amp; //static_cast<uint8_t>(100 * 0.5 * (left->low_band_amp + left->high_band_amp) / UINT8_MAX);
report->output0x03.magnitude_weak = ScaleRumbleAmplitude(left->high_band_amp, min_rumble_hf, max_rumble_hf); //left->high_band_amp; //static_cast<uint8_t>(100 * 0.5 * (left->high_band_amp + right->high_band_amp) / UINT8_MAX);
report->output0x03.magnitude_strong = static_cast<uint8_t>(100 * rumble_data->low_band_amp);
report->output0x03.magnitude_weak = static_cast<uint8_t>(100 * rumble_data->high_band_amp);
report->output0x03.pulse_sustain_10ms = 1;
report->output0x03.pulse_release_10ms = 0;
report->output0x03.loop_count = 0;

View file

@ -134,7 +134,7 @@ namespace ams::controller {
XboxOneController(const bluetooth::Address *address)
: EmulatedSwitchController(address) { };
Result SetVibration(const SwitchRumbleData *left, const SwitchRumbleData *right);
Result SetVibration(const SwitchRumbleData *rumble_data);
void UpdateControllerState(const bluetooth::HidReport *report);
private: