diff --git a/Source/Core/Common/Src/ExtendedTrace.cpp b/Source/Core/Common/Src/ExtendedTrace.cpp index 8cc0ac486a..f1dafa610e 100644 --- a/Source/Core/Common/Src/ExtendedTrace.cpp +++ b/Source/Core/Common/Src/ExtendedTrace.cpp @@ -430,7 +430,7 @@ void etfprintf(FILE *file, const char *format, ...) { } void etfprint(FILE *file, const std::string &text) { - int len = text.length(); + size_t len = text.length(); fwrite(text.data(), 1, len, file); } diff --git a/Source/Core/Core/Src/Core.cpp b/Source/Core/Core/Src/Core.cpp index fb86f4e327..0c480730e6 100644 --- a/Source/Core/Core/Src/Core.cpp +++ b/Source/Core/Core/Src/Core.cpp @@ -75,6 +75,8 @@ void Callback_VideoCopiedToXFB(); void Callback_DSPLog(const TCHAR* _szMessage); void Callback_DSPInterrupt(); void Callback_PADLog(const TCHAR* _szMessage); +void Callback_WiimoteLog(const TCHAR* _szMessage); +void Callback_WiimoteInput(const void* _pData, u32 _Size); // For keyboard shortcuts. void Callback_KeyPress(int key, BOOL shift, BOOL control); @@ -304,6 +306,13 @@ THREAD_RETURN EmuThread(void *pArg) PADInitialize.pLog = Callback_PADLog; PluginPAD::PAD_Initialize(PADInitialize); + // Load and Init WiimotePlugin + SWiimoteInitialize WiimoteInitialize; + WiimoteInitialize.hWnd = g_pWindowHandle; + WiimoteInitialize.pLog = Callback_WiimoteLog; + WiimoteInitialize.pWiimoteInput = Callback_WiimoteInput; + PluginWiimote::Wiimote_Initialize(WiimoteInitialize); + // The hardware is initialized. g_bHwInit = true; @@ -553,4 +562,12 @@ void Callback_KeyPress(int key, BOOL shift, BOOL control) } } +// __________________________________________________________________________________________________ +// Callback_WiimoteLog +// +void Callback_WiimoteLog(const TCHAR* _szMessage) +{ + LOG(WIIMOTE, _szMessage); +} + } // end of namespace Core diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h index 1933624a45..eaabfa3be9 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h @@ -198,7 +198,7 @@ private: u16 Host_num_acl_pkts; /* Max. number of ACL packets */ u16 Host_num_sco_pkts; /* Max. number of SCO packets */ - +public: //hack for wiimote plugin std::vector m_WiiMotes; CWII_IPC_HLE_WiiMote* AccessWiiMote(const bdaddr_t& _rAddr); CWII_IPC_HLE_WiiMote* AccessWiiMote(u16 _ConnectionHandle); 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 821995cf18..7d4db2a573 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 @@ -16,10 +16,10 @@ // http://code.google.com/p/dolphin-emu/ #include "Common.h" +#include "../Plugins/Plugin_Wiimote.h" #include "WII_IPC_HLE_WiiMote.h" #include "l2cap.h" -#include "wiimote_hid.h" #if defined(_MSC_VER) #pragma pack(push, 1) @@ -119,28 +119,20 @@ struct SL2CAP_CommandConfigurationResponse // 0x05 #pragma pack(pop) #endif -static const u8 EepromData_0[] = { - 0xA1, 0xAA, 0x8B, 0x99, 0xAE, 0x9E, 0x78, 0x30, - 0xA7, 0x74, 0xD3, 0xA1, 0xAA, 0x8B, 0x99, 0xAE, - 0x9E, 0x78, 0x30, 0xA7, 0x74, 0xD3, 0x82, 0x82, - 0x82, 0x15, 0x9C, 0x9C, 0x9E, 0x38, 0x40, 0x3E, - 0x82, 0x82, 0x82, 0x15, 0x9C, 0x9C, 0x9E, 0x38, - 0x40, 0x3E -}; +static CWII_IPC_HLE_Device_usb_oh1_57e_305* s_Usb; -static const u8 EepromData_16D0[] = { - 0x00, 0x00, 0x00, 0xFF, 0x11, 0xEE, 0x00, 0x00, - 0x33, 0xCC, 0x44, 0xBB, 0x00, 0x00, 0x66, 0x99, - 0x77, 0x88, 0x00, 0x00, 0x2B, 0x01, 0xE8, 0x13 -}; +namespace Core { + void Callback_WiimoteInput(const void* _pData, u32 _Size) { + s_Usb->m_WiiMotes[0].SendL2capData(HID_OUTPUT_SCID, _pData, _Size); + } +} CWII_IPC_HLE_WiiMote::CWII_IPC_HLE_WiiMote(CWII_IPC_HLE_Device_usb_oh1_57e_305* _pHost, int _Number) : m_Name("Nintendo RVL-CNT-01") , m_pHost(_pHost) { - memset(m_Eeprom, 0, WIIMOTE_EEPROM_SIZE); - memcpy(m_Eeprom, EepromData_0, sizeof(EepromData_0)); - memcpy(m_Eeprom + 0x16D0, EepromData_16D0, sizeof(EepromData_16D0)); + s_Usb = _pHost; + LOG(WIIMOTE, "Wiimote %i constructed", _Number); m_BD.b[0] = 0x11; m_BD.b[1] = 0x02; @@ -317,277 +309,14 @@ void CWII_IPC_HLE_WiiMote::SignalChannel(u8* _pData, u32 _Size) void CWII_IPC_HLE_WiiMote::HidOutput(u8* _pData, u32 _Size) { - // dump raw data - { - LOG(WIIMOTE, "HidOutput"); - std::string Temp; - for (u32 j=0; j<_Size; j++) - { - char Buffer[128]; - sprintf(Buffer, "%02x ", _pData[j]); - Temp.append(Buffer); - } - LOG(WIIMOTE, " Data: %s", Temp.c_str()); - } - - hid_packet* hidp = (hid_packet*) _pData; - - if(hidp->type == HID_TYPE_SET_REPORT && - hidp->param == HID_PARAM_OUTPUT) - { - HidOutputReport((wm_report*)hidp->data); - } else if(hidp->type == HID_TYPE_HANDSHAKE && - hidp->param == HID_HANDSHAKE_WIIMOTE) - { - PanicAlert("HidOutput: Wiimote handshake?"); - } else { - PanicAlert("HidOutput: Unknown type 0x%02x", _pData[0]); - } + PluginWiimote::Wiimote_Output(_pData, _Size); //return handshake - hid_packet handshake; - handshake.type = HID_TYPE_HANDSHAKE; - handshake.param = HID_HANDSHAKE_SUCCESS; + u8 handshake = 0; SendL2capData(HID_OUTPUT_SCID, &handshake, 1); } -static u32 convert24bit(const u8* src) { - return (src[0] << 16) | (src[1] << 8) | src[2]; -} - -static u16 convert16bit(const u8* src) { - return (src[0] << 8) | src[1]; -} - -void CWII_IPC_HLE_WiiMote::HidOutputReport(wm_report* sr) { - LOG(WIIMOTE, " HidOutputReport(0x%02x)", sr->channel); - - switch(sr->channel) - { - case WM_LEDS: - WmLeds((wm_leds*)sr->data); - break; - case WM_READ_DATA: - WmReadData((wm_read_data*)sr->data); - break; - case WM_REQUEST_STATUS: - WmRequestStatus((wm_request_status*)sr->data); - break; - case WM_IR_PIXEL_CLOCK: - case WM_IR_LOGIC: - LOG(WIIMOTE, " IR Enable 0x%02x 0x%02x", sr->channel, sr->data[0]); - break; - case WM_WRITE_DATA: - WmWriteData((wm_write_data*)sr->data); - break; - case WM_DATA_REPORTING: - WmDataReporting((wm_data_reporting*)sr->data); - break; - - default: - PanicAlert("HidOutputReport: Unknown channel 0x%02x", sr->channel); - return; - } -} - -void CWII_IPC_HLE_WiiMote::WmLeds(wm_leds* leds) { - LOG(WIIMOTE, " Set LEDs"); - LOG(WIIMOTE, " Leds: %x", leds->leds); - LOG(WIIMOTE, " Rumble: %x", leds->rumble); - - m_Leds = leds->leds; -} - -void CWII_IPC_HLE_WiiMote::WmDataReporting(wm_data_reporting* dr) { - LOG(WIIMOTE, " Set Data reporting mode"); - LOG(WIIMOTE, " Continuous: %x", dr->continuous); - LOG(WIIMOTE, " Rumble: %x", dr->rumble); - LOG(WIIMOTE, " Mode: 0x%02x", dr->mode); - - if(dr->mode == 0x33) - SendReportCoreAccelIr12(); - else if(dr->mode == 0x31) - SendReportCoreAccel(); -} - -void CWII_IPC_HLE_WiiMote::SendReportCoreAccelIr12() { - u8 DataFrame[1024]; - u32 Offset = WriteWmReport(DataFrame, WM_REPORT_CORE_ACCEL_IR12); - - wm_report_core_accel_ir12* pReport = (wm_report_core_accel_ir12*)(DataFrame + Offset); - Offset += sizeof(wm_report_core_accel_ir12); - memset(pReport, 0, sizeof(wm_report_core_accel_ir12)); - memset(pReport->ir, 0xFF, sizeof(pReport->ir)); - pReport->c.b = 1; - pReport->a.x = 0x81; - pReport->a.y = 0x78; - pReport->a.z = 0xD9; - pReport->ir[0].x = 320 & 0xFF; - pReport->ir[0].y = 240; - pReport->ir[0].size = 10; - pReport->ir[0].xHi = 320 >> 8; - pReport->ir[0].yHi = 0; - - LOG(WIIMOTE, " SendReportCoreAccelIr12()"); - - SendL2capData(HID_INPUT_SCID, DataFrame, Offset); -} - -void CWII_IPC_HLE_WiiMote::SendReportCoreAccel() { - u8 DataFrame[1024]; - u32 Offset = WriteWmReport(DataFrame, WM_REPORT_CORE_ACCEL); - - wm_report_core_accel* pReport = (wm_report_core_accel*)(DataFrame + Offset); - Offset += sizeof(wm_report_core_accel); - memset(pReport, 0, sizeof(wm_report_core_accel)); - pReport->c.a = 1; - pReport->a.x = 0x82; - pReport->a.y = 0x75; - pReport->a.z = 0xD6; - - LOG(WIIMOTE, " SendReportCoreAccel()"); - - SendL2capData(HID_INPUT_SCID, DataFrame, Offset); -} - -void CWII_IPC_HLE_WiiMote::WmReadData(wm_read_data* rd) { - u32 address = convert24bit(rd->address); - u16 size = convert16bit(rd->size); - LOG(WIIMOTE, " Read data"); - LOG(WIIMOTE, " Address space: %x", rd->space); - LOG(WIIMOTE, " Address: 0x%06x", address); - LOG(WIIMOTE, " Size: 0x%04x", size); - LOG(WIIMOTE, " Rumble: %x", rd->rumble); - - if(size <= 16 && rd->space == 0) { - SendReadDataReply(m_Eeprom, address, (u8)size); - } else { - PanicAlert("WmReadData: unimplemented parameters!"); - } -} - -void CWII_IPC_HLE_WiiMote::WmWriteData(wm_write_data* wd) { - u32 address = convert24bit(wd->address); - LOG(WIIMOTE, " Write data"); - LOG(WIIMOTE, " Address space: %x", wd->space); - LOG(WIIMOTE, " Address: 0x%06x", address); - LOG(WIIMOTE, " Size: 0x%02x", wd->size); - LOG(WIIMOTE, " Rumble: %x", wd->rumble); - - if(wd->size <= 16 && wd->space == WM_SPACE_EEPROM) - { - if(address + wd->size > WIIMOTE_EEPROM_SIZE) { - PanicAlert("WmWriteData: address + size out of bounds!"); - return; - } - memcpy(m_Eeprom + address, wd->data, wd->size); - SendWriteDataReply(); - } - else if(wd->size <= 16 && (wd->space == WM_SPACE_REGS1 || wd->space == WM_SPACE_REGS2)) - { - u8* block; - u32 blockSize; - switch((address >> 16) & 0xFE) { - case 0xA2: - block = m_RegSpeaker; - blockSize = WIIMOTE_REG_SPEAKER_SIZE; - break; - case 0xA4: - block = m_RegExt; - blockSize = WIIMOTE_REG_EXT_SIZE; - break; - case 0xB0: - block = m_RegIr; - blockSize = WIIMOTE_REG_IR_SIZE; - break; - default: - PanicAlert("WmWriteData: bad register block!"); - return; - } - address &= 0xFFFF; - if(address + wd->size > blockSize) { - PanicAlert("WmWriteData: address + size out of bounds!"); - return; - } - memcpy(block + address, wd->data, wd->size); - SendWriteDataReply(); - } else { - PanicAlert("WmWriteData: unimplemented parameters!"); - } -} - -void CWII_IPC_HLE_WiiMote::SendWriteDataReply() { - u8 DataFrame[1024]; - u32 Offset = WriteWmReport(DataFrame, WM_WRITE_DATA_REPLY); - - LOG(WIIMOTE, " SendWriteDataReply()"); - - SendL2capData(HID_INPUT_SCID, DataFrame, Offset); -} - -int CWII_IPC_HLE_WiiMote::WriteWmReport(u8* dst, u8 channel) { - u32 Offset = 0; - hid_packet* pHidHeader = (hid_packet*)(dst + Offset); - Offset += sizeof(hid_packet); - pHidHeader->type = HID_TYPE_DATA; - pHidHeader->param = HID_PARAM_INPUT; - - wm_report* pReport = (wm_report*)(dst + Offset); - Offset += sizeof(wm_report); - pReport->channel = channel; - return Offset; -} - -void CWII_IPC_HLE_WiiMote::WmRequestStatus(wm_request_status* rs) { - LOG(WIIMOTE, " Request Status"); - LOG(WIIMOTE, " Rumble: %x", rs->rumble); - - //SendStatusReport(); - u8 DataFrame[1024]; - u32 Offset = WriteWmReport(DataFrame, WM_STATUS_REPORT); - - wm_status_report* pStatus = (wm_status_report*)(DataFrame + Offset); - Offset += sizeof(wm_status_report); - memset(pStatus, 0, sizeof(wm_status_report)); - pStatus->leds = m_Leds; - pStatus->ir = 1; - pStatus->battery = 100; //arbitrary number - - LOG(WIIMOTE, " SendStatusReport()"); - LOG(WIIMOTE, " Flags: 0x%02x", pStatus->padding1[2]); - LOG(WIIMOTE, " Battery: %d", pStatus->battery); - - SendL2capData(HID_INPUT_SCID, DataFrame, Offset); -} - -void CWII_IPC_HLE_WiiMote::SendReadDataReply(void* _Base, u16 _Address, u8 _Size) -{ - u8 DataFrame[1024]; - u32 Offset = WriteWmReport(DataFrame, WM_READ_DATA_REPLY); - - _dbg_assert_(WIIMOTE, _Size <= 16); - - 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 = _Size - 1; - pReply->address = Common::swap16(_Address); - memcpy(pReply->data, _Base, _Size); - if(_Size < 16) { - memset(pReply->data + _Size, 0, 16 - _Size); - } - - LOG(WIIMOTE, " SendReadDataReply()"); - LOG(WIIMOTE, " Buttons: 0x%04x", pReply->buttons); - LOG(WIIMOTE, " Error: 0x%x", pReply->error); - LOG(WIIMOTE, " Size: 0x%x", pReply->size); - LOG(WIIMOTE, " Address: 0x%04x", pReply->address); - - SendL2capData(HID_INPUT_SCID, DataFrame, Offset); -} - -void CWII_IPC_HLE_WiiMote::SendL2capData(u16 scid, void* _pData, u32 _Size) +void CWII_IPC_HLE_WiiMote::SendL2capData(u16 scid, const void* _pData, u32 _Size) { //allocate u8 DataFrame[1024]; diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.h index 5e151d25a5..104db53b36 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.h @@ -20,18 +20,7 @@ #include #include "WII_IPC_HLE_Device_usb.h" -#define WIIMOTE_EEPROM_SIZE (16*1024) -#define WIIMOTE_REG_SPEAKER_SIZE 10 -#define WIIMOTE_REG_EXT_SIZE 0x100 -#define WIIMOTE_REG_IR_SIZE 0x34 - class CWII_IPC_HLE_Device_usb_oh1_57e_305; -struct wm_report; -struct wm_leds; -struct wm_read_data; -struct wm_request_status; -struct wm_write_data; -struct wm_data_reporting; class CWII_IPC_HLE_WiiMote { @@ -52,10 +41,12 @@ public: const char* GetName() const { return m_Name.c_str(); } - void SendACLFrame(u8* _pData, u32 _Size); + void SendACLFrame(u8* _pData, u32 _Size); //to wiimote void Connect(); + void SendL2capData(u16 scid, const void* _pData, u32 _Size); //from wiimote + private: // STATE_TO_SAVE @@ -67,19 +58,10 @@ private: u8 features[HCI_FEATURES_SIZE]; - u8 m_Eeprom[WIIMOTE_EEPROM_SIZE]; - - u8 m_RegSpeaker[WIIMOTE_REG_SPEAKER_SIZE]; - u8 m_RegExt[WIIMOTE_REG_EXT_SIZE]; - u8 m_RegIr[WIIMOTE_REG_IR_SIZE]; - std::string m_Name; CWII_IPC_HLE_Device_usb_oh1_57e_305* m_pHost; - u8 m_Leds; - - struct SChannel { u16 SCID; @@ -96,30 +78,14 @@ private: return m_Channel.find(_SCID) != m_Channel.end(); } - void SendL2capData(u16 scid, void* _pData, u32 _Size); - void SendCommandToACL(u8 _Ident, u8 _Code, u8 _CommandLength, u8* _pCommandData); void SignalChannel(u8* _pData, u32 _Size); void HidOutput(u8* _pData, u32 _Size); - void HidOutputReport(wm_report* sr); - - void WmLeds(wm_leds* leds); - void WmReadData(wm_read_data* rd); - void WmWriteData(wm_write_data* wd); - void WmRequestStatus(wm_request_status* rs); - void WmDataReporting(wm_data_reporting* dr); - void SendConnectionRequest(u16 scid, u16 psm); void SendConfigurationRequest(u16 scid); - void SendReadDataReply(void* _Base, u16 _Address, u8 _Size); - void SendWriteDataReply(); - void SendReportCoreAccel(); - void SendReportCoreAccelIr12(); - - int WriteWmReport(u8* dst, u8 channel); void CommandConnectionReq(u8 _Ident, u8* _pData, u32 _Size); void CommandCofigurationReq(u8 _Ident, u8* _pData, u32 _Size); diff --git a/Source/Core/Core/Src/Plugins/Plugin_Wiimote.cpp b/Source/Core/Core/Src/Plugins/Plugin_Wiimote.cpp index 7226d5f0a4..5300ab8a3b 100644 --- a/Source/Core/Core/Src/Plugins/Plugin_Wiimote.cpp +++ b/Source/Core/Core/Src/Plugins/Plugin_Wiimote.cpp @@ -15,6 +15,7 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ +#include "Common.h" #include "DynamicLibrary.h" #include "Plugin_Wiimote.h" @@ -58,6 +59,7 @@ namespace PluginWiimote { if (plugin.Load(_Filename)) { + LOG(MASTER_LOG, "getting Wiimote Plugin function pointers..."); GetDllInfo = reinterpret_cast (plugin.Get("GetDllInfo")); DllAbout = reinterpret_cast (plugin.Get("DllAbout")); DllConfig = reinterpret_cast (plugin.Get("DllConfig")); @@ -67,6 +69,14 @@ namespace PluginWiimote Wiimote_GetAttachedControllers = reinterpret_cast (plugin.Get("Wiimote_GetAttachedControllers")); Wiimote_DoState = reinterpret_cast (plugin.Get("Wiimote_DoState")); + LOG(MASTER_LOG, "%s: 0x%p", "GetDllInfo", GetDllInfo); + LOG(MASTER_LOG, "%s: 0x%p", "DllAbout", DllAbout); + LOG(MASTER_LOG, "%s: 0x%p", "DllConfig", DllConfig); + LOG(MASTER_LOG, "%s: 0x%p", "Wiimote_Initialize", Wiimote_Initialize); + LOG(MASTER_LOG, "%s: 0x%p", "Wiimote_Shutdown", Wiimote_Shutdown); + LOG(MASTER_LOG, "%s: 0x%p", "Wiimote_Output", Wiimote_Output); + LOG(MASTER_LOG, "%s: 0x%p", "Wiimote_GetAttachedControllers", Wiimote_GetAttachedControllers); + LOG(MASTER_LOG, "%s: 0x%p", "Wiimote_DoState", Wiimote_DoState); if ((GetDllInfo != 0) && (Wiimote_Initialize != 0) && (Wiimote_Shutdown != 0) && diff --git a/Source/PluginSpecs/pluginspecs_wiimote.h b/Source/PluginSpecs/pluginspecs_wiimote.h index 61473e2fa7..420656c103 100644 --- a/Source/PluginSpecs/pluginspecs_wiimote.h +++ b/Source/PluginSpecs/pluginspecs_wiimote.h @@ -13,7 +13,7 @@ typedef void (*TLog)(const char* _pMessage); // Called when the Wiimote sends input reports to the Core. -// Payload: an HID packet. +// Payload: an L2CAP packet. typedef void (*TWiimoteInput)(const void* _pData, u32 _Size); // This data is passed from the core on initialization. @@ -75,7 +75,8 @@ EXPORT void CALL Wiimote_Shutdown(); // __________________________________________________________________________________________________ // Function: Wiimote_Output -// Purpose: An HID packed is passed from the Core to the Wiimote. +// Purpose: An L2CAP packet is passed from the Core to the Wiimote, +// on the HID OUTPUT channel. // input: Da pakket. // output: none // diff --git a/Source/Plugins/Plugin_Wiimote_Test/Plugin_Wiimote_Test.vcproj b/Source/Plugins/Plugin_Wiimote_Test/Plugin_Wiimote_Test.vcproj index b6239b07ca..617d52adce 100644 --- a/Source/Plugins/Plugin_Wiimote_Test/Plugin_Wiimote_Test.vcproj +++ b/Source/Plugins/Plugin_Wiimote_Test/Plugin_Wiimote_Test.vcproj @@ -44,7 +44,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="..\..\PluginSpecs;..\..\..\Externals\SDL\include;..\..\Core\Common\Src;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc" - PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PLUGIN_WIIMOTE_TEST_EXPORTS" + PreprocessorDefinitions="LOGGING;WIN32;_DEBUG;_WINDOWS;_USRDLL;PLUGIN_WIIMOTE_TEST_EXPORTS" MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="1" @@ -375,7 +375,7 @@ + + diff --git a/Source/Plugins/Plugin_Wiimote_Test/Src/SConscript b/Source/Plugins/Plugin_Wiimote_Test/Src/SConscript index 92a2421571..a3f94b104e 100644 --- a/Source/Plugins/Plugin_Wiimote_Test/Src/SConscript +++ b/Source/Plugins/Plugin_Wiimote_Test/Src/SConscript @@ -7,7 +7,7 @@ else: output = "../../../../Binary/linux/Plugins/Plugin_Wiimote.so" files = [ - "main.cpp", + "Wiimote_Test.cpp", ] padenv = env.Copy() diff --git a/Source/Plugins/Plugin_Wiimote_Test/Src/Wiimote_Test.cpp b/Source/Plugins/Plugin_Wiimote_Test/Src/Wiimote_Test.cpp new file mode 100644 index 0000000000..7e475c2405 --- /dev/null +++ b/Source/Plugins/Plugin_Wiimote_Test/Src/Wiimote_Test.cpp @@ -0,0 +1,388 @@ +#include + +#include "Common.h" +#include "StringUtil.h" + +#include "pluginspecs_wiimote.h" + +#include "wiimote_hid.h" + +SWiimoteInitialize g_WiimoteInitialize; +#define VERSION_STRING "0.1" + +//****************************************************************************** +// Definitions and variable declarations +//****************************************************************************** +#define WIIMOTE_EEPROM_SIZE (16*1024) +#define WIIMOTE_REG_SPEAKER_SIZE 10 +#define WIIMOTE_REG_EXT_SIZE 0x100 +#define WIIMOTE_REG_IR_SIZE 0x34 + +u8 g_Leds; + +u8 g_Eeprom[WIIMOTE_EEPROM_SIZE]; + +u8 g_RegSpeaker[WIIMOTE_REG_SPEAKER_SIZE]; +u8 g_RegExt[WIIMOTE_REG_EXT_SIZE]; +u8 g_RegIr[WIIMOTE_REG_IR_SIZE]; + +static const u8 EepromData_0[] = { + 0xA1, 0xAA, 0x8B, 0x99, 0xAE, 0x9E, 0x78, 0x30, + 0xA7, 0x74, 0xD3, 0xA1, 0xAA, 0x8B, 0x99, 0xAE, + 0x9E, 0x78, 0x30, 0xA7, 0x74, 0xD3, 0x82, 0x82, + 0x82, 0x15, 0x9C, 0x9C, 0x9E, 0x38, 0x40, 0x3E, + 0x82, 0x82, 0x82, 0x15, 0x9C, 0x9C, 0x9E, 0x38, + 0x40, 0x3E +}; + +static const u8 EepromData_16D0[] = { + 0x00, 0x00, 0x00, 0xFF, 0x11, 0xEE, 0x00, 0x00, + 0x33, 0xCC, 0x44, 0xBB, 0x00, 0x00, 0x66, 0x99, + 0x77, 0x88, 0x00, 0x00, 0x2B, 0x01, 0xE8, 0x13 +}; + +//****************************************************************************** +// Subroutine declarations +//****************************************************************************** +void __Log(int log, const char *format, ...) +{ + char* temp = (char*)alloca(strlen(format)+512); + va_list args; + va_start(args, format); + CharArrayFromFormatV(temp, 512, format, args); + va_end(args); + g_WiimoteInitialize.pLog(temp); +} +//void PanicAlert(const char* fmt, ...); + +void HidOutputReport(wm_report* sr); + +void WmLeds(wm_leds* leds); +void WmReadData(wm_read_data* rd); +void WmWriteData(wm_write_data* wd); +void WmRequestStatus(wm_request_status* rs); +void WmDataReporting(wm_data_reporting* dr); + +void SendReadDataReply(void* _Base, u16 _Address, u8 _Size); +void SendWriteDataReply(); +void SendReportCoreAccel(); +void SendReportCoreAccelIr12(); + +int WriteWmReport(u8* dst, u8 channel); + +static u32 convert24bit(const u8* src) { + return (src[0] << 16) | (src[1] << 8) | src[2]; +} + +static u16 convert16bit(const u8* src) { + return (src[0] << 8) | src[1]; +} + +//****************************************************************************** +// Exports +//****************************************************************************** +extern "C" void GetDllInfo (PLUGIN_INFO* _PluginInfo) +{ + _PluginInfo->Version = 0x0100; + _PluginInfo->Type = PLUGIN_TYPE_WIIMOTE; +#ifdef DEBUGFAST + sprintf(_PluginInfo->Name, "Wiimote Test (DebugFast) " VERSION_STRING); +#else +#ifndef _DEBUG + sprintf(_PluginInfo->Name, "Wiimote Test " VERSION_STRING); +#else + sprintf(_PluginInfo->Name, "Wiimote Test (Debug) " VERSION_STRING); +#endif +#endif +} + + +extern "C" void DllAbout(HWND _hParent) +{ + wxAboutDialogInfo info; + info.AddDeveloper(_T("masken (masken3@gmail.com)")); + info.SetDescription(_T("Wiimote test plugin")); + wxAboutBox(info); +} + +extern "C" void DllConfig(HWND _hParent) +{ +} + + +extern "C" void Wiimote_Initialize(SWiimoteInitialize _WiimoteInitialize) +{ + g_WiimoteInitialize = _WiimoteInitialize; + + memset(g_Eeprom, 0, WIIMOTE_EEPROM_SIZE); + memcpy(g_Eeprom, EepromData_0, sizeof(EepromData_0)); + memcpy(g_Eeprom + 0x16D0, EepromData_16D0, sizeof(EepromData_16D0)); +} + +extern "C" void Wiimote_DoState(void* ptr, int mode) { +} + +extern "C" void Wiimote_Shutdown(void) +{ +} + +extern "C" void Wiimote_Output(const void* _pData, u32 _Size) { + const u8* data = (const u8*)_pData; + // dump raw data + { + LOG(WIIMOTE, "Wiimote_Output"); + std::string Temp; + for (u32 j=0; j<_Size; j++) + { + char Buffer[128]; + sprintf(Buffer, "%02x ", data[j]); + Temp.append(Buffer); + } + LOG(WIIMOTE, " Data: %s", Temp.c_str()); + } + + hid_packet* hidp = (hid_packet*) data; + + if(hidp->type == HID_TYPE_SET_REPORT && + hidp->param == HID_PARAM_OUTPUT) + { + HidOutputReport((wm_report*)hidp->data); + } else { + PanicAlert("HidOutput: Unknown type 0x%02x", data[0]); + } +} + +extern "C" unsigned int Wiimote_GetAttachedControllers() { + return 1; +} + +//****************************************************************************** +// Subroutines +//****************************************************************************** +void HidOutputReport(wm_report* sr) { + LOG(WIIMOTE, " HidOutputReport(0x%02x)", sr->channel); + + switch(sr->channel) + { + case WM_LEDS: + WmLeds((wm_leds*)sr->data); + break; + case WM_READ_DATA: + WmReadData((wm_read_data*)sr->data); + break; + case WM_REQUEST_STATUS: + WmRequestStatus((wm_request_status*)sr->data); + break; + case WM_IR_PIXEL_CLOCK: + case WM_IR_LOGIC: + LOG(WIIMOTE, " IR Enable 0x%02x 0x%02x", sr->channel, sr->data[0]); + break; + case WM_WRITE_DATA: + WmWriteData((wm_write_data*)sr->data); + break; + case WM_DATA_REPORTING: + WmDataReporting((wm_data_reporting*)sr->data); + break; + + default: + PanicAlert("HidOutputReport: Unknown channel 0x%02x", sr->channel); + return; + } +} + +void WmLeds(wm_leds* leds) { + LOG(WIIMOTE, " Set LEDs"); + LOG(WIIMOTE, " Leds: %x", leds->leds); + LOG(WIIMOTE, " Rumble: %x", leds->rumble); + + g_Leds = leds->leds; +} + +void WmDataReporting(wm_data_reporting* dr) { + LOG(WIIMOTE, " Set Data reporting mode"); + LOG(WIIMOTE, " Continuous: %x", dr->continuous); + LOG(WIIMOTE, " Rumble: %x", dr->rumble); + LOG(WIIMOTE, " Mode: 0x%02x", dr->mode); + + if(dr->mode == 0x33) + SendReportCoreAccelIr12(); + else if(dr->mode == 0x31) + SendReportCoreAccel(); +} + +void SendReportCoreAccelIr12() { + u8 DataFrame[1024]; + u32 Offset = WriteWmReport(DataFrame, WM_REPORT_CORE_ACCEL_IR12); + + wm_report_core_accel_ir12* pReport = (wm_report_core_accel_ir12*)(DataFrame + Offset); + Offset += sizeof(wm_report_core_accel_ir12); + memset(pReport, 0, sizeof(wm_report_core_accel_ir12)); + memset(pReport->ir, 0xFF, sizeof(pReport->ir)); + pReport->c.b = 1; + pReport->a.x = 0x81; + pReport->a.y = 0x78; + pReport->a.z = 0xD9; + pReport->ir[0].x = 320 & 0xFF; + pReport->ir[0].y = 240; + pReport->ir[0].size = 10; + pReport->ir[0].xHi = 320 >> 8; + pReport->ir[0].yHi = 0; + + LOG(WIIMOTE, " SendReportCoreAccelIr12()"); + + g_WiimoteInitialize.pWiimoteInput(DataFrame, Offset); +} + +void SendReportCoreAccel() { + u8 DataFrame[1024]; + u32 Offset = WriteWmReport(DataFrame, WM_REPORT_CORE_ACCEL); + + wm_report_core_accel* pReport = (wm_report_core_accel*)(DataFrame + Offset); + Offset += sizeof(wm_report_core_accel); + memset(pReport, 0, sizeof(wm_report_core_accel)); + pReport->c.a = 1; + pReport->a.x = 0x82; + pReport->a.y = 0x75; + pReport->a.z = 0xD6; + + LOG(WIIMOTE, " SendReportCoreAccel()"); + + g_WiimoteInitialize.pWiimoteInput(DataFrame, Offset); +} + +void WmReadData(wm_read_data* rd) { + u32 address = convert24bit(rd->address); + u16 size = convert16bit(rd->size); + LOG(WIIMOTE, " Read data"); + LOG(WIIMOTE, " Address space: %x", rd->space); + LOG(WIIMOTE, " Address: 0x%06x", address); + LOG(WIIMOTE, " Size: 0x%04x", size); + LOG(WIIMOTE, " Rumble: %x", rd->rumble); + + if(size <= 16 && rd->space == 0) { + SendReadDataReply(g_Eeprom, address, (u8)size); + } else { + PanicAlert("WmReadData: unimplemented parameters!"); + } +} + +void WmWriteData(wm_write_data* wd) { + u32 address = convert24bit(wd->address); + LOG(WIIMOTE, " Write data"); + LOG(WIIMOTE, " Address space: %x", wd->space); + LOG(WIIMOTE, " Address: 0x%06x", address); + LOG(WIIMOTE, " Size: 0x%02x", wd->size); + LOG(WIIMOTE, " Rumble: %x", wd->rumble); + + if(wd->size <= 16 && wd->space == WM_SPACE_EEPROM) + { + if(address + wd->size > WIIMOTE_EEPROM_SIZE) { + PanicAlert("WmWriteData: address + size out of bounds!"); + return; + } + memcpy(g_Eeprom + address, wd->data, wd->size); + SendWriteDataReply(); + } + else if(wd->size <= 16 && (wd->space == WM_SPACE_REGS1 || wd->space == WM_SPACE_REGS2)) + { + u8* block; + u32 blockSize; + switch((address >> 16) & 0xFE) { + case 0xA2: + block = g_RegSpeaker; + blockSize = WIIMOTE_REG_SPEAKER_SIZE; + break; + case 0xA4: + block = g_RegExt; + blockSize = WIIMOTE_REG_EXT_SIZE; + break; + case 0xB0: + block = g_RegIr; + blockSize = WIIMOTE_REG_IR_SIZE; + break; + default: + PanicAlert("WmWriteData: bad register block!"); + return; + } + address &= 0xFFFF; + if(address + wd->size > blockSize) { + PanicAlert("WmWriteData: address + size out of bounds!"); + return; + } + memcpy(block + address, wd->data, wd->size); + SendWriteDataReply(); + } else { + PanicAlert("WmWriteData: unimplemented parameters!"); + } +} + +void SendWriteDataReply() { + u8 DataFrame[1024]; + u32 Offset = WriteWmReport(DataFrame, WM_WRITE_DATA_REPLY); + + LOG(WIIMOTE, " SendWriteDataReply()"); + + g_WiimoteInitialize.pWiimoteInput(DataFrame, Offset); +} + +int WriteWmReport(u8* dst, u8 channel) { + u32 Offset = 0; + hid_packet* pHidHeader = (hid_packet*)(dst + Offset); + Offset += sizeof(hid_packet); + pHidHeader->type = HID_TYPE_DATA; + pHidHeader->param = HID_PARAM_INPUT; + + wm_report* pReport = (wm_report*)(dst + Offset); + Offset += sizeof(wm_report); + pReport->channel = channel; + return Offset; +} + +void WmRequestStatus(wm_request_status* rs) { + LOG(WIIMOTE, " Request Status"); + LOG(WIIMOTE, " Rumble: %x", rs->rumble); + + //SendStatusReport(); + u8 DataFrame[1024]; + u32 Offset = WriteWmReport(DataFrame, WM_STATUS_REPORT); + + wm_status_report* pStatus = (wm_status_report*)(DataFrame + Offset); + Offset += sizeof(wm_status_report); + memset(pStatus, 0, sizeof(wm_status_report)); + pStatus->leds = g_Leds; + pStatus->ir = 1; + pStatus->battery = 100; //arbitrary number + + LOG(WIIMOTE, " SendStatusReport()"); + LOG(WIIMOTE, " Flags: 0x%02x", pStatus->padding1[2]); + LOG(WIIMOTE, " Battery: %d", pStatus->battery); + + g_WiimoteInitialize.pWiimoteInput(DataFrame, Offset); +} + +void SendReadDataReply(void* _Base, u16 _Address, u8 _Size) +{ + u8 DataFrame[1024]; + u32 Offset = WriteWmReport(DataFrame, WM_READ_DATA_REPLY); + + _dbg_assert_(WIIMOTE, _Size <= 16); + + 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 = _Size - 1; + pReply->address = Common::swap16(_Address); + memcpy(pReply->data, _Base, _Size); + if(_Size < 16) { + memset(pReply->data + _Size, 0, 16 - _Size); + } + + LOG(WIIMOTE, " SendReadDataReply()"); + LOG(WIIMOTE, " Buttons: 0x%04x", pReply->buttons); + LOG(WIIMOTE, " Error: 0x%x", pReply->error); + LOG(WIIMOTE, " Size: 0x%x", pReply->size); + LOG(WIIMOTE, " Address: 0x%04x", pReply->address); + + g_WiimoteInitialize.pWiimoteInput(DataFrame, Offset); +} diff --git a/Source/Plugins/Plugin_Wiimote_Test/Src/main.cpp b/Source/Plugins/Plugin_Wiimote_Test/Src/main.cpp deleted file mode 100644 index 65b172b8c1..0000000000 --- a/Source/Plugins/Plugin_Wiimote_Test/Src/main.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include - -#include "pluginspecs_wiimote.h" - -SWiimoteInitialize g_WiimoteInitialize; -#define VERSION_STRING "0.1" - - -void GetDllInfo (PLUGIN_INFO* _PluginInfo) -{ - _PluginInfo->Version = 0x0100; - _PluginInfo->Type = PLUGIN_TYPE_WIIMOTE; -#ifdef DEBUGFAST - sprintf(_PluginInfo->Name, "Wiimote Test (DebugFast) " VERSION_STRING); -#else -#ifndef _DEBUG - sprintf(_PluginInfo->Name, "Wiimote Test " VERSION_STRING); -#else - sprintf(_PluginInfo->Name, "Wiimote Test (Debug) " VERSION_STRING); -#endif -#endif -} - - -void DllAbout(HWND _hParent) -{ - wxAboutDialogInfo info; - info.AddDeveloper(_T("masken (masken3@gmail.com)")); - info.SetDescription(_T("Wiimote test plugin")); - wxAboutBox(info); -} - -void DllConfig(HWND _hParent) -{ -} - - -void Wiimote_Initialize(SWiimoteInitialize* _pWiimoteInitialize) -{ - if (_pWiimoteInitialize == NULL) - return; - - g_WiimoteInitialize = *_pWiimoteInitialize; -} - -void Wiimote_DoState(unsigned char **ptr, int mode) { -} - -void Wiimote_Shutdown(void) -{ -} - -void Wiimote_Output(const void* _pData, u32 _Size) { -} - -unsigned int Wiimote_GetAttachedControllers() { - return 1; -} diff --git a/Source/Plugins/Plugin_Wiimote_Test/Src/wiimote_hid.h b/Source/Plugins/Plugin_Wiimote_Test/Src/wiimote_hid.h new file mode 100644 index 0000000000..0175a1c6b3 --- /dev/null +++ b/Source/Plugins/Plugin_Wiimote_Test/Src/wiimote_hid.h @@ -0,0 +1,168 @@ +#ifndef WIIMOTE_HID_H +#define WIIMOTE_HID_H + +#include + +#ifdef _MSC_VER +#pragma warning(disable:4200) +#pragma pack(push, 1) +#endif + +//source: HID_010_SPC_PFL/1.0 (official HID specification) + +struct hid_packet { + u8 param : 4; + u8 type : 4; + u8 data[0]; +}; + +#define HID_TYPE_SET_REPORT 5 +#define HID_TYPE_DATA 0xA + +#define HID_TYPE_HANDSHAKE 0 +#define HID_HANDSHAKE_SUCCESS 0 +#define HID_HANDSHAKE_WIIMOTE 8 //custom, reserved in HID specs. + +#define HID_PARAM_INPUT 1 +#define HID_PARAM_OUTPUT 2 + +//source: http://wiibrew.org/wiki/Wiimote + +struct wm_report { + u8 channel; + u8 data[0]; +}; + +#define WM_LEDS 0x11 +struct wm_leds { + u8 rumble : 1; + u8 : 3; + u8 leds : 4; +}; + +#define WM_DATA_REPORTING 0x12 +struct wm_data_reporting { + u8 rumble : 1; + u8 continuous : 1; + u8 : 6; + u8 mode; +}; + +#define WM_IR_PIXEL_CLOCK 0x13 +#define WM_IR_LOGIC 0x1A + +#define WM_REQUEST_STATUS 0x15 +struct wm_request_status { + u8 rumble : 1; + u8 : 7; +}; + +#define WM_STATUS_REPORT 0x20 +struct wm_status_report { + u8 padding1[2]; + u8 unknown : 1; + u8 extension : 1; + u8 speaker : 1; + u8 ir : 1; + u8 leds : 4; + u8 padding2[2]; + u8 battery; +}; + +#define WM_WRITE_DATA 0x16 +struct wm_write_data { + u8 rumble : 1; + u8 space : 2; //see WM_SPACE_* + u8 : 5; + u8 address[3]; + u8 size; + u8 data[16]; +}; + +#define WM_WRITE_DATA_REPLY 0x22 //empty, afaik + +#define WM_READ_DATA 0x17 +struct wm_read_data { + u8 rumble : 1; + u8 space : 2; //see WM_SPACE_* + u8 : 5; + u8 address[3]; + u8 size[2]; +}; + +#define WM_SPACE_EEPROM 0 +#define WM_SPACE_REGS1 1 +#define WM_SPACE_REGS2 2 +#define WM_SPACE_INVALID 3 + +#define WM_READ_DATA_REPLY 0x21 +struct wm_read_data_reply { + u16 buttons; + u8 error : 4; //see WM_RDERR_* + u8 size : 4; + u16 address; + u8 data[16]; +}; + +#define WM_RDERR_WOREG 7 +#define WM_RDERR_NOMEM 8 + +struct wm_core { + u8 left : 1; + u8 right : 1; + u8 down : 1; + u8 up : 1; + u8 plus : 1; + u8 : 3; + u8 two : 1; + u8 one : 1; + u8 b : 1; + u8 a : 1; + u8 minus : 1; + u8 : 2; + u8 home : 1; +}; + +struct wm_accel { + u8 x, y, z; +}; + +//filled with 0xFF if empty +struct wm_ir_extended { + u8 x; + u8 y; + u8 size : 4; + u8 xHi : 2; + u8 yHi : 2; +}; + +#define WM_REPORT_CORE 0x30 + +#define WM_REPORT_CORE_ACCEL 0x31 +struct wm_report_core_accel { + wm_core c; + wm_accel a; +}; + +#define WM_REPORT_CORE_EXT8 0x32 + +#define WM_REPORT_CORE_ACCEL_IR12 0x33 +struct wm_report_core_accel_ir12 { + wm_core c; + wm_accel a; + wm_ir_extended ir[4]; +}; + +#define WM_REPORT_CORE_EXT19 0x34 +#define WM_REPORT_CORE_ACCEL_EXT16 0x35 +#define WM_REPORT_CORE_IR10_EXT9 0x36 +#define WM_REPORT_CORE_ACCEL_IR10_EXT6 0x37 +#define WM_REPORT_EXT21 0x3d +#define WM_REPORT_INTERLEAVE1 0x3e +#define WM_REPORT_INTERLEAVE2 0x3f + +#if defined(_MSC_VER) +#pragma pack(pop) +#endif + +#endif //WIIMOTE_HID_H