mirror of
https://github.com/ndeadly/MissionControl
synced 2024-11-22 20:33:07 +00:00
bluetooth-mitm: update amplitude lookup table and clean up rumble code
This commit is contained in:
parent
14146e3d30
commit
b92d4b588b
10 changed files with 39 additions and 103 deletions
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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(); };
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue