From 46dccd280a929f13c9fadf50b126ec77c8dc1820 Mon Sep 17 00:00:00 2001 From: John Peterson Date: Fri, 28 Nov 2008 15:44:10 +0000 Subject: [PATCH] Fixed the digital buttons on the emulated Classic Controller, they are Numpad 4, 5, 6, 8 and Z, C, X, Y, 7, 8, 9, 0 so far git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1321 8ced0084-cf51-0410-be5f-012b33b47a6e --- .../Plugins/Plugin_Wiimote/Src/ConfigDlg.cpp | 4 + .../Plugin_Wiimote/Src/DataReports.cpp | 41 ++++- .../Plugin_Wiimote/Src/EmuSubroutines.h | 15 +- .../Plugins/Plugin_Wiimote/Src/FillReport.cpp | 147 +++++++++++++++++- .../Plugins/Plugin_Wiimote/Src/wiimote_hid.h | 40 ++++- 5 files changed, 232 insertions(+), 15 deletions(-) diff --git a/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.cpp b/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.cpp index 05e8a47038..6e6ad19e17 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.cpp @@ -145,6 +145,8 @@ void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event) case ID_NUNCHUCKCONNECTED: g_Config.bNunchuckConnected = m_NunchuckConnected->IsChecked(); // generate connect/disconnect status event + memcpy(WiiMoteEmu::g_RegExt + 0x20, WiiMoteEmu::nunchuck_calibration, + sizeof(WiiMoteEmu::nunchuck_calibration)); memcpy(WiiMoteEmu::g_RegExt + 0xfa, WiiMoteEmu::nunchuck_id, sizeof(WiiMoteEmu::nunchuck_id)); DoExtensionConnectedDisconnected(); break; @@ -152,6 +154,8 @@ void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event) case ID_CLASSICCONTROLLERCONNECTED: g_Config.bClassicControllerConnected = m_ClassicControllerConnected->IsChecked(); // generate connect/disconnect status event + memcpy(WiiMoteEmu::g_RegExt + 0x20, WiiMoteEmu::classic_calibration, + sizeof(WiiMoteEmu::classic_calibration)); memcpy(WiiMoteEmu::g_RegExt + 0xfa, WiiMoteEmu::classic_id, sizeof(WiiMoteEmu::classic_id)); DoExtensionConnectedDisconnected(); break; diff --git a/Source/Plugins/Plugin_Wiimote/Src/DataReports.cpp b/Source/Plugins/Plugin_Wiimote/Src/DataReports.cpp index 17ac8f2661..c57f8592d9 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/DataReports.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/DataReports.cpp @@ -199,10 +199,23 @@ void SendReportCoreAccelExt16(u16 _channelID) Offset += sizeof(wm_report_core_accel_ext16); memset(pReport, 0, sizeof(wm_report_core_accel_ext16)); + // Make a classic extension struct + wm_classic_extension _ext; + memset(&_ext, 0, sizeof(wm_classic_extension)); + FillReportInfo(pReport->c); FillReportAcc(pReport->a); - //FillReportIRBasic(pReport->ir[0], pReport->ir[1]); // no IR here - FillReportExtension(pReport->ext); + + if(g_Config.bNunchuckConnected) + { + FillReportExtension(pReport->ext); + } + else if(g_Config.bClassicControllerConnected) + { + FillReportClassicExtension(_ext); + // Copy _ext to pReport->ext + memcpy(&pReport->ext, &_ext, sizeof(_ext)); + } LOGV(WII_IPC_WIIMOTE, 2, " SendReportCoreAccelExt16 (0x35)"); LOGV(WII_IPC_WIIMOTE, 2, " Channel: %04x", _channelID); @@ -210,11 +223,11 @@ void SendReportCoreAccelExt16(u16 _channelID) // Debugging #ifdef _WIN32 - /*if(GetAsyncKeyState('V')) + /**/if(GetAsyncKeyState('V')) { std::string Temp = WiiMoteEmu::ArrayToString(DataFrame, Offset, 0, 30); wprintf("DataFrame: %s\n", Temp.c_str()); - }*/ + } #endif g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset); } @@ -232,20 +245,34 @@ void SendReportCoreAccelIr10Ext(u16 _channelID) Offset += sizeof(wm_report_core_accel_ir10_ext6); memset(pReport, 0, sizeof(wm_report_core_accel_ir10_ext6)); + // Make a classic extension struct + wm_classic_extension _ext; + memset(&_ext, 0, sizeof(wm_classic_extension)); + FillReportInfo(pReport->c); FillReportAcc(pReport->a); FillReportIRBasic(pReport->ir[0], pReport->ir[1]); - FillReportExtension(pReport->ext); + + if(g_Config.bNunchuckConnected) + { + FillReportExtension(pReport->ext); + } + else if(g_Config.bClassicControllerConnected) + { + FillReportClassicExtension(_ext); + // Copy _ext to pReport->ext + memcpy(&pReport->ext, &_ext, sizeof(_ext)); + } LOGV(WII_IPC_WIIMOTE, 2, " SendReportCoreAccelIr10Ext()"); // Debugging #ifdef _WIN32 - /*if(GetAsyncKeyState('V')) + /**/if(GetAsyncKeyState('V')) { std::string Temp = WiiMoteEmu::ArrayToString(DataFrame, Offset, 0, 30); wprintf("DataFrame: %s\n", Temp.c_str()); - }*/ + } #endif g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset); } diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuSubroutines.h b/Source/Plugins/Plugin_Wiimote/Src/EmuSubroutines.h index dc9b6e567a..e792def5e2 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/EmuSubroutines.h +++ b/Source/Plugins/Plugin_Wiimote/Src/EmuSubroutines.h @@ -83,6 +83,17 @@ static const u8 nunchuck_calibration[] = 0xe0,0x20,0x80,0xe0, 0x20,0x80,0xee,0x43 }; +/* Classic Controller calibration */ +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, + 0x80,0xd8,0x28,0x80, 0x20,0x20,0x95,0xea +}; + + + /* The Nunchuck id. It should be written to the last bytes of the extension register */ @@ -95,7 +106,7 @@ static const u8 nunchuck_id[] = extension register */ static const u8 classic_id[] = { - 0x00, 0x00, 0x00, 0x00, 0x01, 0x01 + 0x00, 0x00, 0xa4, 0x20, 0x01, 0x01 }; /* The id for nothing inserted */ @@ -136,7 +147,7 @@ void FillReportInfo(wm_core& _core); void FillReportIR(wm_ir_extended& _ir0, wm_ir_extended& _ir1); void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1); void FillReportExtension(wm_extension& _ext); - +void FillReportClassicExtension(wm_classic_extension& _ext); u32 convert24bit(const u8* src); u16 convert16bit(const u8* src); diff --git a/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp b/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp index a99dff5a82..9abcb7f435 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp @@ -485,7 +485,7 @@ void FillReportExtension(wm_extension& _ext) _ext.jx = 0x80; // these are the default values unless we use them _ext.jy = 0x80; _ext.bt = 0x03; // 0x03 means no button pressed, the button is zero active - + #ifdef _WIN32 if(GetAsyncKeyState(VK_NUMPAD4)) @@ -519,24 +519,161 @@ void FillReportExtension(wm_extension& _ext) /* Write the nunchuck inputs to it. We begin writing at 0x08, but it could also be 0x00, the important thing is that we begin at an address evenly divisible - by 0x08 */ + by 0x08 g_RegExtTmp[0x08] = _ext.jx; g_RegExtTmp[0x09] = _ext.jy; g_RegExtTmp[0x0a] = _ext.ax; g_RegExtTmp[0x0b] = _ext.ay; g_RegExtTmp[0x0c] = _ext.az; - g_RegExtTmp[0x0d] = _ext.bt; + g_RegExtTmp[0x0d] = _ext.bt; */ + memcpy(g_RegExtTmp + 0x08, &_ext, sizeof(_ext)); // Encrypt it - wiimote_encrypt(&g_ExtKey, &g_RegExtTmp[0x08], 0x08, 0x06); + wiimote_encrypt(&g_ExtKey, &g_RegExtTmp[0x08], 0x08, sizeof(_ext)); // Write it back + /* _ext.jx = g_RegExtTmp[0x08]; _ext.jy = g_RegExtTmp[0x09]; _ext.ax = g_RegExtTmp[0x0a]; _ext.ay = g_RegExtTmp[0x0b]; _ext.az = g_RegExtTmp[0x0c]; - _ext.bt = g_RegExtTmp[0x0d]; + _ext.bt = g_RegExtTmp[0x0d];*/ + memcpy(&_ext, &g_RegExtTmp[0x08], sizeof(_ext)); +} + + +// =================================================== +/* Generate the 6 byte extension report for the Classic Controller, encrypted. + The bytes are ... */ +// ---------------- +void FillReportClassicExtension(wm_classic_extension& _ext) +{ + + /* These are the default neutral values for the nunchuck accelerometer according + to a source. + _ext.ax = 0x80; + _ext.ay = 0x80; + _ext.az = 0xb3; */ + + _ext.b1.padding = 0x01; // these are the default values unless we use them + _ext.b1.bRT = 0x01; + _ext.b1.bP = 0x01; + _ext.b1.bH = 0x01; + _ext.b1.bM = 0x01; + _ext.b1.bLT = 0x01; + _ext.b1.bdD = 0x01; + _ext.b1.bdR = 0x01; + + _ext.b2.bdU = 0x01; + _ext.b2.bdL = 0x01; + _ext.b2.bZR = 0x01; + _ext.b2.bX = 0x01; + _ext.b2.bA = 0x01; + _ext.b2.bY = 0x01; + _ext.b2.bB = 0x01; + _ext.b2.bZL = 0x01; + + //_ext.bt = 0x03; // 0x03 means no button pressed, the button is zero active + + /* + _ir0.y2 = y2 & 0xff; + _ir0.x2Hi = (x2 >> 8); + _ir0.y2Hi = (y2 >> 8); + + // I don't understand't the & 0x03, should we do that? + //_ir1.x1Hi = (x1 >> 8) & 0x3;*/ + + + + // -------------------------------------- + /* D-Pad + + u8 b1; + 0: + 6: bdD + 7: bdR + + u8 b2; + 0: bdU + 1: bdL + */ +#ifdef _WIN32 + if(GetAsyncKeyState(VK_NUMPAD4)) // left + _ext.b2.bdL = 0x00; + + if(GetAsyncKeyState(VK_NUMPAD8)) // up + _ext.b2.bdU = 0x00; + + if(GetAsyncKeyState(VK_NUMPAD6)) // right + _ext.b1.bdR = 0x00; + + if(GetAsyncKeyState(VK_NUMPAD5)) // down + _ext.b1.bdD = 0x00; + // -------------- + + + // -------------------------------------- + /* Buttons + u8 b1; + 0: + 6: - + 7: - + + u8 b2; + 0: - + 1: - + 2: bZr + 3: bX + 4: bA + 5: bY + 6: bB + 7: bZl + */ + if(GetAsyncKeyState('Z')) + _ext.b2.bA = 0x00; + + if(GetAsyncKeyState('C')) + _ext.b2.bB = 0x00; + + if(GetAsyncKeyState('Y')) + _ext.b2.bY = 0x00; + + if(GetAsyncKeyState('X')) + _ext.b2.bX = 0x00; + + if(GetAsyncKeyState('7')) // digital left trigger + _ext.b1.bLT = 0x00; + + if(GetAsyncKeyState('8')) + _ext.b2.bZL = 0x00; + + if(GetAsyncKeyState('9')) + _ext.b2.bZR = 0x00; + + if(GetAsyncKeyState('0')) // digital right trigger + _ext.b1.bRT = 0x00; + + // All buttons pressed + if(GetAsyncKeyState('C') && GetAsyncKeyState('Z')) + { _ext.b2.bA = 0x01; _ext.b2.bB = 0x01; } + // -------------- +#else + // TODO linux port +#endif + + + // Clear g_RegExtTmp by copying zeroes to it + memset(g_RegExtTmp, 0, sizeof(g_RegExtTmp)); + + /* Write the nunchuck inputs to it. We begin writing at 0x08, see comment above. */ + memcpy(g_RegExtTmp + 0x08, &_ext, sizeof(_ext)); + + // Encrypt it + wiimote_encrypt(&g_ExtKey, &g_RegExtTmp[0x08], 0x08, 0x06); + + // Write it back + memcpy(&_ext, &g_RegExtTmp[0x08], sizeof(_ext)); } diff --git a/Source/Plugins/Plugin_Wiimote/Src/wiimote_hid.h b/Source/Plugins/Plugin_Wiimote/Src/wiimote_hid.h index e8237d67e0..42515e8f69 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/wiimote_hid.h +++ b/Source/Plugins/Plugin_Wiimote/Src/wiimote_hid.h @@ -186,6 +186,45 @@ struct wm_extension u8 bt; // buttons }; +struct wm_cc_4 +{ + u8 padding : 1; + u8 bRT : 1; + u8 bP : 1; + u8 bH : 1; + u8 bM : 1; + u8 bLT : 1; + u8 bdD : 1; + u8 bdR : 1; +}; + +struct wm_cc_5 +{ + u8 bdU : 1; + u8 bdL : 1; + u8 bZR : 1; + u8 bX : 1; + u8 bA : 1; + u8 bY : 1; + u8 bB : 1; + u8 bZL : 1; +}; + +struct wm_classic_extension +{ + u8 Lx : 6; // byte 0 + u8 Rx : 2; + u8 Ly : 6; // byte 1 + u8 Rx2 : 2; + u8 Ry : 5; // byte 2 + u8 lT : 2; + u8 Rx3 : 1; + u8 rT : 5; // byte 3 + u8 lT2 : 3; + wm_cc_4 b1; // byte 4 + wm_cc_5 b2; // byte 5 +}; + #define WM_REPORT_CORE 0x30 struct wm_report_core { wm_core c; @@ -230,7 +269,6 @@ struct wm_report_core_accel_ir10_ext6 wm_extension ext; }; - #define WM_REPORT_EXT21 0x3d // never used? struct wm_report_ext21 {