Skip to content

Commit

Permalink
Apply special remapping to the NSO N64 controller when reported as Pr…
Browse files Browse the repository at this point in the history
…o Controller.
  • Loading branch information
Banz99 committed Nov 17, 2023
1 parent 8f28dec commit 5ff2af5
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 1 deletion.
57 changes: 56 additions & 1 deletion mc_mitm/source/controllers/forced_pro_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,30 @@

namespace ams::controller {

namespace {

bool ApplyN64Remapping(SwitchButtonData *buttons) {
bool alternatescheme = buttons->Y; //C-Up
buttons->Y = buttons->ZR; //C-Down -> Y
buttons->ZR = buttons->lstick_press; //ZR -> ZR
buttons->lstick_press = 0;
if (alternatescheme) {
buttons->lstick_press = buttons->L; //L -> LEFT STICK PRESS
buttons->rstick_press = buttons->R; //R -> RIGHT STICK PRESS
buttons->L = 0;
buttons->R = 0;
}
return alternatescheme;
}

}

ForcedProController::ForcedProController(const bluetooth::Address *address, HardwareID id)
: SwitchController(address, id) {}
: SwitchController(address, id)
, m_is_n64_controller(false) {
if (m_id.pid == 0x2019)
m_is_n64_controller = true;
}


Result ForcedProController::HandleDataReportEvent(const bluetooth::HidReportEventInfo *event_info) {
Expand Down Expand Up @@ -57,6 +79,31 @@ namespace ams::controller {
std::memcpy(response->data.serial_flash_read.data, data, sizeof(data));
}
}
else if (m_is_n64_controller) {
switch (response->data.serial_flash_read.address) {
case 0x603d: //Factory stick calibration
memcpy(&response->data.serial_flash_read.data[9], &response->data.serial_flash_read.data[3], 3); //Swap calibration triplets for the right stick (https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/spi_flash_notes.md)
memcpy(&m_n64_calibrated_stick_zero, &response->data.serial_flash_read.data[3], 3);
memcpy(&response->data.serial_flash_read.data[12], &response->data.serial_flash_read.data[6], 3);
memcpy(&response->data.serial_flash_read.data[15], &response->data.serial_flash_read.data[0], 3);
break;
case 0x8010: //User stick calibration
if (response->data.serial_flash_read.data[0] != 0xFF && response->data.serial_flash_read.data[1] != 0xFF) {
memcpy(&response->data.serial_flash_read.data[11], &response->data.serial_flash_read.data[0], 2); //Copy magic numbers that signal the presence of a user calibration
memcpy(&response->data.serial_flash_read.data[13], &response->data.serial_flash_read.data[5], 3); //Swap calibration triplets for the right stick
memcpy(&m_n64_calibrated_stick_zero, &response->data.serial_flash_read.data[5], 3);
memcpy(&response->data.serial_flash_read.data[16], &response->data.serial_flash_read.data[8], 3);
memcpy(&response->data.serial_flash_read.data[19], &response->data.serial_flash_read.data[2], 3);
}
break;
case 0x6080: //Left stick parameters (always read first) (first 6 bytes are 6-Axis Horizontal Offsets which we don't need)
memcpy(&m_n64_left_stick_param, &response->data.serial_flash_read.data[6],sizeof(SwitchAnalogStickParameters));
break;
case 0x6098: //Right stick parameters (always read after the left ones)
memcpy(&response->data.serial_flash_read.data, &m_n64_left_stick_param, sizeof(SwitchAnalogStickParameters));
break;
}
}
break;
case HidCommand_GetDeviceInfo:
response->data.get_device_info.type = 0x03;
Expand All @@ -65,6 +112,14 @@ namespace ams::controller {
}
}

if (m_is_n64_controller) {
if (ApplyN64Remapping(&input_report->buttons)) {
input_report->right_stick.SetData(input_report->left_stick.GetX(), input_report->left_stick.GetY());
memcpy(&input_report->left_stick.m_xy, &m_n64_calibrated_stick_zero, 3);
}
else memcpy(&input_report->right_stick.m_xy, &m_n64_calibrated_stick_zero, 3);
}

this->ApplyButtonCombos(&input_report->buttons);

return bluetooth::hid::report::WriteHidDataReport(m_address, &m_input_report);
Expand Down
4 changes: 4 additions & 0 deletions mc_mitm/source/controllers/forced_pro_controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ namespace ams::controller {

Result HandleDataReportEvent(const bluetooth::HidReportEventInfo *event_info);
Result HandleOutputDataReport(const bluetooth::HidReport *report);
private:
bool m_is_n64_controller;
SwitchAnalogStickParameters m_n64_left_stick_param;
uint8_t m_n64_calibrated_stick_zero[3];

};

Expand Down

0 comments on commit 5ff2af5

Please sign in to comment.