From cf303e70e9e03419d64ef8c43be550bc9b8899e1 Mon Sep 17 00:00:00 2001 From: John Peterson Date: Wed, 4 Feb 2009 06:40:05 +0000 Subject: [PATCH] Wiimote: Show the decrypted Nunchuck calibration values in the log when a real Wiimote and Nunchuck is used. Fixed an earlier bug that made the neutral emulated nunchuck accelerometer values zero, now they are back to 0x80,0x80,0xb3. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2104 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Common/Src/StringUtil.cpp | 3 +- .../Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp | 27 ++- .../Plugin_Wiimote/Src/DataReports.cpp | 10 +- .../Plugin_Wiimote/Src/EmuDefinitions.h | 13 +- Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp | 13 +- .../Plugin_Wiimote/Src/EmuSubroutines.cpp | 197 +++++++++--------- .../Plugins/Plugin_Wiimote/Src/Encryption.cpp | 4 +- .../Plugins/Plugin_Wiimote/Src/FillReport.cpp | 24 +-- Source/Plugins/Plugin_Wiimote/Src/main.cpp | 92 ++++++-- Source/Plugins/Plugin_Wiimote/Src/main.h | 2 +- .../Plugin_Wiimote/Src/wiimote_real.cpp | 4 +- 11 files changed, 222 insertions(+), 167 deletions(-) diff --git a/Source/Core/Common/Src/StringUtil.cpp b/Source/Core/Common/Src/StringUtil.cpp index ef95259bd0..27ec6a7a2d 100644 --- a/Source/Core/Common/Src/StringUtil.cpp +++ b/Source/Core/Common/Src/StringUtil.cpp @@ -151,14 +151,13 @@ std::string StringFromFormat(const char* format, ...) // ---------------- std::string ArrayToString(const u8 *data, u32 size, u32 offset, int line_len, bool Spaces) { - //const u8* _data = (const u8*)data; std::string Temp; for (u32 i = 0; i < size; i++) { char Buffer[128]; if (Spaces) sprintf(Buffer, "%02x ", data[i + offset]); else sprintf(Buffer, "%02x", data[i + offset]); - if((i + 1) % line_len == 0) Temp.append("\n"); // break long lines + if(i > 0 && i % line_len == 0) Temp.append("\n"); // break long lines Temp.append(Buffer); } return Temp; diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp index e79d6cc096..01da7a8385 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp @@ -996,26 +996,29 @@ void CWII_IPC_HLE_WiiMote::SendCommandToACL(u8 _Ident, u8 _Code, u8 _CommandLeng // ---------------- void CWII_IPC_HLE_WiiMote::SendL2capData(u16 scid, const void* _pData, u32 _Size) { - //allocate + // Allocate DataFrame u8 DataFrame[1024]; u32 Offset = 0; SL2CAP_Header* pHeader = (SL2CAP_Header*)DataFrame; Offset += sizeof(SL2CAP_Header); + // Check if we are already reporting on this channel _dbg_assert_(WII_IPC_WIIMOTE, DoesChannelExist(scid)); SChannel& rChannel = m_Channel[scid]; - //assemble + // Add an additonal 4 byte header to the Wiimote report pHeader->CID = rChannel.DCID; pHeader->Length = _Size; + // Copy the Wiimote report to DataFrame memcpy(DataFrame + Offset, _pData, _Size); + // Update Offset to the final size of the report Offset += _Size; - //send + // Send the report m_pHost->SendACLFrame(GetConnectionHandle(), DataFrame, Offset); - // + // Update the status bar Host_SetWiiMoteConnectionState(2); } @@ -1023,22 +1026,16 @@ void CWII_IPC_HLE_WiiMote::SendL2capData(u16 scid, const void* _pData, u32 _Size namespace Core { - /* This is called continously from the Wiimote plugin as soon as it has received - a reporting mode */ + /* This is called continuously from the Wiimote plugin as soon as it has received + a reporting mode. _Size is the byte size of the report. */ void Callback_WiimoteInput(u16 _channelID, const void* _pData, u32 _Size) { LOGV(WII_IPC_WIIMOTE, 3, "========================================================="); const u8* pData = (const u8*)_pData; LOGV(WII_IPC_WIIMOTE, 3, "Callback_WiimoteInput:"); - std::string Temp; - for (u32 j=0; j<_Size; j++) - { - char Buffer[128]; - sprintf(Buffer, "%02x ", pData[j]); - Temp.append(Buffer); - } - LOGV(WII_IPC_WIIMOTE, 3, " Data: %s", Temp.c_str()); - //LOGV(WII_IPC_WIIMOTE, 3, " Channel: %s", _channelID); + //std::string Temp = ArrayToString(pData, _Size, 0, 50); + //LOGV(WII_IPC_WIIMOTE, 3, " Data: %s", Temp.c_str()); + LOGV(WII_IPC_WIIMOTE, 3, " Channel: %s", _channelID); s_Usb->m_WiiMotes[0].SendL2capData(_channelID, _pData, _Size); LOGV(WII_IPC_WIIMOTE, 3, "========================================================="); diff --git a/Source/Plugins/Plugin_Wiimote/Src/DataReports.cpp b/Source/Plugins/Plugin_Wiimote/Src/DataReports.cpp index 9993ce5307..653bda3173 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/DataReports.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/DataReports.cpp @@ -141,7 +141,7 @@ void SendReportCore(u16 _channelID) g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset); // Debugging - ReadDebugging(true, DataFrame); + ReadDebugging(true, DataFrame, Offset); } @@ -167,7 +167,7 @@ void SendReportCoreAccel(u16 _channelID) g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset); // Debugging - ReadDebugging(true, DataFrame); + ReadDebugging(true, DataFrame, Offset); } @@ -196,7 +196,7 @@ void SendReportCoreAccelIr12(u16 _channelID) { g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset); // Debugging - ReadDebugging(true, DataFrame); + ReadDebugging(true, DataFrame, Offset); } @@ -237,7 +237,7 @@ void SendReportCoreAccelExt16(u16 _channelID) g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset); // Debugging - ReadDebugging(true, DataFrame); + ReadDebugging(true, DataFrame, Offset); } @@ -277,7 +277,7 @@ void SendReportCoreAccelIr10Ext(u16 _channelID) g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset); // Debugging - ReadDebugging(true, DataFrame); + ReadDebugging(true, DataFrame, Offset); } diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.h b/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.h index 9825ac89ff..69fcf2cd57 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.h +++ b/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.h @@ -117,13 +117,13 @@ static const u8 EepromData_16D0[] = { neutral z accelerometer that is adjusted for gravity. */ static const u8 nunchuck_calibration[] = { - 0x80,0x80,0x80,0x00, // x and y neutral - 0xb3,0xb3,0xb3,0x00, // z neutral + 0x80,0x80,0x80,0x00, // accelerometer x, y, z neutral + 0xb3,0xb3,0xb3,0x00, // x, y, z g-force values - 0xe0,0x20,0x80,0xe0, - 0x20,0x80,0xee,0x43, + 0xe0, 0x20, 0x80, 0xe0, // 0x80 = analog stick x and y axis center + 0x20, 0x80, 0xee, 0x43, - 0x80,0x80,0x80,0x00, 0xb3,0xb3,0xb3,0x00, + 0x80,0x80,0x80,0x00, 0xb3,0xb3,0xb3,0x00, // repeat 0xe0,0x20,0x80,0xe0, 0x20,0x80,0xee,0x43 }; @@ -134,7 +134,8 @@ static const u8 classic_calibration[] = { 0xe4,0x1c,0x80,0xe4, 0x1c,0x80,0xd8,0x28, 0x80,0xd8,0x28,0x80, 0x20,0x20,0x95,0xea, - 0xe4,0x1c,0x80,0xe4, 0x1c,0x80,0xd8,0x28, + + 0xe4,0x1c,0x80,0xe4, 0x1c,0x80,0xd8,0x28, // repeat 0x80,0xd8,0x28,0x80, 0x20,0x20,0x95,0xea }; diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp index 20b5685222..60f97c3644 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp @@ -276,11 +276,14 @@ void Initialize() LoadRecordedMovements(); // Set default recording values - g_RecordingPlaying[0] = -1; g_RecordingPlaying[1] = -1; - g_RecordingCounter[0] = 0; g_RecordingCounter[1] = 0; - g_RecordingPoint[0] = 0; g_RecordingPoint[1] = 0; - g_RecordingStart[0] = 0; g_RecordingStart[1] = 0; - g_RecordingCurrentTime[0] = 0; g_RecordingCurrentTime[1] = 0; + for (int i = 0; i < 3; i++) + { + g_RecordingPlaying[i] = -1; + g_RecordingCounter[i] = 0; + g_RecordingPoint[i] = 0; + g_RecordingStart[i] = 0; + g_RecordingCurrentTime[i] = 0; + } // I forgot what these were for? // g_RegExt[0xfd] = 0x1e; diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuSubroutines.cpp b/Source/Plugins/Plugin_Wiimote/Src/EmuSubroutines.cpp index 0409225b4c..d6f779afd8 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/EmuSubroutines.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/EmuSubroutines.cpp @@ -113,7 +113,7 @@ void HidOutputReport(u16 _channelID, wm_report* sr) { break; case WM_WRITE_DATA: // 0x16 - if (!g_Config.bUseRealWiimote || !g_RealWiiMotePresent) WmWriteData(_channelID, (wm_write_data*)sr->data); + WmWriteData(_channelID, (wm_write_data*)sr->data); break; case WM_SPEAKER_ENABLE: // 0x14 LOGV(WII_IPC_WIIMOTE, 1, " WM Speaker Enable 0x%02x: 0x%02x", sr->channel, sr->data[0]); @@ -136,16 +136,19 @@ void HidOutputReport(u16 _channelID, wm_report* sr) { // =================================================== -/* Generate the right address for wm reports. */ +/* Generate the right header for wm reports. The returned values is the length of the header before + the data begins. It's always two for all reports 0x20 - 0x22, 0x30 - 0x37 */ // ---------------- int WriteWmReport(u8* dst, u8 channel) { + // Update the first byte to 0xa1 u32 Offset = 0; hid_packet* pHidHeader = (hid_packet*)(dst + Offset); Offset += sizeof(hid_packet); pHidHeader->type = HID_TYPE_DATA; pHidHeader->param = HID_PARAM_INPUT; + // Update the second byte to the current report type 0x20 - 0x22, 0x30 - 0x37 wm_report* pReport = (wm_report*)(dst + Offset); Offset += sizeof(wm_report); pReport->channel = channel; @@ -208,7 +211,7 @@ void WmSendAck(u16 _channelID, u8 _reportID, u32 address) g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset); // Debugging - ReadDebugging(true, DataFrame); + ReadDebugging(true, DataFrame, Offset); } @@ -261,8 +264,8 @@ void WmReadData(u16 _channelID, wm_read_data* rd) case 0xA4: block = g_RegExt; blockSize = WIIMOTE_REG_EXT_SIZE; - LOGV(WII_IPC_WIIMOTE, 0, " Case 0xa4: Read ExtReg ****************************"); - /*Tmp = ArrayToString(g_RegExt, size, (address & 0xffff)); + LOGV(WII_IPC_WIIMOTE, 0, " Case 0xa4: Read ExtReg"); + /*Tmp = ArrayToString(g_RegExt, size, (address & 0xffff), 40); //LOGV(WII_IPC_WIIMOTE, 0, " Data: %s", Temp.c_str()); Console::Print("Read RegExt: Size %i Address %08x Offset %08x\nData %s\n", size, address, (address & 0xffff), Tmp.c_str());*/ @@ -305,16 +308,15 @@ void WmReadData(u16 _channelID, wm_read_data* rd) // Encrypt g_RegExtTmp at that location wiimote_encrypt(&g_ExtKey, &g_RegExtTmp[address & 0xffff], (address & 0xffff), (u8)size); + // Update the block that SendReadDataReply will eventually send to the Wii + block = g_RegExtTmp; + /* Debugging: Show the encrypted data std::string Temp = ArrayToString(g_RegExtTmp, size, offset); Console::Print("Encrypted data:\n%s\n", Temp.c_str());*/ - - // Update the block that SendReadDataReply will eventually send to the Wii - block = g_RegExtTmp; } } - //--------- - + //------------- address &= 0xFFFF; if(address + size > blockSize) { @@ -324,20 +326,101 @@ void WmReadData(u16 _channelID, wm_read_data* rd) // Let this function process the message and send it to the Wii SendReadDataReply(_channelID, block + address, address, (u8)size); - - } else { PanicAlert("WmReadData: unimplemented parameters (size: %i, addr: 0x%x!", size, rd->space); } - // Acknowledge the 0x17 read, we will do this from InterruptChannel() - //WmSendAck(_channelID, WM_READ_DATA, _address); - LOGV(WII_IPC_WIIMOTE, 0, "==========================================================="); } +// =================================================== +/* Here we produce the actual 0x21 Input report that we send to the Wii. The message + is divided into 16 bytes pieces and sent piece by piece. There will be five formatting + bytes at the begging of all reports. A common format is 00 00 f0 00 20, the 00 00 + means that no buttons are pressed, the f means 16 bytes in the message, the 0 + means no error, the 00 20 means that the message is at the 00 20 offest in the + registry that was read. + + _Base: The data beginning at _Base[0] + _Address: The starting address inside the registry, this is used to check for out of bounds reading + _Size: The total size to send + */ +// ---------------- +void SendReadDataReply(u16 _channelID, void* _Base, u16 _Address, u8 _Size) +{ + LOGV(WII_IPC_WIIMOTE, 0, "========================================="); + int dataOffset = 0; + const u8* data = (const u8*)_Base; + while (_Size > 0) + { + u8 DataFrame[1024]; + // Write the first two bytes to DataFrame + u32 Offset = WriteWmReport(DataFrame, WM_READ_DATA_REPLY); + + // Limit the size to 16 bytes + int copySize = _Size; + if (copySize > 16) copySize = 16; + + // Connect pReply->data to the almost empty DataFrame + wm_read_data_reply* pReply = (wm_read_data_reply*)(DataFrame + Offset); + // Now we increase Offset to the final size of the report + Offset += sizeof(wm_read_data_reply); + // Add header values + pReply->buttons = 0; + pReply->error = 0; + pReply->size = (copySize - 1) & 0xf; + pReply->address = Common::swap16(_Address + dataOffset); + + // Write a pice of _Base to DataFrame + memcpy(pReply->data, data + dataOffset, copySize); + + // Check if we have less than 16 bytes left to send + if(copySize < 16) memset(pReply->data + copySize, 0, 16 - copySize); + + // Update DataOffset for the next loop + dataOffset += copySize; + + /* Out of bounds. The real Wiimote generate an error for the first request to 0x1770 + if we dont't replicate that the game will never read the capibration data at the + beginning of Eeprom. I think this error is supposed to occur when we try to read above + the freely usable space that ends at 0x16ff. */ + if (Common::swap16(pReply->address + pReply->size) > WIIMOTE_EEPROM_FREE_SIZE) + { + pReply->size = 0x0f; + pReply->error = 0x08; + } + + // Logging + LOG(WII_IPC_WIIMOTE, " SendReadDataReply()"); + LOG(WII_IPC_WIIMOTE, " Buttons: 0x%04x", pReply->buttons); + LOG(WII_IPC_WIIMOTE, " Error: 0x%x", pReply->error); + LOG(WII_IPC_WIIMOTE, " Size: 0x%x", pReply->size); + LOG(WII_IPC_WIIMOTE, " Address: 0x%04x", pReply->address); + /*Console::Print(" SendReadDataReply()\n"); + Console::Print(" Offset: 0x%x\n", Offset); + Console::Print(" dataOffset: 0x%x\n", dataOffset); + Console::Print(" copySize: 0x%x\n", copySize); + Console::Print(" Size: 0x%x\n", pReply->size); + Console::Print(" Address: 0x%04x\n", Common::swap16(pReply->address));*/ + //std::string Temp = ArrayToString(data, 0x40); + //Console::Print("Data:\n%s\n", Temp.c_str()); + + // Send a piece + g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset); + // Update the size that is left + _Size -= copySize; + + // Debugging + ReadDebugging(true, DataFrame, Offset); + } + + if (_Size != 0) + PanicAlert("WiiMote-Plugin: SendReadDataReply() failed"); + LOGV(WII_IPC_WIIMOTE, 0, "=========================================="); +} +// ================ // =================================================== @@ -446,88 +529,6 @@ void WmWriteData(u16 _channelID, wm_write_data* wd) LOGV(WII_IPC_WIIMOTE, 0, "=========================================================="); } - -// =================================================== -/* Here we produce the actual 0x21 Input report that we send to the Wii. The message - is divided into 16 bytes pieces and sent piece by piece. There will be five formatting - bytes at the begging of all reports. A common format is 00 00 f0 00 20, the 00 00 - means that no buttons are pressed, the f means 16 bytes in the message, the 0 - means no error, the 00 20 means that the message is at the 00 20 offest in the - registry that was read. */ -// ---------------- -void SendReadDataReply(u16 _channelID, void* _Base, u16 _Address, u8 _Size) -{ - LOGV(WII_IPC_WIIMOTE, 0, "========================================="); - int dataOffset = 0; - const u8* data = (const u8*)_Base; - while (_Size > 0) - { - u8 DataFrame[1024]; - u32 Offset = WriteWmReport(DataFrame, WM_READ_DATA_REPLY); - - // Limit the size to 16 bytes - int copySize = _Size; - if (copySize > 16) copySize = 16; - - // Connect pReply->data to the empty DataFrame - wm_read_data_reply* pReply = (wm_read_data_reply*)(DataFrame + Offset); - Offset += sizeof(wm_read_data_reply); - pReply->buttons = 0; - pReply->error = 0; - pReply->size = (copySize - 1) & 0xf; - pReply->address = Common::swap16(_Address + dataOffset); - - // Write a pice of _Base to DataFrame - memcpy(pReply->data, data + dataOffset, copySize); - - // Check if we have less than 16 bytes left to send - if(copySize < 16) - memset(pReply->data + copySize, 0, 16 - copySize); - - // Update DataOffset for the next loop - dataOffset += copySize; - - /* Out of bounds. The real Wiimote generate an error for the first request to 0x1770 - if we dont't replicate that the game will never read the capibration data at the - beginning of Eeprom. I think this error is supposed to occur when we try to read above - the freely usable space that ends at 0x16ff. */ - if (Common::swap16(pReply->address + pReply->size) > WIIMOTE_EEPROM_FREE_SIZE) - { - pReply->size = 0x0f; - pReply->error = 0x08; - } - - // Logging - LOG(WII_IPC_WIIMOTE, " SendReadDataReply()"); - LOG(WII_IPC_WIIMOTE, " Buttons: 0x%04x", pReply->buttons); - LOG(WII_IPC_WIIMOTE, " Error: 0x%x", pReply->error); - LOG(WII_IPC_WIIMOTE, " Size: 0x%x", pReply->size); - LOG(WII_IPC_WIIMOTE, " Address: 0x%04x", pReply->address); - /*Console::Print(" SendReadDataReply()\n"); - Console::Print(" dataOffset: 0x%x\n", dataOffset); - Console::Print(" copySize: 0x%x\n", copySize); - Console::Print(" Size: 0x%x\n", pReply->size); - Console::Print(" Address: 0x%04x\n", Common::swap16(pReply->address));*/ - - //std::string Temp = ArrayToString(data, 0x40); - //Console::Print("Eeprom: %s\n", Temp.c_str()); - - // Send a piece - g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset); - - _Size -= copySize; - - // Debugging - ReadDebugging(true, DataFrame); - } - - if (_Size != 0) - PanicAlert("WiiMote-Plugin: SendReadDataReply() failed"); - LOGV(WII_IPC_WIIMOTE, 0, "=========================================="); -} -// ================ - - // =================================================== /* Here we produce a status report to send to the Wii. We currently ignore the status request rs and all its eventual instructions it may include (for example turn off @@ -576,7 +577,7 @@ void WmRequestStatus(u16 _channelID, wm_request_status* rs) LOGV(WII_IPC_WIIMOTE, 0, "================================================="); // Debugging - ReadDebugging(true, DataFrame); + ReadDebugging(true, DataFrame, Offset); } } // WiiMoteEmu diff --git a/Source/Plugins/Plugin_Wiimote/Src/Encryption.cpp b/Source/Plugins/Plugin_Wiimote/Src/Encryption.cpp index c96030af73..80f90be5cb 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/Encryption.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/Encryption.cpp @@ -265,10 +265,10 @@ void wiimote_gen_key(wiimote_key *key, u8 *keydata) Console::Print("rand: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", rand[0], rand[1], rand[2], rand[3], rand[4], rand[5], rand[6], rand[7], rand[8], rand[9]); Console::Print("key: %02x %02x %02x %02x %02x %02x\n", skey[0], skey[1], skey[2], skey[3], skey[4], skey[5]); - for(idx=0;idx<7;idx++) + for(idx = 0; idx < 7; idx++) { genkey(rand, idx, testkey); - if(!memcmp(testkey,skey,6)) + if(!memcmp(testkey, skey, 6)) break; } // default case is idx = 7 which is valid (homebrew uses it for the 0x17 case) diff --git a/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp b/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp index db1935291d..6987ee9cbc 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp @@ -761,24 +761,16 @@ void FillReportExtension(wm_extension& _ext) // Recorded movements // -------------- // Check for a playback command - if(g_RecordingPlaying[1] < 0) - { - g_RecordingPlaying[1] = RecordingCheckKeys(1); + if(g_RecordingPlaying[1] < 0) g_RecordingPlaying[1] = RecordingCheckKeys(1); - } - // We should play back the accelerometer values - else + // We should not play back the accelerometer values + if (!(g_RecordingPlaying[1] >= 0 && RecordingPlay(_ext.ax, _ext.ay, _ext.az, 1))) { - //Console::Print("X: %u\n", _acc.x); - // - if (!RecordingPlay(_ext.ax, _ext.ay, _ext.az, 1)) - { - /* These are the default neutral values for the nunchuck accelerometer according to the calibration - data we have in nunchuck_calibration[] */ - _ext.ax = 0x80; - _ext.ay = 0x80; - _ext.az = 0xb3; - } + /* These are the default neutral values for the nunchuck accelerometer according to the calibration + data we have in nunchuck_calibration[] */ + _ext.ax = 0x80; + _ext.ay = 0x80; + _ext.az = 0xb3; } // --------------------- diff --git a/Source/Plugins/Plugin_Wiimote/Src/main.cpp b/Source/Plugins/Plugin_Wiimote/Src/main.cpp index 9299746e37..4debd1cc7d 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/main.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/main.cpp @@ -211,7 +211,7 @@ extern "C" void Shutdown(void) #endif WiiMoteEmu::Shutdown(); - Console::Close(); + //Console::Close(); } @@ -354,10 +354,26 @@ bool IsFocus() #endif } -void ReadDebugging(bool Emu, const void* _pData) +/* +// We have to +void DecryptData(u8 *_data) +{ + // Clear g_RegExtTmp by copying zeroes to it + memset(WiiMoteEmu::g_RegExtTmpReport, 0, sizeof(WiiMoteEmu::g_RegExtTmp)); + // Write the nunchuck inputs to it. We begin writing at 0x08 + memcpy(WiiMoteEmu::g_RegExtTmpReport + 0x08, data + 17, sizeof(wm_extension)); + // Decrypt it + wiimote_decrypt(&WiiMoteEmu::g_ExtKey, &WiiMoteEmu::g_RegExtTmpReport[0x08], 0x08, 0x06); + // Write it back + memcpy(data + 17, &WiiMoteEmu::g_RegExtTmpReport[0x08], sizeof(wm_extension)); +} +*/ + +void ReadDebugging(bool Emu, const void* _pData, int Size) { // - const u8* data = (const u8*)_pData; + //const u8* data = (const u8*)_pData; + u8* data = (u8*)_pData; int size; bool DataReport = false; @@ -392,10 +408,34 @@ void ReadDebugging(bool Emu, const void* _pData) case WM_READ_DATA_REPLY: // 0x21 size = sizeof(wm_read_data_reply); Name = "REPLY"; - // Show the accelerometer neutral values, + // data[4]: Size and error + // data[5, 6]: The registry offset + + // Show the accelerometer neutral values if (data[5] == 0x00 && data[6] == 0x10) - Console::Print("\nGame got neutral values: %i %i %i\n\n", + { + Console::Print("\nGame got the Wiimote accelerometer neutral values: %i %i %i\n\n", data[13], data[14], data[19]); + } + // Show the nunchuck neutral values + // We have already sent the data report so we can safely decrypt it now + wiimote_decrypt(&WiiMoteEmu::g_ExtKey, &data[7], 0x00, Size - 7); + if(data[4] == 0xf0 && data[5] == 0x00 && data[6] == 0x20) + { + Console::Print("\nGame got the Nunchuck calibration:\n"); + Console::Print("Cal_zero.x: %i\n", data[7 + 0]); + Console::Print("Cal_zero.y: %i\n", data[7 + 1]); + Console::Print("Cal_zero.z: %i\n", data[7 + 2]); + Console::Print("Cal_g.x: %i\n", data[7 + 4]); + Console::Print("Cal_g.y: %i\n", data[7 + 5]); + Console::Print("Cal_g.z: %i\n", data[7 + 6]); + Console::Print("Js.Max.x: %i\n", data[7 + 8]); + Console::Print("Js.Min.x: %i\n", data[7 + 9]); + Console::Print("Js.Center.x: %i\n", data[7 + 10]); + Console::Print("Js.Max.y: %i\n", data[7 + 11]); + Console::Print("Js.Min.y: %i\n", data[7 + 12]); + Console::Print("JS.Center.y: %i\n\n", data[7 + 13]); + } break; case WM_WRITE_DATA_REPLY: // 0x22 size = sizeof(wm_acknowledge) - 1; @@ -440,26 +480,38 @@ void ReadDebugging(bool Emu, const void* _pData) if (!DataReport && g_DebugComm) { - std::string Temp = ArrayToString(data, size + 2, 0, 30); + std::string TmpData = ArrayToString(data, size + 2, 0, 30); //LOGV(WII_IPC_WIIMOTE, 3, " Data: %s", Temp.c_str()); - Console::Print("Read[%s] %s: %s\n", (Emu ? "Emu" : "Real"), Name.c_str(), Temp.c_str()); // No timestamp + Console::Print("Read[%s] %s: %s\n", (Emu ? "Emu" : "Real"), Name.c_str(), TmpData.c_str()); // No timestamp //Console::Print(" (%s): %s\n", Tm(true).c_str(), Temp.c_str()); // Timestamp } if (DataReport && g_DebugData) { - std::string Temp = ArrayToString(data, size + 2, 0, 30); + // Decrypt extension data + if(WiiMoteEmu::g_ReportingMode == 0x37) + wiimote_decrypt(&WiiMoteEmu::g_ExtKey, &data[17], 0x00, 0x06); + + // Produce string + std::string TmpData = ArrayToString(data, size + 2, 0, 30); //LOGV(WII_IPC_WIIMOTE, 3, " Data: %s", Temp.c_str()); - // Format accelerometer values - if(Temp.length() > 20) + // Format accelerometer values to regular 10 base values + if(TmpData.length() > 20) { - std::string Tmp1 = Temp.substr(0, 12); - std::string Tmp2 = Temp.substr(20, (Temp.length() - 20)); - std::string Temp = Tmp1 + StringFromFormat("%03i %03i %03i", data[4], data[5], data[6]) + Tmp2; + std::string Tmp1 = TmpData.substr(0, 12); + std::string Tmp2 = TmpData.substr(20, (TmpData.length() - 20)); + TmpData = Tmp1 + StringFromFormat("%03i %03i %03i", data[4], data[5], data[6]) + Tmp2; } - - Console::Print("Read[%s]: %s\n", (Emu ? "Emu" : "Real"), Temp.c_str()); // No timestamp + // Format accelerometer values for the Nunchuck to regular 10 base values + if(TmpData.length() > 68 && WiiMoteEmu::g_ReportingMode == 0x37) + { + std::string Tmp1 = TmpData.substr(0, 60); + std::string Tmp2 = TmpData.substr(68, (TmpData.length() - 68)); + TmpData = Tmp1 + StringFromFormat("%03i %03i %03i", data[19], data[20], data[21]) + Tmp2; + } + + Console::Print("Read[%s]: %s\n", (Emu ? "Emu" : "Real"), TmpData.c_str()); // No timestamp //Console::Print(" (%s): %s\n", Tm(true).c_str(), Temp.c_str()); // Timestamp } if(g_DebugAccelerometer) @@ -500,6 +552,10 @@ void InterruptDebugging(bool Emu, const void* _pData) case WM_WRITE_DATA: // 0x16 if (g_DebugComm) Console::Print("WM_WRITE_DATA"); size = sizeof(wm_write_data); + // data[2]: The address space 0, 1 or 2 + // data[3]: The registry type + // data[5]: The registry offset + // data[6]: The number of bytes switch(data[2] >> 0x01) { case WM_SPACE_EEPROM: @@ -511,7 +567,7 @@ void InterruptDebugging(bool Emu, const void* _pData) case 0xa2: if (g_DebugComm) Console::Print(" REG_SPEAKER"); break; case 0xa4: - if (g_DebugComm) Console::Print(" REG_EXT"); break; + if (g_DebugComm) Console::Print(" REG_EXT"); break; case 0xb0: if (g_DebugComm) Console::Print(" REG_IR"); break; } @@ -520,6 +576,10 @@ void InterruptDebugging(bool Emu, const void* _pData) break; case WM_READ_DATA: // 0x17 size = sizeof(wm_read_data); + // data[2]: The address space 0, 1 or 2 + // data[3]: The registry type + // data[5]: The registry offset + // data[7]: The number of bytes, 6 and 7 together if (g_DebugComm) Console::Print("WM_READ_DATA"); switch(data[2] >> 0x01) { diff --git a/Source/Plugins/Plugin_Wiimote/Src/main.h b/Source/Plugins/Plugin_Wiimote/Src/main.h index 315cda82c1..cff3f478eb 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/main.h +++ b/Source/Plugins/Plugin_Wiimote/Src/main.h @@ -39,7 +39,7 @@ void DoInitialize(); double GetDoubleTime(); int GetUpdateRate(); void InterruptDebugging(bool Emu, const void* _pData); -void ReadDebugging(bool Emu, const void* _pData); +void ReadDebugging(bool Emu, const void* _pData, int Size); bool IsFocus(); diff --git a/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.cpp b/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.cpp index f6b431f316..4fe5c3b0df 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.cpp @@ -283,13 +283,15 @@ void SendEvent(SEvent& _rEvent) // Create the buffer memcpy(&Buffer[Offset], _rEvent.m_PayLoad, MAX_PAYLOAD); + /* This Offset value is not exactly correct like it is for the emulated Wiimote reports. It's + often to big, but I guess that's okay. The game will know how big the actual data is. */ Offset += MAX_PAYLOAD; // Send it g_WiimoteInitialize.pWiimoteInput(m_channelID, Buffer, Offset); // Debugging - ReadDebugging(false, Buffer); + ReadDebugging(false, Buffer, Offset); } ///////////////////// };