diff --git a/Source/Plugins/Plugin_Wiimote/Src/DataReports.cpp b/Source/Plugins/Plugin_Wiimote/Src/DataReports.cpp index d9a4a8676f..c13485ba3f 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/DataReports.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/DataReports.cpp @@ -239,12 +239,18 @@ void SendReportCoreAccelIr10Ext(u16 _channelID) FillReportInfo(pReport->c); FillReportAcc(pReport->a); FillReportIRBasic(pReport->ir[0], pReport->ir[1]); - if ((WiiMapping[g_ID].bMotionPlusConnected) && (( WiiMapping[g_ID].iExtensionConnected == EXT_NUNCHUK ) || (WiiMapping[g_ID].iExtensionConnected == EXT_NONE)) ) + if ((WiiMapping[g_ID].bMotionPlusConnected) ) { if(WiiMapping[g_ID].iExtensionConnected == EXT_NUNCHUK) { - FillReportMotionPlus(pReport->ext, true); - + if (g_RegExt[g_ID][0xFF] == 0x05) { + FillReportMotionPlus(pReport->ext, true); + } + else { + FillReportExtension(pReport->ext); + } + DEBUG_LOG(WIIMOTE, "Motionplus:Nunchuk data -> ext:%01x mp:%01x [ff:0x%02x]", (pReport->ext.az &0x01), (pReport->ext.bt &0x02),g_RegExt[g_ID][0xFF]); + } else if (WiiMapping[g_ID].iExtensionConnected == EXT_NONE) { diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.cpp b/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.cpp index a72871d96f..4388dbd018 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.cpp @@ -47,12 +47,12 @@ u8 g_Speaker[MAX_WIIMOTES]; u8 g_MotionPlus[MAX_WIIMOTES]; u8 g_SpeakerMute[MAX_WIIMOTES]; +u8 g_MotionPlusLastWriteReg[MAX_WIIMOTES]; int g_MotionPlusReadError[MAX_WIIMOTES]; u8 g_RegExtTmp[WIIMOTE_REG_EXT_SIZE]; int g_ID; // Current refreshing Wiimote bool g_ReportingAuto[MAX_WIIMOTES]; // Auto report or passive report -bool g_MotionPlusConnected[MAX_WIIMOTES]; //MotionPlusinitiated bool g_InterleavedData[MAX_WIIMOTES]; //sending alternated data packets from the nunchuk/motionplus u8 g_ReportingMode[MAX_WIIMOTES]; // The reporting mode and channel id u16 g_ReportingChannel[MAX_WIIMOTES]; diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.h b/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.h index 79ef3f9ee3..27ef8a990b 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.h +++ b/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.h @@ -87,8 +87,10 @@ extern u8 g_IR[MAX_WIIMOTES]; extern u8 g_Leds[MAX_WIIMOTES]; extern u8 g_Speaker[MAX_WIIMOTES]; extern u8 g_MotionPlus[MAX_WIIMOTES]; +extern u8 g_MotionPlusLastWriteReg[MAX_WIIMOTES]; extern u8 g_SpeakerMute[MAX_WIIMOTES]; + extern int g_MotionPlusReadError[MAX_WIIMOTES]; extern u8 g_RegExtTmp[WIIMOTE_REG_EXT_SIZE]; @@ -119,13 +121,13 @@ static const u8 EepromData_16D0[] = { static const u8 motionplus_register[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0x79, 0x83, 0x73, 0x54, 0x72, 0xE8, 0x30, 0xC3, 0xCC, 0x4A, 0x34, 0xFC, 0xC8, 0x4F, 0xCC, 0x5B, -0x77, 0x49, 0x75, 0xA4, 0x73, 0x9A, 0x35, 0x52, 0xCA, 0x22, 0x37, 0x26, 0x2D, 0xE5, 0xB5, 0xA2, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0x78, 0x76, 0xDD, 0xF5, 0x6A, 0x3C, 0xCF, 0xF7, 0x2A, 0x0E, 0x32, 0xEE, 0x82, 0xFE, 0x2E, 0xFD, -0x19, 0xE7, 0x0A, 0xCA, 0x67, 0x3B, 0x3A, 0x75, 0xF6, 0x45, 0x55, 0x8E, 0x9D, 0x33, 0xCC, 0xEA, -0x6E, 0x52, 0xC6, 0xC6, 0x16, 0x9B, 0xEE, 0x12, 0x2E, 0x3F, 0x77, 0xB1, 0xA1, 0x80, 0x0B, 0x0E, -0xC2, 0x25, 0x05, 0xEA, 0xC3, 0x2F, 0x85, 0x1E, 0x31, 0x53, 0x74, 0xC7, 0xF1, 0x93, 0xF1, 0x2D, +0x79, 0x83, 0x73, 0x54, 0x72, 0xE8, 0x30, 0xC3, 0xCC, 0x4A, 0x34, 0xFC, 0xC8, 0x4F, 0xCC, 0x5B, //MP calibration data +0x77, 0x49, 0x75, 0xA4, 0x73, 0x9A, 0x35, 0x52, 0xCA, 0x22, 0x37, 0x26, 0x2D, 0xE5, 0xB5, 0xA2, //MP calibration data +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, //Extensions(NC) calibration data +0x1e, 0x54, 0x74, 0xa2, 0x96, 0xec, 0x2b, 0xd6, 0xe1, 0xef, 0xc3, 0xf7, 0x84, 0x9e, 0x06, 0xbb, +0x39, 0x33, 0x3d, 0x20, 0x97, 0xed, 0x75, 0x52, 0xfd, 0x98, 0xaf, 0xd8, 0xc9, 0x5a, 0x17, 0x23, +0x74, 0x3a, 0x49, 0xd3, 0xb9, 0xf6, 0xff, 0x4f, 0x34, 0xa8, 0x6d, 0xc4, 0x96, 0x5c, 0xcd, 0xb2, +0x33, 0x78, 0x98, 0xe9, 0xa9, 0x7f, 0xf7, 0x5e, 0x07, 0x87, 0xbb, 0x29, 0x01, 0x2b, 0x70, 0x3f, 0xC1, 0x6D, 0x84, 0x2A, 0xD8, 0x6F, 0x8A, 0xE5, 0x2D, 0x3B, 0x7B, 0xCC, 0xD2, 0x59, 0xD5, 0xD1, 0x9F, 0x5B, 0x6F, 0xAE, 0x82, 0xDE, 0xEA, 0xC3, 0x73, 0x42, 0x06, 0xA9, 0x77, 0xFF, 0x61, 0xA8, 0x1A, 0x70, 0xE4, 0x16, 0x90, 0x7A, 0x80, 0xF7, 0x79, 0x4B, 0x41, 0x18, 0x82, 0x6C, 0x62, 0x1A, @@ -174,9 +176,10 @@ static const u8 gh3glp_id[] = { 0x00, 0x00, 0xa4, 0x20, 0x01, 0x03 }; static const u8 ghwtdrums_id[] = { 0x01, 0x00, 0xa4, 0x20, 0x01, 0x03 }; static const u8 wbb_id[] = { 0x00, 0x00, 0xa4, 0x20, 0x4, 0x02 }; static const u8 motionplus_id[] = { 0x00, 0x00, 0xa4, 0x20, 0x04, 0x05 }; -static const u8 motionplusnunchuk_id[] = { 0x00, 0x00, 0xa4, 0x20, 0x05, 0x05 }; +static const u8 motionplusnunchuk_id[] = { 0x00, 0x00, 0xa6, 0x20, 0x05, 0x05 }; //initial control packet for datatransfers over 0x37 reports -static const u8 motionpluscheck_id[] = { 0xa3, 0x62, 0x45, 0xaa, 0x04, 0x02}; +static const u8 motionpluscheck_id[] = { 0xa3, 0x62, 0x45, 0xaa, 0x04, 0x02}; +static const u8 motionpluscheck_id2[] = { 0x39, 0xcd, 0x3f, 0x9a, 0x4b, 0x02}; // The id for nothing inserted static const u8 nothing_id[] = { 0x00, 0x00, 0x00, 0x00, 0x2e, 0x2e }; // The id for a partially inserted extension diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp index 0b9ea0f8f5..50e2b8875c 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp @@ -39,6 +39,7 @@ namespace WiiMoteEmu // Settings accel_cal g_wm; nu_cal g_nu; +mp_cal g_mp[2]; //fast[0] and slow[01]-motion cc_cal g_ClassicContCalibration; gh3_cal g_GH3Calibration; @@ -417,6 +418,7 @@ void ResetVariables() { g_ReportingAuto[i] = false; g_MotionPlusReadError[i] = 0; + g_MotionPlusLastWriteReg[i] = 0; g_InterleavedData[i] = false; g_ReportingMode[i] = 0; g_ReportingChannel[i] = 0; @@ -458,6 +460,13 @@ void InitCalibration() g_nu.cal_g.y = nunchuck_calibration[0x05] - nunchuck_calibration[0x01]; g_nu.cal_g.z = nunchuck_calibration[0x06] - nunchuck_calibration[0x02]; + g_mp[0].cal_zero.x = ((motion_plus_calibration[0x00]<<6) + (motion_plus_calibration[0x01]>>2)); + g_mp[0].cal_zero.y = ((motion_plus_calibration[0x02]<<6) + (motion_plus_calibration[0x03]>>2)); + g_mp[0].cal_zero.z = ((motion_plus_calibration[0x04]<<6) + (motion_plus_calibration[0x05]>>2)); + g_mp[1].cal_zero.x = ((motion_plus_calibration[0x10]<<6) + (motion_plus_calibration[0x11]>>2)); + g_mp[1].cal_zero.y = ((motion_plus_calibration[0x12]<<6) + (motion_plus_calibration[0x13]>>2)); + g_mp[1].cal_zero.z = ((motion_plus_calibration[0x14]<<6) + (motion_plus_calibration[0x15]>>2)); + g_nu.jx.max = nunchuck_calibration[0x08]; g_nu.jx.min = nunchuck_calibration[0x09]; g_nu.jx.center = nunchuck_calibration[0x0a]; @@ -500,26 +509,28 @@ void UpdateExtRegisterBlocks(int Slot) if (WiiMapping[Slot].iExtensionConnected == EXT_NONE) { memset(g_RegExt[Slot],0,sizeof(g_RegExt[0])); - memcpy(g_RegMotionPlus[Slot], motionplus_register, sizeof(motionplus_register)); - memcpy(g_RegMotionPlus[Slot] + 0x20, motion_plus_calibration, sizeof(motion_plus_calibration)); //reg 32bytes 0x20-3f; - g_MotionPlus[Slot] = 0; - //memcpy(g_RegMotionPlus[Slot] + 0xfa, motionplus_id, sizeof(motionplus_id)); + memcpy(g_RegExt[Slot], motionplus_register, sizeof(motionplus_register)); + memcpy(g_RegExt[Slot] + 0x20, motion_plus_calibration, sizeof(motion_plus_calibration)); //reg 32bytes 0x20-3f; + memcpy(g_RegExt[Slot] + 0xfa, motionplus_id, sizeof(motionplus_id)); + g_MotionPlus[Slot] = 1; } else if(WiiMapping[Slot].iExtensionConnected == EXT_NUNCHUK) { memset(g_RegMotionPlus[Slot],0,sizeof(g_RegExt[0])); memcpy(g_RegMotionPlus[Slot], motionplus_register, sizeof(motionplus_register)); memcpy(g_RegMotionPlus[Slot] + 0x20, motion_plus_calibration, sizeof(motion_plus_calibration)); //reg 32bytes 0x20-3f; + memcpy(g_RegMotionPlus[Slot] + 0x40, nunchuck_calibration, sizeof(nunchuck_calibration)); + memcpy(g_RegMotionPlus[Slot] + 0xfa, motionplusnunchuk_id, sizeof(motionplusnunchuk_id)); memcpy(g_RegExt[Slot] + 0x20, nunchuck_calibration, sizeof(nunchuck_calibration)); memcpy(g_RegExt[Slot] + 0x30, nunchuck_calibration, sizeof(nunchuck_calibration)); memcpy(g_RegExt[Slot] + 0xfa, nunchuck_id, sizeof(nunchuck_id)); - g_MotionPlus[Slot] = 1; + + g_MotionPlus[Slot] = 0; } g_MotionPlusReadError[Slot] = 0; } else { - // Copy extension id and calibration to its register if(WiiMapping[Slot].iExtensionConnected == EXT_NUNCHUK) { diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.h b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.h index 2ed16a7520..670aa79239 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.h +++ b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.h @@ -33,6 +33,7 @@ namespace WiiMoteEmu // Settings extern accel_cal g_wm; extern nu_cal g_nu; +extern mp_cal g_mp[2]; extern cc_cal g_ClassicContCalibration; extern gh3_cal g_GH3Calibration; diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuSubroutines.cpp b/Source/Plugins/Plugin_Wiimote/Src/EmuSubroutines.cpp index f25f13bd41..e3e157d439 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/EmuSubroutines.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/EmuSubroutines.cpp @@ -227,7 +227,6 @@ void WmReadData(u16 _channelID, wm_read_data* rd) DEBUG_LOG(WIIMOTE, " Case 0xa4: ExtReg"); break; - // MotionPlus is pretty much just a dummy atm :p case 0xA6: block = g_RegMotionPlus[g_ID]; blockSize = WIIMOTE_REG_EXT_SIZE; @@ -270,10 +269,7 @@ void WmReadData(u16 _channelID, wm_read_data* rd) PanicAlert("WmReadData: address + size out of bounds! [%d %d %d]", address, size, blockSize); return; } - //3x read error due activated(or not present device, which is not the case), WII will await a status report after init and attempting to read from write-only area @A600FE/FF - if ((g_MotionPlusReadError[g_ID] == 2) && (g_RegExt[g_ID][0xFF]== 0x05)) { //if motionplus is active, its in the current ExtReg, 0xFF will be always 0x05 - WmRequestStatus(_channelID, (wm_request_status*) rd, 1); - } + // Let this function process the message and send it to the Wii SendReadDataReply(_channelID, block + address, address, addressHI, (u8)size); @@ -341,21 +337,18 @@ void SendReadDataReply(u16 _channelID, void* _Base, u16 _Address, u8 _AddressHI, pReply->size = 0x0f; pReply->error = 0x08; } + if (WiiMapping[g_ID].bMotionPlusConnected) { //MP+ will try to read from this Registeraddress, expecting an error if a previous WM+ activation has been succesful - //it also returns an error if there was no WM+ present at all - if (((_Address == 0x00FE ) || (_Address == 0x00FF )) && (_AddressHI == 0xA6)) + //It will also return an error if there was no WM+ present at all + if (((_Address == 0x00FE ) || (_Address == 0x00FF )) && (_AddressHI == 0xA6) && (g_RegExt[g_ID][0xFF] == 0x05)) { - //Check if MP+ is activated, resp. if its in the current RegExt. - if ((g_RegExt[g_ID][0xFF] == 0x05) && (g_RegMotionPlus[g_ID][0xFF] != 0x05)) - { pReply->size = 0x0f; pReply->error = 0x07; //error: write-only area when activated/or not present // we use the read error at the same time as an indicator whether we need to send a faked 0x37 report or not g_MotionPlusReadError[g_ID]++; - - } + } } @@ -458,9 +451,33 @@ void WmWriteData(u16 _channelID, wm_write_data* wd) // that we send it parts of a key, only the last full key will have an effect if(address >= 0x40 && address <= 0x4c) wiimote_gen_key(&g_ExtKey[g_ID], &g_RegExt[g_ID][0x40]); + } if (WiiMapping[g_ID].bMotionPlusConnected) { - HandlingMotionPlusWrites(wd->data, addressHI, address); + //If the MP+ gets activated, it's important to send a status report if there's another extension connected to MP + int sendreport = HandlingMotionPlusWrites(wd->data, addressHI, address); + g_MotionPlusLastWriteReg[g_ID] = address; + + switch (sendreport) + { + //reconnect device; unplug old extension && plug in new extension + case 1: + WmRequestStatus(_channelID, (wm_request_status*) wd, 0); + WmRequestStatus(_channelID, (wm_request_status*) wd, 1); + break; + //device unplugged(on deactivation) + case 2: + WmRequestStatus(_channelID, (wm_request_status*) wd, 0); + break; + //device plugged in(on activation) + case 3: + WmRequestStatus(_channelID, (wm_request_status*) wd, 1); + break; + + default: + break; + } + } } @@ -506,8 +523,11 @@ void WmRequestStatus(u16 _channelID, wm_request_status* rs, int Extension) // Check if we have a specific order about the extension status if (Extension == -1) { + if (WiiMapping[g_ID].bMotionPlusConnected) + pStatus->extension = ((g_MotionPlus[g_ID]) || (WiiMapping[g_ID].iExtensionConnected != EXT_NONE)) ? 1 : 0; + else + pStatus->extension = (WiiMapping[g_ID].iExtensionConnected == EXT_NONE) ? 0 : 1; // Read config value for the first time - pStatus->extension = ((g_MotionPlus[g_ID]) || (WiiMapping[g_ID].iExtensionConnected != EXT_NONE)) ? 1 : 0; } else { @@ -528,19 +548,25 @@ void WmRequestStatus(u16 _channelID, wm_request_status* rs, int Extension) //ReadDebugging(true, DataFrame, Offset); } - -void HandlingMotionPlusWrites(u8* data, u8 addressHI, u32 address){ +//http://snzgoo.blogspot.com for more details on what this is doing +int HandlingMotionPlusWrites(u8* data, u8 addressHI, u32 address){ switch (addressHI) { case 0xA4: switch (address) { - case 0x00FE: + case 0x00FE: if (data[0] == 0x00) { - if ((g_RegExt[g_ID][0xFF] == 0x05) && (g_RegMotionPlus[g_ID][0xFF] != 0x05)) + if (g_RegExt[g_ID][0xFF] == 0x05) { SwapExtRegisters(); - DEBUG_LOG(WIIMOTE, "Writing [0x%02x] to [0x%02x:%04x]: Disabling WM+ and swapping registers back", data[0], addressHI, address); + if (WiiMapping[g_ID].iExtensionConnected != EXT_NONE){ + DEBUG_LOG(WIIMOTE, "Writing [0x%02x] to [0x%02x:%04x]: Disabling WM+ and swapping registers back", data[0], addressHI, address); + g_RegMotionPlus[g_ID][0xFE] = 0x00; + + return 1; // we need to issue a 0x20 report, if there's an extension connected to the MP+! + } + } else { DEBUG_LOG(WIIMOTE, "Writing [0x%02x] to [0x%02x:%04x]: WM+ already inactive", data[0], addressHI, address); @@ -549,42 +575,105 @@ void HandlingMotionPlusWrites(u8* data, u8 addressHI, u32 address){ } break; - case 0x00FB: - //1. Initializing the extension: writing 0x55 ->0xA400F0 and then 0x00 to 0xA400FB. - //2. Disables an active wiimote; ext disconnect. - if (data[0] == 0x00) { - //1. connecting extension - if ((g_RegExt[g_ID][0xFF] != 0x05) && (g_RegMotionPlus[g_ID][0xFF] == 0x05)) + //1. Initializing the pass-through extension: writing 0x55 ->0xA400F0 and then 0x00 to 0xA400FB. + //2. Disables an active wiimote; 0x20 report sent when iExtensionConnected != NONE : ext disconnect. + //3. single write 0x00 to 0x00FB when MP got activated, part of the MP activation. + case 0x00FB: + + if ((data[0] == 0x00) && (g_MotionPlusLastWriteReg[g_ID] == 0xF0)) { + + //1. Default extension init, disable mp if actitaved, else do nothing + if (g_RegMotionPlus[g_ID][0xFF] == 0x05) //mp already deactivated, no register swap needed { - g_RegMotionPlus[g_ID][0xFE] = 0x04; - g_RegMotionPlus[g_ID][0xF7] = 0x08; //control init byte, ingame check - SwapExtRegisters(); - DEBUG_LOG(WIIMOTE, "Writing [0x%02x] to [0x%02x:%04x]: Enabling WM+ and swapping rgisters", data[0], addressHI, address); - g_MotionPlus[g_ID] = 0; - } //2. disconnecting extension - else if ((g_RegExt[g_ID][0xFF] == 0x05) && (g_RegMotionPlus[g_ID][0xFF] != 0x05)){ - g_RegExt[g_ID][0xFE] = 0x04; - g_MotionPlus[g_ID] = 1; - DEBUG_LOG(WIIMOTE, "Writing [0x%02x] to [0x%02x:%04x]: Disabling WM+ and swapping registers back", data[0], addressHI, address); + DEBUG_LOG(WIIMOTE, "Writing [0x%02x] to [0x%02x:%04x]: WM+ already disabled [ext:%i] - no swapping", data[0], addressHI, address, WiiMapping[g_ID].iExtensionConnected); + g_RegMotionPlus[g_ID][0xFE] = 0x05; + g_RegMotionPlus[g_ID][0xF7] = 0x08; + + } //2. disabling wiimote, + else if (g_RegExt[g_ID][0xFF] == 0x05){ + + DEBUG_LOG(WIIMOTE, "Writing [0x%02x] to [0x%02x:%04x]: Disabling WM+ and swapping registers back", data[0], addressHI, address) + + if (!WiiMapping[g_ID].iExtensionConnected){ + g_RegExt[g_ID][0xFE] = 0x05; + g_MotionPlus[g_ID] = 0; + SwapExtRegisters(); + return 2; + } + else { + g_RegExt[g_ID][0xFE] = 0x05; + SwapExtRegisters(); + g_MotionPlus[g_ID] = 1; + + } + + } + } //3. + else if ((data[0] == 0x00) && (g_MotionPlusLastWriteReg[g_ID] != 0xF0)) { + + if (g_RegExt[g_ID][0xFF] == 0x05) { + g_RegExt[g_ID][0xF1] = 0x01; + g_RegExt[g_ID][0xF7] = 0x08; //init/calibration state flag + + if (WiiMapping[g_ID].iExtensionConnected){ + //I don't know what these are for: F6h,F8h, F9h; but they seem necessary to be set to 0x00 + //if there's an extension connected to the MP, else they are 0xFF + g_RegExt[g_ID][0xF6] = 0x00; + g_RegExt[g_ID][0xF8] = 0x00; + g_RegExt[g_ID][0xF9] = 0x00; + } } } break; + + //switch for invalid/valid data calibration (00/01) + case 0x00F1: + if (g_RegExt[g_ID][0xFF] == 0x05) { + g_RegExt[g_ID][0xF7] = 0x1A; + } + break; + + //switch for triggering the calibration/syncing between wiimote and MP (corresponding data will be at 50h) + case 0x00F2: + if((g_RegExt[g_ID][0xFF] == 0x05) && (g_RegExt[g_ID][0xF7] < 0x0E)) { + g_RegExt[g_ID][0xF7] = 0x0E; + } + break; + + //case 0x00F3/0x00F4: //It'ss probably just the same as either F1/F2, needs more investigation tho, + // but most likely just a different calibration sensitivity; wii sports resort does use it, but redsteel doesnt } break; + //MotionPlus Register case 0xA6: switch (address) { case 0x00FE: - //Enabling WM+, swapping extension registers - if (data[0] == 0x05) { - if ((g_RegExt[g_ID][0xFF] != 0x05) && (g_RegMotionPlus[g_ID][0xFF] == 0x05) ) { - //The WII will try to read from the readprotected A6 WM+ register now, we need to reply with an error each time, - //plus sent an statusreport 0x20(depending on if nunchuk inserted or not) + //Enabling WM+: swapping extension registers + if ((data[0] == 0x04) || (data[0] == 0x05)) { + if (g_RegMotionPlus[g_ID][0xFF] == 0x05) { + DEBUG_LOG(WIIMOTE, "Writing [0x%02x] to [0x%02x:%04x]: Enabling WM+ and swapping registers", data[0], addressHI, address); + + //The WII will try to read from the A6 WM+ register directly after activation, + //but we need to reply with an error each time as long the mp is still activate. + //In addition, we need to sent 1-2 0x20 statusreports depending on if theres an extension connected to the MP or not. g_MotionPlusReadError[g_ID] = 0; + + g_RegMotionPlus[g_ID][0xF7] = 0x08; + g_RegMotionPlus[g_ID][0xFE] = data[0]; g_MotionPlus[g_ID] = 1; SwapExtRegisters(); - DEBUG_LOG(WIIMOTE, "Writing [0x%02x] to [0x%02x:%04x]: Enabling WM+ and swapping rgisters back", data[0], addressHI, address); + + if (WiiMapping[g_ID].iExtensionConnected != EXT_NONE){ + + g_RegExt[g_ID][0xF1] = 0x01; + g_RegExt[g_ID][0xF6] = 0x00; // i dont knwo what these are for: F6h,F8h, F9h; but they are necessary to be set to 0x00 if theres a nunchuk/ext connected + g_RegExt[g_ID][0xF8] = 0x00; + g_RegExt[g_ID][0xF9] = 0x00; + return 1; // we need to issue 2 0x20 reports, if there's an extension connected to the MP + } + return 3; // we need to issue 1 0x20 report, if there's an extension connected to the MP } else { DEBUG_LOG(WIIMOTE, "Writing [0x%02x] to [0x%02x:%04x]: WM already enabled no register swapping", data[0], addressHI, address); @@ -592,23 +681,16 @@ void HandlingMotionPlusWrites(u8* data, u8 addressHI, u32 address){ } break; - case 0x00F0: //init() WM+, this will change some control bits in the WM+ register - if (data[0] == 0x55) { //enables passthroug, convert to 0405* A6 swap - if ((g_RegMotionPlus[g_ID][0xFF] == 0x05)) - { - //control init byte, ingame check - g_RegMotionPlus[g_ID][0xF7] = 0x08; - - //motion plus id - g_RegMotionPlus[g_ID][0xFE] = 0x05; - - //we will swap the register on write to 0x00FE - } - else if (g_RegExt[g_ID][0xFF] == 0x05) { //if the wiimote is already active, we will init() the WM+ directly in the ExtReg + case 0x00F0: //Part of the WM+ init() + if (data[0] == 0x55) { + + //if the wiimote is already active, we will init() the WM+ directly in the ExtReg, shouldnt happen usually + if (g_RegExt[g_ID][0xFF] == 0x05) { g_RegExt[g_ID][0xFE] = 0x05; - g_RegExt[g_ID][0xF7] = 0x08; + g_RegExt[g_ID][0xF7] = 0x08;//calibdata trigger } - g_MotionPlus[g_ID] = 0; + if (WiiMapping[g_ID].iExtensionConnected == EXT_NONE) + g_MotionPlus[g_ID] = 0; } break; @@ -618,6 +700,7 @@ void HandlingMotionPlusWrites(u8* data, u8 addressHI, u32 address){ } break; } + return false; } //Swapping Ext/WM+-registers diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuSubroutines.h b/Source/Plugins/Plugin_Wiimote/Src/EmuSubroutines.h index f77ac49a0b..6f02304cf6 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/EmuSubroutines.h +++ b/Source/Plugins/Plugin_Wiimote/Src/EmuSubroutines.h @@ -53,7 +53,7 @@ int WriteWmReportHdr(u8* dst, u8 wm); void WmSendAck(u16 _channelID, u8 _reportID); void SendReadDataReply(u16 _channelID, void* _Base, u16 _Address, u8 _AddressHI, int _Size); void SwapExtRegisters(); -void HandlingMotionPlusWrites(u8* data, u8 addressHI, u32 address); +int HandlingMotionPlusWrites(u8* data, u8 addressHI, u32 address); void FillReportAcc(wm_accel& _acc); void FillReportInfo(wm_core& _core); diff --git a/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp b/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp index 7d336e1d4e..145fd2c9ba 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp @@ -1253,10 +1253,10 @@ void FillReportGuitarHero3Extension(wm_GH3_extension& _ext) void FillReportMotionPlus(wm_extension& ext, bool extension){ //sending initial control packet, this must be sent first, its some kind of verifiation, all control bits are set to 0! - if (g_MotionPlusReadError[g_ID]) { - + if ((g_MotionPlusReadError[g_ID]) && (g_RegExt[g_ID][0xFE] == 0x05) && (!extension)) { memcpy(&ext, motionpluscheck_id, sizeof(motionpluscheck_id)); - g_MotionPlus[g_ID] = (extension) ? 1 : 0; + + //g_MotionPlus[g_ID] = (extension) ? 1 : 0; g_MotionPlusReadError[g_ID] = 0; } //nunchuk inserted @@ -1288,18 +1288,24 @@ void FillReportMotionPlusNoExtension(wm_extension& _ext) { wm_mp_nc_0 ext; memset(&ext, 0, sizeof(wm_mp_nc_0)); - ext.YawLeftLS = 0x00; //dummy data atm - ext.RollLeftLS = 0x00; - ext.PitchDownLS = 0x00; - ext.pitchfast = 0x00; - ext.yawfast = 0x00; - ext.YawLeftHI = 0x00; - ext.ExtCon = 0x00; // 0 (important, since we don't use a nunchuk here) - ext.rollfast = 0x00; - ext.RollLeftHI = 0x00; - ext.dummy = 0x00; // 0 (important) + + //bookkeeping bits + ext.ExtCon = ((WiiMapping[g_ID].iExtensionConnected != EXT_NONE)) ? 1 : 0; //0 = no passed-through ext., 1 = ext. connected; ext.mpdata = 0x01; //1 (important, using MP+ report instead of NC report) - ext.PitchDownHI = 0x00; + ext.dummy = 0x00; // 0 (important) +/* + ext.yawslow = 0x01; + ext.pitchslow = 0x01; + ext.rollslow = 0x01; + + ext.YawLeftLS = g_mp[1].cal_zero.x; + ext.RollLeftLS = g_mp[1].cal_zero.y; + ext.PitchDownLS = g_mp[1].cal_zero.z; + + ext.YawLeftHI = g_mp[1].cal_zero.x>>8; + ext.RollLeftHI = g_mp[1].cal_zero.y>>8; + ext.PitchDownHI = g_mp[1].cal_zero.z>>8; +*/ memcpy(&_ext, &ext, sizeof(ext)); } @@ -1316,9 +1322,6 @@ void FillReportMotionPlusNunchukExtension(wm_extension& _ext) ext.ax = g_nu.cal_zero.x; ext.ay = g_nu.cal_zero.y; ext.az = g_nu.cal_zero.z + g_nu.cal_g.z; - ext.axLS = 0x00; - ext.ayLS = 0x00; - ext.azLS = 0x00; ext.bz = 0x01; ext.bc = 0x01; @@ -1326,7 +1329,6 @@ void FillReportMotionPlusNunchukExtension(wm_extension& _ext) ext.mpdata = 0; //0 NC report, interleaved data (important) ext.ExtCon = 1; // must be 1 when in NC-MP+ Mode - if (IsFocus()) { int acc_x = g_nu.cal_zero.x; diff --git a/Source/Plugins/Plugin_Wiimote/Src/wiimote_hid.h b/Source/Plugins/Plugin_Wiimote/Src/wiimote_hid.h index 30414967e1..21c5446d39 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/wiimote_hid.h +++ b/Source/Plugins/Plugin_Wiimote/Src/wiimote_hid.h @@ -66,6 +66,9 @@ struct wm_accel { u8 x, y, z; }; +struct mp_gyro { + u16 x:14, y:14, z:14; +}; // Four bytes for two objects. Filled with 0xFF if empty struct wm_ir_basic { @@ -138,23 +141,23 @@ struct wm_classic_extension wm_cc_5 b2; // byte 5 }; -struct wm_mp_nc_0 //motionplus+nunchuk_pass-through +struct wm_mp_nc_0 //motionplus data { u8 YawLeftLS; //7e u8 RollLeftLS; //82 u8 PitchDownLS; //83 - u8 pitchfast : 1; //1 - u8 yawfast : 1; //0 + u8 pitchslow : 1; //1 + u8 yawslow : 1; //0 u8 YawLeftHI : 6; //01 1010 /1a u8 ExtCon : 1; // 1 usually - u8 rollfast : 1; //0 + u8 rollslow : 1; //0 u8 RollLeftHI : 6; //00 1010 u8 dummy : 1; // 0 usually. 1 in dem fall mhh u8 mpdata : 1; //1 in this case, interleaved motion+ data u8 PitchDownHI : 6;//01 1100 }; // default for yaw/roll/pitch around 0x1F7F -struct wm_mp_nc_1 //motionplus+nunchuk_pass-through +struct wm_mp_nc_1 //nunchuk data on motion-plus pass-through { u8 jx; u8 jy; @@ -378,6 +381,14 @@ struct nu_cal nu_js jx; // nu_js jy; // }; + +struct mp_cal +{ + mp_gyro cal_zero; + mp_gyro cal_min; + mp_gyro cal_max; +}; + struct cc_cal { nu_js Lx; //