summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorayuanx <ayuanx@gmail.com>2009-11-24 17:10:38 +0000
committerayuanx <ayuanx@gmail.com>2009-11-24 17:10:38 +0000
commit29774c35e8a4077cad3a2db01e657ada96fc906b (patch)
tree993c051dbd3783a99395a4359a788d0dd50b83e6 /Source
parent6a46befc2aa419a9c0527f52cdced3fd3adfae0e (diff)
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
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Common/Src/ChunkFile.h41
-rw-r--r--Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp63
-rw-r--r--Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.h14
-rw-r--r--Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp8
-rw-r--r--Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp154
-rw-r--r--Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h24
-rw-r--r--Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp4
-rw-r--r--Source/Plugins/Plugin_Wiimote/Src/EmuDynamics.cpp2
-rw-r--r--Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp4
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<class T>
- void Do(std::map<unsigned int, T> &x) {
+ void Do(std::map<unsigned int, T> &x)
+ {
// TODO
PanicAlert("Do(map<>) does not yet work.");
}
-
+
+ void Do(std::map<unsigned int, std::string> &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<unsigned int, std::string>::iterator itr = x.begin();
+ while (number > 0)
+ {
+ Do(itr->first);
+ Do(itr->second);
+ --number;
+ ++itr;
+ }
+ }
+ break;
+ }
+ }
+
// Store vectors.
template<class T>
void Do(std::vector<T> &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<u32, IWII_IPC_HLE_Device*> TDeviceMap;
TDeviceMap g_DeviceMap;
// STATE_TO_SAVE
+typedef std::map<u32, std::string> 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_LastCmd<m_WiiMotes.size())
+ if(m_LastCmd < m_WiiMotes.size())
{
SendEventLinkKeyNotification(m_WiiMotes[m_LastCmd]);
m_LastCmd++;
@@ -1900,6 +1957,9 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandDisconnect(u8* _Input)
CWII_IPC_HLE_WiiMote* pWiimote = AccessWiiMote(pDiscon->con_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;