From 29774c35e8a4077cad3a2db01e657ada96fc906b Mon Sep 17 00:00:00 2001 From: ayuanx Date: Tue, 24 Nov 2009 17:10:38 +0000 Subject: [PATCH] My first commit :) Fixed more memory leaks when doing state load. Now all file devices(handles) are stored in state, and this will fix some crash after loading state. Warning: Do NOT Save/Load state before game title is shown and controllable, or else you will get a corrupt state. If you encounter "Emu WiiMote Desync" frequently, please report the condition (PS: To recover from wiimote desync, just load a saved state) git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4608 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Common/Src/ChunkFile.h | 41 ++++- Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp | 63 +++++-- Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.h | 14 ++ .../Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp | 8 + .../Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp | 154 ++++++++++++------ .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h | 24 ++- .../IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp | 4 +- .../Plugin_Wiimote/Src/EmuDynamics.cpp | 2 +- .../Plugins/Plugin_Wiimote/Src/FillReport.cpp | 4 +- 9 files changed, 239 insertions(+), 75 deletions(-) diff --git a/Source/Core/Common/Src/ChunkFile.h b/Source/Core/Common/Src/ChunkFile.h index 706b0d7be9..00b50b4a8d 100644 --- a/Source/Core/Common/Src/ChunkFile.h +++ b/Source/Core/Common/Src/ChunkFile.h @@ -74,13 +74,48 @@ public: (*ptr) += size; } - // Store maps to file. Very useful. template - void Do(std::map &x) { + void Do(std::map &x) + { // TODO PanicAlert("Do(map<>) does not yet work."); } - + + void Do(std::map &x) + { + unsigned int number = (unsigned int)x.size(); + Do(number); + switch (mode) { + case MODE_READ: + { + x.clear(); + while (number > 0) + { + unsigned int first; + Do(first); + std::string second; + Do(second); + x[first] = second; + --number; + } + } + break; + case MODE_WRITE: + case MODE_MEASURE: + { + std::map::iterator itr = x.begin(); + while (number > 0) + { + Do(itr->first); + Do(itr->second); + --number; + ++itr; + } + } + break; + } + } + // Store vectors. template void Do(std::vector &x) { diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp index 91e111f138..fe0d1837cf 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp @@ -74,6 +74,9 @@ typedef std::map TDeviceMap; TDeviceMap g_DeviceMap; // STATE_TO_SAVE +typedef std::map TFileNameMap; +TFileNameMap g_FileNameMap; + u32 g_LastDeviceID = 0x13370000; std::string g_DefaultContentFile; @@ -85,16 +88,15 @@ void Init() void Reset() { - // AyuanX: We really should save this to state or build the map and devices statically - // Mem dynamic allocation is too risky when doing state save/load TDeviceMap::const_iterator itr = g_DeviceMap.begin(); while (itr != g_DeviceMap.end()) { - if (itr->second) + if(itr->second) delete itr->second; ++itr; } - g_DeviceMap.clear(); + g_DeviceMap.clear(); + g_FileNameMap.clear(); } void Shutdown() @@ -130,8 +132,6 @@ IWII_IPC_HLE_Device* AccessDeviceByID(u32 _ID) return g_DeviceMap[_ID]; // ID = 0 just means it hasn't been created yet - _dbg_assert_msg_(WII_IPC, _ID == 0, "IOP tries to access an unknown device 0x%x", _ID); - return NULL; } @@ -231,7 +231,7 @@ IWII_IPC_HLE_Device* CreateDevice(u32 _DeviceID, const std::string& _rDeviceName // Let the game read the setting.txt file -void CopySettingsFile(std::string DeviceName) +void CopySettingsFile(std::string& DeviceName) { std::string Source = File::GetSysDirectory() + WII_SYS_DIR + DIR_SEP; if(Core::GetStartupParameter().bNTSC) @@ -259,14 +259,43 @@ void CopySettingsFile(std::string DeviceName) void DoState(PointerWrap &p) { p.Do(g_LastDeviceID); - //p.Do(g_DefaultContentFile); + p.Do(g_DefaultContentFile); - // AyuanX: I think maybe we really should create devices statically at initilization + // AyuanX: I think we should seperate hardware from file handle + // and create hardware at initilization instead of runtime allocation when first accessed IWII_IPC_HLE_Device* pDevice = AccessDeviceByID(GetDeviceIDByName(std::string("/dev/usb/oh1/57e/305"))); if (pDevice) pDevice->DoState(p); else - PanicAlert("WII_IPC_HLE: Save/Load State failed, /dev/usb/oh1/57e/305 doesn't exist!"); + PanicAlert("WII_IPC_HLE: Save/Load State failed, Device /dev/usb/oh1/57e/305 doesn't exist!"); + + // Let's just hope hardware device IDs are constant throughout the game + // If there is any ID overlapping between hardware IDs and file IDs, we are dead + if (p.GetMode() == PointerWrap::MODE_READ) + { + // Delete file Handles + TFileNameMap::const_iterator itr = g_FileNameMap.begin(); + while (itr != g_FileNameMap.end()) + { + delete g_DeviceMap[itr->first]; + g_DeviceMap.erase(itr->first); + ++itr; + } + // Load file names + p.Do(g_FileNameMap); + // Rebuild file handles + itr = g_FileNameMap.begin(); + while (itr != g_FileNameMap.end()) + { + g_DeviceMap[itr->first] = new CWII_IPC_HLE_Device_FileIO(itr->first, itr->second); + ++itr; + } + } + else + { + p.Do(g_FileNameMap); + } + } void ExecuteCommand(u32 _Address) @@ -307,15 +336,16 @@ void ExecuteCommand(u32 _Address) g_LastDeviceID++; CmdSuccess = pDevice->Open(_Address, Mode); - if(pDevice->GetDeviceName().find("/dev/") == std::string::npos - || pDevice->GetDeviceName().c_str() == std::string("/dev/fs")) - { - INFO_LOG(WII_IPC_FILEIO, "IOP: Open (Device=%s, DeviceID=%08x, Mode=%i, CmdSuccess=%i)", + if(pDevice->GetDeviceName().find("/dev/") == std::string::npos) + // || pDevice->GetDeviceName().c_str() == std::string("/dev/fs")) + { + g_FileNameMap[CurrentDeviceID] = DeviceName; + INFO_LOG(WII_IPC_FILEIO, "IOP: Open File (Device=%s, DeviceID=%08x, Mode=%i, CmdSuccess=%i)", pDevice->GetDeviceName().c_str(), CurrentDeviceID, Mode, (int)CmdSuccess); } else { - INFO_LOG(WII_IPC_HLE, "IOP: Open (Device=%s, DeviceID=%08x, Mode=%i)", + INFO_LOG(WII_IPC_HLE, "IOP: Open Device (Device=%s, DeviceID=%08x, Mode=%i)", pDevice->GetDeviceName().c_str(), CurrentDeviceID, Mode); } } @@ -438,7 +468,10 @@ void ExecuteCommand(u32 _Address) ERROR_LOG(WII_IPC_HLE, "IOP: Reply to unknown device ID (DeviceID=%i)", DeviceID); if (ClosedDeviceID > 0 && (ClosedDeviceID == DeviceID)) + { DeleteDeviceByID(DeviceID); + g_FileNameMap.erase(DeviceID); + } } } else diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.h index 6941eb0238..626e0b8f34 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.h @@ -20,6 +20,8 @@ #include "ChunkFile.h" +class IWII_IPC_HLE_Device; + namespace WII_IPC_HLE_Interface { // Init @@ -31,12 +33,24 @@ void Shutdown(); // Reset void Reset(); +void DeleteDeviceByID(u32 ID); + +u32 GetDeviceIDByName(const std::string& _rDeviceName); + +IWII_IPC_HLE_Device* AccessDeviceByID(u32 _ID); + +void DeleteDeviceByID(u32 _ID); + +IWII_IPC_HLE_Device* CreateDevice(u32 _DeviceID, const std::string& _rDeviceName); + // Do State void DoState(PointerWrap &p); // Set default content file void SetDefaultContentFile(const std::string& _rFilename); +void CopySettingsFile(std::string& DeviceName); + // Update void Update(); diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp index 32e8282cfe..65d3206376 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp @@ -411,6 +411,14 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32 ERROR_LOG(WII_IPC_DVD, "DVDLowAudioBufferConfig"); break; + // New Super Mario Bros.Wii sends these cmds + // but it seems we don't need to implement anything + case 0x95: + case 0x96: + WARN_LOG(WII_IPC_DVD, "unimplemented cmd 0x%08x (Buffer 0x%08x, 0x%x)", + Command, _BufferOut, _BufferOutSize); + break; + default: ERROR_LOG(WII_IPC_DVD, "unknown cmd 0x%08x (Buffer 0x%08x, 0x%x)", Command, _BufferOut, _BufferOutSize); diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp index 494d99003b..e7137da403 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp @@ -38,8 +38,9 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305::CWII_IPC_HLE_Device_usb_oh1_57e_305(u32 _De , m_HostNumACLPackets(0) , m_HostNumSCOPackets(0) , m_HCIBuffer(NULL) + , m_HCIPool(0) , m_ACLBuffer(NULL) - , m_ACLFrame(0) + , m_ACLPool(0) , m_LastCmd(NULL) , m_PacketCount(0) { @@ -63,7 +64,9 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305::CWII_IPC_HLE_Device_usb_oh1_57e_305(u32 _De } CWII_IPC_HLE_Device_usb_oh1_57e_305::~CWII_IPC_HLE_Device_usb_oh1_57e_305() -{} +{ + m_WiiMotes.clear(); +} void CWII_IPC_HLE_Device_usb_oh1_57e_305::DoState(PointerWrap &p) { @@ -71,8 +74,9 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::DoState(PointerWrap &p) p.Do(m_PacketCount); p.Do(m_CtrlSetup); p.Do(m_HCIBuffer); + p.Do(m_HCIPool); p.Do(m_ACLBuffer); - p.Do(m_ACLFrame); + p.Do(m_ACLPool); } // =================================================== @@ -138,7 +142,7 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::IOCtlV(u32 _CommandAddress) // check termination _dbg_assert_msg_(WII_IPC_WIIMOTE, *(u8*)Memory::GetPointer(CommandBuffer.InBuffer[5].m_Address) == 0, "WIIMOTE: Termination != 0"); - + #if defined(_DEBUG) || defined(DEBUGFAST) DEBUG_LOG(WII_IPC_WIIMOTE, "USB_IOCTL_CTRLMSG (0x%08x) - execute command", _CommandAddress); DEBUG_LOG(WII_IPC_WIIMOTE, " bRequestType: 0x%x", m_CtrlSetup.bRequestType); DEBUG_LOG(WII_IPC_WIIMOTE, " bRequest: 0x%x", m_CtrlSetup.bRequest); @@ -147,6 +151,7 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::IOCtlV(u32 _CommandAddress) DEBUG_LOG(WII_IPC_WIIMOTE, " wLength: 0x%x", m_CtrlSetup.wLength); DEBUG_LOG(WII_IPC_WIIMOTE, " m_PayLoadAddr: 0x%x", m_CtrlSetup.m_PayLoadAddr); DEBUG_LOG(WII_IPC_WIIMOTE, " m_PayLoadSize: 0x%x", m_CtrlSetup.m_PayLoadSize); + #endif ExecuteHCICommandMessage(m_CtrlSetup); // Replies are generated inside @@ -177,9 +182,9 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::IOCtlV(u32 _CommandAddress) SendToDevice(pACLHeader->ConnectionHandle, Memory::GetPointer(BulkBuffer.m_buffer + 4), pACLHeader->Size); m_PacketCount++; - // If ACLFrame is not used, we can send a reply immediately + // If ACLPool is not used, we can send a reply immediately // or else we have to delay this reply - if (m_ACLFrame.m_number == 0) + if (m_ACLPool.m_number == 0) _SendReply = true; } break; @@ -279,10 +284,9 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendToDevice(u16 _ConnectionHandle, u8 // The header is for example 07 00 41 00 which means size 0x0007 and channel 0x0041. // --------------------------------------------------- - // AyuanX: Basically, our WII_IPC_HLE is efficient enough to send the packet immediately // rather than enqueue it to some other memory -// But...the only exception is the Wiimote_Plugin +// But...the only exception comes from the Wiimote_Plugin // void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendACLPacket(u16 _ConnectionHandle, u8* _pData, u32 _Size) { @@ -308,48 +312,49 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendACLPacket(u16 _ConnectionHandle, u // Invalidate ACL buffer m_ACLBuffer.m_address = NULL; m_ACLBuffer.m_buffer = NULL; - m_ACLFrame.m_number = 0; + } + else if ((sizeof(UACLHeader) + _Size) > 64 ) + { + ERROR_LOG(WII_IPC_HLE, "ACL Packet size is too big! (>64B)"); + PanicAlert("WII_IPC_HLE: ACL Packet size is too big! (>64B)"); + } + else if (m_ACLPool.m_number >= 16) + { + ERROR_LOG(WII_IPC_HLE, "ACL Pool is full, something must be wrong!"); + PanicAlert("WII_IPC_HLE: ACL Pool is full, something must be wrong!"); } else { - // Actually this temp storage is not quite necessary - // the whole WII_IPC (HLE+USB+BT) won't need it - // but current implementation of WiiMote_Plugin has ruined everything - // although I can fix the Eme_WiiMote but that requires a little change of the plugin spec - // so unless somebody who works on the Real_WiiMote agrees, I won't do that - // - UACLHeader* pHeader = (UACLHeader*)(m_ACLFrame.m_data + m_ACLFrame.m_number * 64); // I belive 64B is enough + UACLHeader* pHeader = (UACLHeader*)(m_ACLPool.m_data + m_ACLPool.m_number * 64); // I belive 64B is enough pHeader->ConnectionHandle = _ConnectionHandle; pHeader->BCFlag = 0; pHeader->PBFlag = 2; pHeader->Size = _Size; memcpy((u8*)pHeader + sizeof(UACLHeader), _pData, _Size); - m_ACLFrame.m_number++; - - if (m_ACLFrame.m_number > 16) - { - ERROR_LOG(WII_IPC_WIIMOTE, "ACL Frame is full, something must be wrong!"); - PanicAlert("WII_IPC_WIIMOTE: ACL Frame is full, something must be wrong!"); - } + m_ACLPool.m_number++; } } -// AyuanX: this ugly function is only useful when there are -// multiple L2CAP packets come from WiiMote_Plugin in one cycle +// The normal hardware behavior is like this: +// e.g. if you have 3 packets to send you have to send them one by one in 3 cycles +// and this is the mechanism how our IPC works +// but current implementation of WiiMote_Plugin doesn't comply with this rule +// It acts like sending all the 3 packets in one cycle and idling around in the other two cycles +// that's why we need this contingent ACL pool // -void CWII_IPC_HLE_Device_usb_oh1_57e_305::PurgeACLFrame() +void CWII_IPC_HLE_Device_usb_oh1_57e_305::PurgeACLPool() { if(m_ACLBuffer.m_address == NULL) return; - INFO_LOG(WII_IPC_WIIMOTE, "Purging ACL Frame: 0x%08x ....", m_ACLBuffer.m_address); + INFO_LOG(WII_IPC_WIIMOTE, "Purging ACL Pool: 0x%08x ....", m_ACLBuffer.m_address); - if(m_ACLFrame.m_number > 0) + if(m_ACLPool.m_number > 0) { - m_ACLFrame.m_number--; + m_ACLPool.m_number--; // Fill the buffer - u8* _Address = m_ACLFrame.m_data + m_ACLFrame.m_number * 64; + u8* _Address = m_ACLPool.m_data + m_ACLPool.m_number * 64; memcpy(Memory::GetPointer(m_ACLBuffer.m_buffer), _Address, 64); // Write the packet size as return value Memory::Write_U32(sizeof(UACLHeader) + ((UACLHeader*)_Address)->Size, m_ACLBuffer.m_address + 0x4); @@ -366,6 +371,15 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::PurgeACLFrame() // ---------------- u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update() { + // Check if HCI Pool is not purged + if (m_HCIPool.m_number > 0) + { + PurgeHCIPool(); + if (m_HCIPool.m_number == 0) + WII_IPCInterface::EnqReply(m_CtrlSetup.m_Address); + return true; + } + // Check if last command needs more work if (m_HCIBuffer.m_address && m_LastCmd) { @@ -373,11 +387,11 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update() return true; } - // Check if temp ACL frame is not purged - if (m_ACLFrame.m_number > 0) + // Check if ACL Pool is not purged + if (m_ACLPool.m_number > 0) { - PurgeACLFrame(); - if (m_ACLFrame.m_number == 0) + PurgeACLPool(); + if (m_ACLPool.m_number == 0) WII_IPCInterface::EnqReply(m_CtrlSetup.m_Address); return true; } @@ -427,14 +441,15 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update() } } - // AyuanX: This event should be sent periodically or WiiMote will desync automatically - // but not too many or it will jam the bus and cost extra CPU time + // AyuanX: This event should be sent periodically after ACL connection is accepted + // or CPU will disconnect WiiMote automatically + // but don't send too many or it will jam the bus and cost extra CPU time // static u32 FreqDividerSync = 0; - if (m_HCIBuffer.m_address && !WII_IPCInterface::GetAddress() && m_WiiMotes[0].IsLinked()) + if (m_HCIBuffer.m_address && !WII_IPCInterface::GetAddress() && m_WiiMotes[0].IsConnected()) { FreqDividerSync++; - if ((m_PacketCount >0) || (FreqDividerSync > 15)) // Feel free to tweak it + if ((m_PacketCount > 0) || (FreqDividerSync > 30)) // Feel free to tweak it { FreqDividerSync = 0; SendEventNumberOfCompletedPackets(m_WiiMotes[0].GetConnectionHandle(), m_PacketCount); @@ -453,7 +468,7 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update() if (m_ACLBuffer.m_address && !WII_IPCInterface::GetAddress() && !m_LastCmd && m_WiiMotes[0].IsLinked()) { FreqDividerMote++; - if(FreqDividerMote > 100) // Feel free to tweak it + if(FreqDividerMote > 99) // Feel free to tweak it { FreqDividerMote = 0; CPluginManager::GetInstance().GetWiimote(0)->Wiimote_Update(); @@ -474,6 +489,7 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update() // Our WII_IPC_HLE is so efficient that we could fill the buffer immediately // rather than enqueue it to some other memory and this will do good for StateSave +// void CWII_IPC_HLE_Device_usb_oh1_57e_305::AddEventToQueue(const SQueuedEvent& _event) { if (m_HCIBuffer.m_address != NULL) @@ -491,16 +507,54 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::AddEventToQueue(const SQueuedEvent& _e // Invalidate HCI buffer m_HCIBuffer.m_address = NULL; m_HCIBuffer.m_buffer = NULL; - - return; + } + else if (_event.m_size > 64) + { + ERROR_LOG(WII_IPC_HLE, "HCI Packet size too big! (>64B)"); + PanicAlert("WII_IPC_HLE: HCI Packet size too big! (>64B)"); + } + else if (m_HCIPool.m_number >= 16) + { + ERROR_LOG(WII_IPC_HLE, "HCI Pool is full, something must be wrong!"); + PanicAlert("WII_IPC_HLE: HCI Pool is full, something must be wrong!"); } else - { - ERROR_LOG(WII_IPC_WIIMOTE, "Sending HCI Packet failed, HCI Buffer is invald!"); - PanicAlert("WII_IPC_HLE_DEVICE_USB: Sending HCI Packet failed, HCI Buffer is invald!"); + { + memcpy(m_HCIPool.m_data + m_HCIPool.m_number * 64, _event.m_buffer, _event.m_size); + // HCI Packet doesn't contain size info inside, so we have to store it somewhere + m_HCIPool.m_size[m_HCIPool.m_number] = _event.m_size; + m_HCIPool.m_number++; } } +// Generally, CPU should send us a valid HCI buffer before issuing any HCI command +// but since we don't know the exact frequency at which IPC should be running +// so when IPC is running too fast that CPU can't catch up +// then CPU(actually it is the usb driver) sometimes throws out a command before sending us a HCI buffer +// So I put this contingent HCI Pool here until we figure out the true reason +// +void CWII_IPC_HLE_Device_usb_oh1_57e_305::PurgeHCIPool() +{ + if(m_HCIBuffer.m_address == NULL) + return; + + INFO_LOG(WII_IPC_WIIMOTE, "Purging HCI Pool: 0x%08x ....", m_HCIBuffer.m_address); + + if(m_HCIPool.m_number > 0) + { + m_HCIPool.m_number--; + // Fill the buffer + u8* _Address = m_HCIPool.m_data + m_HCIPool.m_number * 64; + memcpy(Memory::GetPointer(m_HCIBuffer.m_buffer), _Address, 64); + // Write the packet size as return value + Memory::Write_U32(m_HCIPool.m_size[m_HCIPool.m_number], m_HCIBuffer.m_address + 0x4); + // Send a reply to indicate ACL buffer is sent + WII_IPCInterface::EnqReply(m_HCIBuffer.m_address); + // Invalidate ACL buffer + m_HCIBuffer.m_address = NULL; + m_HCIBuffer.m_buffer = NULL; + } +} bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventCommandStatus(u16 _Opcode) { @@ -744,7 +798,10 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventLinkKeyNotification(const CWI DEBUG_LOG(WII_IPC_WIIMOTE, " bd: %02x:%02x:%02x:%02x:%02x:%02x", pEventLinkKey->bdaddr.b[0], pEventLinkKey->bdaddr.b[1], pEventLinkKey->bdaddr.b[2], pEventLinkKey->bdaddr.b[3], pEventLinkKey->bdaddr.b[4], pEventLinkKey->bdaddr.b[5]); + +#if MAX_LOGLEVEL >= DEBUG_LEVEL LOG_LinkKey(pEventLinkKey->LinkKey); +#endif return true; }; @@ -1247,9 +1304,9 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::ExecuteHCICommandMessage(const SHCICom break; } - if (m_LastCmd == NULL) + if ((m_LastCmd == NULL) && (m_HCIPool.m_number == 0)) { - // HCI command finished, send a reply to command + // If HCI command is finished and HCI pool is empty, send a reply to command WII_IPCInterface::EnqReply(_rHCICommandMessage.m_Address); } } @@ -1375,7 +1432,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadStoredLinkKey(u8* _Input) // generate link key // Let us have some fun :P - if(m_LastCmdcon_handle); if (pWiimote) pWiimote->EventDisconnect(); + + // Here we should enable scan so reconnect is possible + m_ScanEnable = 0x2; */ static bool OneShotMessage = true; 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 1787f0f890..07fae6b809 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 @@ -73,7 +73,8 @@ public: virtual u32 Update(); void SendACLPacket(u16 _ConnectionHandle, u8* _pData, u32 _Size); - void PurgeACLFrame(); + void PurgeACLPool(); + void PurgeHCIPool(); //hack for wiimote plugin @@ -120,12 +121,24 @@ private: u32 m_Address; }; - struct ACLFrame + struct ACLPool { u32 m_number; - u8 m_data[1024]; + u8 m_data[1024]; // Capacity: 64B x 16 - ACLFrame(int num) + ACLPool(int num) + : m_number(num) + { + } + }; + + struct HCIPool + { + u32 m_number; + u8 m_data[1024]; // Capacity: 64B x 16 + u8 m_size[16]; + + HCIPool(int num) : m_number(num) { } @@ -171,8 +184,9 @@ private: // STATE_TO_SAVE SHCICommandMessage m_CtrlSetup; CtrlBuffer m_HCIBuffer; + HCIPool m_HCIPool; CtrlBuffer m_ACLBuffer; - ACLFrame m_ACLFrame; + ACLPool m_ACLPool; u32 m_LastCmd; int m_PacketCount; diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp index 9a052a6118..6211448878 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp @@ -323,7 +323,7 @@ u8 CWII_IPC_HLE_Device_usb_kbd::m_KeyCodesAZERTY[256] = { 0x00, // Minus 0x36, // Period 0x37, // '/' - 0x34, // 'ù' + 0x34, // ' ' 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -331,7 +331,7 @@ u8 CWII_IPC_HLE_Device_usb_kbd::m_KeyCodesAZERTY[256] = { 0x2D, // ')' 0x32, // '\' 0x2F, // '^' - 0x00, // '²' + 0x00, // ' ' 0x38, // '!' 0x00, // Nothing interesting past this point. diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuDynamics.cpp b/Source/Plugins/Plugin_Wiimote/Src/EmuDynamics.cpp index b2f8c11703..6ce59d4fa8 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/EmuDynamics.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/EmuDynamics.cpp @@ -64,7 +64,7 @@ void TiltTest(u8 x, u8 y, u8 z) /* Angles adjustment for the upside down state when both roll and pitch is - used. When the absolute values of the angles go over 90° the Wiimote is + used. When the absolute values of the angles go over 90 the Wiimote is upside down and these adjustments are needed. */ void AdjustAngles(float &Roll, float &Pitch) { diff --git a/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp b/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp index 1efb8dbcef..a54e7a866a 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp @@ -432,7 +432,7 @@ void SingleShake(u8 &_y, u8 &_z, int i) /* Tilting Wiimote with gamepad. We can guess that the game will calculate a Wiimote pitch and use it as a measure of the tilting of the Wiimote. We are - interested in this tilting range 90?to -90?*/ + interested in this tilting range 90 to -90*/ void TiltWiimoteGamepad(float &Roll, float &Pitch) { // Return if we have no pads @@ -456,7 +456,7 @@ void TiltWiimoteGamepad(float &Roll, float &Pitch) float Tl = (float)_Tl; float Tr = (float)_Tr; - // Save the Range in degrees, 45?and 90?are good values in some games + // Save the Range in degrees, 45 and 90 are good values in some games float RollRange = (float)g_Config.Trigger.Range.Roll; float PitchRange = (float)g_Config.Trigger.Range.Pitch;