diff --git a/mc_mitm/source/controllers/dualsense_controller.cpp b/mc_mitm/source/controllers/dualsense_controller.cpp index 7a82d87..78c3f4e 100644 --- a/mc_mitm/source/controllers/dualsense_controller.cpp +++ b/mc_mitm/source/controllers/dualsense_controller.cpp @@ -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(255 * rumble_data->low_band_amp); + m_rumble_state.amp_motor_right = static_cast(255 * rumble_data->high_band_amp); return this->PushRumbleLedState(); } diff --git a/mc_mitm/source/controllers/dualsense_controller.hpp b/mc_mitm/source/controllers/dualsense_controller.hpp index a66a15a..404800f 100644 --- a/mc_mitm/source/controllers/dualsense_controller.hpp +++ b/mc_mitm/source/controllers/dualsense_controller.hpp @@ -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); diff --git a/mc_mitm/source/controllers/dualshock4_controller.cpp b/mc_mitm/source/controllers/dualshock4_controller.cpp index af45908..628ddbe 100644 --- a/mc_mitm/source/controllers/dualshock4_controller.cpp +++ b/mc_mitm/source/controllers/dualshock4_controller.cpp @@ -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(255 * rumble_data->low_band_amp); + m_rumble_state.amp_motor_right = static_cast(255 * rumble_data->high_band_amp); return this->PushRumbleLedState(); } diff --git a/mc_mitm/source/controllers/dualshock4_controller.hpp b/mc_mitm/source/controllers/dualshock4_controller.hpp index 8177498..2c64373 100644 --- a/mc_mitm/source/controllers/dualshock4_controller.hpp +++ b/mc_mitm/source/controllers/dualshock4_controller.hpp @@ -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); diff --git a/mc_mitm/source/controllers/emulated_switch_controller.cpp b/mc_mitm/source/controllers/emulated_switch_controller.cpp index bc254cd..7c309fb 100644 --- a/mc_mitm/source/controllers/emulated_switch_controller.cpp +++ b/mc_mitm/source/controllers/emulated_switch_controller.cpp @@ -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(((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(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) { diff --git a/mc_mitm/source/controllers/emulated_switch_controller.hpp b/mc_mitm/source/controllers/emulated_switch_controller.hpp index c09f8a8..053f555 100644 --- a/mc_mitm/source/controllers/emulated_switch_controller.hpp +++ b/mc_mitm/source/controllers/emulated_switch_controller.hpp @@ -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(); }; diff --git a/mc_mitm/source/controllers/wii_controller.cpp b/mc_mitm/source/controllers/wii_controller.cpp index e5d2703..60f6d0c 100644 --- a/mc_mitm/source/controllers/wii_controller.cpp +++ b/mc_mitm/source/controllers/wii_controller.cpp @@ -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(s_output_report.data); diff --git a/mc_mitm/source/controllers/wii_controller.hpp b/mc_mitm/source/controllers/wii_controller.hpp index 9b5e917..762ed52 100644 --- a/mc_mitm/source/controllers/wii_controller.hpp +++ b/mc_mitm/source/controllers/wii_controller.hpp @@ -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); diff --git a/mc_mitm/source/controllers/xbox_one_controller.cpp b/mc_mitm/source/controllers/xbox_one_controller.cpp index 91b879b..f6d0edb 100644 --- a/mc_mitm/source/controllers/xbox_one_controller.cpp +++ b/mc_mitm/source/controllers/xbox_one_controller.cpp @@ -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(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(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(100 * 0.5 * (left->high_band_amp + right->high_band_amp) / UINT8_MAX); + report->output0x03.magnitude_strong = static_cast(100 * rumble_data->low_band_amp); + report->output0x03.magnitude_weak = static_cast(100 * rumble_data->high_band_amp); report->output0x03.pulse_sustain_10ms = 1; report->output0x03.pulse_release_10ms = 0; report->output0x03.loop_count = 0; diff --git a/mc_mitm/source/controllers/xbox_one_controller.hpp b/mc_mitm/source/controllers/xbox_one_controller.hpp index 4f6b090..12d9194 100644 --- a/mc_mitm/source/controllers/xbox_one_controller.hpp +++ b/mc_mitm/source/controllers/xbox_one_controller.hpp @@ -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: